Integration GuideAPI Reference
Integration Guide

H2H: Payments with Saved Cards

Create a payment using a saved paymentInstrumentToken instead of sending the card details again. Set tokenPaymentReason to identify whether the customer or the merchant initiates the payment.

📘

Token payments are available for BankCardRU. The token must belong to the same settlement account and customer as the payment. H2H tokenization must be enabled by the integration team.

To obtain a token, see Card Tokenization via API. To find a customer's saved cards, see Manage Saved Cards.

Choose CIT or MIT

CITMIT
Who initiates the paymentThe customerThe merchant's system
ExampleA customer selects a saved card and presses Pay for another purchaseA service charges a saved card after a journey ends
tokenPaymentReasonCITMIT
Customer interactionThe customer is present; additional confirmation may be requiredThe payment runs without the customer taking part
Return URLRequired for the BankCardRU CIT requestNot required

MIT supports unscheduled card-on-file payments: your system initiates a charge when the relevant business event occurs. There is no additional MIT subtype parameter.

You can use the same eligible saved-card token for CIT and MIT, including tokens saved previously through the API or Hosted Checkout.

📘

An ACTIVE card status does not guarantee that a particular MIT payment can be processed or approved. The card details endpoint does not return a separate MIT-availability flag.

flowchart TD
    A[Saved card token] --> B{Who initiates the payment?}
    B -->|Customer| C[CIT request with a return URL]
    C --> D{Additional confirmation required?}
    D -->|Yes| E[Open the returned URL for the customer]
    D -->|No| F[Retrieve the result with GET or receive a webhook]
    E --> F
    B -->|Merchant system| G[MIT request without customer interaction]
    G --> F

Request requirements

Use POST /api/v1/intents, relative to your environment's processing base URL. See Access URLs and API Authentication.

Use the following headers for both CIT and MIT. The examples cover standard card payments. Include any additional fields required by your account, business category or the BankCardRU payment method.

Headers
HeaderValue
AuthorizationBearer <access_token>
settlement-account-idThe account in which the card is saved
Content-Typeapplication/json
📘

Do not send the card number, expiry date, holder name or CVV alongside a saved-card token. Omit savePaymentInstrument: the card is already saved, and combining a token with savePaymentInstrument: true is not allowed.


Customer initiated payment (CIT)

Use CIT when the customer chooses to make a payment with their saved card. Include a return URL so the customer can return to your application after any required confirmation.

📘

A CIT payment may complete its authorisation without further interaction, or it may require the customer to follow an authentication flow. Using a saved card does not guarantee that 3DS will be skipped.

Request: POST /api/v1/intents

{
  "clientReferenceId": "order-1002",
  "payments": [
    {
      "payer": {
        "merchantPayerReference": "12345"
      },
      "paymentInstrument": {
        "paymentMethodName": "BankCardRU",
        "paymentInstrumentToken": "pi_01J8ZC4M7QK3T5V9XB2NDR6HAG",
        "tokenPaymentReason": "CIT",
        "incomingDetails": {
          "redirectUrl": "https://merchant.example/payment/return",
          "failureUrl": "https://merchant.example/payment/failure"
        }
      },
      "submittedAmount": {
        "value": 500,
        "currency": "RUB"
      },
      "authCurrencyCode": "RUB",
      "webhookUrl": "https://merchant.example/webhooks/payments"
    }
  ]
}
Request body
FieldRequirement
clientReferenceIdYour reference for this Intent. Use a new value for each new Intent
paymentsThe array of payments to create. The examples contain one payment
payments[]
FieldRequirement
payerIdentifies the customer whose saved card is used
paymentInstrumentIdentifies the saved card, payment method and initiator
submittedAmountThe payment amount and currency, using the usual payment rules
authCurrencyCodeThe authorisation currency, using the usual payment rules
webhookUrlThe endpoint that receives payment notifications
payments[].payer
FieldRequirement
merchantPayerReferenceRequired. The same customer reference used when the card was saved

