🇷🇺 RU: SBP - Faster Payments System

📘

"paymentMethodName": "SBP"


Payment Method Features

Payment MethodSBP
CountryRussia
Processing CurrenciesRUS
PaymentsYes
-- Min per transaction amount1 RUB
-- Max per transaction amountVary, depends on your contract
DisbursementsLater
-- Disbursement Limits--
RefundsFull & Partial
ChargebacksNo

Possible Payment Scenarios:

Our API will provide you with all the necessary information to execute on of the following scenarios:

Name

Steps

Displaying a QR Code in a Web Browser

  1. The client requests a payment link.
  2. The system returns a QR payload (data for rendering the QR code).
  3. The client renders the QR code on the page.
  4. The end user scans the QR code using a mobile device and is redirected to the payment page.

The payment status is returned via a callback.

Payment via Mobile Application

  1. The client requests a payment link.
  2. The system returns a deeplink (a link to open the user's banking app).
  3. The client either displays the deeplink or redirects the user to it.
  4. The user completes the payment in their banking application. The payment status is returned via a callback

Workflow: Payment & Refund

Download in high resolution


Section “QR Generation”

[Step 1.3] You need to create a new intent

  • Use the following API method to create an intent: POST /processing/api/v1/intents.
  • When creating the intent, complete the Payment object.
  • Most fields are common across all payment methods and are thoroughly described in the API Reference section.
  • Method-specific parameters ( please make sure you provided them correctly):
    • "paymentMethodName": "SBP" ← always “SBP” for SBP payment method

    • "incomingDetails":

      {
          "paymentDescription": "",
          "accountNumber": "",
          "redirectUrl": ""
      }
  • Ensure these all the required fields are completed accurately so that we can process your request correctly.

Request Example

{
    "clientReferenceId": "1234",
    "payments": [
        {
            "paymentInstrument": {
                "paymentMethodName": "SBP",
                "incomingDetails": {
                    "paymentDescription": "",
                    "accountNumber": "",
                    "redirectUrl": ""
                }
            },
            "description": "Purchase description",
            "webhookUrl": "webhookUrl",
            "submittedAmount": {
                "value": 100.05,
                "currency": "RUB"
            },
            "authCurrencyCode": "RUB"
        }
    ]
}


Request fields description:

FieldRequiredTypeDescriptionExample
clientReferenceIdRequiredstringn/a
paymentsRequiredArray of objects "payment"n/a

Object "payment" fields description:

FieldRequiredTypeDescriptionExample
paymentInstrumentRequiredObjectThe receiver payment instrumentn/a
submittedAmountRequiredObjectn/a
authCurrencyCodeRequiredStringThe currency the transaction will be processed. Always RUB for this methodRUB

Object "payments[].paymentInstrument" fields description:

FieldRequiredTypeDescriptionExample
paymentMethodNameRequiredStringPayment method nameSBP
incomingDetailsRequiredObjectAdditional data related to payment methodn/a

Object "payments[].paymentInstrument.incomingDetails" fields description:

FieldRequiredTypeDescriptionExample
paymentDescriptionRequiredStringPayment description
accountNumberOptionalStringPayer ID123456
redirectUrlRequiredStringThe URL on the Merchant’s side to which the Payer is redirected upon completion of the Operation, instead of being shown the default receipt pagehttps://example.com

Object "payments[].submittedAmount" fields description:

FieldRequiredTypeDescriptionExample
valueRequiredNumberTransaction amount100.40
currencyRequiredStringThe original currency of the transaction. Can vary, will be converted into auth currency during the processingUSD

[Step 1.7] Return the QR in response

  • In the response, you will receive an additional object payments.additionalData. It contains the following fields:
    • QR_BASE64 – a QR code encoded in Base64
    • URL – a URL to which the user should be redirected to complete the payment

Response Example

{
  "intentId": "232510340021612544",
  "payments": [
    {
      "id": "232510340646563840",
      "submittedAmount": {
        "value": 100.05,
        "currency": "RUB"
      },
      "authAmount": {
	      "value": 100.05,
        "currency": "RUB"
      },
      "paymentInstrument": {
        "id": "PI204264628196626432",
        "paymentMethodId": "PM199507277233246209",
        "paymentMethodName": "SBP",
        "storedDetails": {
          "paymentDescription": "",
          "accountNumber": "",
          "redirectUrl": ""
        }
      },
      "status": "ACCEPTED",
      "additionalData": {
        "qrBase64": "qrBase64",
        "url": "url"
      }
    }
  ],
  "disbursements": [],
  "clientReferenceIntentId": "123456789",
  "paymentCreationErrors": [],
  "disbursementCreationErrors": [],
  "intentStatus": "CREATED"
}

Section “QR Payment”

[2.7] Receive the webhook with the transaction status

🔗

More about Payment Callbacks on the dedicated page

  • After the transaction was processed and reached its final status (CAPTURED or DECLINED)
  • The Platform will notify you about the latest status change via the callback
  • In some cases, the acquire might return extra information about the transaction. In that case we will return additional data in the webhook

SIMPLE WEBHOOK WITH TRANSACTION STATUS

{
  "transactionType": "PAYMENT",
  "transactionId": "111122223333444455",
  "status": "CAPTURED",
  "additionalData": {
    "sbpPhone": "79998887766",
    "payerFio": "ИВАН ИВАНОВИЧ И",
    "sbpBank": "Банк"
  }
}

REFUNDS

📘

General Inforamtion:

  • They cannot exceed the total value of the original transaction
  • Refund can be full or partial

Send a Refund Request

  • To initiate the refund (full or partial) to the payer's original payment instrument, you must send a separate Refund request.
  • If the payment involved FX and there two currencies involved, then you can use any these two currencies here.
  • There is no difference between currencies, because we will use the historical rate that was used during the payment processing and the payer will receive the exact amount they spent.
  • However you must fill in only one object paymentSubmittedAmount or paymentAuthAmount
    • paymentSubmittedAmount must be filled in the currency specified in field during the payment creation in submittedAmount.currency
    • paymentAuthAmount must be filled in the currency specified in field during the payment creation in authCurrencyCode
  • Use the following endpoint: Create Refund inside existing Intent and specify the following parameters:

Example:

//For full refund
{
  "paymentId": 204264682781298700
  }
  
//For partial refund
{
  "paymentId": 204264682781298700,
  "partial": true,
  "paymentSubmittedAmount": {
    "value": 100.05,
    "currency": "RUB"
  },
  "webhookUrl": "webhookUrl"
}

Field

Type

Required

Description

paymentId

int64

Required

• You must to let us know what payment transaction this refund must be linked to.

• Input here the ID of a Payment transaction your received during the Intent Creation from us.

partial

boolean

Optional

true - for partial refunds. If the refund is partial, then you need to specify the amount and currency

fasle - for full refunds. You don't need to specify the amount. If the filed is not specified at all, the platform will try to issue the refund for the full available amount

if not specified - the platform will initiate a full refund

paymentSubmittedAmount

object

Optional

• Need to specify this object OR paymentAuthAmount • Must be filled in the currency specified in field during the payment creation in submittedAmount.currency

-- value

number

Optional

-- currency

string

Optional

paymentAuthAmount

object

Optional

• Need to specify this object OR paymentSubmittedAmount • Must be filled in the currency specified in field during the payment creation in authCurrencyCode

-- value

number

Optional

-- currency

string

Optional

reason

string

Optional

Reason for the refund

webhookUrl

string

Optional

Webhook URL that will receive notifications about refund status updates

  • After the creation of the refund request you must wait for the callback, that will provide you with the latest transaction status

Receive the webhook with the transaction status

🔗

More about Refund Callbacks on the dedicated page

  • After the transaction was processed and reached its final status (REFUNDED or DECLINED)
  • The Platform will notify you about the latest status change via the callback

SIMPLE WEBHOOK WITH TRANSACTION STATUS

{
    "transactionType": "REFUND",
    "transactionId": "111122223333444455",
    "status": "ACCEPTED"
}

Test Data

Our system allows emulating different test cases in the sandbox environment. To simulate specific scenarios and receive different results, use the intent.description parameter.

SBP Payment Test flow

High-resolution image is available on the link: SBP_TestFlow.jpg

Caseintent.descriptionfinal paymentStatus
Successful payment--CAPTURED
Successful Payment with extra payer detailsReturnAdditionalPayerInfoCAPTURED
Payment DeclinedDeclinedPaymentDECLINED
FailureLinkCreationErrorERROR

Case "Successful payment"

Steps:

  1. The client creates an intent via POST /processing/api/v1/intents.
  2. A synchronous response is returned with paymentStatus = AUTHORIZATION_REQUESTED.
  3. The client follows the link from payments.additionalData.url.
  4. A callback is received with paymentStatus = CAPTURED.

Case "Successful Payment with extra payer details"

📘

Not all transactions can have the extra payer information. That depends on the Processor and sometimes the information might be returned. To test receiving this data and process it on your side, please follow the instructions below.

Steps:

  1. The client creates an intent viaPOST /processing/api/v1/intents using the intent.description parameter with the value "ReturnAdditionalPayerInfo".
  2. A synchronous response is returned with paymentStatus = AUTHORIZATION_REQUESTED.
  3. The client follows the link from payments.additionalData.url.
  4. A callback is received with paymentStatus = CAPTURED and extra payer details.

Case "Payment Declined"

Steps:

  1. The client creates an intent viaPOST /processing/api/v1/intents using the intent.description parameter with the value "DeclinedPayment".
  2. A synchronous response is returned with paymentStatus = AUTHORIZATION_REQUESTED.
  3. The client follows the link from payments.additionalData.url.
  4. A callback is received with paymentStatus = DECLINED.

Case "Failure"

Steps:

  1. The client creates an intent viaPOST /processing/api/v1/intents using the intent.description parameter with the value "LinkCreationError".
  2. A synchronous response is returned with paymentStatus = ERROR.