Resources and configuration
Configure your sandbox and production environment to ensure API requests are optimal.
Checkout Protocol
Checkout Protocol API resources.
Authentication request
Authenticate to the APIs and start using the Checkout.
Endpoint: POST {CHECKOUT_URL}/api/v1/session
Header: Content-Type: application/json
Common parameters for Checkout Protocol
These apply to all operations (purchase, debit, credit, transfer). Operation-specific extras are listed in each API call.
| Parameter | Type | Required | Description |
|---|---|---|---|
merchant_key | string | yes | Your merchant key from admin panel. |
operation | string | yes | One of purchase, debit, credit, transfer. |
success_url | string (URL, ≤1024) | yes | Where to redirect after a successful payment. May contain query parameters. |
cancel_url | string (URL, ≤1024) | no | Where to redirect when the customer closes the form. Trigger conditions configurable via "Maximum count declines" in Protocol Mappings. |
expiry_url | string (URL, ≤1024) | no | Redirect target when the session expires before completion. |
error_url | string (URL, ≤1024) | no | Redirect target on a Checkout-side technical error (e.g., misconfiguration). If omitted, Checkout shows a default error page. |
url_target | string | no | HTML browsing context for return: _self, _parent, _top. |
session_expiry | integer (1–720) | no | Session lifetime in minutes. Default 60. |
checkout_language | string | no | Default Checkout Page language. Highest-priority language source. Allowed values: fr, en, es, de, kk, ru, ar, zh, az, ua, no, zho. An unsupported value returns the error The checkout_language parameter is incorrect. |
channel_id | string (≤16) | no | Routes the payment to a specific MID (Merchant Mapping). Configured in admin panel. If used together with methods, the MID must support the chosen method. |
hash | string | yes | Request signature. See hash signature. |
order | object | yes | See below. |
order.number | string (≤255, [A-Za-z0-9-!"#$%&'()*+,./:;&@]) | yes | Your unique order identifier. Idempotency key: see idempotency. |
order.amount | string | yes | Decimal string. Format depends on the currency exponent. See Amount format. |
order.currency | string (3 chars fiat / 3–6 chars crypto) | yes | ISO 4217 for fiat. |
order.description | string (2–1024) | yes | Human-readable product name shown on the receipt. |
customer | object | conditional | Required when the chosen payment method needs it. If omitted, Checkout asks the customer to fill the missing fields. |
customer.name | string (2–200, Latin basic [a-zA-Z]) | conditional | Customer's name. Its validation (including whether the field is required) is governed by the Protocol Mapping settings. If it is not specified in the request, the Checkout page shows it — when a payment method needs it — as the Cardholder field. Example: John Doe. |
customer.email | string (email) | conditional | |
customer.birth_date | string (yyyy-mm-dd, ISO 8601) | conditional | Required by some APMs. |
billing_address | object | conditional | Required by AVS / 3DS / some APMs. |
billing_address.country | string (alpha-2) | conditional | ISO 3166-1. |
billing_address.state | string (2–32) | optional | Collected and validated only when billing_address.country is US, CA, AU, JP, or IN (2-letter code); ignored for other countries. |
billing_address.city | string (2–40) | conditional | |
billing_address.address | string (2–32) | conditional | |
billing_address.house_number | string (1–9) | optional | |
billing_address.zip | string (2–10) | conditional | |
billing_address.phone | string (1–32, digits/+()-) | conditional | |
billing_address.phone_country_code | string | optional | E.g., +380. |
billing_address.district | string (2–32) | optional | |
billing_address.language | string | optional | Language for the billing context, e.g. UA (case-insensitive). |
parameters | object | optional | Extra parameters required by a specific payment method. Keyed by method name: parameters.card.foo, parameters.paypal.bar. |
custom_data | object | optional | Arbitrary key-value data that will be echoed back in the callback. |
General fields for Checkout Page
The list of the general fields and possible errors on the Checkout page is below:
| Fields | Type | Limitations | Error |
|---|---|---|---|
Card number | Integral | Lun algorithm, length 14-19 numbers | Invalid card |
Expiry Date | Date | 2-2 numbers (in the format mm-yy), after today's date | The expiration date of card is expired and not valid. |
Security code | Integral | Up to 4 characters | Invalid security code |
Name on card | String | Up to 32 characters | The name on card field Must contain at least 2 words: first name and last name. Allowed special characters: hyphens, apostrophes, diacritics |
Country | List | 2-letters code | Country is required. Please enter a valid Country |
State/Region | String List - for USA, Canada, Australia, Japan, India | 2-letter code for US, CA, AU, JP, IN; free string elsewhere | Varies by country |
City | String | Up to 32 characters | City is required. Please enter a valid City |
Address line | String | Up to 32 characters | Address line is required. Please enter a valid Address line |
Zip code | String | Up to 32 characters | Zip code is required. Please enter a valid Zip code |
Phone number | String | Up to 32 characters | Phone number is required. Please enter a valid Phone number |
Operation-specific parameters
| Parameter | Type | Operations | Description |
|---|---|---|---|
methods | array of strings | purchase, debit, credit | Restricts the methods shown on the Checkout page (e.g. ["card","paypal"]). If omitted, pre-routing rules apply. |
req_token | boolean (default false) | purchase, debit | When true, Checkout returns a card_token in the callback for future tokenized payments. Ignored if card_token is supplied. |
card_token | array of strings (each 64 chars) | purchase, debit, credit | Use a previously saved token to skip card-data entry. For credit, no card data is collected (no MM / YY, no CVV) and there is no redirect to the checkout page; the payee name is taken from the token, or from payee_first_name + payee_last_name if supplied (those take priority). |
auth | boolean (default false) | purchase only | Authenticate only, do not capture. This is the two-step Dual Message System (DMS) flow; see DMS mode. When true, routing selects DMS or SMS/DMS (both) MIDs and the capture-type logic applies. |
recurring_init | boolean (default false) | purchase, debit | Initializes a recurring chain. Once the initializing transaction settles, recurring_token (and recurring_init_trans_id for purchase) is returned in the response and the callback. Subsequent recurring payments use /api/v1/payment/recurring. |
schedule_id | string | purchase, debit, when recurring_init=true | Schedule for recurring billing. Schedules are not separated by operation type. |
vat_calc | boolean (default false) | purchase only | Enables VAT calculation for this payment. |
payee | object | transfer, credit | Recipient details. See below. |
payee.name | string (2–32, Latin) | transfer, credit | Required. |
payee.email | string (email) | transfer, credit | Conditional. |
payee_billing_address.* | object | transfer, credit | Same shape as billing_address. |
crypto.network | string (≤50) | any with crypto methods | Network to display, e.g. ERC20, TRC20, solana, polygon. |
form_id | string (UUID) | any | Identifier for a custom payment form. See SDK CHECKOUT docs. |
Amount format
order.amount is a string. Its format depends on the currency exponent:
| Currency exponent | Format | Examples |
|---|---|---|
| 0 (e.g., JPY, KRW, CLP, UGX) | "XX.XX" (with trailing zeros) | "1000.00" |
| 2 (most fiat: USD, EUR, UAH, ...) | "XX.XX" | "100.99" |
| 3 (BHD, KWD, ...) | "XXX.XXX" | "100.999" |
| 4 (CLF, ...) | "XXX.XXXX" | "100.9999" |
| Crypto | Use the exponent appropriate for the asset | "0.00000001" for BTC |
Special cases:
purchasewith crypto: omitamountentirely (and exclude it from the hash) when the customer enters the amount on a third-party UI (e.g., wallet app).transferwithamount = -1: shows an empty amount field on Checkout so the customer can enter it.
Idempotency
order.number is not globally unique in the system — multiple merchants can reuse the same value. Use a unique order.number for each payment attempt so you can reliably match callbacks to orders. To limit a customer to one attempt per session, set Maximum number of declines to 1 in admin panel > Protocol mapping.
Server-side deduplication. A repeated request with the same merchant_key + order.number within 15 seconds of the previous one returns:
{ "error_code": "400", "error_message": "Duplicate request." }
This protects against accidental double-submits (network retries, double-clicks). After the 15-second window the request is treated as new.
Recommended pattern: generate a UUID (or your own monotonic ID) for each payment attempt your customer makes; do not reuse it across cart-abandon retries.
Responses
On success the API returns:
{
"redirect_url": "https://checkout-sandbox.example.com/p/abc123",
}
On validation failure the API returns 400 Bad Request with errors[]. See Error reference.
Examples
Purchase (one-step, card, with billing address)
curl -X POST "$CHECKOUT_URL/api/v1/session" \
-H "Content-Type: application/json" \
-d '{
"merchant_key": "27106696-656c-...-7e11ae873370",
"operation": "purchase",
"methods": ["card"],
"session_expiry": 60,
"order": {
"number": "order-1234",
"amount": "0.19",
"currency": "USD",
"description": "Important gift"
},
"success_url": "https://example.com/success",
"cancel_url": "https://example.com/cancel",
"expiry_url": "https://example.com/expiry",
"url_target": "_blank",
"customer": {
"name": "John Doe",
"email": "[email protected]"
},
"billing_address": {
"country": "US",
"state": "CA",
"city": "Los Angeles",
"address": "Moor Building 35274",
"zip": "123456",
"phone": "347771112233"
},
"req_token": true,
"hash": "<sha1(md5(uppercase(order.number+amount+currency+description+password)))>"
}'
Debit (charge with a saved token)
curl -X POST "$CHECKOUT_URL/api/v1/session" \
-H "Content-Type: application/json" \
-d '{
"merchant_key": "27106696-...-7e11ae873370",
"operation": "debit",
"methods": ["card"],
"card_token": ["f5d6a0ab6fcfb6487a39e2256e50fff3c95aaa97075ee5e539bb662fceff4dc1"],
"order": {
"number": "order-1234",
"amount": "0.19",
"currency": "USD",
"description": "Important gift"
},
"success_url": "https://example.com/success",
"cancel_url": "https://example.com/cancel",
"customer": { "name": "John Doe", "email": "[email protected]" },
"hash": "<auth signature>"
}'
Transfer (P2P)
curl -X POST "$CHECKOUT_URL/api/v1/session" \
-H "Content-Type: application/json" \
-d '{
"merchant_key": "27106696-...-7e11ae873370",
"operation": "transfer",
"order": {
"number": "order-1234",
"amount": "100.55",
"currency": "USD",
"description": "P2P transfer"
},
"success_url": "https://example.com/success",
"cancel_url": "https://example.com/cancel",
"customer": { "name": "John Doe", "email": "[email protected]" },
"payee": { "name": "Jane Doe", "email": "[email protected]" },
"billing_address": { "country": "US", "state": "CA", "city": "Los Angeles", "address": "Moor Building 35274", "zip": "94538", "phone": "0987654321" },
"payee_billing_address": { "country": "US", "state": "NY", "city": "New York", "address": "123 Park Ave", "zip": "10001", "phone": "0987654321" },
"hash": "<auth signature>"
}'
Credit (payout to a card)
curl -X POST "$CHECKOUT_URL/api/v1/session" \
-H "Content-Type: application/json" \
-d '{
"merchant_key": "27106696-...-7e11ae873370",
"operation": "credit",
"methods": ["airtel"],
"order": {
"number": "order-1234",
"amount": "100.55",
"currency": "USD",
"description": "Reward payout"
},
"success_url": "https://example.com/success",
"cancel_url": "https://example.com/cancel",
"payee_billing_address": { "country": "US", "phone": "347771112255" },
"hash": "<auth signature>"
}'
Errors
The Payments APIs use standard HTTP status codes to indicate the success or failure of a request.
| Status Code | Description |
|---|---|
| 200 | OK |
| 201 | Created |
| 204 | No Content |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 429 | Too Many Requests |
| 500 | Internal Server Error |
We also return a code and message in the response body for each error. Learn more about error codes in Error handling.