Any additional payer information required by the payment method or your account still applies.

payments[].paymentInstrument
FieldRequirement
paymentMethodNameRequired. BankCardRU; must match the saved card
paymentInstrumentTokenRequired. The customer's saved pi_ token
tokenPaymentReasonRequired. CIT
incomingDetailsRequired. Carries the BankCardRU CIT return URL
payments[].paymentInstrument.incomingDetails
FieldRequirement
redirectUrlRequired for the CIT example. The customer's return URL after confirmation
failureUrlOptional. The return URL after an unsuccessful confirmation flow

Do not put card details in this object when paying by token.

payments[].submittedAmount
FieldDescription
valuePayment amount. This example uses 500
currencySubmitted currency. This example uses RUB

authCurrencyCode is a sibling field on the payment. The normal currency-conversion rules apply.

Open the returned URL in the customer's browser or web view and follow the BankCardRU authorisation flow. Retrieve the payment result or receive its webhook after the customer finishes.

📘

A browser return to your application is not itself confirmation of payment success. Check the payment result through GET or a webhook.


Merchant initiated payment (MIT)

Use MIT when your system charges a previously saved card without the customer taking part. Supply the saved token and tokenPaymentReason: "MIT". The standard MIT request can omit incomingDetails, return URLs and threeDSContext.

Request: POST /api/v1/intents

{
  "clientReferenceId": "journey-1003",
  "payments": [
    {
      "payer": {
        "merchantPayerReference": "12345"
      },
      "paymentInstrument": {
        "paymentMethodName": "BankCardRU",
        "paymentInstrumentToken": "pi_01J8ZC4M7QK3T5V9XB2NDR6HAG",
        "tokenPaymentReason": "MIT"
      },
      "submittedAmount": {
        "value": 750,
        "currency": "RUB"
      },
      "authCurrencyCode": "RUB",
      "webhookUrl": "https://merchant.example/webhooks/payments"
    }
  ]
}
Request body
FieldRequirement
clientReferenceIdYour reference for this Intent. Use a new value for each new Intent
paymentsThe array of payments to create. This example contains one payment
payments[]
FieldRequirement
payerIdentifies the customer whose saved card is used
paymentInstrumentThe saved card, its payment method and the MIT reason
submittedAmountThe payment amount and currency
authCurrencyCodeThe authorisation currency; RUB in the example
webhookUrlThe endpoint that receives payment notifications

threeDSContext is not required for MIT.

payments[].payer
FieldRequirement
merchantPayerReferenceRequired. The same customer reference used when the card was saved

Any additional payer information required by the payment method or your account still applies.

payments[].paymentInstrument
FieldRequirement
paymentMethodNameRequired. BankCardRU; must match the saved card
paymentInstrumentTokenRequired. The customer's saved pi_ token
tokenPaymentReasonRequired. MIT
incomingDetailsNot required for this example. Return URLs are not required; include any noninteractive context required for your account

Do not send card details or savePaymentInstrument: true when paying by token.

payments[].submittedAmount
FieldDescription
valuePayment amount. This example uses 750
currencySubmitted currency. This example uses RUB

authCurrencyCode is a sibling field on the payment. The normal currency-conversion rules apply.

The initial response may contain an intermediate or an already available result.

📘

MIT does not return an interactive 3DS step for the customer to complete. If the saved card cannot be used for MIT, the payment fails with the applicable error; it is not automatically converted into a CIT payment.


Get the payment result

For either CIT or MIT, use GET /api/v1/intents/{intentId}, GET /api/v1/payments/{paymentId}, or payment webhooks. The normal payment status model applies. See Payment Overview.

Request: GET /api/v1/intents/204264682781298720

No request body is required. Use the same account and API authentication as for the original Intent.

Payment webhook

The equivalent payment webhook uses transactionId for the payment identifier and includes isStoredCredential: true:

{
  "transactionType": "PAYMENT",
  "transactionId": "204264682781298721",
  "intentId": "204264682781298720",
  "status": "CAPTURED",
  "isStoredCredential": true,
  "paymentInstrument": {
    "paymentMethodName": "BankCardRU",
    "paymentInstrumentToken": "pi_01J8ZC4M7QK3T5V9XB2NDR6HAG"
  }
}
Webhook body
FieldDescription
transactionTypePAYMENT
transactionIdThe payment identifier; corresponds to payments[].id in an Intent response
intentIdThe parent Intent identifier
statusThe payment status reported by this notification
isStoredCredentialtrue because the payment used a previously saved card
paymentInstrument
FieldDescription
paymentMethodNameThe payment method, BankCardRU in the example
paymentInstrumentTokenThe saved-card token used for the payment

These are response excerpts. A payment by a saved token does not request a new save, so its token can be returned without savingRequested or isSaved. See Webhooks for the standard notification contract.


Handle errors

Check the request result, payment creation result and payment status separately.

Where the problem occursWhere to read the result
Request validation or accessHTTP error response, including errorCode and failureMessage
Payment creationpaymentCreationErrors in the Intent response, including createStatusCode and statusMessage. An HTTP success response can still contain creation errors
Payment processingThe payment's status and error or decline details. Read platform errors from the Intent's payment object (processingStatusCode and statusMessage) or the payment webhook (errorCode and errorMessage)

Errors relevant to saved cards

CodeMeaningAction
HTTP 400Invalid fields, such as a missing customer reference or reason, or card details supplied with a tokenCorrect the request
CAPABILITY_DISABLED — HTTP 403H2H tokenization is disabled for the settlement accountContact the integration team
INSTRUMENT_NOT_FOUND — HTTP 404The token is unknown, deleted or unavailable within the requested account and customer scopeCheck the token, account and customer; retrieve the customer's saved cards
CODE_CT0005Payment initiator type is not allowed for this account or methodCheck CIT/MIT availability with the integration team
CODE_PT0007Payment instrument is invalid or blockedAsk the customer to use another card
CODE_PT0009Payment instrument is not available for merchant-initiated paymentsAsk the customer to complete a new card-saving flow before another MIT payment

An instrument already recognised as invalid can also be rejected with payment status DECLINED and declineCode: "36" (Restricted card). Handle the payment status and decline details as well as platform error codes.

An existing token without a usable MIT payment capability produces a payment with status ERROR and CODE_PT0009. For example, a GET Intent response may contain this excerpt:

{
  "id": "204264682781298720",
  "payments": [
    {
      "id": "204264682781298721",
      "status": "ERROR",
      "processingStatusCode": "CODE_PT0009",
      "statusMessage": "Payment instrument is not available for merchant-initiated payments",
      "paymentInstrument": {
        "paymentMethodName": "BankCardRU",
        "paymentInstrumentToken": "pi_01J8ZC4M7QK3T5V9XB2NDR6HAG"
      }
    }
  ]
}

Bank declines use the normal payment decline fields. See Decline Reasons, Creation Errors and Processing Errors for the general error model.


Currency conversion and refunds

Token payments use the same amount and currency rules as other payments. Currency conversion remains available: submittedAmount and the resulting authAmount may be in different currencies. The examples use RUB for both to keep the token-specific fields clear.

Where the payment method supports refunds, refund a CIT or MIT payment through the normal refund API, referencing the original payment. A refund does not delete the saved-card token.

Test the integration

Use the test cards listed under BankCardRU Sandbox, an account with H2H tokenization enabled and the appropriate configuration for card binding. Keep sandbox tokens and credentials separate from production.

Cover the complete customer journey: save a card, retrieve its token, make a CIT payment, handle any required confirmation, make a MIT payment, handle an unsuccessful payment, delete the token and save the card again. For binding without a purchase, also cover zero amount authorisation and cancellation of a nonzero hold.


Did this page help you?