API Reference

REST API

REST over HTTPS, JSON in both directions. Base — https://api.nerezpay.ru. Bearer key from the dashboard, optionally with an HMAC signature; Idempotency-Key on create operations.

Payments

The shop is determined by the API key — one key maps to one shop. For multiple shops issue separate keys in the dashboard.

Create a payment

POST/v1/public/payments
Creates a payment session. The response contains the payment object and a payment_url to redirect the customer to.
Request body
amountAmount in minor units. For RUB — kopeks. Required.
currencyISO-4217 currency code. Defaults to RUB.
methodPayment method: sbp, cards, tpay, sberpay, recurrent or any. Defaults to any — customer picks on our hosted page.
order_idYour order identifier. If omitted we generate ord_<timestamp>.
customer_idYour customer identifier. Saved into metadata and used to group operations.
return_urlURL the customer returns to after paying. Requires https://.
descriptionPayment purpose. Shown in the customer receipt.
webhook_urlPer-payment webhook receiver URL. Overrides shop settings.
metadataArbitrary key-value pairs. Up to 20 pairs, values are strings up to 500 characters.
Request
curl -X POST https://api.nerezpay.ru/v1/public/payments \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f2a-pay-1042' \
  -d '{
    "amount":      150000,
    "currency":    "RUB",
    "method":      "sbp",
    "order_id":    "ORDER-1042",
    "customer_id": "user-7821",
    "return_url":  "https://example.com/order/1042/done"
  }'
Response
{
  "payment": {
    "id":          "5a331a39-32bf-4940-afb1-855e2fc6757f",
    "merchant_id": "22222222-2222-2222-2222-222222222222",
    "shop_id": "33333333-3333-3333-3333-333333333333",
    "order_id":    "ORDER-1042",
    "amount":      150000,
    "currency":    "RUB",
    "method":      "sbp",
    "status":      "pending",
    "expires_at":  "2026-05-05T13:42:00Z",
    "created_at":  "2026-05-05T12:42:00Z"
  },
  "payment_url": "https://nerezpay.ru/pay/5a331a39-…",
  "mode":        "live",
  "bank":        "Sber",            // acquiring bank name if it responded sync
  "bank_ref":    "262512345678"     // operation ID at the bank (h2h only)
}

idempotent: true, failure_code and failure_message are returned on a repeat request keyed by Idempotency-Key or a synchronous bank failure. In test mode the response also has simulator service fields — described on the Sandbox page.

Check payment status

GET/v1/public/payments/{id}
Returns the full payment object with current status, finalized_at and the list of refunds[]. Use for synchronous status checks and after receiving a webhook.
Request
curl -X GET https://api.nerezpay.ru/v1/public/payments/5a331a39-32bf-4940-afb1-855e2fc6757f \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{
  "id":              "5a331a39-32bf-4940-afb1-855e2fc6757f",
  "merchant_id":     "22222222-2222-2222-2222-222222222222",
  "shop_id":     "33333333-3333-3333-3333-333333333333",
  "shop_name":   "Web checkout",
  "order_id":        "ORDER-1042",
  "status":          "succeeded",
  "amount":          150000,
  "amount_refunded": 0,
  "currency":        "RUB",
  "method":          "sbp",
  "rrn":             "262512345678",
  "bank_name":       "Sber",
  "return_url":      "https://example.com/order/1042/done",
  "created_at":      "2026-05-05T12:42:00Z",
  "captured_at":     "2026-05-05T12:43:11Z",
  "finalized_at":    "2026-05-05T12:43:11Z",
  "expires_at":      "2026-05-05T13:42:00Z",
  "processing_until":"2026-05-05T13:02:00Z",
  "metadata":        { "customer_id": "user-7821" },

  "customer_card_brand":  "visa",
  "customer_card_mask":   "411111******1111",
  "customer_card_holder": "IVAN IVANOV",
  "customer_phone_mask":  "+7•••••••12-34",
  "customer_payer_bank":  "Sber",

  "refunds": [
    {
      "id":           "9b2c1f8a-1111-2222-3333-444444444444",
      "payment_id":   "5a331a39-32bf-4940-afb1-855e2fc6757f",
      "amount":       50000,
      "reason":       "partial per request",
      "status":       "succeeded",
      "created_at":   "2026-05-05T15:10:00Z",
      "completed_at": "2026-05-05T15:10:08Z"
    }
  ]
}

