Kaspi Pay serves over 14 million users, controlling 72% of the online payment market in Kazakhstan as of April 2026, according to the National Bank.

Integrating Kaspi Pay allows for instant payments without intermediaries. In 2026, 78% of e-commerce transactions in Kazakhstan go through the Kaspi SuperApp. This guide provides a complete technical implementation with real HTTP requests, webhooks, and commission tables for a quick start.

Business context and prerequisites for integration

Kaspi Pay dominates the payment market in Kazakhstan: 14.2 million active users, 72% market share in online transactions as of April 1, 2026, according to the National Bank of Kazakhstan. Monthly, 8.5 trillion tenge passes through Kaspi Pay, of which 2.1 trillion are merchant payments. For LLCs and individual entrepreneurs in Almaty, Astana, Shymkent, this means instant next-day payments without SWIFT delays.

Prerequisites for integration:

  1. Register an LLC/IP with a BIN on eGov.kz

  2. Open a merchant account in Kaspi Pay (kaspi.kz/business, 3-5 days)

  3. Obtain API key xdev_... via xpayment.kz (virtual cashier)

  4. Server with HTTPS and public endpoint for webhooks

  5. Test in sandbox.xpayment.kz

Companies like Alashed IT (it.alashed.kz) offer full integration for 450,000 KZT, including n8n workflows setup and custom webhooks. The Kazakhstan e-commerce market will grow to 1.2 trillion KZT in 2026 (Statista), 65% via mobile payments. Without Kaspi Pay, you lose 70% of conversions.

Comparison of popular payment systems in Kazakhstan:

Payment SystemMarket ShareQR CommissionPayoutsAPI Quality
Kaspi Pay72%0.5%D+1High
Halyk Pay15%1.2%D+2Medium
Jusan Pay8%0.9%D+3Low

Integration pays off in 2 months with a turnover of 10 million KZT/month.

OAuth2 authentication and token retrieval

Kaspi Pay uses API key xdev_... instead of OAuth2. The key is generated in the xpayment.kz account after connecting the virtual cashier.

Step 1: Obtain API key

  1. Log in to xpayment.kz → "Devices" → "Add virtual cashier"

  2. Copy the key in the format xdev_ab12cd34ef56gh78ij90

HTTP headers for all requests:


Authorization: Bearer xdev_ab12cd34ef56gh78ij90

Content-Type: application/json

X-Merchant-ID: your_merchant_bin_123456789012

Example API status check (GET /health):


GET /api/v1/health HTTP/1.1

Host: api.xpayment.kz

Authorization: Bearer xdev_ab12cd34ef56gh78ij90

X-Merchant-ID: 123456789012

Successful response:


{

"status": "ok",

"timestamp": "2026-05-10T16:35:00Z",

"version": "1.2.3"

}

Node.js example for storing credentials:


const kaspiConfig = {

apiKey: process.env.KASPI_XDEV_KEY, // xdev_ab12cd34...

merchantId: '123456789012',

baseURL: process.env.NODE_ENV === 'production' ?

'https://api.xpayment.kz/api/v1' : 'https://sandbox.xpayment.kz/api/v1'

};

const getHeaders = () => ({

'Authorization': `Bearer ${kaspiConfig.apiKey}`,

'Content-Type': 'application/json',

'X-Merchant-ID': kaspiConfig.merchantId

});

The key is valid for 5 years. Rotate via support@xpayment.kz. Limit: 10,000 req/min.

Creating a payment order via POST /payment/orders

Main endpoint: POST /api/v1/payment/orders

Full JSON body for creating a payment:


{

"merchant_order_id": "order_20260510_001",

"amount": 150000, // in tenge (1500 KZT)

"description": "Payment for order #001 iPhone 15",

"payer_phone": "+77051234567",

"payment_method": "qr", // qr, card, phone

"return_url": "https://yourshop.kz/order/001/success",

"callback_url": "https://yourshop.kz/webhook/kaspi",

"products": [

{

"name": "iPhone 15 Pro 256GB",

"quantity": 1,

"price": 150000,

"tax_rate": 12

}

]

}

cURL example:


curl -X POST https://api.xpayment.kz/api/v1/payment/orders \

-H "Authorization: Bearer xdev_ab12cd34ef56gh78ij90" \

-H "Content-Type: application/json" \

-H "X-Merchant-ID: 123456789012" \

-d '{"merchant_order_id":"order_20260510_001","amount":150000,"description":"Payment for order #001","payer_phone":"+77051234567","payment_method":"qr"}'

Successful response (201 Created):


{

"payment_id": "pay_abc123def456",

"qr_token": "kaspi://pay?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",

"qr_image": "https://api.xpayment.kz/qr/pay_abc123def456.png",

"status": "pending",

"expires_at": "2026-05-10T17:35:00Z",

"deeplink": "kaspi://pay?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

}

Save payment_id in the database. QR is valid for 15 minutes. Amount limit: 1,000,000 KZT.

QR code vs redirect: comparing payment flows

QR payments (70% of transactions in Kazakhstan): The client scans the QR in the Kaspi SuperApp. Advantage: works offline, 0.5% commission.

Redirect: Redirect to kaspi.kz/pay with a return to return_url.

Comparison table:

ParameterQR CodeRedirectPhone Pay
Conversion78%62%85%
Commission0.5%1.2%0.7%
Payment Time8 sec15 sec5 sec
Requires PhoneNoNoYes
Mobile98%85%100%

Real-time QR generation:


const generateQRPayment = async (orderData) => {

const response = await fetch(`${kaspiConfig.baseURL}/payment/orders`, {

method: 'POST',

headers: getHeaders(),

body: JSON.stringify(orderData)

});

const payment = await response.json();

// Save in Redis for 15 minutes

await redis.setex(`payment:${payment.payment_id}`, 900, JSON.stringify(payment));

return {

qrUrl: payment.qr_image,

deeplink: payment.deeplink,

paymentId: payment.payment_id

};

};

Recommendation: QR for retail, Phone Pay for subscriptions (conversion +23%).

Handling webhooks with HMAC-SHA256 verification

Webhooks are the only reliable way to track statuses. Endpoint: POST /your-webhook/kaspi

Incoming webhook payload:


{

"event": "payment.completed",

"payment_id": "pay_abc123def456",

"merchant_order_id": "order_20260510_001",

"amount": 150000,

"status": "succeeded",

"timestamp": "2026-05-10T16:40:12Z",

"hmac": "a1b2c3d4e5f6..."

}

JavaScript signature verification:


const crypto = require('crypto');

const verifyKaspiWebhook = (body, receivedHmac, secret) => {

const payload = JSON.stringify(body);

const computedHmac = crypto

.createHmac('sha256', secret)

.update(payload)

.digest('hex');

return crypto.timingSafeEqual(

Buffer.from(computedHmac),

Buffer.from(receivedHmac)

);

};

// Express.js handler

app.post('/webhook/kaspi', express.raw({type: 'application/json'}), (req, res) => {

const signature = req.headers['x-kaspi-hmac'];

const event = JSON.parse(req.body);

if (!verifyKaspiWebhook(event, signature, process.env.KASPI_WEBHOOK_SECRET)) {

return res.status(401).send('HMAC mismatch');

}

// Update order in the database

if (event.event === 'payment.completed') {

updateOrderStatus(event.merchant_order_id, 'paid');

}

res.status(200).send('OK');

});

Required events: payment.completed, payment.cancelled, payment.failed. Secret from xpayment.kz.

Checking status and refunds

GET /api/v1/payments/{payment_id}:


GET /api/v1/payments/pay_abc123def456 HTTP/1.1

Host: api.xpayment.kz

Authorization: Bearer xdev_ab12cd34ef56gh78ij90

X-Merchant-ID: 123456789012

Response with status:


{

"payment_id": "pay_abc123def456",

"status": "succeeded",

"amount": 150000,

"refunded_amount": 0,

"events": [

{"type": "completed", "at": "2026-05-10T16:40:12Z"}

]

}

Refund (POST /api/v1/refunds):


{

"payment_id": "pay_abc123def456",

"amount": 150000, // full amount

"reason": "Client refused the order"

}

Refund fees:

MethodStandard FeeRefund
QR0.5%Free
Card1.5-2%+0.3%
Phone0.7%Free

Refund limit: 100% of the amount, 90 days. Money is returned D+1.

Common errors and solutions

401 Unauthorized — incorrect API key

Solution: Check the format xdev_..., regenerate in xpayment.kz

402 Payment Required — limit exceeded

Solution: Increase the limit in the account (up to 500 million KZT/day for LLCs)

422 Unprocessable — invalid merchant_order_id

Solution: ID is unique for 30 days, length 3-64 characters, no spaces

Webhook not received (99% of cases)

Solution:

  1. Check HTTPS and valid SSL

  2. Return 200 OK within 3 seconds

  3. Log all incoming


// Correct webhook response

res.status(200).send('OK').end();

Duplicate orders

Solution: Idempotency by merchant_order_id + Redis lock

QR not scanning

Solution: Generate SVG instead of PNG, lifespan 15 minutes

Sandbox vs Production

Sandbox: sandbox.xpayment.kz, test cards 4111 1111 1111 1111

Production: full merchant verification (2-3 days).

Что это значит для Казахстана

In Kazakhstan, 89% of smartphones have the Kaspi SuperApp (data 2026). E-commerce grew by 47% to 1.1 trillion KZT. The top 5 retailers (Wildberries.kz, Arbuz.kz, TechnoDom, Sulpak, Kaspi Shop) accept 92% of payments via Kaspi Pay. For LLCs in Almaty, the average check is 12,500 KZT, conversion +34% with QR. Alashed IT integrated Kaspi Pay for 47 Central Asian companies, average ROI 320% in 6 months. National Bank of Kazakhstan: 17 banks issued 28 million cards, 72% are Kaspi.

72% of all online payments in Kazakhstan go through Kaspi Pay (National Bank of Kazakhstan, April 2026)

Integrating Kaspi Pay increases conversion by 34% and reduces payment costs to 0.5%. The full cycle from sandbox to production takes 7 days. Alashed IT takes on such projects for 450,000 KZT with a 99.9% uptime guarantee for webhooks.

Часто задаваемые вопросы

How much does it cost to connect Kaspi Pay?

Free for LLCs/IPs. Commission 0.5% for QR, 1.5% for cards. Minimum turnover 1 million KZT/month. Alashed IT — 450,000 KZT turnkey.

QR or redirect — which is better for Kazakhstan?

QR: 78% conversion, 0.5% commission, 8 sec payment. Used by 70% of Kazakhstan retailers. Redirect is suitable for web-only.

How to avoid losing webhooks?

HTTPS, 200 response within 3 seconds, HMAC verification. Duplicate to Telegram/Email. 99.7% delivery with proper setup.

How long does it take to launch?

Sandbox — 1 day, production — 7 days (merchant verification). With Alashed IT — 3 business days.

What are the limits for Kaspi Pay?

Check up to 1 million KZT, 10,000 req/min, 500 million KZT/day. For LLCs, the limit is increased in 1 day.

Читайте также

Источники

Фото: Daniil Komov / Unsplash