Документация API

OpenAPI ↗К интеграциям →

Первый запрос

Подключите свой сайт к платежам FastPay. Начните с тестового ключа — без реальных оплат.

  1. 1

    Создайте ключ

    В разделе «Интеграции» выберите тестовый режим и права payments:read и payments:write.

  2. 2

    Сохраните на сервере

    Задайте FASTPAY_API_KEY в переменных окружения. Для FASTPAY_BASE_URL используйте адрес FastPay, например https://fastpay.ink.

  3. 3

    Проверьте подключение

    Запрос ниже вернёт бизнес и эффективный режим этого ключа. Он не создаёт платежей.

cURL · проверить ключ
curl "$FASTPAY_BASE_URL/api/v1/account" \
  -H "Authorization: Bearer $FASTPAY_API_KEY"

Примеры только копируются. Эта страница не отправляет API-запросы.

Один ключ — одно подключение.

Передавайте ключ в заголовке Authorization: Bearer …. Ключ привязан к бизнесу и режиму, выбранному при создании.

payments:read

Просмотр платежей, их статусов и расписаний.

payments:write

Создание и изменение платежей, возвраты и управление расписаниями.

Как определяется режим.

Эффективный режим будет тестовым, если тестовый режим выбран у ключа или у кабинета. Реальный запрос в Kaspi возможен только тогда, когда и ключ, и кабинет работают в боевом режиме. Поля keyEnvironment, workspaceMode и effectiveMode возвращаются методом GET /api/v1/account.

Не передавайте ключ в браузер.

Полный ключ показывается один раз. Если потеряли его — замените в кабинете и обновите на сервере. Старый ключ перестанет работать.

Счёт на телефон или QR.

Отправьте POST /api/v1/payments с правом payments:write. Сумма передаётся в тенге, не в тиынах.

cURL · тестовый QR на 100 ₸
curl -X POST "$FASTPAY_BASE_URL/api/v1/payments" \
  -H "Authorization: Bearer $FASTPAY_API_KEY" \
  -H "Idempotency-Key: order-42-attempt-1" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "qr",
    "amount": 100,
    "currency": "KZT",
    "externalOrderId": "ORDER-42"
  }'
method

Обязательно. qr — QR-код; invoice — счёт на телефон.

amount

Обязательно. Число больше 0, максимум 999 999 999.

customerPhone

Для invoice — номер без пробелов и «+», например 77001234567.

externalOrderId

Ваш номер заказа, до 200 символов. Не заменяет заголовок идемпотентности.

Ответ содержит data.id и data.status. При создании QR также возвращается data.qrCodeDataUrl.

Не создавайте дубли.

Для создания платежа и возврата обязателен Idempotency-Key длиной 8–200 символов. При повторе того же запроса передавайте тот же ключ. Срок хранения — 24 часа.

Проведите платёж от создания до возврата.

Тестовый QR открывает безопасную страницу FastPay и сам не меняет статус. Задайте результат через API или в деталях платежа в кабинете. Ни один из этих шагов не обращается в Kaspi.

  1. 1

    Создайте платёж

    Выполните запрос из раздела выше и сохраните data.id как PAYMENT_ID.

  2. 2

    Имитируйте оплату

    Передайте один из результатов: paid, failed, expired или cancelled.

  3. 3

    Проверьте интеграцию

    Получите платёж через API и убедитесь, что вебхук принял соответствующее событие.

  4. 4

    Проверьте возврат

    После результата paid верните тестовую сумму без подключения Kaspi.

cURL · имитировать успешную оплату
curl -X POST "$FASTPAY_BASE_URL/api/v1/payments/PAYMENT_ID/simulate-status" \
  -H "Authorization: Bearer $FASTPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"paid"}'
cURL · вернуть тестовый платёж
curl -X POST "$FASTPAY_BASE_URL/api/v1/payments/PAYMENT_ID/refunds" \
  -H "Authorization: Bearer $FASTPAY_API_KEY" \
  -H "Idempotency-Key: refund-order-42-attempt-1" \
  -H "Content-Type: application/json" \
  -d '{"amount":100}'