Cancel a payment

POST/v1/public/payments/{id}/cancel
Only works for status pending. Other statuses return 409 not_pending. A successful cancel triggers a payment.cancelled webhook.
Request
curl -X POST https://api.nerezpay.ru/v1/public/payments/5a331a39-32bf-4940-afb1-855e2fc6757f/cancel \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{
  "status": "cancelled"
}

method any (multi-form)

When the merchant creates a payment with method: "any" (or without a method field at all), the response\u2019s payment_url points to our hosted page https://nerezpay.ru/pay/<id>. The customer picks a payment method themselves: card, SBP, T-Pay, SberPay or recurrent.

Lifecycle

  1. Payment is created with status pending and methods=any. No bank session yet, processing_until is empty.
  2. Customer opens payment_url, sees method buttons.
  3. Customer clicks "Pay via SBP" (for example). Method is fixed: status stays pending, the method field changes from any to sbp. No webhook on this step.
  4. Bank session opens: status becomes processing, processing_until is filled with the method TTL (20 min for SBP). No webhook on this transition.
  5. Bank returns a final status: succeeded or failed. A payment.succeeded or payment.failed webhook is delivered.
If the bank doesn\u2019t return a status before processing_until, the payment moves to expired and the merchant gets a payment.expired webhook. Different semantics than failed: the bank didn\u2019t reject, it just never closed the session.

Before a method is picked, the payment cannot be cancelled (cancel only works in pending — and it will here) or refunded (succeeded hasn\u2019t happened). The merchant can check status via GET /payments/{id} or wait for a webhook.

metadata field

metadata is arbitrary key-value pairs you pass when creating a payment. We don\u2019t interpret them, just store and echo them back. Convenient for cart IDs, traffic source, A/B-test tags and so on.

Limits

  • All values are strings. Pass numbers and booleans as "42" / "true" — we don\u2019t touch them.
  • We recommend no more than 20 pairs per payment and 500 characters per value. There’s no hard cap, but everything lives in a single JSONB column.
  • Encoding is UTF-8.

Where you’ll see them

  • In the POST /payments response — payment.metadata.
  • In GET /payments/{id} — same field.
  • In the webhook data object.

Reserved keys

Alongside your data, metadata may contain system keys that we set. Nothing scary, just don\u2019t be surprised:

keywhen it appears
modealways. Value is test or live depending on the key used.
webhook_urlif you passed webhook_url in the POST /payments body.
customer_idif you passed customer_id in the POST /payments body.
bank_reflive mode: operation ID at the acquiring bank.
failure_codeon failed/expired: our unified failure code (see the "Failure codes" section).
bank_failure_codeon failed: raw bank code. Audit-only — rely on failure_code in code.
simulator_outcometest mode: the planned simulator outcome (succeeded, failed, requires_action, pending).
simulator_failure_codetest mode: the code the simulator passes off as the bank response.

Don’t use these names for your own keys: on collision we overwrite your value.

Returning the customer to the shop

If you supplied return_url in POST /payments, after the payment reaches a final status we redirect the customer to that URL with two query parameters:

https://example.com/order/1042/done?payment_id=5a331a39-…&status=succeeded
parametervalue
payment_idPayment UUID.
statussucceeded | failed | cancelled | refunded | expired.

Existing query parameters in your return_url are kept. If the URL already had ?ref=email, it stays — and our two are appended.

Don\u2019t trust these parameters as proof of payment. Customers can rewrite the URL by hand. Before celebrating a purchase, confirm the status server-side — via the payment.succeeded webhook or an explicit GET /payments/{id}.

When the redirect happens

  • succeeded: ~2 seconds after the "Payment complete" screen.
  • failed / cancelled / refunded / expired: immediately.
  • If return_url isn\u2019t set we keep the customer on our status page.

Recurring payments

A subscription is a recurring charge on a saved payment method, selected via method: cards, sbp (FPS) or tpay. The first payment binds the method (with customer consent; 3DS for cards), the bank issues a token, then the platform charges on schedule without the customer (MIT). If you just need bind-and-charge primitives, see Recurring tokens.

