Skip to content

Cross-Border Payments

Cross-border is a bank-to-bank transfer scheme in which the payer chooses the bank they will send from, and Wirekassa issues the recipient requisites (a card number or a phone number) for that specific bank. The payer then makes the transfer in their own banking application.

  • Base URL: https://api.wirekassa.com/api/v1/payment/
  • Endpoint: POST /v1/payment/

All request and response bodies are flat: amount and currency are separate top-level fields, payment_method is the method type as a string, and every method field sits at the top level of the body.

Availability

Cross-border must be enabled on your channel before it can be used. A request for a method your channel does not carry is rejected with 1007 / Please contact support for further action. Ask us to confirm the method is switched on for your channel.

Supported Currencies

  • RUB

Flow Overview

Cross-border follows the same shape as a card-to-card transfer, with one extra step: the payer first picks the bank they will send from, and the recipient requisites are issued only afterwards.

1. You create the payment                    POST /v1/payment/
2. Payer supplies personal data              hosted page
3. Payer picks the sending bank              hosted page
4. Wirekassa issues recipient requisites     hosted page
5. Payer transfers, Wirekassa settles        poll or wait for the callback

Steps 2–4 happen on the hosted page reached through redirect_url. Your backend creates the payment and then waits for a final status — there are no intermediate API calls to make.

If you supply the payer's personal data at creation, step 2 is skipped and the payer lands directly on the bank list.

Create the Payment

Common fields (see Payment API):

  • channel (UUID, required)
  • amount (string, required) → amount in major units
  • currency (must be RUB)
  • external_id (string, optional)
  • return_url (string, recommended)
  • callback_url (string, optional)
  • payment_method (string, required) → "cross_border"

Method fields (payment_method: cross_border)

Sent at the top level of the request body, all optional:

  • user_id → Your internal user identifier
  • first_name → Payer first name
  • surname → Payer surname
  • phone → Payer phone number
  • code → Sender bank code, if you already know which bank the payer will send from. Supplying it skips the bank-selection step

Example Request

json
{
  "channel": "550e8400-e29b-41d4-a716-446655440000",
  "amount": "1000.00",
  "currency": "RUB",
  "payment_method": "cross_border",
  "user_id": "user_test",
  "first_name": "Ivan",
  "surname": "Petrov",
  "phone": "+79998887766",
  "external_id": "ORDER-10002",
  "return_url": "https://your-company.com/return",
  "callback_url": "https://your-company.com/callback"
}

Example Response

json
{
  "status": "processing",
  "transaction_id": "7d1c94b2-6f3a-4e58-9a21-15c0be7742d9",
  "amount": "1000.0",
  "currency": "RUB",
  "redirect_url": "https://pay.wirekassa.com/7d1c94b2-6f3a-4e58-9a21-15c0be7742d9/",
  "channel": "550e8400-e29b-41d4-a716-446655440000",
  "external_id": "ORDER-10002",
  "payment_method": "cross_border",
  "payment_method_first_name": "Ivan",
  "payment_method_surname": "Petrov",
  "create_date": "2025-10-15T23:54:13.008007+00:00",
  "update_date": "2025-10-15T23:54:13.008007+00:00"
}

Recipient Requisites

Once the payer has chosen a sending bank, the requisites are issued and surface in the payment response as payment_method_* fields:

FieldDescription
payment_method_requisite_type"card" or "phone" — which kind of destination the payer sends to
payment_method_numberThe card number or phone number to transfer to
payment_method_bank_nameRecipient's bank name
payment_method_owner_nameName of the recipient
payment_method_sender_bank_codeCode of the bank the payer chose to send from
payment_method_phoneRecipient phone number, when the provider returns one alongside a card
payment_method_bank_countryRecipient bank country as an object with code and name
payment_method_statewaiting_for_confirm while the transfer is expected

WARNING

payment_method_bank_country is the one field in the flat format that is still an object. Everything else is a scalar.

Example Response (card requisite)

