Перейти к содержимому
ZeroKYC Pay

Лимиты и идемпотентность

Лимиты на ключ с заголовками X-RateLimit и Retry-After, плюс семантика Idempotency-Key: реплеи, конфликты, 24-часовое окно.

Два механизма делают интеграцию надёжной под нагрузкой и при ретраях: лимиты на ключ и идемпотентное создание инвойсов.

Лимиты

Лимиты считаются на ключ API в фиксированном 60-секундном окне:

ScopeЭндпоинтыLive-ключSandbox-ключ (pk_test_…)
Создание инвойсовPOST /v1/invoices30 / мин10 / мин
ЧтениеGET /v1/invoices…, /v1/events, /v1/payouts300 / мин90 / мин

Каждый авторизованный ответ несёт счётчики — гадать не приходится:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 27
X-RateLimit-Reset: 1694007937

X-RateLimit-Reset — Unix-timestamp конца окна. При превышении API отвечает 429 rate_limited с дополнительным заголовком Retry-After: <секунды> — дождитесь его, не крутите цикл вплотную. Если ваш чекаут легитимно требует больше, батчите создание заказов или напишите нам о повышении лимита.

Про опрос: GET /v1/invoices/{id} раз в несколько секунд на открытый чекаут — сильно ниже бюджета на чтение. Опрос обычно вообще не нужен: вебхук — основной канал; опрос — запасной.

Идемпотентное создание инвойсов

POST /v1/invoices принимает заголовок Idempotency-Key (до 120 символов). Отправляйте его при каждом создании — он превращает ретраи после сетевых таймаутов из «случайный дубль инвойса» в «тот же инвойс вернулся снова»:

  • Тот же ключ + то же тело в течение 24 часов → исходный инвойс вернётся снова со статусом 201 и дополнительным заголовком Idempotent-Replay: true. Это не дубль и не ошибка.
  • Тот же ключ + другое тело → 409 idempotency_conflict. Ключ привязывается к точному телу запроса (канонический хеш): изменили payload — меняйте и ключ.
  • Ключи скоупятся на мерчанта и на режим: один и тот же ключ с pk_test_… и позже с pk_live_… никогда не столкнутся.
curl -X POST https://api.zerokyc-payments.com/v1/invoices \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-create" \
  -d '{"amount": "49.00", "order_id": "order-1042", "payment_currency": "any"}'

Хороший ключ детерминирован — стройте его из своего order id и намерения (order-1042-create), тогда ретрай после крэша или таймаута переиспользует его автоматически. Случайные ключи лишают механизм смысла.

Как это сочетается

  1. Создавайте с детерминированным Idempotency-Key; и 201 с Idempotent-Replay, и без него — успех; сохраняйте id инвойса против своего заказа.
  2. При 429 — спать Retry-After секунд и повторить тот же запрос: идемпотентность делает это безопасным.
  3. При 5xx/таймаутах — ретраить с экспоненциальным бэкоффом, тот же ключ, то же тело.
  4. Исполняйте заказ по вебхуку payment.confirmed; чтение — для сверки, а не как основной сигнал.