How it works

  1. POST /v1/public/subscriptions — create the subscription. Response contains pay_url.
  2. Send the customer to pay_url — they pay the first amount and consent to recurring charges.
  3. On success a webhook arrives, the token is stored, the subscription becomes active and next_charge_at is set.
  4. The platform charges automatically on schedule.
  5. After 3 consecutive failed charges the subscription is auto-cancelled.

Subscription object

FieldTypeDescription
idUUIDSubscription identifier.
amountint64Recurring charge amount in minor units.
currencystringCurrency (RUB).
methodenumcards (card), sbp (FPS/СБП), tpay (T-Pay). The first charge is taken immediately.
periodenumday | week | month | year.
interval_countintCharge every N periods.
trial_daysintTrial period in days before the first charge (0 — no trial).
statusenumpending → active → (past_due) → cancelled.
next_charge_attimeWhen the next charge is scheduled.

Create subscription

POST/v1/public/subscriptions
Creates a subscription and its initial bind payment. Returns pay_url for payment and binding. Requires the recurring scope on the shop.
Request body
amountRecurring charge amount in minor units. Required.
customer_refYour customer identifier. Required.
methodcards (default) | sbp | tpay.
periodday | week | month | year. Defaults to month.
interval_countEvery N periods. Defaults to 1.
trial_daysTrial period in days (method=cards and sbp). The binding takes no charge (a 1 ₽ verification for cards, a 1 ₽ binding for FPS), the full amount is charged after the trial. Not available for tpay. Defaults to 0.
customer_emailOptional.
plan_nameOptional plan label.
Request
curl -X POST https://api.nerezpay.ru/v1/public/subscriptions \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 199000,
  "customer_ref": "user_42",
  "method": "cards",
  "period": "month",
  "interval_count": 1
}'
Response
{
  "subscription": {
    "id":             "7f0e…",
    "status":         "pending",
    "amount":         199000,
    "currency":       "RUB",
    "method":         "cards",
    "period":         "month",
    "interval_count": 1,
    "next_charge_at": "2026-07-13T10:00:00Z"
  },
  "initial_payment": { "id": "4f0e…", "status": "pending" },
  "pay_url": "https://nerezpay.ru/pay/4f0e…"
}

Until the customer pays via pay_url the subscription stays pending and does not charge.

List subscriptions

GET/v1/public/subscriptions
All subscriptions of the shop the API key belongs to.
Request
curl -X GET https://api.nerezpay.ru/v1/public/subscriptions \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'

Get subscription

GET/v1/public/subscriptions/{id}
A single subscription by id (your own only).
Request
curl -X GET https://api.nerezpay.ru/v1/public/subscriptions/7f0e... \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'

Charge schedule

GET/v1/public/subscriptions/{id}/schedule
History of the subscription’s charges + projection of the next upcoming charge dates (for active/past_due).
Request
curl -X GET https://api.nerezpay.ru/v1/public/subscriptions/7f0e.../schedule \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{
  "subscription_id": "7f0e…",
  "status":          "active",
  "amount":          199000,
  "currency":        "RUB",
  "period":          "month",
  "interval_count":  1,
  "next_charge_at":  "2026-07-13T10:00:00Z",
  "charges": [
    { "payment_id": "4f0e…", "kind": "subscription_init",   "amount": 199000, "status": "succeeded", "created_at": "2026-06-13T10:00:00Z" },
    { "payment_id": "5a1c…", "kind": "subscription_charge", "amount": 199000, "status": "succeeded", "created_at": "2026-07-13T10:00:01Z" }
  ],
  "upcoming": ["2026-08-13T10:00:00Z", "2026-09-13T10:00:00Z"]
}

Cancel subscription

POST/v1/public/subscriptions/{id}/cancel
Stops future charges. Past payments are untouched.
Request
curl -X POST https://api.nerezpay.ru/v1/public/subscriptions/7f0e.../cancel \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json' \
  -d '{ "reason": "per customer request" }'
Response
{ "status": "cancelled" }

Creating subscriptions via the API requires the recurring scope on the shop. Otherwise 403 scope_required is returned.

Recurring tokens

Save a payment method and charge it whenever you need; build your subscription logic on your side. The method is set via method: cards, sbp or tpay. A card is bound with a 1 ₽ verification, no charge. For СБП and T-Pay the binding happens together with the first charge: pass amount, it is charged and issues the token at once. Then you charge by token (MIT) and revoke it when needed. You never store PAN or CVV, only our token.

