Квази-еком (quasi_ecom)
Плательщик вводит карту и, если банк прислал SMS, код из сообщения. Создайте платёж с method: "quasi_ecom" и валютой AZN или TRY — в ответе будет checkoutUrl. Подпись и webhook как у обычного платежа.
Три варианта: вся оплата на нашей странице, карта у вас а код на нашей ссылке, или оба шага на вашем сайте.
Создание
/api/v1/paymentsНужны orderId, amount, currency (AZN / TRY), callbackUri, method: "quasi_ecom". Поля requisite в ответе нет — вместо него ссылка. Передайте payer.userId (id игрока у вас): после того как он один раз введёт карту, на этой же кассе следующие платежи того же игрока откроются с уже заполненным номером, сроком и именем. CVV каждый раз вводится заново.
{
"orderId": "az-order-001",
"amount": "50",
"currency": "AZN",
"callbackUri": "https://example.com/hooks/protopays",
"method": "quasi_ecom",
"payer": { "userId": "1" }
}{
"message": "Payment created",
"data": {
"id": "<uuid>",
"orderId": "az-order-001",
"status": "pending",
"amount": "50.00",
"currency": "AZN",
"method": "quasi_ecom",
"checkoutUrl": "https://pay.protopays.io/pay/ckt_<token>",
"quasiEcom": {
"phase": "awaiting_payer_details",
"codeResendCount": 0,
"codeResendMax": 3,
"attemptsLeft": 3,
"nextAllowedAt": null,
"codeResendLastBy": null,
"codeResendLastAt": null
},
"expiresAt": "2026-06-27T16:15:00+00:00"
}
}Для TRY — то же самое с currency: "TRY". Метод должен быть включён на вашей кассе.
Готовая страница
Отправьте плательщика на checkoutUrl. На странице два шага:
- Карта (номер, срок, CVV) → «Оплатить»
- Код из SMS — только если банк прислал SMS. Если кода нет, плательщик ничего не вводит и ждёт завершения оплаты.
Если в создании платежа был payer.userId и этот игрок уже вводил карту на этой кассе — номер, срок и имя подставятся сами. CVV нужно ввести снова.
Если карту вы уже отправили через API (см. Карта у себя), берите из ответа otpUrl — плательщик увидит только форму кода.
Итог придёт в webhook.
Карта у себя
Карту отправляете вы через API. В ответе придёт otpUrl — откройте её плательщику: на странице только ввод кода из SMS, без полей карты.
- Создайте платёж — возьмите токен из
checkoutUrl(путь после/pay/). - Со своего сервера отправьте карту на
POST /api/v1/checkout/{token}/payer-details(подпись мерчанта не нужна). - Из ответа возьмите
data.otpUrlи откройте её плательщику.
https://api.protopays.io/api/v1/checkout/{token}/payer-details{
"pan": "4111111111111111",
"expMonth": "12",
"expYear": "30",
"cvv": "123",
"cardHolder": "Anar Rzayev"
}Ответ — ссылка на ввод кода:
{
"message": "Данные карты приняты. Откройте otpUrl плательщику для ввода кода из SMS.",
"data": {
"amount": "50.00",
"currency": "AZN",
"phase": "awaiting_trader_bank_sms",
"orderIdMasked": "…0001",
"expiresAt": "2026-06-27T16:15:00+00:00",
"paymentStatus": "pending",
"isTerminal": false,
"otpUrl": "https://pay.protopays.io/pay/ckt_<token>"
}
}Код можно принять на странице по otpUrl или отправить сами через POST …/payer-otp (см. «Своя страница»).
Своя страница
Возьмите токен из URL после /pay/ (это не data.id). Подпись мерчанта на этих запросах не нужна. Финал — webhook или isTerminal: true в GET статуса.
Карта
https://api.protopays.io/api/v1/checkout/{token}/payer-details| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| pan | string | да | Номер карты. |
| expMonth | string | да | Месяц (1–2 цифры). |
| expYear | string | да | Год (2 или 4 цифры). |
| cvv | string | да | CVV, 3–4 цифры. |
| cardHolder | string | нет | Имя на карте (Ad Soyad), до 64 символов. |
{
"pan": "4111111111111111",
"expMonth": "12",
"expYear": "30",
"cvv": "123",
"cardHolder": "Anar Rzayev"
}SMS
https://api.protopays.io/api/v1/checkout/{token}/payer-otpКод из SMS банка, 4–8 цифр. Можно отправить сразу после карты. Если банк код не просит — этот шаг можно пропустить; итог придёт в webhook.
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| otp | string | нет | Код из SMS, только цифры, от 4 до 8. Нужен, если банк запросил SMS. |
{ "otp": "123456" }Отмена
https://api.protopays.io/api/v1/checkout/{token}/cancelПлательщик отменяет оплату на странице checkout. Платёж сразу становится cancelled для трейдера и мерчанта (webhook).
Реквизиты плательщика в webhook
После ввода карты в статусных webhook и в GET /api/v1/payments/{id} приходит payerRequisites: cardLast4 и при наличии cardHolder. Полный номер карты, CVV, OTP и срок действия не передаём. Подробнее — webhook.
Статус
https://api.protopays.io/api/v1/checkout/{token}По желанию опрашивайте раз в 2–5 с, чтобы увидеть финал на странице.
Повторный код
Если SMS от банка не пришла или код устарел — вызовите этот метод один раз по событию «код не пришёл». Не опрашивайте статус платежа ради повторной отправки. ProtoPays не шлёт SMS в банк: запрос только сбрасывает сохранённый код в заявке и даёт трейдеру сигнал снова запросить SMS в личном кабинете банка.
/api/v1/payments/{id}/quasi-ecom/resend-codeПодпись как у остальных merchant-запросов (пустое тело {}). Пауза между вызовами — около 45 секунд; не больше трёх попыток на одну заявку.
200— принято; в ответеattemptsLeftиnextAllowedAt429— слишком рано; подождите доnextAllowedAt422— лимит исчерпан или неверный шаг оплаты
{
"message": "Повторный запрос кода принят.",
"data": {
"phase": "awaiting_payer_otp",
"attemptsLeft": 2,
"nextAllowedAt": "2026-07-27T15:01:00+00:00",
"codeResendCount": 1,
"codeResendMax": 3,
"codeResendLastBy": "merchant",
"codeResendLastAt": "2026-07-27T15:00:15+00:00"
}
}Если повторный код запросил трейдер, на ваш callbackUri придёт webhook payment.quasi_ecom.code_resend (статус платежа остаётся PENDING). В data.requestedBy будет trader. То же видно в GET статуса: quasiEcom.codeResendLastBy / codeResendLastAt.
{
"type": "payment.quasi_ecom.code_resend",
"eventId": "evt_01hz…",
"createdAt": "2026-07-27T15:00:15Z",
"data": {
"id": "<uuid>",
"orderId": "az-order-001",
"status": "PENDING",
"amount": "50",
"currency": "AZN",
"requestedBy": "trader",
"quasiEcom": {
"phase": "awaiting_payer_otp",
"codeResendCount": 1,
"codeResendMax": 3,
"attemptsLeft": 2,
"codeResendLastBy": "trader",
"codeResendLastAt": "2026-07-27T15:00:15+00:00"
}
},
"id": "<uuid>",
"order_id": "az-order-001"
}Фазы
SMS можно отправить сразу после карты. Код не обязателен, если банк его не запрашивает.
awaiting_payer_details— ввод картыawaiting_payer_otp— ждём код (если банк запросил SMS)awaiting_trader_confirm— данные приняты, ждём завершения
PAN/CVV на сервере шифруются; сессия действует до expiresAt.