protopaysAPI

Квази-еком (quasi_ecom)

Плательщик вводит карту и, если банк прислал SMS, код из сообщения. Создайте платёж с method: "quasi_ecom" и валютой AZN или TRY — в ответе будет checkoutUrl. Подпись и webhook как у обычного платежа.

Три варианта: вся оплата на нашей странице, карта у вас а код на нашей ссылке, или оба шага на вашем сайте.

Создание

POST/api/v1/payments

Нужны orderId, amount, currency (AZN / TRY), callbackUri, method: "quasi_ecom". Поля requisite в ответе нет — вместо него ссылка. Передайте payer.userId (id игрока у вас): после того как он один раз введёт карту, на этой же кассе следующие платежи того же игрока откроются с уже заполненным номером, сроком и именем. CVV каждый раз вводится заново.

json
{
  "orderId": "az-order-001",
  "amount": "50",
  "currency": "AZN",
  "callbackUri": "https://example.com/hooks/protopays",
  "method": "quasi_ecom",
  "payer": { "userId": "1" }
}
json
{
  "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. На странице два шага:

  1. Карта (номер, срок, CVV) → «Оплатить»
  2. Код из SMS — только если банк прислал SMS. Если кода нет, плательщик ничего не вводит и ждёт завершения оплаты.

Если в создании платежа был payer.userId и этот игрок уже вводил карту на этой кассе — номер, срок и имя подставятся сами. CVV нужно ввести снова.

Если карту вы уже отправили через API (см. Карта у себя), берите из ответа otpUrl — плательщик увидит только форму кода.

Итог придёт в webhook.

Карта у себя

Карту отправляете вы через API. В ответе придёт otpUrl — откройте её плательщику: на странице только ввод кода из SMS, без полей карты.

  1. Создайте платёж — возьмите токен из checkoutUrl (путь после /pay/).
  2. Со своего сервера отправьте карту на POST /api/v1/checkout/{token}/payer-details (подпись мерчанта не нужна).
  3. Из ответа возьмите data.otpUrl и откройте её плательщику.
POSThttps://api.protopays.io/api/v1/checkout/{token}/payer-details
json
{
  "pan": "4111111111111111",
  "expMonth": "12",
  "expYear": "30",
  "cvv": "123",
  "cardHolder": "Anar Rzayev"
}

Ответ — ссылка на ввод кода:

json
{
  "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 статуса.

Карта

POSThttps://api.protopays.io/api/v1/checkout/{token}/payer-details
ПолеТипОбяз.Описание
panstringдаНомер карты.
expMonthstringдаМесяц (1–2 цифры).
expYearstringдаГод (2 или 4 цифры).
cvvstringдаCVV, 3–4 цифры.
cardHolderstringнетИмя на карте (Ad Soyad), до 64 символов.
json
{
  "pan": "4111111111111111",
  "expMonth": "12",
  "expYear": "30",
  "cvv": "123",
  "cardHolder": "Anar Rzayev"
}

SMS

POSThttps://api.protopays.io/api/v1/checkout/{token}/payer-otp

Код из SMS банка, 4–8 цифр. Можно отправить сразу после карты. Если банк код не просит — этот шаг можно пропустить; итог придёт в webhook.

ПолеТипОбяз.Описание
otpstringнетКод из SMS, только цифры, от 4 до 8. Нужен, если банк запросил SMS.
json
{ "otp": "123456" }

Отмена

POSThttps://api.protopays.io/api/v1/checkout/{token}/cancel

Плательщик отменяет оплату на странице checkout. Платёж сразу становится cancelled для трейдера и мерчанта (webhook).

Реквизиты плательщика в webhook

После ввода карты в статусных webhook и в GET /api/v1/payments/{id} приходит payerRequisites: cardLast4 и при наличии cardHolder. Полный номер карты, CVV, OTP и срок действия не передаём. Подробнее — webhook.

Статус

GEThttps://api.protopays.io/api/v1/checkout/{token}

По желанию опрашивайте раз в 2–5 с, чтобы увидеть финал на странице.

Повторный код

Если SMS от банка не пришла или код устарел — вызовите этот метод один раз по событию «код не пришёл». Не опрашивайте статус платежа ради повторной отправки. ProtoPays не шлёт SMS в банк: запрос только сбрасывает сохранённый код в заявке и даёт трейдеру сигнал снова запросить SMS в личном кабинете банка.

POST/api/v1/payments/{id}/quasi-ecom/resend-code

Подпись как у остальных merchant-запросов (пустое тело {}). Пауза между вызовами — около 45 секунд; не больше трёх попыток на одну заявку.

  • 200 — принято; в ответе attemptsLeft и nextAllowedAt
  • 429 — слишком рано; подождите до nextAllowedAt
  • 422 — лимит исчерпан или неверный шаг оплаты
json
{
  "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.

json
{
  "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 можно отправить сразу после карты. Код не обязателен, если банк его не запрашивает.

  1. awaiting_payer_details — ввод карты
  2. awaiting_payer_otp — ждём код (если банк запросил SMS)
  3. awaiting_trader_confirm — данные приняты, ждём завершения

PAN/CVV на сервере шифруются; сессия действует до expiresAt.