API Integration Manual
Everything you need to integrate RubitPay into your platform — accepting payments from Russian consumers via a single, unified REST API.
Base URL
All API requests are made over HTTPS to the base URL below. All requests must use UTF-8 encoding with the header Content-Type: application/json.
https://api.rubitpay.com
Dates and times follow ISO 8601 standard. When no time zone is specified, UTC+03:00 (Moscow Time) is assumed.
Authentication
Every API request must be signed using your shop_id and secret key. The signature is passed as the sign parameter in the request body. Contact your account manager at tech@rubitpay.com to receive credentials.
Request Signing
All request parameters (excluding sign) are used to generate the signature:
- Sort all parameter keys alphabetically.
- Concatenate their values with a colon
:separator. - Append
:and your secret key at the end. - Compute the SHA-256 hash of the resulting string.
- Pass the hex digest as the
signfield in your request body.
Python Example
import hashlib, requests
def make_sign(params: dict, secret: str) -> str:
keys = sorted(k for k in params if k != "sign")
raw = ":".join(str(params[k]) for k in keys)
return hashlib.sha256((raw + ":" + secret).encode()).hexdigest()
# Example — invoice/create
params = {
"shop_id": "79834981",
"shop_order_id": "ORDER-001",
"amount": "2990.00",
"currency": "RUB",
"payway": "sbp",
}
# Sorted keys: amount, currency, payway, shop_id, shop_order_id
# String: "2990.00:RUB:sbp:79834981:ORDER-001:your_secret"
params["sign"] = make_sign(params, "your_secret_key")
Backward Compatibility
The following changes may occur without incrementing the API version and are considered backward-compatible:
- Adding new optional request parameters to existing methods
- Adding new fields to existing API responses
- Changing the order of fields in responses or callbacks
- Adding new error codes or optional HTTP headers
- Adding new types of webhook callback notifications
Single-Step Payment Flow
Funds are blocked and charged immediately in one request. Use invoice/create for this flow.
- User places an order on your platform.
- Call
invoice/tryto pre-calculate and retrieve any additional parameters. - If
result: true, checkadd_ons_configfor required extra fields. - Call
invoice/createwith all parameters. Redirect the user to the returned payment URL. - RubitPay sends a webhook to your notification URL with the payment result.
- On successful notification, the payment is complete.
Two-Step Payment Flow
Funds are first held (blocked), then explicitly charged or released. Commonly used for bank card payments.
- Call
invoice/tryto pre-calculate. - Call
invoice/holdto block funds. Redirect the user to complete authorization. - RubitPay notifies your URL when funds are successfully held.
- Call
invoice/chargeto capture funds, orinvoice/unholdto release them. - RubitPay sends a final webhook confirming the charge or release result.
Idempotency
shop_order_id must be unique per shop account. Submitting a request with a duplicate shop_order_id returns the existing invoice rather than creating a new one.
invoice/try — Pre-calculate Invoice
Retrieves additional parameters required for invoice creation. Use before invoice/create or invoice/hold to determine if extra fields are needed for the selected payment method.
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
shop_id | string | Required | Your unique shop identifier, provided by RubitPay. |
shop_order_id | string | Required | Unique order ID on your system. Must be unique per shop. |
amount | string | Required | Payment amount in decimal format. Example: "2990.00" |
currency | string | Required | ISO 4217 code. Example: "RUB", "CNY" |
payway | string | Required | Payment method. Example: "bank_card", "sbp" |
sign | string | Required | SHA-256 request signature. See Request Signing. |
Response Fields
| Field | Type | Description |
|---|---|---|
result | boolean | true if pre-calculation succeeded. |
add_ons_config | object | Additional fields required for the selected payment method. Pass these in the subsequent invoice request. |
error_code | string | Present when result: false. See Error Codes. |
invoice/create — Create Payment Invoice
Creates a payment invoice and returns the URL to redirect the user to complete payment (single-step flow).
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
shop_id | string | Required | Your shop identifier. |
shop_order_id | string | Required | Unique order ID. Must be unique per shop. |
amount | string | Required | Payment amount in decimal format. |
currency | string | Required | ISO 4217 currency code. |
payway | string | Required | Payment method identifier. |
description | string | Optional | Human-readable description shown to the payer. |
customer_email | string | Optional | Payer's email address. |
success_url | string | Optional | Redirect URL after successful payment. |
fail_url | string | Optional | Redirect URL after failed payment. |
add_ons | object | Optional | Additional parameters from invoice/try response. |
sign | string | Required | SHA-256 request signature. |
Full Example
import hashlib, requests
def make_sign(params, secret):
keys = sorted(k for k in params if k != "sign")
raw = ":".join(str(params[k]) for k in keys)
return hashlib.sha256((raw+":"+secret).encode()).hexdigest()
payload = {
"shop_id": "YOUR_SHOP_ID",
"shop_order_id": "ORD-20240412-001",
"amount": "2990.00",
"currency": "RUB",
"payway": "sbp",
"description": "Order #001",
"success_url": "https://yourshop.com/success",
"fail_url": "https://yourshop.com/fail",
}
payload["sign"] = make_sign(payload, "YOUR_SECRET")
resp = requests.post(
"https://api.rubitpay.com/invoice/create",
json=payload,
headers={"Content-Type": "application/json"}
)
data = resp.json()
if data["result"]:
redirect_url = data["redirect_url"] # send user here
else:
error = data["error_code"]
invoice/hold — Hold Funds
Initiates the first step of a two-step payment. Blocks funds on the payer's account without charging immediately. Use invoice/charge to capture or invoice/unhold to release.
Request parameters are identical to invoice/create. Contact your account manager to confirm which payment methods support two-step flow.
invoice/charge — Capture Held Funds
Completes the second step by capturing previously held funds. Must be called after a successful invoice/hold.
| Field | Type | Required | Description |
|---|---|---|---|
shop_id | string | Required | Your shop identifier. |
shop_order_id | string | Required | Order ID matching the original invoice/hold request. |
sign | string | Required | SHA-256 request signature. |
invoice/unhold — Release Held Funds
Cancels a previously held payment and returns funds to the payer. Must be called after invoice/hold and before invoice/charge. Request parameters are the same as invoice/charge.
Webhook Notifications
After each significant payment event, RubitPay sends an HTTP POST to your configured callback URL. Your server must respond with HTTP 200 to acknowledge receipt.
sign field in the webhook payload using the same signing algorithm as your API requests.
Notification Payload Fields
| Field | Description |
|---|---|
shop_id | Your shop identifier. |
shop_order_id | Your original order ID. |
invoice_id | RubitPay internal invoice ID. |
status | Payment status: success, fail, hold, refund. |
amount | Amount charged. |
currency | Currency code. |
created_at | ISO 8601 timestamp of the event. |
sign | Signature for webhook verification. |
Error Codes
When result: false is returned, the error_code field indicates the error type. Fatal errors require stopping and notifying the user. Non-fatal errors — wait for a server notification; the payment may still resolve.
| Code | Type | Description |
|---|---|---|
invalid_sign | Fatal | Request signature is invalid. Check algorithm and secret key. |
invalid_shop | Fatal | shop_id is unrecognized or inactive. |
duplicate_order | Fatal | shop_order_id already exists with different amount or currency. |
unsupported_payway | Fatal | Payment method not available for this shop or currency. |
processing_error | Non-fatal | Temporary processing issue. Wait for webhook notification. |
insufficient_funds | Fatal | Payer has insufficient funds. |
Supported Currencies
RubitPay supports the following currencies for payment acceptance and settlement:
Sandbox Environment
A full sandbox environment is available for testing your integration before going live. All API methods are supported. Sandbox transactions do not process real funds.
# Sandbox base URL
https://sandbox.api.rubitpay.com
# Use test credentials from your account manager
# All methods work identically to production