Новинка! API для Telegram ботів: Документація Telegram API
Швидкий старт
- Отримайте shop_id та секретний ключ у налаштуваннях мерчанта (розділ «Інформація про касу»).
- Створіть рахунок через
POST /api/v2/invoices/createі перенаправте користувача наpayment_urlз відповіді. - Вкажіть Webhook URL у налаштуваннях каси — система надішле POST-повідомлення після успішної оплати. Перевірте підпис і оновіть статус замовлення.
Swagger API Документація
Для зручної роботи з API ми надали інтерактивну Swagger документацію, яка дозволяє переглядати всі доступні API endpoints, бачити параметри запитів та приклади відповідей, тестувати API прямо в браузері та імпортувати специфікацію в Postman та інші інструменти.
Swagger документація:
https://aifo.pro/docs/swaggerSwagger документація містить всю інформацію про API endpoints, які описані нижче, але в більш зручному та інтерактивному форматі. Рекомендуємо використовувати Swagger для розробки та тестування інтеграцій.
JSON специфікація доступна за адресою: https://aifo.pro/docs/swagger/spec
Основний API створення рахунку
Для web-каси і Telegram-каси використовуйте єдиний endpoint створення рахунку. У відповіді система поверне системний invoice_id і готове посилання payment_url.
/api/v2. Підтримує рядковий external_id, суму через amount_minor, HMAC SHA-256 та стабільні error_code. /api/v1 залишається доступним для зворотної сумісності.
Endpoint:
POST https://aifo.pro/api/v2/invoices/create| Параметр | Примітка | Тип |
|---|---|---|
shop_id | ID каси з кабінету мерчанта. | Обов'язковий. |
amount | Сума рядком: 100.50. Можна замінити на amount_minor. | Обов'язковий. |
amount_minor | Сума в мінімальних одиницях: 10050 = 100.50 UAH. Має пріоритет над amount. | Необов'язковий. |
external_id | Ваш унікальний ID замовлення: рядок, UUID або число. Макс. 191 символ. Допустимі символи: літери, цифри, ._:@#-. | Обов'язковий. |
signature, timestamp, nonce | HMAC SHA-256 авторизація. Передаються у тілі POST-запиту або як HTTP-заголовки X-AIFO-Signature, X-AIFO-Timestamp, X-AIFO-Nonce. | Обов'язковий. |
description | Коментар до платежу. | Необов'язковий. |
lifetime_minutes | Час життя рахунку у хвилинах, від 0 до 43200. Необов'язково. | Необов'язковий. |
idempotency_key | Ключ ідемпотентності: повторний запит з тим самим nonce поверне початкову відповідь (впродовж 10 хв). | Необов'язковий. |
HMAC canonical string: METHOD\nPATH\nTIMESTAMP\nNONCE\nSORTED_PARAMS. Параметри сортуються за ключем (ksort) і кодуються через http_build_query. Поля авторизації (signature, timestamp, nonce) виключаються з SORTED_PARAMS. Часове вікно: ±300 секунд. Nonce: 8–128 символів [a-zA-Z0-9._:-].
Приклад генерації HMAC-підпису (PHP):
function buildHmacSignature(
string $method,
string $path,
int $timestamp,
string $nonce,
array $params,
string $secretKey
): string {
// Remove auth fields from params before signing
$authFields = ['sign', 'signature', 'timestamp', 'nonce', 'idempotency_key',
'aifo_signature', 'aifo_timestamp', 'aifo_nonce'];
foreach ($authFields as $f) {
unset($params[$f]);
}
ksort($params); // sort by key — required
$canonical = http_build_query($params, '', '&');
$base = $method . "\n" . $path . "\n" . $timestamp . "\n" . $nonce . "\n" . $canonical;
return hash_hmac('sha256', $base, $secretKey);
}
// -------- Create Invoice example --------
$secretKey = 'YOUR_SECRET_KEY'; // from merchant panel → secret key
$shopId = 123; // your shop_id
$externalId = 'ORDER-456'; // your unique order ID
$amount = '100.50'; // invoice amount
$timestamp = time();
$nonce = bin2hex(random_bytes(16)); // unique per request, 8-128 chars
$params = [
'shop_id' => $shopId,
'amount' => $amount,
'external_id' => $externalId,
];
$signature = buildHmacSignature('POST', '/api/v2/invoices/create', $timestamp, $nonce, $params, $secretKey);
// Add auth fields to POST body
$postData = array_merge($params, [
'timestamp' => $timestamp,
'nonce' => $nonce,
'signature' => $signature,
]);
// Send request
$ctx = stream_context_create(['http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($postData),
'timeout' => 10,
]]);
$response = file_get_contents('https://aifo.pro/api/v2/invoices/create', false, $ctx);
$result = json_decode($response, true);
if ($result['status'] === 'success') {
$paymentUrl = $result['data']['payment_url'];
$invoiceId = $result['data']['invoice_id'];
// Redirect the user: header('Location: ' . $paymentUrl);
}
Приклад відповіді:
{
"status": "success",
"message": "Invoice created",
"data": {
"api_version": "v2",
"invoice_id": 456,
"external_id": "ORDER-456",
"amount": "100.50",
"amount_minor": 10050,
"currency": "UAH",
"status": 0,
"status_text": "pending",
"merchant_type": "domain",
"checkout_endpoint": "/pay",
"payment_url": "https://aifo.pro/pay?shop_id=123&pay_id=456&amount=100.50&sign=...",
"created_at": "2024-01-15 10:30:00",
"expires_at": 1705309800,
"lifetime_minutes": 60,
"auth_mode": "hmac",
"key_status": "active"
}
}API перевірки статусу рахунку
Статус рахунку доступний тільки з shop_id і підписом. Це захищає платежі від перегляду лише за одним ID.
GET https://aifo.pro/api/v2/invoices/status?shop_id=123&invoice_id=456×tamp=...&nonce=...&signature=...| Параметр | Примітка | Тип |
|---|---|---|
shop_id | ID каси з кабінету мерчанта. | Обов'язковий. |
invoice_id | Системний invoice_id з відповіді API при створенні. Можна замінити на external_id. | Один з двох. |
external_id | Ваш external_id, переданий при створенні рахунку. Альтернатива invoice_id. | Один з двох. |
signature, timestamp, nonce | HMAC SHA-256 авторизація. Передаються у тілі POST-запиту або як HTTP-заголовки X-AIFO-Signature, X-AIFO-Timestamp, X-AIFO-Nonce. | Обов'язковий. |
Коди статусів рахунку
| Код | status_text |
Опис |
|---|---|---|
0 | pending | Очікує оплати |
1 | paid | Успішно оплачений |
2 | expired | Термін дії минув |
3 | test | Тестовий платіж (sandbox) |
Приклад генерації HMAC-підпису (PHP): (GET)
$params = [
'shop_id' => $shopId,
'invoice_id' => 456, // or 'external_id' => 'ORDER-456'
];
$timestamp = time();
$nonce = bin2hex(random_bytes(16));
$signature = buildHmacSignature('GET', '/api/v2/invoices/status', $timestamp, $nonce, $params, $secretKey);
$queryString = http_build_query(array_merge($params, [
'timestamp' => $timestamp,
'nonce' => $nonce,
'signature' => $signature,
]));
$response = file_get_contents('https://aifo.pro/api/v2/invoices/status?' . $queryString);
$result = json_decode($response, true);
if ($result['status'] === 'success') {
$statusText = $result['data']['status_text']; // 'pending', 'paid', 'expired', 'test'
$isPaid = ($statusText === 'paid');
}
Коди помилок API
При помилці API повертає JSON з полем error_code. Використовуйте його для обробки конкретних помилок у коді.
{
"status": "error",
"error_code": "invalid_signature",
"message": "Invalid API signature: timestamp_out_of_window",
"code": 401
}| error_code | HTTP | Опис |
|---|---|---|
invalid_shop_id | 400 | shop_id не вказаний або некоректний |
merchant_not_found | 404 | Мерчант з таким shop_id не знайдений |
merchant_not_active | 403 | Мерчант не активований |
merchant_inactive_deactivated | 403 | Мерчант деактивований через відсутність активності (30 днів без оплат) |
invalid_signature | 401 | Невірний або прострочений HMAC-підпис. Перевірте timestamp (вікно ±300 с), nonce та правильність обчислення |
invalid_amount | 400 | Некоректна сума: має бути позитивним числом, до 2 знаків після коми |
invalid_amount_minor | 400 | amount_minor має бути позитивним цілим числом |
external_id_required | 400 | Поле external_id обов'язкове |
external_id_too_long | 400 | external_id перевищує 191 символ |
invalid_external_id | 400 | external_id містить неприпустимі символи (допустимі: літери, цифри, ._:@#-) |
description_too_long | 400 | description перевищує 255 символів |
request_blocked | 429 | Запит заблокований антифрод-системою (перевищено ліміт або підозріла активність) |
invoice_not_found | 404 | Рахунок не знайдений |
invoice_create_failed | 500 | Внутрішня помилка при створенні рахунку |
Прямий checkout URL
Для ініціалізації платежу через єдину форму оплати достатньо направити користувача за спеціальною URL-адресою, а також передати ряд обов'язкових параметрів.
URL форми оплати:
https://aifo.pro/pay/?shop_id=ID&pay_id=ORDER_ID&amount=AMOUNT&sign=SIGNФорма оплати містить усі необхідні дані для проведення платежу. Передається методом GET/POST на адресу.
| Параметр | Примітка | Тип |
|---|---|---|
shop_id |
ID каси, можна отримати в налаштуваннях проєкту. | Обов'язковий. |
amount |
Сума платежу. | Обов'язковий. |
pay_id |
Номер рахунку. Може бути ваш ID замовлення (виджет або пряме посилання) або системний invoice_id (посилання з API). Система спочатку шукає інвойс за вашим id (invoice_uid), потім за invoice_id. | Обов'язковий. |
sign |
Підпис платежу. | Обов'язковий. |
desc |
Коментар до платежу. | Необов'язковий. |
- Ваш ID замовлення — для посилань з віджету в налаштуваннях каси або згенерованих вручну. Підпис: hash(shop_id:amount:secret:ваш_id). Система спочатку шукає інвойс за вашим id.
- Системний invoice_id — для посилань з API (payment_url після створення через API). Якщо за вашим id інвойс не знайдено і pay_id — число, використовується пошук за invoice_id. Рекомендується використовувати payment_url з відповіді API, не формувати посилання вручну.
Підпис для створення платежу формується шляхом обчислення SHA256 || SHA1 || SHA512 || SHA384 || RIPEMD160-хешу. Рекомендується SHA256.
Увага: MD5 застарілий і небезпечний. Використовуйте SHA256 або інші безпечні алгоритми.
Важливо: Для генерації підпису використовуйте секретний ключ (kassa_secretkey), а не публічний ключ. Секретний ключ доступний тільки вам і не повинен публікуватися.
Приклад коду на PHP (підпис):
$shop_id = 123; // your shop ID
$amount = '100.50'; // payment amount (string)
$secret_key = 'YOUR_SECRET'; // secret key from merchant settings
$order_id = 'ORDER-456'; // your order ID (string or number)
// SHA-256 (default, recommended)
$sign = hash('sha256', $shop_id . ':' . $amount . ':' . $secret_key . ':' . $order_id);
// SHA-1 (legacy only — not recommended)
// $sign = hash('sha1', $shop_id . ':' . $amount . ':' . $secret_key . ':' . $order_id);
// Build checkout URL:
$payment_url = 'https://aifo.pro/pay/'
. '?shop_id=' . $shop_id
. '&pay_id=' . urlencode($order_id)
. '&amount=' . $amount
. '&sign=' . $sign;
Перевірка IP
Рекомендуємо перевіряти IP сервера, що надсилає інформацію. Наші IP — 77.83.102.155
Приклад коду на PHP:
function getIP() {
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
return $_SERVER['REMOTE_ADDR'];
}
$allowed = array('77.83.102.155');
if (!in_array(getIP(), $allowed)) die('hacking attempt!');
Сповіщення про платіж
Після ініціалізації оплати користувач переходить на сторінку чеку, де відбувається відстеження статусу платежу. При отриманні успішного або помилкового статусу користувач перенаправляється на сайт партнера (поля Fail URL / Success URL у налаштуваннях кабінету) з POST-параметрами:
POST-параметри повідомлення
| Параметр | Примітка |
|---|---|
sum |
Сума платежу. |
invoice |
Номер рахунку. |
http_auth_signature |
Підпис, згенерований у MD5 || SHA1 || SHA256 || SHA512 || SHA384 || RIPEMD160 із секретним ключем. |
aifo_event_id |
Унікальний ID події, наприклад invoice.456.paid.1705309800 |
aifo_timestamp |
Unix-час відправки повідомлення |
aifo_signature_version |
v2 |
aifo_signature |
HMAC-SHA256 всіх полів payload (крім aifo_signature): ksort + http_build_query |
HTTP-заголовки повідомлення (додатково)
| Параметр | Примітка |
|---|---|
X-Signature | Підпис, згенерований у MD5 || SHA1 || SHA256 || SHA512 || SHA384 || RIPEMD160 із секретним ключем. |
X-AIFO-Signature | HMAC-SHA256 всіх полів payload (крім aifo_signature): ksort + http_build_query |
X-AIFO-Timestamp | Unix-час відправки повідомлення |
X-AIFO-Event-Id | Унікальний ID події, наприклад invoice.456.paid.1705309800 |
Формула legacy-підпису у webhook: hash(sha256, shop_id:sum:secret_key:invoice), де invoice — значення поля invoice з POST (ваш external_id або системний invoice_id).
Приклад обробника платежу
Рекомендується також перевіряти суму платежу та те, що запит ще не був оплачений.
Приклад обробника на PHP:
Після перевірки — оновіть статус замовлення у вашій БД. Обов'язково поверніть рядок ok (HTTP 200) — інакше сервер повторить відправку повідомлення.
<?php
// webhook.php — handler for payment notifications
function getIP() {
if (isset($_SERVER['HTTP_X_REAL_IP'])) return $_SERVER['HTTP_X_REAL_IP'];
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) return $_SERVER['HTTP_CF_CONNECTING_IP'];
return $_SERVER['REMOTE_ADDR'];
}
// 1. IP whitelist check (get actual IPs from the "IP Check" section above)
$allowed = array('77.83.102.155');
if (!in_array(getIP(), $allowed)) {
http_response_code(403);
die('Forbidden');
}
// 2. Incoming data
$sum = $_POST['sum'] ?? '';
$invoice = $_POST['invoice'] ?? '';
$legacySig = $_POST['http_auth_signature'] ?? '';
$aifoSig = $_POST['aifo_signature'] ?? '';
$shop_id = 123; // your shop_id
$secret_key = 'YOUR_SECRET_KEY'; // secret key from merchant panel
// 3. Verify legacy signature
$expected = hash('sha256', $shop_id . ':' . $sum . ':' . $secret_key . ':' . $invoice);
if (!hash_equals($expected, $legacySig)) {
http_response_code(400);
die('Error signature');
}
// 4. (Optional) Verify aifo_signature for extra security
if ($aifoSig !== '') {
$payload = $_POST;
unset($payload['aifo_signature']);
ksort($payload);
$expectedHmac = hash_hmac('sha256', http_build_query($payload, '', '&'), $secret_key);
if (!hash_equals($expectedHmac, $aifoSig)) {
http_response_code(400);
die('Error HMAC signature');
}
}
// 5. Check the invoice has not already been paid (prevent duplicate processing)
// $order = DB::find('orders', ['external_id' => $invoice]);
// if ($order && $order->status === 'paid') { echo 'ok'; exit; }
// 6. Update order status in your database
// DB::update('orders', ['status' => 'paid', 'paid_amount' => $sum], ['external_id' => $invoice]);
// IMPORTANT: Return "ok" (HTTP 200) — otherwise the server will retry the notification
echo 'ok';