How to Accept Payments via Redirect to Provider's Page
You need to accept payments without handling card data on your side — the user enters card details directly on the provider’s page. You are implementing a Redirect flow: Gateway creates a payment session with the provider and returns a URL for redirection.
Difference from H2H: Card data is not transmitted through Gateway — user enters it directly on the provider’s page. What you’ll need: Provider’s API key and public key, specification of their endpoints (pay, callback, status), test account.
1. Implement Session Creation (POST /pay)
Section titled “1. Implement Session Creation (POST /pay)”Step 1. Accept Request Without Card Data
Section titled “Step 1. Accept Request Without Card Data”Incoming request contains only user and payment information:
{ "method_name": "pay", "params": { "customer": { "email": "user@example.com", "first_name": "Ivan", "last_name": "Ivanov", "country": "US", "ip": "192.168.1.1" } }, "payment": { "token": "tok_xxxx", "gateway_amount": 10000, "gateway_currency": "USD", "product": "Premium Plan", "order_number": "ORD-001" }, "settings": { "api_key": "provider_api_token", "public_key": "provider_public_key", "sandbox": false }, "processing_url": "https://merchant.com/processing", "callback_url": "https://merchant.com/callback"}Full request structure is described in Basic Contracts.
Step 2. Create Session with Provider
Section titled “Step 2. Create Session with Provider”Send amount, currency, user data, and return URL (processing_url) to provider. Provider will create a payment page and return a URL for redirection.
Step 3. Return redirect_request
Section titled “Step 3. Return redirect_request”{ "result": true, "status": "pending", "gateway_token": "session_12345", "amount": 10000, "currency": "USD", "redirect_request": { "url": "https://provider.com/payment_page", "type": "get_with_processing", "params": {} }, "logs": [...]}Redirect Types (redirect_request.type)
Section titled “Redirect Types (redirect_request.type)”| Type | Description |
|---|---|
"get_with_processing" |
GET redirect + show processing page (most commonly used) |
"post_iframes" |
POST to iframe |
"get" |
Simple GET redirect |
"post" |
Auto-submit POST form |
More details about
redirect_requestformat — in Basic Contracts (section 3).
2. Implement Callback Handling (POST /callback)
Section titled “2. Implement Callback Handling (POST /callback)”After payment, provider sends webhook to your Gateway’s POST /callback:
- Validate provider’s signature (method depends on provider — JWT, RSA, HMAC)
- Normalize status (
approved/declined) - Send result to Business, signing with JWT key
settings.sign_key
Full callback and JWT instruction — in Callbacks & JWT.
3. Implement Status Check (POST /status)
Section titled “3. Implement Status Check (POST /status)”For cases when callback doesn’t arrive, implement a status check endpoint:
{ "method_name": "status", "payment": { "token": "tok_xxxx", "gateway_token": "session_12345" }, "settings": { "api_key": "provider_api_token" }}Detailed specification — in Status and Payout.
Implementation Checklist
Section titled “Implementation Checklist”- Create endpoint
POST /pay - Extract
payment.gateway_amount / 100,payment.token,settings - Create session with provider
- Get payment page URL from provider
- Return
status: "pending"+redirect_requestwith URL and type - Form
logs - Implement
POST /callbackwith signature validation (see Callbacks & JWT) - Implement
POST /statusfor status check (see Status and Payout)
Node.js Implementation Example
Section titled “Node.js Implementation Example”app.post("/pay", async (req, res) => { const body = req.body; const amount = body.payment.gateway_amount / 100; const apiKey = body.settings.api_key;
// 1. Formulate request to provider (without card!) const providerPayload = { amount, currency: body.payment.gateway_currency, externalPaymentId: body.payment.token, returnUrl: body.processing_url, senderName: body.params?.customer?.first_name, senderCountry: body.params?.customer?.country, };
// 2. Send request const providerRes = await fetch("https://api.provider.com/v1/payments", { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify(providerPayload), }); const data = await providerRes.json();
// 3. Return redirect_request with payment page URL res.status(200).json({ result: true, status: "pending", gateway_token: data.paymentId, amount: body.payment.gateway_amount, currency: body.payment.gateway_currency, redirect_request: { url: data.redirectUrl, type: "get_with_processing", params: {}, }, logs: [ { request: { body: providerPayload }, status: providerRes.status, response: data, kind: "pay", duration: 0.5, }, ], });});