Перейти до вмісту

Вебхуки

Вебхук — це HTTP-запит, який Invoise надсилає на ваш сервер, коли змінюється платіж. Можна почати з перевірок статусу через GET і додати вебхуки, коли знадобляться автоматичні оновлення.

1. Зареєструйте свій ендпоінт

Section titled “1. Зареєструйте свій ендпоінт”
Terminal window
curl -X POST 'https://platform.invoise.me/api/v1/shops/{shop_id}/webhooks' \
-H 'Authorization: Bearer ivk_...' \
-H 'Idempotency-Key: <saved-unique-key>' \
-H 'Content-Type: application/json' \
-d '{"url":"https://example.com/invoise","filters":["transfer","invoice","payout"]}'

Використовуйте власну публічну HTTPS-адресу. Локальні та приватні адреси відхиляються. Збережіть secret, повернутий під час створення ендпоінту: він потрібен для перевірки запитів.

У магазину може бути до 10 ендпоінтів. URL ендпоінту можна змінити, тож використовуйте наявний замість додавання нового. Див. Ліміти.

2. Оберіть потрібні події

Section titled “2. Оберіть потрібні події”
Подія Значення
transfer.observed Переказ помічено; він ще не підтверджений.
transfer.confirmed Вхідний переказ має достатньо підтверджень. Це може бути лише частковий платіж за рахунком.
transfer.reverted Попередню подію переказу відкотили.
invoice.closed Рахунок закрився в мережі.
invoice.cancelled Сторінку оплати скасовано або в рахунку минув термін; це не повернення коштів.
payout.sent Виплату розіслано в мережу або помічено її вихідний переказ.
payout.confirmed Доступний повний облік розрахунку.
payout.reverted Попереднє підтвердження виплати відкотили.
payout.failed Остаточна невдача виплати потребує втручання.

Для invoice.cancelled data.reason пояснює причину: expired, коли скінчився термін дії рахунку, merchant_blocked, коли персонал Invoise заблокував мерчанта. Скасування мерчантом не має reason.

Підписуйтеся за групами: transfer, invoice, payout. Вхідні перекази та вихідні виплати — різні події. Тимчасова затримка RPC чи газу — це не payout.failed.

gas.wait і sweep.failed приймаються як фільтри, але Invoise не надсилає їх на ваш ендпоінт. Це внутрішні сигнали: gas.wait означає, що виплата очікує кошти на мережеву комісію й продовжується сама; sweep.failed означає, що спроба перемістити кошти вашому отримувачу не вдалася. Для жодного з них дія не потрібна. Виплата, яка не може завершитися, доходить до вас як payout.failed.

У магазині-пісочниці можна симулювати обидва через POST /shops/{shop_id}/sandbox/simulate, щоб перевірити, що затримана виплата не ламає ваш процес. Вони змінюють лише стан виплати й не надсилають вебхук.

3. Перевірте перед обробкою

Section titled “3. Перевірте перед обробкою”

Invoise-Signature має форму t=<timestamp>,v1=<hex>. Підпис — це HMAC-SHA256 від timestamp + "." + raw_body, з використанням вашого секрету вебхука.

Наступний приклад на Node.js також відхиляє часові мітки, що відрізняються від годинника сервера більш ніж на п’ять хвилин. Тримайте цей годинник синхронізованим і свідомо обирайте свій допуск.

import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(rawBody, header, secret) {
const match = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(header ?? '');
if (!match) return false;
const [, timestamp, signature] = match;
const age = Math.abs(Date.now() / 1000 - Number(timestamp));
if (!Number.isFinite(age) || age > 300) return false;
const expected = createHmac('sha256', secret)
.update(timestamp + '.')
.update(rawBody)
.digest();
return timingSafeEqual(Buffer.from(signature, 'hex'), expected);
}

Передавайте оригінальні байти запиту як rawBody. Не розбирайте JSON і не перетворюйте його назад у рядок перед перевіркою підпису. Відхиляйте неправильні підписи до збереження чи дії за їхнім вмістом.

Скорочений вміст виглядає так:

{
"id": "<event-id>",
"type": "transfer.confirmed",
"created_at": "2026-09-19T10:00:00Z",
"data": {
"issuance_id": "<issuance-id>",
"shop_id": "<shop-id>",
"external_id": "order-123",
"type": "invoice",
"invoice_cancelled": false
}
}
Випадок Обробка
Дублікати Усувайте дублікати за Invoise-Event-ID, який збігається з id конверта. Зберігайте ID і бізнес-оновлення атомарно.
Прийняття події Зберігайте прийняті події надійно, повертайте 2xx одразу, а чергу обробляйте потім.
Повтори й відтворення Повтори й ручні відтворення повторюють той самий ID події. Invoise-Attempt-ID змінюється і не є ключем усунення дублікатів.
Порядок подій Події можуть надходити не по порядку. Використовуйте їхній вміст і за потреби звіряйте з поточним статусом.

Для відкатів chain_event.reference_event_id вказує на попередню подію мережі. Дані виплати містять стабільний payout_id, хеш транзакції, суми та деталі комісії; невідомі суми — null. Список ID вхідних переказів у них обмежено 100 записами, з позначкою усічення.

Старіші збережені події можуть використовувати project_id; спершу читайте shop_id, а за потреби повертайтеся до нього. Відтворення зберігають оригінальні байти.

Перегляд невдалої доставки

Section titled “Перегляд невдалої доставки”

Список: GET /api/v1/shops/{shop_id}/deliveries. Повторіть доставку через POST /api/v1/shops/{shop_id}/deliveries/{id}/replay зі збереженим ключем ідемпотентності. Повтор не створює нову бізнес-подію.