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:
-
Register an LLC/IP with a BIN on eGov.kz
-
Open a merchant account in Kaspi Pay (kaspi.kz/business, 3-5 days)
-
Obtain API key xdev_... via xpayment.kz (virtual cashier)
-
Server with HTTPS and public endpoint for webhooks
-
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 System | Market Share | QR Commission | Payouts | API Quality |
|---|---|---|---|---|
| Kaspi Pay | 72% | 0.5% | D+1 | High |
| Halyk Pay | 15% | 1.2% | D+2 | Medium |
| Jusan Pay | 8% | 0.9% | D+3 | Low |
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
-
Log in to xpayment.kz → "Devices" → "Add virtual cashier"
-
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:
| Parameter | QR Code | Redirect | Phone Pay |
|---|---|---|---|
| Conversion | 78% | 62% | 85% |
| Commission | 0.5% | 1.2% | 0.7% |
| Payment Time | 8 sec | 15 sec | 5 sec |
| Requires Phone | No | No | Yes |
| Mobile | 98% | 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:
| Method | Standard Fee | Refund |
|---|---|---|
| QR | 0.5% | Free |
| Card | 1.5-2% | +0.3% |
| Phone | 0.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:
-
Check HTTPS and valid SSL
-
Return 200 OK within 3 seconds
-
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.
Читайте также
- Telegram боты для бизнеса Казахстана: Полный гид 2026
- Интеграция онлайн-касс для e-commerce в Казахстане 2026: Полный гайд
- Интеграция 1С:Предприятие с сайтом и интернет-магазином в Казахстане 2026
Источники
Фото: Daniil Komov / Unsplash