Callbacks¶
Callbacks дозволяють отримувати сповіщення, коли змінюється статус операції.
Щоб налаштувати Callbacks для операцій, необхідно задати адресу callback_url
у налаштуваннях інтеграції або відправляти цей параметр у запиті.
Note
Callback – асинхронна функція, тому не рекомендується для завдань із жорстким обмеженням часу. Існує ймовірність, що ваша програма отримає повідомлення не в порядку надсилання або вони продублюються. Тому на додаток до Callbacks ми рекомендуємо використовувати реконсиляцію (звірку) за API для оновлення даних у системі.
Налаштування¶
Для налаштування Callbacks потрібно перейти до налаштувань акаунту та додати значення «Callback URL».
Формат повідомлення¶
HTTP запит, який ми відправимо на ваш callback_url
, матиме наступні характеристики:
- це буде POST запит;
- Тіло запиту буде передано в JSON API форматі;
- об'єкти
type
таid
обов'язково будуть у тілі запиту (а не в URL-параметрі).
{
"data": {
"type": "payment-invoices",
"id": "cpi_yv1RgJ2l8ty2AxIs",
"attributes": {
"serial_number": "yv1RgJ2l8ty2AxIs",
"status": "processed",
"resolution": "ok",
"moderation_required": false,
"amount": 22,
"payment_amount": 22,
"currency": "USD",
"service_currency": "USD",
"reference_id": "da1b0b9d-c249-4f6e-9949-2a2f2d4b1758",
"test_mode": true,
"fee": 0,
"deposit": 22,
"processed": 1592232071,
"processed_amount": 22,
"refunded_amount": null,
"processed_fee": 0,
"processed_deposit": 22,
"metadata": {
"merchant_url": "https://yu.test.this"
},
"flow_data": {
"action": "https://example.domain/hpp/cgi_Q0fYDFaHlqb5MCdl",
"method": "GET",
"params": [],
"metadata": {
"sid": "cgi_Q0fYDFaHlqb5MCdl",
"token": "eyJ0eXAiOiJKV1QiLRiGCg2O...nGE7E"
}
},
"flow": "hpp",
"payment_flow": "charge",
"created": 1592232050,
"updated": 1592232071,
"payload": {
"token": null,
"client_ip": "54.36.117.30",
"payment_card": {
"last": "0000",
"mask": "512381******0000",
"brand": "mastercard",
"перший": "512381",
"holder": null,
"expiry_year": "33",
"issuer_name": "FIRST DATA CORPORATION",
"expiry_month": "11",
"issuer_country": "US"
}
},
"description": null,
"descriptor": null,
"callback_url": "https://test.doc.home",
"return_url": "https://example.com",
"return_urls": {
"fail": "https://example.com/sorry-page",
"pending": "https://example.com/wait-for-it-page",
"success": "https://example.com/thank-you-page"
},
"original_data": null,
"rrn": null,
"approval_code": null,
"reserved_amount": null,
"reserve_expires": null,
"unreserved": null,
"source": null,
"callback_logs": []
},
"relationships": {
"payment-service": {
"data": {
"type": "payment-services",
"id": "payment_card_usd_hpp"
}
},
"payment-method": {
"data": {
"type": "payment-methods",
"id": "payment_card"
}
},
"customer": {
"data": null
}
},
"links": {
"self": "/api/payment-invoices/cpi_yv1RgJ2l8ty2AxIs"
}
}
}
{
"data": {
"type": "payout-invoices",
"id": "cpoi_sIzOuMKJg98J22NC",
"attributes": {
"serial_number": "sIzOuMKJg98J22NC",
"status": "processed",
"resolution": "ok",
"amount": 100,
"payout_amount": 100,
"currency": "USD",
"service_currency": "USD",
"service_amount": 100,
"service_payout_amount": 100,
"reference_id": "45284707-d243-439e-8b41-d657322e693b",
"test_mode": true,
"description": null,
"fee": 0,
"writeoff": 100,
"exchange_rate": 1,
"processed": 1621335982,
"processed_amount": 100,
"processed_fee": 0,
"processed_writeoff": 100,
"metadata": [],
"created": 1621335974,
"updated": 1621335982,
"fields": {
"card_number": "512381******0000"
},
"callback_url": "https://test.doc.home",
"source": "merchant_dashboard",
"callback_logs": [],
"payouts": [
{
"id":"po_4a3Bgz6YR3cRjW6k",
"rrn":null,
"amount":72.5,
"currency":"USD",
"status":"processed"
},
{
"id":"po_3cR4z6kgYR6aj3BW",
"rrn":null,
"amount":27.5,
"currency":"USD",
"status":"processed"
}
]
},
"relationships": {
"payout-service": {
"data": {
"type": "payout-services",
"id": "payment_card_usd"
}
},
"payout-method": {
"data": {
"type": "payout-methods",
"id": "payment_card"
}
},
"customer": {
"data": null
}
},
"links": {
"self": "/api/payout-invoices/cpoi_sIzOuMKJg98J22NC"
}
}
}
Тіло запиту Callback містить тіло відповідної операції інвойсу.
Статуси інвойсів описані в посібниках:
Перевірка автентичності¶
MilkyPay підписує дані, використовуючи ключі в хедері запиту X-Signature
.
Алгоритм генерування підпису (PHP)
<?php
$secret="yourPrivateKey";
$callbackData='{"data":{"type":"payment-invoices","id":"cpi_exampleID","attributes":{"serial_number":"exampleID","status":"processed","resolution":"ok","moderation_required":false,"amount":1000,"payment_amount":1000,"currency":"USD","service_currency":"USD","reference_id":"yourReferenceId","test_mode":true,"fee":38,"deposit":962,"processed":1647077297,"processed_amount":1000,"refunded_amount":null,"processed_fee":38,"processed_deposit":962,"metadata":[],"flow_data":{"action":"https:\/\/pay.example.com\/hpp\/cgi_exampleId","method":"GET","params":[],"metadata":{"sid":"cgi_exampleId","token":"bearerToken-for-H2H-api-auth"}},"flow":"hpp","payment_flow":"charge","created":1647077285,"updated":1647077297,"payload":{"token":"token-if-tokenize-true","auth_type":"card","client_ip":"192.168.0.1","payment_card":{"last":"0000","mask":"512381******0000","brand":null,"first":"512381","holder":"Test Customer","network":"mastercard","expiry_year":"99","issuer_name":"FIRST DATA CORPORATION","expiry_month":"09","issuer_country":"US"}},"description":null,"descriptor":null,"callback_url":"https:\/\/your.callback.url","return_url":null,"return_urls":{"fail":"https:\/\/your.fail-return.url","pending":"https:\/\/your.default-return.url","success":"https:\/\/your.success-return.url"},"original_data":null,"rrn":null,"approval_code":null,"reserved_amount":null,"reserve_expires":null,"unreserved":null,"source":"merchant_api","callback_logs":[],"charged_back_amount":null,"resolution_message":null,"hpp_url":"https:\/\/api.example.com\/hpp?cpi=cpi_exampleID"},"relationships":{"payment-service":{"data":{"type":"payment-services","id":"payment_card_usd_hpp"}},"payment-method":{"data":{"type":"payment-methods","id":"payment_card"}},"customer":{"data":{"type":"customers","id":"cus_exampleID"}},"active-payment":{"data":{"type":"payments","id":"pay_exampleID"}}},"links":{"self":"\/api\/payment-invoices\/cpi_exampleID"}},"included":[{"type":"customers","id":"cus_exampleID","attributes":{"reference_id":"example-customer-id","email":null,"name":null,"phone":null,"description":null,"created":1646833439,"metadata":[],"avatar":"https:\/\/www.gravatar.com\/avatar\/exampleAvatarID?s=20&d=mm&r=g","archived":false,"processing_options":{"payment_enabled":true,"payout_enabled":true},"address":{"street":null,"country":null,"region":null,"city":null,"full_address":null,"post_code":null}},"relationships":{"commerce-account":{"data":{"type":"commerce-accounts","id":"coma_exampleID"}}}}]}';
$signature = base64_encode(sha1($secret . $callbackData . $secret, true));
echo $signature;
- В прикладі вище:
-
$secret
— бойовий ("Live key") або тестовий ("Test key") секретний (приватний) ключ, який знаходиться в налаштуваннях акаунту; -
$callbackData
— неформатований JSON тіла отриманого callback. -
$signature
— алгоритм генерування.
Щоб переконатися в достовірності джерела, згенеруйте підпис, використовуючи відповідний ключ і raw JSON тіло Callback.
В результаті ви отримаєте стрічку base64 вигляду:
B86Af35b/IfM0z0rGROHw5gVw14=
яка повинна бути аналогічною значенню підпису в хедері Callback.
Перевищення часу очікування (тайм-аут)¶
MilkyPay виділяє три типи тайм-аутів для Callbacks:
- Тайм-аут з'єднання (Connection Timeout): граничний час для встановлення початкового з'єднання з HTTP-сервером URL Callbacks.
- Тайм-аут читання (Read Timeout): граничний час повідомлення про отримання даних HTTP сервером після встановлення з'єднання.
- Загальний тайм-аут надсилання Callbacks (Execution Timeout): на додаток до попередніх MilkyPay також перевіряє загальний час виконання Callbacks.
Значення тайм-аутів:
Тип | Для тестового з'єднання | Для бойового з'єднання |
---|---|---|
Connection Timeout | 10,000 мс | 20,000 мс |
Read Timeout | 10,000 мс | 20,000 мс |
Execution Timeout | 20,000 мс | 60,000 мс |
Доставка Calbacks та автоповтор відправки¶
Подальші дії визначаються за HTTP-кодом, отриманим у відповіді на відправку Callbacks:
Код | значення | Подальші дії системи |
---|---|---|
200 | Callback успішно доставлено | Повторне відправлення не потрібно, наступні заплановані спроби доставки анулюються |
429 | Занадто багато запитів, Callback не прийнято | Повторне відправлення примусово зупинено, наступні заплановані спроби доставки анулюються |
Будь-який інший HTTP-код у відповіді означає, що запит не доставлено. За замовчуванням запит повторно надсилається із проміжком очікування між спробами:
- 1-й повтор запиту буде відправлено через 1 хвилину після початкової спроби;
- 2-й повтор - через 2 хвилини після 1-го повтору;
- 3-й - через 3 хвилини після 2-го;
- 4-й - через 4 хвилини після 3-го;
- 5-й - через 5 хвилин після 4-го;
- і 6-й - через 6 хвилин після 5го.
- і т.д. до 100 спроб або до отримання
200
або429
HTTP-коду.
Існує можливість налаштування інтервалу відправлення та кількості спроб
Надіслати запит нашій службі підтримки , щоб ми разом підібрали найбільш підходящий варіант.
Note
Якщо ви хочете синхронізувати дані негайно, можна перенаправити запит з панелі керування. Для цього потрібно перейти до огляду транзакції, вибрати вкладку Callbacks та кнопку Відправити заново.
Дублювання¶
Через повторне відправлення Callbacks є ймовірність, що програма отримає ті самі дані кілька разів. Ви можете переконатися в ідемпотентності операції (властивості об'єкта або операції при повторному застосуванні операції до об'єкта давати той самий результат, що і при першому), виявивши такі дублікати даних програми.
Це не є проблемою, якщо програма визначає ідемпотентність. Для контролю використовуйте параметр id
даних запиту Callbacks, т.к. його значення є унікальним для операції.
Пакетна обробка¶
Ми пов'язуємо Callbacks для найближчих статусів. Так, якщо платіж відразу ж перейшов зі статусу created
(створений) у статус pending
(в обробці) та у статус processed
(оброблений), ви отримаєте лише один Callback з останнім за часом статусом (тобто processed
).
Перевага такого підходу: можливість уникнути перевантаження ваших серверів HTTP запитами та позбавити вашу програму необхідності ускладнювати логіку взаємодії з послідовними змінами статусу. Ваша програма повинна піклуватися лише останній статус об'єкта.
Доставка не по порядку¶
Callbacks можуть приходити не по порядку через проблеми мережі або надсилання. Ви все одно можете встановити правильну послідовність подій, орієнтуючись на атрибут updated
в Callbacks - часову мітку у форматі Timestamp.
IP-адреси¶
Для підвищення безпеки взаємодії між платформою MilkyPay та вашим сервером, необхідно використовувати контроль IP-адрес.