При роботі з терміналами через Device Manager (далі ДМ) можливо отримувати попередню інформацію з терміналу про платіжний засіб клієнта, а саме PAN картки та платіжну систему, перед фінальним проведенням оплати.
Процес роботи в даному режимі виглядає наступним чином:
Важливо!
Для терміналів, що працюють по протоколу POSAPI
дана схема роботи доступна лише з версії застосунку 5.198.3.0
або вище. Також дану операцію можливо провести лише на терміналах моделі castles
(наприклад castles vega 3000
або castles saturn 1000
). Для інших терміналів, наприклад Verifone VX520, даний функціонал не підтримується розробниками бібліотеки POSAPI
(станом на січень 2025).
Для терміналів Приватбанку
під управлінням JSON протоколу, схема роботи доступна з версії застосунку 6.0.0.0
або вище.
Для терміналів ingenico що працюють по протоколу BPOS1
, схема роботи з корекцією доступна з версії застосунку 6.1.0.0
або вище. Також не всі банки можуть вмикати на терміналах функціонал корекції. Чи доступна така операції на вашому терміналі - рекомендовано уточнити в банку.
Для терміналів під управлінням інших протококолів дана схема роботи не підтримується в Device Manager.
Можливо проводити лише оплати з очікуванням підтвердження, для повернень з боку терміналу такий функціонал недоступний.
Робота з терміналами по протоколу POSAPI
:
Термінал має бути з боку банку чи підрядника на стороні банку, на еквайринг з яким налаштовано термінал, оновлений до останньої версії ПЗ та налаштований на підтримку операцій з очікуванням підтвердження від каси, при цьому звичайні оплати без очікування підтвердження також будуть доступні.
Час очікування відповіді після відправки PAN картки 1хв. після очікування якщо не було відповіді з каси - термінал скасовує проведення операції.
Приватбанку
по JSON протоколу:Термінал має бути з боку банку налаштований в режим "Корекції операції". Пілся налаштування термінал зможе проводити оплати лише з очікуванням відповіді від каси, тобто звичайні оплати не будуть доступні.
В терміналах Приватбанку та терміналах ingenico по протоколу BPOS1 час очікування відповіді після відправки PAN картки за замовчуванням 10 секунд. Цей час можна збільшити звернувшись до техпідтримки вашого банку. Якщо за відведений час очікування - не було відповіді від каси - термінал продовжить проведення операції оплати.
Для уникнення проблем з можливими розбіжностями між обліковою системою та терміналом, ДМ, якщо не дочекається відповіді від облікової системи, після того як повернув PAN картки - автоматично виконає переривання операції по завершенню таймауту що встановив банк і кошти з покупця списані не будуть.
Для проведення операції з очікування підтвердження/корекції в ДМ розроблено 2 окремі завдання
"task": 6
- Запит на оплату із сумою та очікуванням підтвердження. У відповідь на цей запий після прикладання картки покупцем - буде повернуто відповідь із даними по картці."task": 7
- Завершення запиту на оплату з підтвердженням. В тілі запиту потрібно буде передати чи завершити оплату чи скасувати, відповідно в разі завершення буде повернуто відповідь з терміналу із даними про оплату. В пакетному режимі - буде фіскалізовано чек.Приватбанку
додатково є можливість в рамках цього запиту змінювати суму до оплати.Завершення однієї операції оплати передбачає виконання 6 завдання і за ним 7 з передачею oper_action
.
Якщо після отримання відповіді на 6 завдання не буде відправлено 7 завдання протягом встановленого таймауту на стороні терміналу - запит на оплату буде скасовано і потрібно буде його ініціювати спочатку.
Схема взаємодії буде трохи відрізнятись залежно від того як облікова система взаємодіє з терміналом в ДМ через окремий API запит чи за допомогою пакетного режиму (запит на /dm/execute-pkg
).
Запит на оплату з очікуванням підтвердження
curl --location --globoff 'http://localhost:3939/dm/execute' \
--header 'Content-Type: application/json' \
--data '{
"ver": 6,
"source": "DM_API",
"device": "Terminal",
"type": 3,
"pay": {
"task": 6,
"merch": "7777798",
"sum": 1
}
}'
Відповідь POSAPI
(дані про карту містяться в cardmask
)
{
"transaction_id": "a446c4df-88bb-4652-8354-1d6863374e38",
"transaction_search": 0,
"info": {
"dt": "",
"termid": "",
"bankid": "",
"bankname": "Райффайзенбанк",
"payid": "",
"cancelid": "206",
"refundid": "",
"cardmask": "989898**********",
"paysys": "Простір",
"sum": 0,
"sumcash": 0,
"curr": "UAH",
"restxt": "",
"sliptxt": "",
"isprint": 0,
"devinfo": "",
"deb_amount": 0,
"deb_num": 0,
"cred_amount": 0,
"cred_num": 0,
"canc_amount": 0,
"canc_num": 0,
"tx_num": 0,
"receipt": "",
"hstFld63Sf89": "",
"merch": "",
"submerch": "",
"reference": "",
"purchase_dt": "",
"pan": ""
},
"ver": 6,
"resp_ver": 3,
"source": "",
"device": "Terminal",
"tag": "",
"task_status": 1,
"type": 3,
"task": 6,
"dt": "20241127151711358",
"res": 0,
"res_action": 0,
"errortxt": "",
"aq_errortxt": "",
"warnings": []
}
Відповідь PrivatBankJSON
(дані про карту містяться в cardmask
)
{
"transaction_id": "d4b1380a-aa71-4f79-a675-2f3d8cbe4ed8",
"transaction_search": 0,
"info": {
"dt": "",
"termid": "",
"bankid": "",
"bankname": "Приватбанк",
"payid": "",
"cancelid": "",
"refundid": "",
"cardmask": "438752566******8",
"paysys": "",
"sum": 0,
"sumcash": 0,
"curr": "UAH",
"restxt": "",
"sliptxt": "",
"isprint": 1,
"devinfo": "",
"deb_amount": 0,
"deb_num": 0,
"cred_amount": 0,
"cred_num": 0,
"canc_amount": 0,
"canc_num": 0,
"tx_num": 0,
"receipt": "",
"hstFld63Sf89": "",
"merch": "",
"submerch": "",
"reference": "",
"purchase_dt": "20250114153418",
"pan": "",
"acquirerid": ""
},
"ver": 6,
"resp_ver": 4,
"source": "",
"device": "priv",
"tag": "",
"task_status": 1,
"type": 3,
"task": 6,
"dt": "20250114153418523",
"res": 0,
"res_action": 0,
"errortxt": "",
"aq_errortxt": "",
"warnings": []
}
Запит завершення операції оплати POSAPI
(oper_action
: 0 - скасувати оплату (за замовчуванням якщо не передано), 1 - продовжити оплату по карті клієнта)
curl --location --globoff 'http://{{dm_ip}}:3939/dm/execute' \
--header 'Content-Type: application/json' \
--data '{
"ver": 6,
"source": "DM_API",
"device": "Terminal",
"type": 3,
"pay": {
"task": 7,
"oper_action": 1
}
}'
Запит завершення операції оплати PrivatBankJSON
oper_action
: 0 - скасувати оплату (за замовчуванням якщо не передано), 1 - продовжити оплату по карті клієнтаsum
- сума до стягнення з клієнта, 2 знаки після коми. Має бути більше 0, якщо передано 0 - термінал скасує оплату. Необов'язковий параметр, якщо не передано - термінал буде проводити оплату з тією ж сумою що була в першому запиті.curl --location --globoff 'http://{{dm_ip}}:3939/dm/execute' \
--header 'Content-Type: application/json' \
--data '{
"ver": 6,
"source": "DM_API",
"device": "Terminal",
"type": 3,
"pay": {
"task": 7,
"sum": 2,
"oper_action": 1
}
}'
Відповідь (буде аналогічна як і при виконанні звичайної оплати "task": 1
)
POSAPI
{
"transaction_id": "3e7f1396-f49b-43c3-ae0e-0b1f5eb03fe2",
"transaction_search": 0,
"info": {
"dt": "20241127152436",
"termid": "S0130027",
"bankid": "7777798",
"bankname": "Райффайзенбанк",
"payid": "904629",
"cancelid": "207",
"refundid": "433215000149",
"cardmask": "989898**********",
"paysys": "TEST CARD",
"sum": 1,
"sumcash": 0,
"curr": "980",
"restxt": "",
"sliptxt": "",
"isprint": 0,
"devinfo": "",
"deb_amount": 0,
"deb_num": 0,
"cred_amount": 0,
"cred_num": 0,
"canc_amount": 0,
"canc_num": 0,
"tx_num": 0,
"receipt": "",
"hstFld63Sf89": "",
"merch": "",
"submerch": "",
"reference": "",
"purchase_dt": "20241127152436",
"pan": ""
},
"ver": 6,
"resp_ver": 3,
"source": "",
"device": "Terminal",
"tag": "",
"task_status": 1,
"type": 3,
"task": 7,
"dt": "20241127152517319",
"res": 0,
"res_action": 0,
"errortxt": "",
"aq_errortxt": "",
"warnings": []
}
PrivatBankJSON
{
"transaction_id": "3daa618c-55b5-45a6-97b5-a8cb7050f30a",
"transaction_search": 0,
"info": {
"dt": "14.01.2025 15:34:35",
"termid": "S1K90CY8",
"bankid": "S1K90CY8",
"bankname": "ПриватБанк",
"payid": "767215",
"cancelid": "469309",
"refundid": "092665730122",
"cardmask": "438752******7008",
"paysys": "VISA_MER",
"sum": 2,
"sumcash": 0,
"curr": "UAH",
"restxt": "APPROVED",
"sliptxt": "",
"isprint": 1,
"devinfo": "",
"deb_amount": 0,
"deb_num": 0,
"cred_amount": 0,
"cred_num": 0,
"canc_amount": 0,
"canc_num": 0,
"tx_num": 0,
"receipt": "ПРИВАТБАНК\n\"ВЧАСНО КАСА\"\nШ.ХАРКIВСЬКЕ,БУД.201/203\nМ.КИЇВ\n'ТОВ ВЧАСНО СЕРВIС\"\n41231992\nОПЛАТА\nСУМА:2.00 ГРН\n\n438752******7008\nContactless\nVISA AID: A0000000031010\nТЕРМIНАЛ # S1K90CY814 СIЧ 2025 15:34:35\nКОД АВТОРИЗ.: 767215ЧЕК N: 469309\nRRN: 092665730122\n\n(с)SSI 2024 PRIVATBANK v.T5PRVa_.04J\nSmartPos_EMV 01.001\n",
"hstFld63Sf89": "",
"merch": "S1K90CY8",
"submerch": "",
"reference": "",
"purchase_dt": "20250114153435",
"pan": "",
"acquirerid": ""
},
"ver": 6,
"resp_ver": 4,
"source": "",
"device": "priv",
"tag": "",
"task_status": 1,
"type": 3,
"task": 7,
"dt": "20250114153442943",
"res": 0,
"res_action": 0,
"errortxt": "",
"aq_errortxt": "",
"warnings": []
}
Запит на оплату з очікуванням підтвердження. Все що потрібно передати в запит на фіскалізацію чеку це 6 номер завдання в корінь JSON ("pay": {"task": 6}
) все інше - стандартні дані для фіскалізації чеку. По результату виконання цього запиту чек ще не буде фіскалізовано.
curl --location 'http://localhost:3939/dm/execute-pkg' \
--header 'Content-Type: application/json' \
--data '{
"tag": "",
"ver": 6,
"type": 1,
"device": "test",
"pay": {
"task": 6
},
"fiscal": {
"task": 1,
"cashier": "it",
"receipt": {
"sum": 1,
"pays": [
{
"sum": 1,
"type": 2
}
],
"rows": [
{
"cnt": 1,
"code": "1568725",
"name": "Товар",
"price": 1,
"taxgrp": 1
}
]
}
}
}'
Відповідь POSAPI
(дані про карту містяться в cardmask
)
{
"transaction_id": "9117e476-00ae-4141-afcb-b0ba2b14f9e7",
"transaction_search": 0,
"info": {
"dt": "",
"termid": "",
"bankid": "",
"bankname": "Райффайзенбанк",
"payid": "",
"cancelid": "208",
"refundid": "",
"cardmask": "989898**********",
"paysys": "Простір",
"sum": 0,
"sumcash": 0,
"curr": "UAH",
"restxt": "",
"sliptxt": "",
"isprint": 0,
"devinfo": "",
"deb_amount": 0,
"deb_num": 0,
"cred_amount": 0,
"cred_num": 0,
"canc_amount": 0,
"canc_num": 0,
"tx_num": 0,
"receipt": "",
"hstFld63Sf89": "",
"merch": "",
"submerch": "",
"reference": "",
"purchase_dt": "",
"pan": "989898**********"
},
"ver": 6,
"resp_ver": 3,
"source": "",
"device": "test",
"tag": "",
"task_status": 1,
"type": 1,
"task": 1,
"dt": "20241127152930208",
"res": 0,
"res_action": 0,
"errortxt": "",
"aq_errortxt": "",
"warnings": []
}
Відповідь PrivatBankJSON
(дані про карту містяться в cardmask
)
{
"transaction_id": "d4b1380a-aa71-4f79-a675-2f3d8cbe4ed8",
"transaction_search": 0,
"info": {
"dt": "",
"termid": "",
"bankid": "",
"bankname": "Приватбанк",
"payid": "",
"cancelid": "",
"refundid": "",
"cardmask": "438752566******8",
"paysys": "",
"sum": 0,
"sumcash": 0,
"curr": "UAH",
"restxt": "",
"sliptxt": "",
"isprint": 1,
"devinfo": "",
"deb_amount": 0,
"deb_num": 0,
"cred_amount": 0,
"cred_num": 0,
"canc_amount": 0,
"canc_num": 0,
"tx_num": 0,
"receipt": "",
"hstFld63Sf89": "",
"merch": "",
"submerch": "",
"reference": "",
"purchase_dt": "20250114153418",
"pan": "",
"acquirerid": ""
},
"ver": 6,
"resp_ver": 4,
"source": "",
"device": "priv",
"tag": "",
"task_status": 1,
"type": 3,
"task": 6,
"dt": "20250114153418523",
"res": 0,
"res_action": 0,
"errortxt": "",
"aq_errortxt": "",
"warnings": []
}
Запит завершення операції оплати. В корені JSON в об'єкті pay
потрібно передати 7 номер завдання та oper_action
: 0 - скасувати оплату (за замовчуванням), 1 - продовжити оплату по карті клієнта. Якщо було передано 1 - після завершення оплати на терміналі буде автоматично фіскалізовано чек з усіма даними по транзакції.
Для терміналів Приватбанку
якщо потрібно змінити суму - змінюється сума всього чеку, сума товарів та оплат, відповідно нова сума - буде відправлена на термінал. Додатково sum
в об'єкті pay
не зазначається при роботі в пакетному режимі.
curl --location 'http://localhost:3939/dm/execute-pkg' \
--header 'Content-Type: application/json' \
--data '{
"tag": "",
"ver": 6,
"type": 1,
"device": "Test",
"pay": {
"task": 7,
"oper_action": 1
},
"fiscal": {
"task": 1,
"cashier": "it",
"receipt": {
"sum": 1,
"pays": [
{
"sum": 1,
"type": 2
}
],
"rows": [
{
"cnt": 1,
"code": "1568725",
"name": "Товар",
"price": 1,
"taxgrp": 1
}
]
}
}
}'
Відповідь (буде аналогічна як і при виконанні звичайної оплати).
{
"info": {
"qr": "https://kasa.vchasno.com.ua/c/TEST_h2R3t1LmDLrRJg?MAC:7406a6c0fa3c9bdd0576d3fe49fbe59236575b7d44f0198d71f2f66ec0709194;DT:27-11-2024T15:35:30;FR:TEST_h2R3t1LmDLrRJg;SUM:100;FN:9999-2993680803756",
"qr1": "7406a6c0fa3c9bdd0576d3fe49fbe59236575b7d44f0198d71f2f66ec0709194|27.11.2024 15:35:30|TEST_h2R3t1LmDLrRJg|100|9999-2993680803756",
"cancelid": "TEST_h2R3t1LmDLrRJg",
"printinfo": {
"name": "ФОП МУЗИЧУК ЯРОСЛАВ ВОЛОДИМИРОВИЧ",
"shopname": "Тестова торгова точка",
"shoptype": "",
"shopad": "Україна, м.Київ, вул. Хрещатик, 99",
"vat_code": "",
"fis_code": "3680803756",
"dfs_local_number": "",
"goods": [
{
"name": "Товар",
"code": "1568725",
"code1": "",
"code2": "",
"code3": "",
"code_a": "",
"code_aa": [],
"cnt": 1,
"price": 100,
"cost": 100,
"cost_after_disc": 100,
"disc": 0,
"disc_type": 0,
"disc_name": "",
"disc_apply_type": 0,
"taxgrp": 1,
"taxgrps": [],
"taxlit": "А",
"taxlits": "",
"comment": "",
"discounts": [],
"commission": 0,
"commission_included": 0
}
],
"lines": [],
"lines1": [],
"lines2": [],
"lines3": [],
"lines4": [],
"lines5": [],
"sum_0": 100,
"sum_receipt": 100,
"sum_disc": 0,
"disc_total": 0,
"disc_type_total": 0,
"disc_name_total": "",
"disc_calc_alg_total": 0,
"disc_apply_type_total": 3,
"disc_sum_total": 0,
"discounts": [],
"sum_topay": 100,
"round": 0,
"pays": [
{
"type": 2,
"typen": "Картка",
"sum": 100,
"sum_orig": 100,
"incl_tax_sum": 0,
"commission": 0,
"commission_included": 0,
"currency": "грн",
"oper_type": "Оплата",
"show_additional_info": false,
"info": "Платіжна система TEST CARD \\n картка 989898********** \\n RRN 433215000150",
"comment": "",
"comment_up": "",
"comment_down": "",
"purchase_dt": "20241127153449",
"paysys": "TEST CARD",
"rrn": "433215000150",
"cardmask": "989898**********",
"term_id": "S0130027",
"bank_id": "7777798",
"bank_name": "Райффайзенбанк",
"auth_code": "517455"
}
],
"taxes": [
{
"gr_code": 1,
"base_sum": 100,
"tax_name": "ПДВ_А",
"tax_fname": "ПДВ 20%",
"tax_lit": "А",
"tax_percent": 20,
"base_tax_sum": 100,
"tax_sum": 16.67,
"ex_name": "",
"ex_percent": 0,
"base_ex_sum": 100,
"ex_sum": 0,
"activation_dt": "12-11-2024 16:45:42",
"tax_not_incl": 0,
"tax_alg": 0,
"tax_link": 0
}
],
"fisn": "TEST_h2R3t1LmDLrRJg",
"dt": "27-11-2024 15:35:30",
"open_shift_dt": "20241127132023",
"qr": "https://kasa.vchasno.com.ua/c/TEST_h2R3t1LmDLrRJg?MAC:7406a6c0fa3c9bdd0576d3fe49fbe59236575b7d44f0198d71f2f66ec0709194;DT:27-11-2024T15:35:30;FR:TEST_h2R3t1LmDLrRJg;SUM:100;FN:9999-2993680803756",
"qr1": "7406a6c0fa3c9bdd0576d3fe49fbe59236575b7d44f0198d71f2f66ec0709194|27.11.2024 15:35:30|TEST_h2R3t1LmDLrRJg|100|9999-2993680803756",
"isOffline": false,
"mac": "7406a6c0fa3c9bdd0576d3fe49fbe59236575b7d44f0198d71f2f66ec0709194",
"fisid": "9999-2993680803756",
"manuf": "Вчасно-каса",
"cashier": "it",
"task": 1,
"subtask": 0,
"fcId": "",
"fisdoctype": "Тестовий чек",
"comment_down": "",
"comment_up": "",
"safe": 0,
"safe_start_shift": 0,
"docno": "6",
"userdata1": "",
"userdata2": "",
"userdata3": "",
"crc32": 4138,
"tax_not_incl_alg": 0
},
"dt": "20241127153530",
"open_shift_dt": "20241127132023",
"fisid": "9999-2993680803756",
"docno": "6",
"doccode": "TEST_h2R3t1LmDLrRJg",
"isprint": 1,
"ispay": 0,
"cashier": "it",
"userdata1": "",
"userdata2": "",
"userdata3": "",
"safe": 0,
"safe_start_shift": 0,
"task": 1,
"dtype": 0,
"shift_link": 2,
"shift_prev_link": 1,
"vacant_off_nums": -1,
"dataid": 14,
"devinfo": "",
"dfs_local_number": "",
"printheader": null,
"billing": {
"paid_date_to": "",
"enough_to_renew_subscription": 0
}
},
"ver": 6,
"resp_ver": 3,
"source": "",
"device": "Test",
"tag": "CF832515-4419-48C5-833B-5CF88276D6E6",
"task_status": 1,
"type": 1,
"task": 1,
"dt": "20241127153530",
"res": 0,
"res_action": 0,
"errortxt": "",
"aq_errortxt": "",
"warnings": [],
"term_info": {
"dt": "20241127153449",
"termid": "S0130027",
"bankid": "7777798",
"bankname": "Райффайзенбанк",
"payid": "517455",
"cancelid": "209",
"refundid": "433215000150",
"cardmask": "989898**********",
"paysys": "TEST CARD",
"sum": 100,
"sumcash": 0,
"curr": "980",
"restxt": "",
"sliptxt": "",
"isprint": 0,
"devinfo": "",
"deb_amount": 0,
"deb_num": 0,
"cred_amount": 0,
"cred_num": 0,
"canc_amount": 0,
"canc_num": 0,
"tx_num": 0,
"receipt": "",
"hstFld63Sf89": "",
"merch": "",
"submerch": "",
"reference": "",
"purchase_dt": "20241127153449",
"pan": ""
}
}
Як було вказано раніше для коректної роботи потрібно зберігати послідовність виконання завдань.
Спочатку "task": 6
, після успішної відповіді з номером карти та платіжною системою - "task": 7
.
У разі якщо не було відправлено "task": 6
, у відповідь на "task": 7
отримаєте помилку:
{
"ver": 6,
"resp_ver": 3,
"source": "",
"device": "raif",
"tag": "",
"task_status": 3,
"type": 3,
"task": 7,
"dt": "20241128171817895",
"res": 5074,
"res_action": 1,
"errortxt": "По терміналу немає активного запиту на оплату з підтвердженням",
"aq_errortxt": "",
"warnings": []
}
"task": 6
при виконанні "task": 6
повторно до отримання відповіді від терміналу по попередньому запиту - отримаєте помилку:{
"ver": 6,
"resp_ver": 3,
"source": "",
"device": "raif",
"tag": "",
"task_status": 3,
"type": 3,
"task": 6,
"dt": "20241128172158075",
"res": 1105,
"res_action": 1,
"errortxt": "Пристрій зайнятий",
"aq_errortxt": "",
"warnings": []
}
"task": 6
при виконанні "task": 6
повторно після отримання відповіді від терміналу по попередньому запиту але до виконання "task": 7
- отримаєте помилку:{
"ver": 6,
"resp_ver": 3,
"source": "",
"device": "raif",
"tag": "",
"task_status": 3,
"type": 3,
"task": 6,
"dt": "20241128172214985",
"res": 5073,
"res_action": 1,
"errortxt": "Запит на оплату з підтвердженням уже було відправлено на термінал. Для завершення/скасування операції необхідно відправити \\\"task\\\": 7 або почекати до 70 секунд",
"aq_errortxt": "",
"warnings": []
}
"task": 6
та після "task": 7
. у разі якщо після відправки "task": 6
до прикладання картки операцію на терміналі буде скасовано натисненням червоної кнопки або термінал скасує її по таймауту очікування карти - в такому разі для повторного запиту на оплату з підтвердженням потрібно буде:"task": 7
на який отримаєте помилку з кодом "res": 5074
"task": 6