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:
| Status | Meaning |
|---|---|
pending | The 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. |
pending_confirmation | (Payments only) The receipt was accepted and automatic validation is in progress. Non-terminal; do not request another upload. |
manual_check | (Payments only) The uploaded receipt requires manual review. Non-terminal — nothing more is needed from you or the end user; it will still resolve to completed or failed. manual_check_reason is potential_fake when the evidence is suspicious, or not_terminal when the receipt does not prove a completed transfer — it shows a transfer that has not reached a terminal status, or it is not a PDF and therefore could not be validated at all. |
completed | Funds settled successfully. Terminal. |
failed | The provider was reached but rejected the operation. Terminal. |
rejected | No route accepted the operation, or it was rejected before being routed. Terminal. |
cancelled | The operation was explicitly cancelled through an active cancellation path. Terminal. |
A webhook is delivered when the status passes the shop's callback-status filter;
an empty filter means all statuses below (terminals plus the intermediate
awaiting_confirmation / pending_confirmation / manual_check). A one-shot,
best-effort callback is attempted when the operation enters any of these three
receipt lifecycle statuses;
because the filter applies to them too, a shop that narrows the filter must list
an intermediate status explicitly to keep receiving it (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 CasherMatch commission:
commission_amount— the CasherMatch 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 tocurrencywhen the route did not convert, or torecorded_currencywhen 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 CasherMatch 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 bynumber(card number).WT_RUB_PHONE— RUB via the consumer-to-consumer rail. Destination is keyed bynumber(phone number) plusbankname.
Sending an unknown method results in a 400 Bad Request.
Destinations
Payments and payouts share a unified destination shape. bankname_details is
response-only and provides a human-readable bank name while bankname remains
the stable code:
| Field | Card rail (WT_RUB_C2C) | Phone rail (WT_RUB_PHONE) |
|---|---|---|
number | card number | phone number |
name | optional; defaults to аноним | optional; defaults to аноним |
bankname | ignored | required (see bank codes below) |
bankname_details | absent | response-only human-readable bank name |
bankname must belong to the same currency as the method; a bank code from
another currency's dictionary is rejected
with a 400 Bad Request.
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 CasherMatch 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 also results in a
400 Bad Request.
RUB banks (WT_RUB_PHONE)
| Code | Bank |
|---|---|
sber | Сбербанк |
tcs | Т-Банк |
alfa | Альфа-Банк |
vtb | ВТБ |
ozon | Озон Банк (Ozon) |
raif | Райффайзен Банк |
gazprom | Газпромбанк |
otkritie | Банк Открытие |
sovcom | Совкомбанк |
psb | Банк ПСБ |
mts | МТС-Банк |
yandex | Яндекс Банк |
rshb | Россельхозбанк |
pochta | Почта Банк |
rosbank | Росбанк |
uralsib | БАНК УРАЛСИБ |
akbars | Ак Барс Банк |
homecredit | Хоум Кредит |
rnkb | РНКБ |
yoomoney | НКО ЮМани |
wildberries | Вайлдберриз Банк |
zenit | Банк Зенит |
vbrr | Банк ВБРР |
otp | ОТП Банк |
akibank | АКИБАНК |
ingobank | Инго Банк |
forabank | ФОРА-БАНК |
unicredit | Юникредит Банк |
rencredit | Ренессанс Банк (Ренессанс Кредит) |
mkb | МКБ |
creditural | Кредит Урал Банк |
dvbank | Дальневосточный банк |
mobilecard | НКО Мобильная карта |
bspb | Банк Санкт-Петербург |
albank | Алмазэргиэнбанк |
absolut | Абсолют Банк |
severgaz | Севергазбанк |
atb | Азиатско-Тихоокеанский Банк |
mbrus | МБ РУС Банк |
tkb | Транскапиталбанк |
hlynov | КБ Хлынов |
kontur | Контур.Банк |
centrinvest | Центр-инвест |
rsb | Банк Русский Стандарт |
crediteurope | Кредит Европа Банк (Россия) |
ubrir | УБРиР |
toyota | Тойота Банк |
koshelev | КОШЕЛЕВ-БАНК |
Confirmation requests
Some payment methods require an out-of-band confirmation step. Only while the
operation status is awaiting_confirmation, 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 a
failed, wrong-amount, suspicious, or unavailable validation moves the operation
to manual_check for an operator, with the final status delivered by webhook.
Confirming without a receipt is not supported on the public API.
The field is omitted after the confirmation is submitted and from every
terminal response.