How it works

  1. Create a token via POST /v1/public/tokens (method=cards|sbp|tpay). The response contains pay_url.
  2. Send the customer to pay_url. They confirm the binding: a card via 3DS and a 1 ₽ verification, СБП and T-Pay by paying the amount.
  3. On success the token becomes active. Charge it via POST /v1/public/tokens/{id}/charge with any amount, as many times as you need.
  4. To stop charges, call POST /v1/public/tokens/{id}/cancel.

Token object

FieldTypeDescription
idUUIDSaved-token identifier.
customer_refstringYour customer identifier.
methodenumBinding and charge method: cards, sbp, tpay.
statusenumpending, active, cancelled.
card_brandstringCard brand (Visa, Mastercard, MIR). For cards, after binding.
card_maskstringLast 4 digits. For cards, after binding.
last_charged_attimeWhen it was last charged.

Bind a payment method

POST/v1/public/tokens
Creates a token and a bind payment. Returns pay_url to confirm binding. Requires the api:recurrent:bind scope.
Request body
customer_refYour customer identifier. Required.
methodcards (default) | sbp | tpay.
amountFirst-charge amount in minor units. Required for sbp/tpay (binding charges). Ignored for cards (1 ₽ verification).
customer_emailOptional.
Request
curl -X POST https://api.nerezpay.ru/v1/public/tokens \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json' \
  -d '{
  "customer_ref": "user_42",
  "customer_email": "user@example.ru"
}'
Response
{
  "card": {
    "id":           "9a1c…",
    "customer_ref": "user_42",
    "status":       "pending"
  },
  "pay_url": "https://nerezpay.ru/pay/4f0e…"
}

Until the customer confirms via pay_url the token stays pending; charges work only after active.

Charge a token

POST/v1/public/tokens/{id}/charge
MIT charge using the saved token (same method as the binding). The token must be active. Requires the api:recurrent:charge scope.
Request body
amountAmount in minor units. Required.
order_idYour order identifier. Optional.
descriptionPayment purpose. Optional.
Request
curl -X POST https://api.nerezpay.ru/v1/public/tokens/9a1c.../charge \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 199000,
  "order_id": "order-7781",
  "description": "Pro plan"
}'
Response
{ "id": "p_55a2…", "status": "succeeded", "amount": 199000 }

List tokens

GET/v1/public/tokens
Saved tokens of the shop. Filter with ?customer_ref=.
Request
curl -X GET https://api.nerezpay.ru/v1/public/tokens?customer_ref=user_42 \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'

Revoke a token

POST/v1/public/tokens/{id}/cancel
Deactivates the token, no further charges. Past payments are untouched.
Request
curl -X POST https://api.nerezpay.ru/v1/public/tokens/9a1c.../cancel \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{ "status": "cancelled" }

Tokenization via the API requires the recurring scope on the shop (api:recurrent:bind / api:recurrent:charge). Otherwise 403 scope_required is returned.

Refunds

A refund is a standalone object attached to a payment. Multiple partial refunds are allowed on one payment; once their sum reaches the original amount, the payment\u2019s status becomes refunded. Every successful refund triggers a payment.refunded webhook.

Refund object

FieldTypeDescription
idUUIDRefund identifier.
payment_idUUIDPayment the refund belongs to.
merchant_idUUIDMerchant. Determined from the API key.
amountint64Refund amount in minor units.
reasonstringRefund reason. Lands in the receipt and audit log.
statusenumpending → succeeded or failed.
created_attimeWhen the refund was created.
completed_attimeWhen it reached its final status.
{
  "id":           "9b2c1f8a-1111-2222-3333-444444444444",
  "payment_id":   "5a331a39-32bf-4940-afb1-855e2fc6757f",
  "merchant_id":  "22222222-2222-2222-2222-222222222222",
  "amount":       50000,
  "reason":       "partial refund per customer request",
  "status":       "succeeded",
  "created_at":   "2026-05-05T15:10:00Z",
  "completed_at": "2026-05-05T15:10:02Z"
}

Refund funds