Тестовые данные отделены от реальных.

Тестовый ключ не может вернуть реальный платёж. Уже созданный тестовый платёж остаётся тестовым, даже если позже переключить кабинет в боевой режим.

Проверяйте статус, а не скриншот.

Замените PAYMENT_ID на data.id созданного платежа.

cURL · статус платежа
curl "$FASTPAY_BASE_URL/api/v1/payments/PAYMENT_ID" \
  -H "Authorization: Bearer $FASTPAY_API_KEY"
Ожидает оплаты

created, requires_customer_action, pending

Оплачен

paid

Не оплачен

failed, expired, cancelled

unknown не подтверждает оплату — дождитесь уточнения. Возвраты: partially_refunded или refunded.

Полный сценарий имитации оплаты и возврата приведён в разделе «Тестовый цикл».

Получайте изменения автоматически.

Добавьте webhook URL в настройках ключа. FastPay отправляет на него POST с событием и данными платежа. Сохраните отдельный секрет подписи webhook на сервере.

  1. Проверьте X-Webhook-Timestamp и подпись X-Webhook-Signature по исходному телу запроса.
  2. Обработайте событие один раз: используйте X-Webhook-Id для защиты от повторов.
  3. После сохранения события верните ответ 2xx.
Node.js · проверка подписи
import { createHmac, timingSafeEqual } from 'node:crypto';

// rawBody is the original body Buffer, before JSON.parse.
export function verifyWebhook(headers, rawBody, secret) {
  const timestamp = headers['x-webhook-timestamp'];
  const signature = headers['x-webhook-signature'];
  if (typeof timestamp !== 'string' ||
      typeof signature !== 'string' ||
      !/^\d+$/.test(timestamp) ||
      !/^sha256=[a-f0-9]{64}$/.test(signature)) return false;

  // A five-minute window is the receiver policy.
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300)
    return false;

  const expected = 'sha256=' + createHmac('sha256', secret)
    .update(timestamp + '.').update(rawBody).digest('hex');
  return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

Подпись: sha256= + hex HMAC-SHA256 от timestamp + "." + rawBody. Не вычисляйте подпись по повторно сериализованному JSON. X-Webhook-Delivery обозначает доставку, а не уникальное событие.

Посмотреть историю доставок в кабинете →

Если запрос не прошёл.

400

Проверьте обязательные поля и формат значений.

401 / 403

Проверьте ключ, его режим и разрешения.

404

Объект не найден в бизнесе, которому принадлежит ключ.

409

Конфликт состояния или тот же Idempotency-Key с другим содержимым запроса.

502

Операция не завершилась у провайдера. Проверьте статус платежа перед повтором.

Ответ ошибки содержит error и может содержать requestId. Сохраните requestId для разбора ошибки; API-ключ в логи не записывайте.

Все методы.

Общий префикс — /api/v1. Полные схемы запросов и ответов — в OpenAPI.

GET/account

Проверить ключ и получить бизнес

Любой ключ
POST/payments

Создать QR или счёт на телефон

payments:write
GET/payments

Список платежей

payments:read
GET/payments/{id}

Статус платежа

payments:read
PATCH/payments/{id}

Изменить внутреннюю заметку

payments:write
POST/payments/{id}/cancel

Отменить ожидающий счёт на телефон

payments:write
POST/payments/{id}/refunds

Оформить возврат

payments:write
POST/payments/{id}/simulate-status

Изменить статус в тестовом режиме

payments:write
GET/subscriptions

Список расписаний

payments:read
POST/subscriptions

Создать расписание счетов

payments:write
GET/subscriptions/{id}

Получить расписание

payments:read
PUT/subscriptions/{id}

Изменить расписание

payments:write
POST/subscriptions/{id}/pause

Приостановить расписание

payments:write
POST/subscriptions/{id}/resume

Возобновить расписание

payments:write
POST/subscriptions/{id}/cancel

Отменить расписание

payments:write
GET/subscriptions/{id}/invoices

Счета по расписанию

payments:read