json
{
  "status": "processing",
  "transaction_id": "7d1c94b2-6f3a-4e58-9a21-15c0be7742d9",
  "amount": "1000.0",
  "currency": "RUB",
  "redirect_url": "https://pay.wirekassa.com/7d1c94b2-6f3a-4e58-9a21-15c0be7742d9/",
  "channel": "550e8400-e29b-41d4-a716-446655440000",
  "external_id": "ORDER-10002",
  "payment_method": "cross_border",
  "payment_method_requisite_type": "card",
  "payment_method_number": "2200 1234 5678 9010",
  "payment_method_bank_name": "Ozon Bank",
  "payment_method_owner_name": "Petr S.",
  "payment_method_sender_bank_code": "sber",
  "payment_method_bank_country": {
    "code": "RU",
    "name": "Russia"
  },
  "payment_method_state": "waiting_for_confirm",
  "create_date": "2025-10-15T23:54:13.008007+00:00",
  "update_date": "2025-10-15T23:56:02.441911+00:00"
}

Example Response (phone requisite)

json
{
  "status": "processing",
  "transaction_id": "7d1c94b2-6f3a-4e58-9a21-15c0be7742d9",
  "amount": "1000.0",
  "currency": "RUB",
  "channel": "550e8400-e29b-41d4-a716-446655440000",
  "external_id": "ORDER-10002",
  "payment_method": "cross_border",
  "payment_method_requisite_type": "phone",
  "payment_method_number": "+7 900 123-45-67",
  "payment_method_bank_name": "T-Bank",
  "payment_method_owner_name": "Petr S.",
  "payment_method_sender_bank_code": "vtb",
  "payment_method_bank_country": {
    "code": "RU",
    "name": "Russia"
  },
  "payment_method_state": "waiting_for_confirm",
  "create_date": "2025-10-15T23:54:13.008007+00:00",
  "update_date": "2025-10-15T23:56:02.441911+00:00"
}

Completing the Payment

The payer performs the transfer in their banking application. There is no confirmation call for cross-border — the provider reports the result and the transaction is settled on our side.

Poll GET /v1/payment/ or wait for the callback until the transaction reaches a final status:

  • completed → the transfer was received in full
  • mispaid → the transfer was received, but the amount differs from the requested one. Use received_amount instead of amount. See Mispaid status
  • failed → the transfer was not received before the payment expired, or the provider declined the payment

Example Response (Completed)

json
{
  "status": "completed",
  "transaction_id": "7d1c94b2-6f3a-4e58-9a21-15c0be7742d9",
  "amount": "1000.0",
  "currency": "RUB",
  "redirect_url": "https://pay.wirekassa.com/7d1c94b2-6f3a-4e58-9a21-15c0be7742d9/",
  "channel": "550e8400-e29b-41d4-a716-446655440000",
  "external_id": "ORDER-10002",
  "payment_method": "cross_border",
  "create_date": "2025-10-15T23:54:13.008007+00:00",
  "update_date": "2025-10-15T23:58:41.114902+00:00"
}

Example Response (Mispaid)

json
{
  "status": "mispaid",
  "transaction_id": "7d1c94b2-6f3a-4e58-9a21-15c0be7742d9",
  "amount": "1299.0",
  "currency": "RUB",
  "received_amount": "1100.0",
  "redirect_url": "https://pay.wirekassa.com/7d1c94b2-6f3a-4e58-9a21-15c0be7742d9/",
  "channel": "550e8400-e29b-41d4-a716-446655440000",
  "external_id": "ORDER-10002",
  "payment_method": "cross_border",
  "create_date": "2025-10-15T23:54:13.008007+00:00",
  "update_date": "2025-10-15T23:58:41.114902+00:00"
}

Notes:

  • The recipient requisites are issued per transaction and are tied to the sending bank the payer chose. Do not cache them and do not reuse them for another payment.
  • The requisites expire if the payer does not complete the transfer in time. Create a new payment in that case.
  • The transfer is matched by the recipient requisite and the exact amount, so a transfer of a different amount is settled as mispaid.