nspay

Concepts

Operations, statuses, amounts, and currencies.

Operations

Everything in the API revolves around a single concept: an operation.

  • A payment is an operation where money flows toward the merchant.
  • A payout is an operation where money flows from the merchant to a client.

Each operation is identified in the public API by a server-issued operation_id (UUID). It is deterministic — derived from your (shop, merchant_operation_id) pair, not randomly generated — so retrying the same create request always resolves to the same operation_id (idempotency by construction). Your merchant_operation_id is an idempotency key for creates, but it is not echoed in responses or webhooks.

Status lifecycle

An operation moves through one of these statuses:

StatusMeaning
pendingThe operation was accepted and is waiting on the provider.
awaiting_confirmation(Payments only) The route requires a receipt — the payment is waiting for the merchant to upload a receipt via POST /v1/confirm_payment. Non-terminal; a webhook fires on entry so you can prompt the user immediately.
completedFunds settled successfully. Terminal.
failedThe provider was reached but rejected the operation. Terminal.
rejectedNo route accepted the operation, or it was rejected before being routed. Terminal.
cancelledThe operation was explicitly cancelled through an active cancellation path. Terminal.

A terminal webhook is delivered when the status passes the shop's callback status filter; an empty filter means all terminal statuses. A one-shot, best-effort callback is also attempted when the operation enters awaiting_confirmation (see Webhooks).

Amounts

Amounts are encoded as decimal strings, not numbers, to avoid floating-point loss across systems. The fixed scale is 2 (two decimal places):

"amount": "1500.00"

That is 1500.00 RUB, i.e. 150 000 minor units (kopecks). The same encoding is used for expected_amount and actual_amount in responses.

When confirming a payment via multipart, the actual_amount form field follows the same decimal-string format.

Settlement and commission

Operation responses and webhooks also carry what actually moved on your balance after the nspay commission:

  • commission_amount — the nspay commission for the operation.
  • settlement_amount — the net balance movement. For a payment it is the amount credited to you (gross − commission_amount); for a payout it is the total charged to you (gross + commission_amount).
  • settlement_currency — the currency both figures are expressed in (the ledger currency; equal to currency when the route did not convert, or to recorded_currency when it did).

Before an operation is terminal these reflect the expected figures for the routed amount; on a partial capture they settle to the captured amount. They always match what nspay books internally, so you can reconcile your balance directly against settlement_amount.

Currencies

The currency is sent as an ISO 4217 alphabetic code:

"currency": "RUB"

Today the production routing supports RUB via the White Triangle payment methods. Additional currencies and methods are added without API changes — the field stays a free string and is validated on the server.

Payment methods

The method field on payment/payout requests names a logical method, not a specific provider. Routing to a concrete provider is configured per merchant. The currently supported values are:

  • WT_RUB_C2C — RUB via the card rail. Destination is keyed by number (card number).
  • WT_RUB_PHONE — RUB via the consumer-to-consumer rail. Destination is keyed by number (phone number) plus bankname.

Sending an unknown method results in a 400 Bad Request.

Destinations

Payments and payouts share a unified destination shape with three fields:

FieldWT_RUB_C2CWT_RUB_PHONE
numbercard numberphone number
namecardholder namerecipient name
banknameignoredrequired (see bank codes below)

For payouts, the merchant fills the destination — that's the recipient the funds go to.

For payments, the destination is the inbound account the end user should transfer funds to. It is allocated by nspay once the operation is routed and surfaced back on the response and webhook so the merchant can display it to the user. Until allocation completes, the destination fields are absent from the response.

Bank codes

On the WT_RUB_PHONE rail the bank is required and must be one of the following codes (case-sensitive). Sending any other value results in a 400 Bad Request.

CodeBank
sberСбербанк
tcsТ-Банк (Тинькофф)
alfaАльфа-Банк
vtbВТБ
ozonОзон Банк
raifРайффайзенбанк
gazpromГазпромбанк
otkritieБанк Открытие
sovcomСовкомбанк
psbПромсвязьбанк
mtsМТС Банк
yandexЯндекс Банк
rshbРоссельхозбанк
pochtaПочта Банк
rosbankРосбанк
uralsibУралсиб
akbarsАк Барс
homecreditХоум Кредит
rnkbРНКБ
yoomoneyЮMoney
wildberriesВайлдберриз Банк (WB)
zenitБанк Зенит
vbrrБанк ВБРР

Confirmation requests

Some payment methods require an out-of-band confirmation step. When the provider needs one, the operation response contains:

"external_confirmation": {
  "required": true,
  "methods": ["receipt"],
  "reason": "manual receipt verification"
}

When required is true, call POST /v1/confirm_payment with confirmation_type=receipt to advance the operation. Public confirmation always requires a receipt: a multipart receipt upload with a required file of up to 10 MB. Clean receipt validation can complete the payment automatically, while failed, wrong-amount, or unavailable validation leaves the operation pending for an operator, with the final status delivered by webhook. Confirming without a receipt is not supported on the public API.

On this page