При роботі з терміналами через Device Manager (далі ДМ) можливо отримувати попередню інформацію з терміналу про платіжний засіб клієнта, а саме PAN картки та платіжну систему, перед фінальним проведенням оплати.
Процес роботи в даному режимі виглядає наступним чином:
Важливо!
Дана схема працює для наступних протоколів:
Для терміналів під управлінням інших протококолів дана схема роботи наразі не підтримується.
Можливо проводити лише оплати з очікуванням підтвердження/корекції, для повернень з боку терміналу такий функціонал недоступний.
Важливі деталі для кожного з протоколів:
Час очікування відповіді після відправки PAN картки за замовчуванням 10 секунд. Цей час можна збільшити звернувшись до техпідтримки вашого банку. Якщо за відведений час очікування - не було відповіді від каси - термінал продовжить проведення операції оплати.
Для уникнення проблем з можливими розбіжностями між обліковою системою та терміналом, ДМ, якщо не дочекається відповіді від облікової системи, після того як повернув PAN картки - автоматично виконає переривання операції по завершенню таймауту що встановив банк і кошти з покупця списані не будуть.
Термінал має бути з боку банку оновлений до останньої версії ПЗ.
Додаткового налаштування на підтримку підтвердження/корекції не потрібно, при цьому звичайні оплати без очікування підтвердження також будуть доступні.
Час очікування відповіді після відправки PAN картки 1хв. після очікування якщо не було відповіді з каси - термінал самостійно скасовує проведення операції.
Корегування суми наразі доступно лише у Android версії Device Manager що встановлюється на сам термінал. У версії для Windows/Linux доступно лише підтвердження для продовження чи скасування операції.
Для проведення операції з очікування підтвердження/корекції в ДМ розроблено 2 окремі завдання
"task": 6 - Запит на оплату із сумою та очікуванням підтвердження/корекції. У відповідь на цей запий після прикладання картки покупцем - буде повернуто відповідь із даними по картці (PAN картки та платіжну систему)."task": 7 - Завершення запиту на оплату з підтвердженням/корекцією. В тілі запиту потрібно буде передати чи завершити оплату чи скасувати, та, за потреби нову суму операції, відповідно в разі успішного завершення буде повернуто відповідь з терміналу із даними про оплату. В пакетному режимі - буде фіскалізовано чек.Завершення однієї операції оплати передбачає виконання завдання (task) 6 і за ним 7 з передачею oper_action.
Якщо після отримання відповіді на 6 завдання не буде відправлено 7 завдання протягом встановленого таймауту на стороні терміналу - оплата буде скасована. Потрібно створювати нову починаючи з завдання 6.
Схема взаємодії буде трохи відрізнятись залежно від того як облікова система взаємодіє з терміналом в ДМ через окремий API запит чи за допомогою пакетного режиму (запит на /dm/execute-pkg).
Запит на оплату з очікуванням підтвердження (task 6)
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
}
}'
Приклад відповіді при використанні Printec 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": []
}
Запит завершення операції оплати (task 7)
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)
Приклад відповіді при використанні Printec 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
}
]
}
}
}'
Приклад відповіді при використанні Printec 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 номер завдання ("task": 7) та
oper_action: 0 - скасувати оплату (за замовчуванням якщо не передано), 1 - продовжити оплату по карті клієнта.Для корегування суми - потрібно змінювати суму всього чеку, сумe товарів та оплат, відповідно нова сума - буде відправлена на термінал. Додатково 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