Надёжность

Идемпотентность

Сетевой сбой может оборвать ответ, хотя платёж уже создан. Ключ идемпотентности позволяет безопасно повторить запрос: второй платёж не появится, вы получите первый ответ.

Запрос с ключом идемпотентности
curl -X POST https://api.nordpay.pro/v1/payments \
  -H "Authorization: Bearer $NORDPAY_SECRET_KEY" \
  -H "Idempotency-Key: 3f1b8a52-6c0e-4d1a-9b7e-21c4f0a9e5d3" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 499000,
    "currency": "RUB",
    "method": "sbp",
    "description": "Заказ №1042",
    "order_id": "1042",
    "customer": {
      "email": "buyer@example.com"
    },
    "return_url": "https://shop.example/orders/1042",
    "metadata": {
      "cart_id": "c_77"
    }
  }'

Ключ идемпотентности

Передайте заголовок Idempotency-Key в любом POST-запросе — создании платежа, ссылки, подписки, возврата. Значение — уникальная строка, удобнее всего UUID v4.

  • Ключ хранится 24 часа. В течение этого времени повтор с тем же ключом и тем же телом вернёт сохранённый ответ.
  • У повторного ответа есть заголовок Idempotent-Replayed: true.
  • Генерируйте новый ключ для каждой новой операции и сохраняйте его вместе с заказом, чтобы повторять попытку тем же ключом.
  • GET-запросы идемпотентны сами по себе, ключ для них не нужен.
Повторный ответ
HTTP/1.1 201 Created
Idempotent-Replayed: true
X-Request-Id: req_c27d90f1e4
Повтор с тем же ключом
import crypto from 'node:crypto';

export async function createPaymentSafely(body, attempts = 4) {
  const key = crypto.randomUUID();
  for (let i = 0; i < attempts; i++) {
    try {
      const res = await fetch('https://api.nordpay.pro/v1/payments', {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${process.env.NORDPAY_SECRET_KEY}`,
          'Content-Type': 'application/json',
          'Idempotency-Key': key,
        },
        body: JSON.stringify(body),
      });
      if (res.status < 500 && res.status !== 429) return res.json();
    } catch {}
    await new Promise((r) => setTimeout(r, 500 * 2 ** i));
  }
  throw new Error('NordPay API недоступен');
}

Конфликт

Если ключ уже использован с другим телом запроса, API ответит 409 с кодом idempotency_conflict. Обычно это значит, что один ключ случайно переиспользовали для разных заказов.

Не повторяйте с тем же ключом запросы, которые завершились ошибкой валидации 422: исправьте параметры и отправьте запрос с новым ключом.
Ответ · 409
{
  "error": {
    "type": "invalid_request_error",
    "code": "idempotency_conflict",
    "message": "Ключ идемпотентности уже использован с другими параметрами",
    "request_id": "req_5a0e81bb3c"
  }
}