Оплата за допомогою додатку "Термінал"
З питань отримання ідентифікаторів зовнішніх сервісів, ключів для підпису, та адреси сервісу перевірки платежів звертатися:
Галушкін Максим Сергійович
E-mail: maksim.galushkin@privatbank.ua
1.Підготовка параметрів та підпис даних запитів
Для правильного формування запиту на любой з сервісів ( token.php чи check.php) потрібно до скрипта додвати параметри clid, signed, signature
url = {https://dio.privatbank.ua}
* - запит token/check
POST {url}/api/nfcpos/integrators/*.php?clid=test&signed=1476193110
&signature=2b3a694f0fe2574bd85edb0f5e723af013c089d9
Атрибут | Опис |
---|---|
clid | ідентифікатор зовнішнього сервісу, попередньо узгоджується і видається банком. Додається до адреси запиту. |
secret | ключ для підпису, видається разом з ідентифікатором зовнішнього сервісу |
signed | час відправлення запиту (кількість секунд, що минув з 1 січня 1970р 00: 00:00 GMT до моменту відправки запиту). Додається до адреси запиту |
signature | підпис сформований на основі параметтрів sercet, signed, data. Додається до адреси запиту. |
data | тіло запиту |
Параметр signature розраховується за формулою:
sha1( signed + secret + data + secret )
де:
secret - ключ для підпису, видається разом з ідентифікатором зовнішнього сервісу data - вміст тіла запиту
Параметри clid, signed, signature завжди передаються всередині url.
Приклад запиту
clid = test
secret = test
signed = 1697051765 (Wed Oct 11 2023 19:16:05 GMT+0000)
data = {"operation" : "pay" ,"amount":1.0, "purpose" : "test"}
POST https://dio.privatbank.ua/api/nfcpos/integrators/token.php?clid=test
&signed=1697051765&signature=0c19f9efae8ce89efb542bd52c88954a99496126
Content-Type: application/json
тіло запиту
{"operation" : "pay" ,"amount":1.0, "purpose" : "test"}
PHP приклад формування і підпісу праметрів запіту отрімання токену для операції Оплата
$clid = 'test';
$secret = 'abcdef';
//для тестування та перевірки
//в реальных запросах должно быть текущее в время серверв UTC в секундах
$signed = '1624023225'; // (для UTC 2021-06-18 13:33:45 +0000)
/***
Pay
*/
$params = array(
'operation' => 'pay',
'amount' => 3.33,
'purpose' => 'Test'
);
$data = json_encode($params);
//формирование подписи sha1( signed + secret + data + secret )
$signature = sha1( $signed . $secret . $data . $secret );
//значення після обчислення для перевірки
// signature=896e7808ed56bde0e3966b46b30688e0715bb439
$url = 'https://dio.privatbank.ua/api/nfcpos/integrators/token.php?clid='
.$clid . '&signed=' . $signed . '&signature=' . $signature;
$options = array( CURLOPT_HTTPHEADER => array( 'Content-Type' => 'application/json' ));
2.Сервіс токенізації операцій
Для взаємодії з платіжним застосунок Термінал та виконання фінансових операцій оплата/повернення необхідно використовувати API для отримання токенів. Залежно від типу виконуваної операції необхідно підготувати та передати у запиті відповідні параметри.
Коли клієнт надає агрегатору токен, то агрегатор має додати до тіла запита ще один параметр, під назвою "client_token".
Запрос отримання токену:
POST https://dio.privatbank.ua/api/nfcpos/integrators/token.php? clid= {ID компанії яка створює токен}&signed={ключ}&signature={значення хешу}
Параметри тіла запитів:
Оплата
{
"operation": "pay",
" amount": 3.33,
"purpose": "Test",
"client_token": "zgvIgAQ5jbXIsvDrAahW7MVKNXk7Tq1114SnG9UKYtyXTNZJD437xwmAnk4IYUyN"
}
Повернення
{
"operation": "refund",
" amount": 3.33,
"transaction_id": "Test",
"client_token": "zgvIgAQ5jbXIsvDrAahW7MVKNXk7Tq1114SnG9UKYtyXTNZJD437xwmAnk4IYUyN"
}
Формат вхідних параметрів
Параметр | Опис | Формат даних |
---|---|---|
operation | операція (pay/refund) | String |
amount | сума платежу/повернення (мінімальна сума для сплати 1.00 грн) | Double |
purpose | призначення платежу (заборонені сурогатні та “Other Symbol”) Поле для операції pay | String |
transaction_id | Ідентифікатор оригінальної платіжної транзакціїю Обов'язкове поле для операції refund | String |
client_token | Токен клієнта для якого потрібно створити токен для проведення операцій (pay або refund ). Якщо параметр не вказується то операційний токен (jwt) створюється для інтегратора, компанії, яка ініціює запит. | Stirng(64) |
Успішна відповідь
{
"success": true,
"rid": "b3e195e0eba6d921a95231cd78937d6a",
"jwt": "ey******kzMzZkOVGVzdCJ9.x-qLonr823cU2NK0ETJ1gaaUpmJ-WXov0",
"status": 200
}
Опис Вихідних параметрів
Параметр | Опис | Формат даних |
---|---|---|
success | признак успішної операції | boolean |
rid | ідентифікатор запита | string |
jwt | токен сформовааний для певної операції | sting( BASE64) |
status | код HTTP відповіді | int |
3.Виклик додатку "Термінал" для здійснення оплати (Android)
Після успішного отримання токена для фінансової операції
Приклад виклику та передачі параметрів
val jwtToken:String = "*****" //JWT токен операциії (П. 1)
val callback = "https://******" //callback
startTerminalApp(jwtToken: String, callback:String)
Формат параметрів
Параметр | Опис | Формат даних | Обов'язковий |
---|---|---|---|
jwtToken | JWT токен операциії (П. 1) | String | Так |
callback | callback зовнішньої інтеграційної системи для передачі події (успішного/неуспішного) завершення операції | String? | Ні |
Функція виклику додатку
const val DEEP_LINK_URL = "nfcterminal://executor"
private fun startTerminalApp(jwtToken: String, callback:String) {
val launchIntent =
packageManager.getLaunchIntentForPackage("ua.privatbank.pterminal")
if (launchIntent != null) {
val intent = Intent(Intent.ACTION_VIEW)
val jwtTokenEncode = URLEncoder.encode(jwtToken, "utf-8")
intent.data = Uri.parse(DEEP_LINK_URL+"?token=$jwtTokenEncode&callback=$callback")
try {
startTerminalForResult.launch(intent)
} catch (e: Exception) {
e.printStackTrace()
}
} else {
try {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("market://details?id=ua.privatbank.pterminal")
)
)
} catch (e: android.content.ActivityNotFoundException) {
try {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("https://play.google.com/store/apps/details?id=ua.privatbank.pterminal")
)
)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
Отримання та обробка результату
private val startTerminalForResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode == AppCompatActivity.RESULT_OK) {
val intent = result.data
if (intent != null) {
val tresult = intent.getStringExtra("result") //результат виконання операції
Log.d(TAG,"Intent Transaction result = $tresult")
binding.edResult.setText(tresult)
} else {
Log.d(TAG,"intent == NULL")
}
} else {
Log.d(TAG, "result != RESULT_OK")
}
}
Результат виконання операції повертається у форматі JSON
Формат відповіді
Атрибут | Опис | Формат даних |
---|---|---|
result | результат успішна / нi | Boolean (true/false) |
token | інтеграційний JWT токен | String |
operation_id | ідентифікатор операції | String |
date | дата та час проведення | String |
error | опис помилки | String |
{
"token": "eyJ0eXAiOiJKV1QiLCJhbG*******",
"date": "2022-07-13 16:30:50",
"error": "",
"operation_id": "PAX62cec9140b7052.60786725",
"result": true
}
4.Виклик додатку "Термінал" для здійснення оплати (iOS)
Після успішного отримання токена для фінансової операції.
Приклад виклику та передачі параметрів:
let jwtToken = "*****" // JWT токен операциії (П. 1)
let callback = "https://******/?id=unique_identifier" // буде виклакано по завершеню операції, id=unique_identifier як приклад ідентифікації операції
let terminalUrlScheme = "nfcterminal://executor"
let urlString = terminalUrlScheme + "?token=\(jwtToken)&callback=\(callbackUrl)"
if let url = URL(string: urlString) {
UIApplication.shared.open(url)
}
Формат параметрів
Параметр | Опис | Формат даних | Обов'язковий |
---|---|---|---|
jwtToken | JWT токен операциії (П. 1) | String | Так |
callback | callback зовнішньої інтеграційної системи для передачі події завершення операції | String | Так |
Для обробки виклику callback, застосунок може бути налаштовано одним із способів:
- universal links, наприклад "https://my.app.site/callback/result/?id=unique_identifier" Apple документація
- url scheme, наприклад "myappcallback://result?id=unique_identifier" Apple документація
Отримання та обробка результату відбуваєтся через Сервіс отримання інформації щодо операції
5.Сервіс отримання інформації щодо операції
Використовується для отримання результату операції, зробленої за допомогою додатку "Термінал"
POST [https://dio.privatbank.ua/api/nfcpos/integrators/check.php?**clid=**{ID клієнта}&signed={ключ}&signature={значення хешу}
Параметри операції
jwt - токен, отриманий для виконання операції
{
"jwt": "ey******kzMzZkOVGVzdCJ9.x-qLonr823cU2NK0ETJ1gaaUpmJ-WXov0"
}
Успішна відповідь для операції Оплата
{
"success": true,
"rid": "addc2a61a4d0d23abbdf09bf24b46bdd",
"pay": {
"code": "iso00_Approved",
"user_message": "Успішно",
"merchant": "M11302GG",
"traceId": "0471edb9526efc43ad9e680c2dec0ee5",
"approval_code": "131192",
"processing_code": "000000",
"response_code": "00",
"rrn": "014722766522",
"batch_id": 0,
"discount_amount": 0,
"discount_percent": 0,
"discount_type": "no_discount",
"amount_full": 3.33,
"payment_system": "Visa",
"masked_pan": "4149********1451",
"qr_code": "",
"receipt": "HTML чек ",
"receipt_id": 0,
"date": "20230705 08:20:09 +0000",
"stan": "082597",
"transaction_id": "PAX-TEST-64a527b82b7479.87095729"
},
"status": 200
}
Успішна відповідь для операції Повернення
{
"success": true,
"rid": "a60a7953e5678664398f15755b12410f",
"pay": {
"code": "iso00_Approved",
"user_message": "Успішно",
"merchant": "M11302GG",
"traceId": "0471edb9526efc43ad9e680c2dec0ee5",
"approval_code": "131192",
"processing_code": "000000",
"response_code": "00",
"rrn": "014722766522",
"batch_id": 0,
"discount_amount": 0,
"discount_percent": 0,
"discount_type": "no_discount",
"amount_full": 3.33,
"payment_system": "Visa",
"masked_pan": "4149********1451",
"qr_code": "",
"receipt": "HTML чек",
"receipt_id": 0,
"date": "20230705 08:20:09 +0000",
"stan": "082597",
"transaction_id": "PAX-TEST-64a527b82b7479.87095729"
},
"refunds": [
{
"amount": 3.33,
"state": 1,
"date": "2023-07-05T11:27:56.522626"
}
],
"status": 200
}
Опис вихідних параметрів
Атрибут | Опис | Формат даних |
---|---|---|
Блок pay ( інформація про оригінальну транзакцію) | ||
transaction_id | Ідентифікатор транзакції | String |
code | Код відповіді у процесінгу | String |
merchant | Мерчант під яким робиласть транзакція | String |
user_message | Відповідь операції продажу процесінга | String |
traceId | Ідентифікатор для відстеження | String |
approval_code | Містить ідентифікаційний код відповіді , назначений авторизуючим інститутом | String |
responce_code | Код відповіді авторизатора | String |
rrn | RRN | String |
batch_id | Ідентифікатор батча транзакції | String |
discount_amount | Сума знижки | float |
discount_percent | Процент знижки | float |
discount_type | Тип знижки | String |
amount_full | Повна сума транзакції (грн) | float |
payment_system | Платіжна система | String |
masked_pan | Маска платіжної картки | String |
qr_code | QR коду | String |
receipt | Чек в формате HTML | String |
receipt_id | Ідентифікатор чека | String |
date | Дата проведення транзакції | String |
stan | Це не унікальне числове значення транзакції | String |
Блок refuns (заявки на повернення по платежу) | ||
date | Дата створення запиту на повернення | String |
amount | Сума заявки на повернення у грн | float |
state | Статус заявки ( 1-Запит обробляється, 2- Виконано, 3 - Відмова ) ) | int |
status | код стану http запиту | int |
6.Коди відповідей
HTTP code | Опис |
---|---|
200 | Успішна обробка |
400 | Неправильний запит |
401 | Неправильно сформовано підпис |
418 | Час який використовувася у параметрі signed більший на 60 секунд ніж час обробки запиту |
500 | Внутрішня помилка сервісу |
Приклад відповіді з помилкою
{
"success": false,
"rid": "ce2f4a3454c35a6429adfd7a67f35ddc",
"status": 400,
}