Переход с v1 на v2

Diff между v1 и v2, sunset timeline, чеклист миграции

v1 продолжает работать, но переведена в режим deprecated. Финальный sunset — 31 декабря 2026. v2 предлагает идемпотентность, курсорную пагинацию, унифицированные ошибки и payment links.

Что нового в v2

  • Idempotency-Key стал обязательным для POST /v2/qr, /v2/invoices, /v2/refunds
  • Cursor pagination вместо offset на всех списочных эндпоинтах
  • Унифицированные ошибки{error: {type, code, message, request_id}}
  • Payment Links — новая сущность, нет аналога в v1
  • OpenAPI 3.1 с примерами для всех эндпоинтов
  • HTTPS-only, минимум TLS 1.2

Соответствие эндпоинтов

v1 (deprecated)v2 (актуально)Изменения
POST /v1/qr/createPOST /v2/qrIdempotency-Key обязателен; ответ нормализован
GET /v1/qr/status/{id}GET /v2/qr/{operation_id}Параметр в path
POST /v1/invoice/createPOST /v2/invoicesIdempotency-Key обязателен
POST /v1/invoice/cancelPOST /v2/invoices/{id}/cancelREST-стиль
POST /v1/historyGET /v2/paymentsGET вместо POST, cursor pagination
POST /v1/refundPOST /v2/refundsIdempotency-Key обязателен
GET /v1/client/{phone}GET /v2/client?phone=Query вместо path
POST /v2/payment-linksНовая сущность
GET /v2/eventsНовый journal

Sunset timeline

ДатаЧто происходит
сейчасv1 работает, в ответах Deprecation: true, Sunset и Link headers
1 июля 2026Email-напоминание всем активным v1-аккаунтам
1 октября 2026v1 включает throttling: 5 req/min на эндпоинт
31 декабря 2026v1 возвращает 410 Gone

Deprecation headers

На каждом ответе v1:

code
Deprecation: true
Sunset: Wed, 31 Dec 2026 23:59:59 GMT
Link: </v2/qr>; rel="successor-version"

Используйте Sunset и Link для автоматического алерта в мониторинге: «обнаружен deprecated-эндпоинт».

Diff-таблица: создание QR

v1

bash
Скачать
curl -X POST https://payapi.aibot.kz/v1/qr/create \
  -H "X-API-Key: kp_live_xxx" \
  -d '{"amount": 5000}'
json
Скачать
{
  "Data": {
    "QrOperationId": 14837690870,
    "Status": "QrTokenCreated",
    "QrToken": "https://qr.kaspi.kz/...",
    "ExpireDate": "2026-05-11T12:05:00+05:00"
  },
  "StatusCode": 0,
  "Message": "OK"
}

v2

bash
Скачать
curl -X POST https://payapi.aibot.kz/v2/qr \
  -H "X-API-Key: kp_live_xxx" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"amount": 5000}'
json
Скачать
{
  "operation_id": 14837690870,
  "status": "QrTokenCreated",
  "qr_token": "https://qr.kaspi.kz/...",
  "expire_date": "2026-05-11T12:05:00+05:00",
  "amount": 5000
}

Главное: больше нет обёртки Data/StatusCode/Message. Поля в snake_case. Ошибки — в отдельной структуре error.

Diff: список платежей

v1

bash
POST /v1/history
{"page": 1, "limit": 25}

v2

bash
GET /v2/payments?cursor=&limit=25

В v2 первый запрос без cursor, далее — со значением из next_cursor. См. Пагинацию.

Diff: ошибки

v1

json
Скачать
{
  "StatusCode": 9,
  "Message": "Invalid amount",
  "Data": null
}

Коды — числовые, не документированы. Машинно-обрабатывать сложно.

v2

json
Скачать
{
  "error": {
    "type": "validation_error",
    "code": "amount_too_small",
    "message": "Минимальная сумма платежа — 100 тенге",
    "request_id": "req_abc123",
    "param": "amount"
  }
}

Полная таблица — Коды ошибок.

Чеклист миграции

  • Заменить базовый путь /v1/ на /v2/ в коде
  • Сменить shape ответа: убрать data.Data.*, использовать корневые поля
  • Добавить Idempotency-Key на все POST в /v2/qr, /v2/invoices, /v2/refunds
  • Заменить POST /v1/history {page} на GET /v2/payments?cursor=
  • Обновить error handling: ловить error.code, не StatusCode
  • Запустить через kp_test_* ключ, прогнать тестовые сценарии
  • Переключить продакшен на https://payapi.aibot.kz (новый домен)
  • Мониторинг: ловить заголовок Deprecation: true — он значит, что код ещё стучит в v1

Параллельная работа

v1 и v2 разделяют одни и те же объекты в БД. Можно мигрировать постепенно:

  • QR, созданный через v1, доступен в GET /v2/qr/{id}
  • Платёж, оплаченный через v1, попадёт в GET /v2/payments
  • Webhooks работают для обеих версий — формат payload в headers и body совпадает

Это позволяет переезжать модуль за модулем без downtime.

Что дальше