POST/v1/public/payments/{id}/refund
Full or partial refund of a succeeded payment. Cumulative refunds cannot exceed the original amount. Every successful refund triggers a payment.refunded webhook.
Request body
amountRefund amount in minor units. If omitted or 0 — refunds the entire remainder: amount − amount_refunded.
reasonRefund reason. Shown to the customer in the receipt and recorded in the audit log.
Request
curl -X POST https://api.nerezpay.ru/v1/public/payments/5a331a39-32bf-4940-afb1-855e2fc6757f/refund \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json' \
  -d '{
  "amount": 50000,
  "reason": "partial refund per customer request"
}'
Response
{
  "id":           "9b2c1f8a-1111-2222-3333-444444444444",
  "payment_id":   "5a331a39-32bf-4940-afb1-855e2fc6757f",
  "merchant_id":  "22222222-2222-2222-2222-222222222222",
  "amount":       50000,
  "reason":       "partial refund per customer request",
  "status":       "succeeded",
  "created_at":   "2026-05-05T15:10:00Z"
}

There\u2019s no separate "get refund by id" endpoint in the public API. Refunds for a specific payment are always returned in the refunds[] array of GET /v1/public/payments/{id}, and the full refund registry is available via GET /v1/public/refunds (see the "Operation registries" section).

Payouts

A single endpoint POST /v1/public/payouts; the method is selected by the method field: SBP, to a card, or to a bank account (RKO). The shop is determined by the API key; the mode is set by the key (sk_test_ → simulator, sk_live_ → real bank). The key needs the matching method scope. The final status (succeeded/failed) arrives via the payout.* webhook. Below are the three request-body variants.

SBP payout

POST/v1/public/payouts
To a phone number + recipient bank member_id.
Request body
amountAmount in minor units (kopeks). Required.
method"payouts_sbp". Scope: api:payouts:sbp.
phoneRecipient phone in the +7XXXXXXXXXX format. Required.
bank_idRecipient bank member_id in the NSPK registry (12 digits). Example: 100000000111 — Sberbank. Required. See “SBP banks”.
full_nameRecipient full name. Used by the bank for matching.
Request
curl -X POST https://api.nerezpay.ru/v1/public/payouts \
  -H 'Authorization: Bearer sk_live_…' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f2a-payout-sbp' \
  -d '{
    "amount":    250000,
    "method":    "payouts_sbp",
    "phone":     "+79001234567",
    "bank_id":   "100000000111",
    "full_name": "Иванов Иван Иванович"
  }'
Response
{
  "payout": {
    "id":          "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "merchant_id": "22222222-2222-2222-2222-222222222222",
    "shop_id":     "33333333-3333-3333-3333-333333333333",
    "amount":      250000,
    "currency":    "RUB",
    "method":      "payouts_sbp",
    "status":      "pending",
    "recipient": {
      "phone":     "+79001234567",
      "bank_id":   "100000000111",
      "full_name": "Иванов Иван Иванович"
    },
    "created_at":  "2026-05-05T16:01:00Z"
  },
  "mode":     "live",
  "bank":     "Sber",
  "bank_ref": "PAY2026050601234"
}

failure_reason and idempotent fields are returned on failure or a repeated request keyed by Idempotency-Key. In test mode the response also has simulator service fields — described on the Sandbox page.

Card payout

POST/v1/public/payouts
To a recipient card number (OCT).
Request body
amountAmount in minor units (kopeks). Required.
method"payouts_card". Scope: api:payouts:card.
card_panRecipient card number (16–18 digits). Required.
full_nameRecipient full name (optional).
Request
curl -X POST https://api.nerezpay.ru/v1/public/payouts \
  -H 'Authorization: Bearer sk_live_…' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f2a-payout-card' \
  -d '{ "amount": 250000, "method": "payouts_card", "card_pan": "2200110033445566" }'
Response
{
  "payout": {
    "id":                  "…",
    "amount":              250000,
    "method":              "payouts_card",
    "status":              "pending",
    "recipient_card_mask": "5566",
    "recipient": { }
  },
  "mode":     "live",
  "bank_ref": "PAY2026050609876"
}

The response has recipient_card_mask — last 4 digits of the card (for the receipt). The full card number is neither stored nor returned.

Account payout (RKO)

