Skip to content

Making a payout to a card

Creates a payout to a bank card by card number or card token.

Integration flow

  1. Generate a unique transaction and choose how to pass the recipient's card.
  2. Sign the exact request body and send the payout.
  3. Poll the operation status by transaction until you receive completed or canceled.

URL

POST https://api.pay.kvell.group/v1/orders/account2card
POST https://api.pay.stage.kvell.group/v1/orders/account2card

Request

Headers

Name Type Required Description
X-Api-Key string Yes Shop identifier.
X-Signature string Yes Signature of the request body.

Building the signature

The request must be signed with an RSA/SHA-256 electronic signature. Pass the result in the X-Signature header.

The step-by-step algorithm, key requirements, examples for Python, PHP and OpenSSL, and troubleshooting for error 20002 are given in the general section «Building a signature for payouts».

Request body

Parameter Type Required Description
recipient_pan string Yes Recipient's card number, without spaces or separators.
amount integer Yes Amount in kopecks. For example, 15000 is 150 RUB.
transaction string Yes Unique operation identifier in the merchant's system.
description string Yes Purpose of the payout, no more than 210 characters.
customer string No Customer identifier — email or phone number.
extra_data object No Additional merchant data.
fiscal_data object No Data for receipt fiscalization under 54-FZ.

Handling the card number

recipient_pan contains payment data. Don't log the full card number or store it unless necessary. Comply with applicable PCI DSS requirements.

Example

{
  "recipient_pan": "4111111111111111",
  "amount": 15000,
  "transaction": "payout-card-20260810-0001",
  "description": "Payout under contract 42",
  "customer": "customer@example.com"
}

Response

Choose an HTTP code to see an example, the response parameters, and the recommended actions.

If no HTTP response is received

Handle a timeout or connection loss the same way as a 5XX response: the operation result is unknown, so first check the status by the original transaction. Don't create a new payout with a different identifier.

200 (OK) response example
{
  "order": {
    "id": "3b3c19f4-c680-4f5d-bf2e-c0835439cf12",
    "status": "processing",
    "transaction": "payout-card-20260810-0001",
    "amount": 15000,
    "commission": 150,
    "description": "Payout under contract 42",
    "additional_data": {
      "auth_code": null,
      "rrn": null
    },
    "error_code": null,
    "error_message": null,
    "created_at": "2026-08-10T09:15:27.231000+00:00"
  },
  "transaction": "payout-card-20260810-0001",
  "status": "processing"
}

Response parameters

Parameter Type Description
order object The created payout.
id string Payout identifier in KVELL.
status string Current payout status. Possible values are given in «Payout statuses».
transaction string Operation identifier passed by the merchant.
amount integer Payout amount in kopecks.
commission integer Commission in kopecks.
description string | null Purpose of the payout. May include a prefix configured for the shop.
∟ additional_data object | null Additional data received while processing the payout.
 ∟ auth_code string | null Authorization code, if returned by the bank.
 ∟ rrn string | null Bank transaction identifier generated by the acquiring bank.
error_code string | null Rejection reason code. Possible values are given in «Transaction error codes».
error_message string | null Description of the rejection reason. Returns null for a payout that wasn't rejected.
created_at string Date and time the payout was created, in ISO 8601 format.
transaction string Operation identifier in the merchant's system.
status string Current payout status; matches order.status.
400 (Bad Request) response example
{
  "errors": [
    {
      "code": 20019,
      "message": "Shop payout limit exceeded"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of errors. Codes and handling recommendations are given in «HTTP response errors».
code integer Error code. In the example — 20019.
message string Description of the reason the request was rejected.
403 (Forbidden) response example
{
  "errors": [
    {
      "code": 20037,
      "message": "Access denied"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of errors. Codes and handling recommendations are given in «HTTP response errors».
code integer Error code. For access denial — 20037.
message string Description of the reason for the access denial.
404 (Not Found) response example
{
  "errors": [
    {
      "code": 20006,
      "message": "Shop not found"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of errors. Codes and handling recommendations are given in «HTTP response errors».
code integer Error code. For a shop that wasn't found — 20006.
message string Description of why the resource wasn't found.

What this response means

The shop with the passed X-Api-Key wasn't found in the selected environment. The payout wasn't created.

422 (Unprocessable Entity) response example
{
  "errors": [
    {
      "code": 20020,
      "message": "Recipient not specified"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of validation errors. Codes and handling recommendations are given in «HTTP response errors».
code integer Error code.
message string Reason for the validation error.
5XX (Internal Server Error) response example
{
  "errors": [
    {
      "code": 20000,
      "message": "Unknown error"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of errors. Codes and handling recommendations are given in «HTTP response errors».
code integer Error code. For an unknown error — 20000.
message string Description of the technical error.

5XX, timeout, and connection loss

In all of these cases, the request result is considered undefined: the payout may have been created even if the client didn't receive a response. Keep the transaction in your system in a "processing" state until you get a confirmed result from KVELL.

This scenario can occur due to a network failure, connection loss, timeout, or a technical error on the server or client side.

Unified handling algorithm

  1. Don't mark the payout as successful or rejected based solely on a technical error.
  2. Save the payout in your system in a "processing" state.
  3. Request the transaction status using the original transaction value.
  4. If the transaction is found, keep checking it until you receive a final status.
  5. If status requests keep failing, contact support and provide the transaction.

Don't create a duplicate payout

Don't resend the payout with a new transaction until the result of the original operation is established.

Payout statuses

Status Final What to do
new No Poll the transaction status.
processing No Poll the transaction status. Don't create a new payout.
completed Yes The payout was completed.
canceled Yes The payout was rejected.

A full reference of common operation statuses is given in «Transaction statuses».

OTP confirmation

Only used for shops with OTP enabled

Confirming a payout with a one-time code isn't part of the main flow. This option is enabled individually in the shop's settings. If it isn't enabled for you, you can skip this section.

When OTP is enabled, instead of the created payout object the API returns:

{
  "order": null,
  "transaction": "payout-card-20260810-0001",
  "status": "wait_confirm"
}

Response parameters

Parameter Type Description
order null The payout hasn't been created yet.
transaction string Operation identifier to pass to the confirmation method.
status string wait_confirm — the payout is awaiting OTP code confirmation.

What this response means

The request was accepted, but the payout is awaiting confirmation and hasn't yet moved to bank processing. That's why the response has no id, amount, commission, or created_at.

What to do next

  1. Get the OTP code from the user.
  2. Pass the transaction and the OTP code to the payout confirmation method.
  3. After confirmation, get the final status.