Host-to-Host integration — direct server-to-server communication. You create an invoice via the API, receive the payment details and show them to the payer on your side, with no redirect to CrocoPay.
You create an invoice via the API, receive the payment details (card, phone number or QR) and show them to the payer on your side — no redirect to CrocoPay.
All requests require the headers Client-Id and Client-Secret. You will find the keys under “Shops” → the gear icon next to the merchant.
Creates a new payment invoice. Returns the invoice ID and the payment details.
POST /api/v2/h2h/invoices HTTP/1.1
Host: crocopay.tech
Client-Id: GnHqauRCUVtB8sECR7m
Client-Secret: vpBpXo7REyApkDnLIOpMR3lk1ndaLmY2qoZptV9cHOtjJLUDsW26GBSe2kda1IVQIMR758Z
Content-Type: application/json
{
"amount": 5000,
"currency": "RUB",
"payment_option": "TO_CARD",
"callback_url": "https://example.com/payment?user_id=42"
}
HTTP/1.1 200 OK
{
"id": "911c2823-f55b-43b5-9881-d5653107f7dc",
"status": "Pending",
"amount": 5000,
"currency": "RUB",
"payment_option": "TO_CARD",
"card": "4276 1234 5678 9012",
"bank_receiver": "Sberbank",
"card_owner": "IVAN PETROV",
"expires_at": "2026-09-15T12:30:00Z"
}
HTTP/1.1 200 OK
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "Pending",
"amount": 5000,
"currency": "RUB",
"payment_option": "SBP",
"card": "+79001234567",
"bank_receiver": "Alfa-Bank",
"card_owner": "ANNA SIDOROVA",
"expires_at": "2026-09-15T12:30:00Z"
}
HTTP/1.1 422 Unprocessable Entity
{
"status": "error",
"message": "payment_option TO_CARD is not enabled for currency UZS"
}
Returns the current status and details of an invoice by its UUID — use it to poll until the invoice is paid.
Returns the payment methods available to your shop — call it before creating an invoice.
HTTP/1.1 200 OK
{
"methods": [
{ "currency": "RUB", "payment_option": "TO_CARD", "name": "Card (any Russian bank)" },
{ "currency": "RUB", "payment_option": "SBP", "name": "SBP (any Russian bank)" },
{ "currency": "RUB", "payment_option": "SBP_ALFA", "name": "SBP Alfa-Bank" },
{ "currency": "RUB", "payment_option": "QR_NSPK", "name": "QR NSPK" },
{ "currency": "RUB", "payment_option": "TRANSGRAN_SBER", "name": "Cross-border · SberPay" },
{ "currency": "UAH", "payment_option": "TO_CARD", "name": "Card (Ukraine)" },
{ "currency": "UZS", "payment_option": "TO_CARD", "name": "Card (Uzbekistan)" },
{ "currency": "TJS", "payment_option": "TO_CARD", "name": "Card (Tajikistan)" },
{ "currency": "AZN", "payment_option": "TO_CARD", "name": "Card (Azerbaijan)" },
{ "currency": "KZT", "payment_option": "TO_CARD", "name": "Card (Kazakhstan)" },
{ "currency": "KGS", "payment_option": "TO_CARD", "name": "Card (Kyrgyzstan)" }
]
}
The value of payment_option depends on the currency. Ask your manager which methods are enabled for your shop.
TO_CARD
Bank card transfer (any Russian bank)
Card number
SBP
SBP transfer — any Russian bank
Phone number
SBP_ALFA
SBP transfer — Alfa-Bank
Phone number
SBP_TBANK
SBP transfer — T-Bank
Phone number
QR_NSPK
NSPK QR code payment
QR code
MOBILE_PHONE
Mobile phone top-up
Phone number
TO_CARD_TRANSGRAN
Cross-border card transfer (any bank)
Card number
SBP_TRANSGRAN
Cross-border SBP transfer (any bank)
Phone number
TRANSGRAN_ALFA
Cross-border — Alfa-Bank
Card / phone
TRANSGRAN_VTB
Cross-border — VTB
Card / phone
TRANSGRAN_SBER
Cross-border — SberPay
Phone number
TRANSGRAN_TPAY
Cross-border — T-Pay (T-Bank)
Card / phone
TO_CARD
Bank card transfer (Ukraine)
Card number
UZCARD
UzCard card transfer
Card number
HUMO
Humo card transfer
Card number
PAYME
Payme transfer
Card / phone
CLICK
Click transfer
Card / phone
BANK_TRANSFER
Bank transfer (Kazakhstan)
Card number
BANK_TRANSFER
Bank transfer (Azerbaijan)
Card number
KORTI_MILLI
Transfer — Korti Milli
Card number
DUSHANBE_CITY
Transfer — Dushanbe City Bank
Card number
TO_CARD
Bank card transfer (Kyrgyzstan)
Card number
After a successful payment CrocoPay sends a POST to your callback_url.
POST /payment?user_id=42 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"timestamp": 1753282096,
"subtotal": 500000,
"percentage": 0,
"charge_percentage": 0,
"charge_fixed": 0,
"total": 500000,
"sign": "ef5954715c663e3f96194a03981a0b04dd0772bfa5164afcdb507470c9c5078d"
}
$expected = hash_hmac('sha256',
"{$_POST['timestamp']}|{$_POST['subtotal']}|{$_POST['percentage']}|" .
"{$_POST['charge_percentage']}|{$_POST['charge_fixed']}|{$_POST['total']}",
$yourClientSecret
);
if (!hash_equals($expected, $_POST['sign'])) {
http_response_code(403);
exit('Invalid signature');
}
// payment confirmed Express integration — you create a payment link with a single API request and the payer lands on a ready-made branded CrocoPay payment form. Multiple countries and currencies per shop work out of the box.
Create a payment link with a single POST request — the payer opens the branded CrocoPay form, picks a country and a payment method and completes the payment.
Initiates a payment and returns redirect_url — the link to the payment form.
POST /api/v2/initiate-payment HTTP/1.1 Host: crocopay.tech Content-Type: application/x-www-form-urlencoded client_id=GnHAFAZsT1ktFYqauUVtB8sECR7m &client_secret=vpBpXN40yaWQWicAobl...R758Z &amount=5000 ¤cy=RUB &successUrl=https://example.com/success &cancelUrl=https://example.com/cancel &callbackUrl=https://example.com/payment?user_id=42
HTTP/1.1 200 OK
{
"status": "success",
"message": "Initiated payment successfully.",
"redirect_url": "https://crocopay.tech/restapi/payment?grant_id=78784424&token=DuMJThhEimrrdiCKrW2A"
}
// Currency is not enabled for the merchant
{ "status": "error", "message": "Currency UAH is not supported by this merchant." }
// Amount is zero
{ "status": "error", "message": "Amount cannot be 0 or less than 0." }
// Fractional amount for a whole-number-only currency (HTTP 422)
{ "message": "The amount for currency RUB must be a whole number, without minor units." }
// Invalid client_id / client_secret (HTTP 403)
{ "message": "Can not verify the client. Please check client Id and Client Secret." }
Example: the shop is set up for RUB + UZS and the request amount is 5,000 RUB. A payer from Uzbekistan picks UZ — the form converts the amount to UZS at the current rate, and the merchant receives the notification in UZS.
After a successful payment CrocoPay sends a POST to your callback_url.
POST /payment?user_id=42 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"timestamp": 1753282096,
"subtotal": 500000,
"percentage": 0,
"charge_percentage": 0,
"charge_fixed": 0,
"total": 500000,
"sign": "ef5954715c663e3f96194a03981a0b04dd0772bfa5164afcdb507470c9c5078d"
}
$expected = hash_hmac('sha256',
"{$_POST['timestamp']}|{$_POST['subtotal']}|{$_POST['percentage']}|" .
"{$_POST['charge_percentage']}|{$_POST['charge_fixed']}|{$_POST['total']}",
$yourClientSecret
);
if (!hash_equals($expected, $_POST['sign'])) {
http_response_code(403);
exit('Invalid signature');
}
// payment confirmed Accept payments from customers worldwide — in US dollars, euros, Canadian dollars and rupees, through the same H2H API. The payer uses a regular Visa/Mastercard card, Apple Pay, Google Pay, PayPal, Revolut and more — no CIS bank account needed.
amount
yes
Amount. Cents are allowed for USD, EUR, INR: 49.99
currency
yes
USD, EUR, CAD or INR
provider
no
Provider code (stripe, paypal, revolut…). If omitted, the payer chooses on our page
callback_url
no
Where to send the payment notification. Include your order ID in it
success_url
no
Where to return the payer after payment
cancel_url
no
Where to return the payer on cancellation
provider is optional — it decides where the link leads:
GET /api/v2/h2h/payment-method/available (currencies USD / EUR) — it changes, so don’t hard-code it. If the provider isn’t enabled for you or is temporarily unavailable, the invoice is not rejected — you get the picker link instead. An unknown provider code returns error 422. The legacy parameter name onramp_provider is still accepted.stripe
Stripe / Link (cards, Apple Pay, Google Pay)coinbase
Coinbasepaypal
PayPal — requires a PayPal accountrobinhood
Robinhood — requires a Robinhood accountrevolut
Revolut — requires a Revolut accounttopper
Topperbanxa
Banxabinance
Binance Connectblockchaincom
Blockchain.comtransak
Transakmeld
Meld (aggregator)particle
Particle Networksardine
Sardineinterac
Interacupi
UPI / IMPSMinimums are set by the providers and change over time. An amount below the minimum is rejected on the provider’s page, not by the API. The country is detected from the payer’s IP: a provider that doesn’t serve it will decline the payment (e.g. PayPal and Robinhood are USA only). For customers outside the USA/EU use stripe, topper, banxa, transak or binance — or omit provider and let the payer choose. The first payment may require a quick ID check (KYC, ~2 min); the card must support 3-D Secure. Payments are final — no chargebacks.
POST /api/v2/h2h/invoices HTTP/1.1
Host: crocopay.tech
Client-Id: GnHqauRCUVtB8sECR7m
Client-Secret: vpBpXo7REyApkDnLIOpMR3lk1ndaLmY2qoZptV9cHOtjJLUDsW26GBSe2kda1IVQIMR758Z
Content-Type: application/json
{
"amount": 49.99,
"currency": "USD",
"callback_url": "https://example.com/webhook?order=1042",
"success_url": "https://example.com/success",
"cancel_url": "https://example.com/cancel"
}
{
"amount": 120,
"currency": "EUR",
"provider": "revolut",
"callback_url": "https://example.com/webhook?order=1043"
}
HTTP/1.1 200 OK
{
"message": "Payment url was successfully generated",
"url": "https://pay.crocopay.tech/...",
"transaction": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "Pending",
"currency": "USD",
"amount": 49.99,
"expiredAt": "2026-10-19T12:30:00.000000Z"
}
}
transaction.id from the response — pass it to GET /api/v2/h2h/invoices/{id}. The callback_url notification carries no ID — add your order ID to callback_url (?order=1042).
Ask your manager about the fee mode and enabling international payments for your shop.
After a successful payment CrocoPay sends a POST to your callback_url.
POST /payment?user_id=42 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"timestamp": 1753282096,
"subtotal": 500000,
"percentage": 0,
"charge_percentage": 0,
"charge_fixed": 0,
"total": 500000,
"sign": "ef5954715c663e3f96194a03981a0b04dd0772bfa5164afcdb507470c9c5078d"
}
$expected = hash_hmac('sha256',
"{$_POST['timestamp']}|{$_POST['subtotal']}|{$_POST['percentage']}|" .
"{$_POST['charge_percentage']}|{$_POST['charge_fixed']}|{$_POST['total']}",
$yourClientSecret
);
if (!hash_equals($expected, $_POST['sign'])) {
http_response_code(403);
exit('Invalid signature');
}
// payment confirmed