POST/v1/public/payouts
To a bank account by its details.
Request body
amountAmount in minor units (kopeks). Required.
method"payouts_account". Scope: api:payouts:account.
account_numberRecipient bank account (20 digits). Required.
bikRecipient bank BIC (9 digits). Required.
innRecipient INN (optional).
full_nameRecipient title. Used by the bank for matching.
Request
curl -X POST https://api.nerezpay.ru/v1/public/payouts \
  -H 'Authorization: Bearer sk_live_…' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7f2a-payout-acc' \
  -d '{
    "amount":         250000,
    "method":         "payouts_account",
    "account_number": "40817810099910004312",
    "bik":            "044525225",
    "inn":            "771234567890",
    "full_name":      "Romashka LLC"
  }'

Payout registry (batch)

POST/v1/public/payouts/batch
An items array (up to 500) in a single request, scoped to the key’s shop. Not atomic: valid rows execute, invalid ones return an error in results[]. Method comes from the row or the shared method. The total balance is checked once up front for the whole registry. Idempotency-Key makes re-submitting the same registry safe (duplicate rows are marked status=duplicate).
Request body
{
  "method": "payouts_sbp",
  "items": [
    { "amount": 150000, "phone": "+79001234567", "bank_id": "100000000111", "full_name": "Иванов И.И." },
    { "amount": 250000, "phone": "+79007654321", "bank_id": "100000000004", "full_name": "Петров П.П." }
  ]
}
Request
curl -X POST https://api.nerezpay.ru/v1/public/payouts/batch \
  -H 'Authorization: Bearer sk_live_x9k…' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: reg-2026-05-05-001' \
  -d '{"method":"payouts_sbp","items":[{"amount":150000,"phone":"+79001234567","bank_id":"100000000111","full_name":"Иванов И.И."}]}'
Response
{
  "mode":    "live",
  "created": 1,
  "failed":  1,
  "total":   2,
  "results": [
    { "index": 0, "status": "created", "payout_id": "7c1f...", "method": "payouts_sbp", "amount": 150000 },
    { "index": 1, "status": "failed",  "method": "payouts_sbp", "amount": 250000, "code": "recipient_not_in_sbp", "error": "получатель не найден в СБП" }
  ]
}

Each result row: status = created | failed | duplicate, with payout_id or code/error. Final statuses arrive via payout.* webhooks per created payout.

Payout status

GET/v1/public/payouts/{id}
Returns the current payout state. Status walks pending → succeeded or failed. The final status triggers a payout.succeeded or payout.failed webhook.
Request
curl -X GET https://api.nerezpay.ru/v1/public/payouts/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{
  "id":            "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "merchant_id":   "22222222-2222-2222-2222-222222222222",
  "shop_id":       "33333333-3333-3333-3333-333333333333",
  "amount":        250000,
  "currency":      "RUB",
  "method":        "payouts_sbp",
  "status":        "succeeded",
  "fail_reason":   "",
  "recipient": {
    "phone":     "+79001234567",
    "bank_id":   "100000000111",
    "full_name": "Иванов Иван Иванович"
  },
  "bank_ref":      "PAY2026050601234",
  "created_at":    "2026-05-05T16:01:00Z",
  "completed_at":  "2026-05-05T16:01:09Z"
}

bank_ref is the provider payout reference. For a card payout the response also includes recipient_card_mask (last 4 digits of the card) for the receipt.

Balance

The merchant\u2019s current balance: total, available for payout, and a per-shop breakdown. Read-only, requires the api:balance:read scope. All amounts are in minor units.

Get balance

GET/v1/public/balance
Total balance, available balance (net of amounts reserved for pending payouts and settlements), and the balance of each of the merchant’s shops.
Response
FieldTypeDescription
balanceint64Total merchant balance in minor units.
availableint64Available for payout: balance minus reserves for pending payouts and settlements.
currencystringCurrency (ISO 4217), currently RUB.
shops[]arrayPer-shop balance breakdown.
shops[].shop_idUUIDShop identifier.
shops[].shop_namestringShop name.
shops[].balanceint64Shop balance in minor units.
Request
curl -X GET https://api.nerezpay.ru/v1/public/balance \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{
  "balance":   172150,
  "available": 172150,
  "currency":  "RUB",
  "shops": [
    { "shop_id": "1d8243bb-...", "shop_name": "shop-one",  "balance": 122150 },
    { "shop_id": "6a9b6b58-...", "shop_name": "shop-two",  "balance":  50000 }
  ]
}

A payout cannot exceed available — the available balance already accounts for funds reserved by not-yet-completed payouts.

Operation registries

Lists of payments, payouts and refunds. Read-only, requires the api:reports:read scope. Registries are strictly scoped to the shop: a key only sees its own shop\u2019s operations, even if the merchant has several shops.

Pagination & filters

Cursor pagination: the response contains an items array and next_cursor. Pass cursor=<next_cursor> for the next page. When next_cursor = null there are no more pages. Common query parameters:

ParameterTypeDescription
limitintPage size, 1…200. Defaults to 50.
cursorstringNext-page cursor (next_cursor from the previous response).
statusstringFilter by status. Comma-separated for multiple.
fromdatePeriod start (YYYY-MM-DD), inclusive.
todatePeriod end (YYYY-MM-DD), inclusive.

Payments registry

GET/v1/public/payments
The shop’s incoming payments, newest first. Test payments are hidden for live keys by default (include_test=1 to show).
Query parameters
include_test1 — include test payments (hidden by default for sk_live_ keys).
Request
curl -X GET https://api.nerezpay.ru/v1/public/payments?status=succeeded&limit=20 \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{
  "items": [
    {
      "id":         "5a331a39-32bf-4940-afb1-855e2fc6757f",
      "order_id":   "order-1024",
      "amount":     150000,
      "currency":   "RUB",
      "method":     "sbp",
      "status":     "succeeded",
      "created_at": "2026-05-05T15:00:00Z"
    }
  ],
  "next_cursor": "MTcxNTAw..."
}

Payouts registry

GET/v1/public/payouts
The shop’s payouts, newest first.
Query parameters
methodFilter by method: payouts_sbp | payouts_card | payouts_account.
Request
curl -X GET https://api.nerezpay.ru/v1/public/payouts?status=succeeded&limit=20 \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{
  "items": [
    {
      "id":         "7c1f...",
      "shop_id":    "1d8243bb-...",
      "amount":     50000,
      "currency":   "RUB",
      "method":     "payouts_sbp",
      "status":     "succeeded",
      "bank_ref":   "10293847",
      "created_at": "2026-05-05T16:00:00Z"
    }
  ],
  "next_cursor": null
}

Refunds registry

GET/v1/public/refunds
The shop’s refunds, newest first.
Request
curl -X GET https://api.nerezpay.ru/v1/public/refunds?limit=20 \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{
  "items": [
    {
      "id":         "9b2c1f8a-...",
      "payment_id": "5a331a39-...",
      "amount":     50000,
      "reason":     "refund per customer request",
      "status":     "succeeded",
      "created_at": "2026-05-05T15:10:00Z"
    }
  ],
  "next_cursor": null
}

All amounts are in minor units. Timestamps are UTC (ISO 8601). Each registry returns only the operations of the shop the key belongs to; use that shop\u2019s key for another shop. The total balance across all shops is in the "Balance" section.

SBP banks

The bank_id field in POST /payouts is an NSPK participant\u2019s member_id (12 digits). The official registry is maintained by NSPK; we mirror it through our Bank 131 integration and return it as a single list.

SBP bank directory

GET/v1/public/banks/sbp
Full registry of SBP participants with member_id and names in Russian and English. Synced with the NSPK registry via bank131. Suitable for rendering a dropdown in a payout form.
Request
curl -X GET https://api.nerezpay.ru/v1/public/banks/sbp \
  -H 'Authorization: Bearer sk_test_x9k…' \
  -H 'Content-Type: application/json'
Response
{
  "items": [
    { "member_id": "100000000004", "name": "Тинькофф Банк", "name_en": "T-Bank" },
    { "member_id": "100000000005", "name": "ВТБ",            "name_en": "VTB" },
    { "member_id": "100000000007", "name": "Альфа-Банк",     "name_en": "Alfa-Bank" },
    { "member_id": "100000000111", "name": "Сбербанк",       "name_en": "Sberbank" },
    // … the whole NSPK registry (~200 participants), sorted by name
  ]
}

If the bank you need isn’t in the list

The directory is a UI list, not an allow-list. We accept any member_id from the official NSPK registry; there are no restrictions, and validation happens at the receiving bank.

Platform-side validation

  • bank_id not 12 digits — 400 bad_request before we call the bank.
  • member_id is formally valid but missing from NSPK — the acquiring bank declines, the operation transitions to failed with failure_code do_not_honor or bank_unknown, or the request returns 502 router_error.