Kassa & Webhook integratsiya — inPAY
Bosh sahifaga qaytish
Kassa integratsiyasi

Kassa & Webhook qo'llanmasi

Saytingiz yoki Telegram botingizga inPAY to'lov kassasini ulang — kassa oching, to'lov yarating, mijozni checkout'ga yo'naltiring va natijani real-time webhook orqali qabul qiling. Quyida tayyor namuna kodlar va imzo (signature) tekshiruvi bor.

Base URL
https://inpay.uz/api/v1
Auth
Bearer token
Operational
Standard tarif
Real-time
Webhook bildirishnoma
SHA-256
Imzo tekshiruvi
Auto-retry
Yetib bormasa qayta urinish
1 000+
Minimal so'm
Qanday ishlaydi To'lov hayot sikli — 5 qadam
1
Kassa oching
Kabinetda kassa (merchant) yarating. Sizga merchant_id va merchant_token beriladi. Bular API kalitlaringiz.
2
Bearer token oling
merchant_id + merchant_token bilan /api/v1/authorization/ ga so'rov yuboring — javobda bearer_token qaytadi.
3
To'lov yarating
Bearer token bilan /api/v1/create/ ga summa va callback_url yuboring. Javobda order_id va pay_url qaytadi.
4
Mijozni yo'naltiring
Mijozni pay_url (checkout sahifasi) ga yuboring. U yerda Click / Payme / karta orqali to'laydi.
5
Webhook qabul qiling
To'lov yakunlangach inPAY sizning callback_url ga natijani POST qiladi. Imzoni tekshirib buyurtmani yopasiz va 200 qaytarasiz.
Whitelist eslatma. callback_url domeni kassangizning saytiga (website / webhook_url) mos bo'lsa avtomatik ishonchli hisoblanadi. Boshqa domen bo'lsa — uni /merchant/whitelist/ orqali qo'shing, aks holda CALLBACK_NOT_WHITELISTED xatosi qaytadi.
1-qadam — Bearer token olish GET /api/v1/authorization
GET/api/v1/authorization
# merchant_id + merchant_token kabinetdan olinadi curl "https://inpay.uz/api/v1/authorization/?merchant_id=YOUR_ID&merchant_token=YOUR_TOKEN" # Javob: # { "success": true, "bearer_token": "a1b2c3d4e5..." }
<?php $url = "https://inpay.uz/api/v1/authorization/?merchant_id=YOUR_ID&merchant_token=YOUR_TOKEN"; $res = json_decode(file_get_contents($url), true); if (empty($res['success'])) { exit('Auth xatosi: ' . ($res['message'] ?? 'noma\'lum')); } $bearer = $res['bearer_token']; // keyingi so'rovlar uchun saqlang
const r = await fetch("https://inpay.uz/api/v1/authorization/?merchant_id=YOUR_ID&merchant_token=YOUR_TOKEN"); const data = await r.json(); if (!data.success) throw new Error(data.message); const bearer = data.bearer_token;
2-qadam — To'lov yaratish POST /api/v1/create
POST/api/v1/create
curl -X POST "https://inpay.uz/api/v1/create/" \ -H "Authorization: Bearer YOUR_BEARER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "user_id": 1, "amount": 15000, "description": "Buyurtma #123", "callback_url": "https://sizning-saytingiz.uz/webhook.php", "payment_method": "" }' # Javob: # { # "success": true, # "order_id": "9f3a8c2b1d4e5f60", # "pay_url": "https://inpay.uz/checkout/9f3a8c2b1d4e5f60", # "message": "invoice yaratildi" # }
<?php $payload = json_encode([ 'user_id' => 1, // kassa egasi (kabinetdagi user_id) 'amount' => 15000, // so'mda, min 1000 'description' => 'Buyurtma #123', 'callback_url' => 'https://sizning-saytingiz.uz/webhook.php', 'payment_method' => '', // '' | 'click' | 'payme' ]); $ch = curl_init("https://inpay.uz/api/v1/create/"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $payload, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . $bearer, 'Content-Type: application/json', ], ]); $resp = json_decode(curl_exec($ch), true); curl_close($ch); // Mijozni to'lov sahifasiga yo'naltiring: header('Location: ' . $resp['pay_url']);
const res = await fetch("https://inpay.uz/api/v1/create/", { method: "POST", headers: { "Authorization": `Bearer ${bearer}`, "Content-Type": "application/json", }, body: JSON.stringify({ user_id: 1, amount: 15000, description: "Buyurtma #123", callback_url: "https://sizning-saytingiz.uz/webhook.php", payment_method: "", }), }); const data = await res.json(); location.href = data.pay_url; // checkout sahifasiga o'tkazish
So'rov parametrlari POST /api/v1/create tanasi
MaydonTuriMajburiyIzoh
amountnumberHaTo'lov summasi (so'm). Minimal 1000.
user_idintHaKassa egasining kabinetdagi user_id'si.
callback_urlstringTavsiyaWebhook qabul qiladigan manzilingiz. Bo'sh bo'lsa kassaning standart webhook_url'i ishlatiladi.
descriptionstringYo'qTo'lov izohi (chek va webhook'da ko'rinadi).
payment_methodstringYo'q'' (mijoz tanlaydi), yoki click / payme.
phonestringYo'qMijoz telefoni (998…), chek uchun.
Webhook (callback) formati inPAY → sizning callback_url
POSTapplication/json
{ "order_id": "9f3a8c2b1d4e5f60", "amount": 15000, "status": "success", // success | failed | canceled | pending "description": "Buyurtma #123", "created_at": "2026-06-11 14:30:00", "signature": "3b9f...e1" // sha256(order_id + amount + status + SALT) }
Content-Type: application/json User-Agent: InPay-Webhook/1.0 X-Webhook-Source: InPay X-Transaction-ID: 9f3a8c2b1d4e5f60
Imzo (signature) — majburiy tekshiring. Har bir webhook'da signature keladi: sha256(order_id . amount . status . SALT). SALT — sizning maxfiy kalitingiz (kabinetda kassa sozlamalarida). Imzoni qayta hisoblab solishtirmasdan to'lovni qabul qilmang — aks holda soxta so'rov yuborilishi mumkin.
Namuna — Sayt webhook qabul qiluvchi webhook.php
to'liq namuna
<?php // webhook.php — inPAY to'lov natijasini qabul qiladi $SALT = 'SIZNING_MAXFIY_SALT'; // kassa sozlamalaridan oling $raw = file_get_contents('php://input'); $data = json_decode($raw, true); if (!$data) { http_response_code(400); exit; } $order_id = $data['order_id'] ?? ''; $amount = $data['amount'] ?? ''; $status = $data['status'] ?? ''; $sig = $data['signature'] ?? ''; // 1) Imzoni tekshiring $expected = hash('sha256', $order_id . $amount . $status . $SALT); if (!hash_equals($expected, $sig)) { http_response_code(403); exit(json_encode(['ok' => false, 'error' => 'bad signature'])); } // 2) Holatga qarab buyurtmani yangilang (idempotent — faqat bir marta!) if ($status === 'success') { // ... buyurtmani 'paid' deb belgilang, mahsulotni bering } elseif (in_array($status, ['failed', 'canceled'])) { // ... buyurtmani bekor qiling } // 3) Albatta 200 qaytaring — aks holda inPAY qayta uradi http_response_code(200); echo json_encode(['ok' => true]);
const express = require("express"); const crypto = require("crypto"); const app = express(); const SALT = "SIZNING_MAXFIY_SALT"; app.post("/webhook", express.json(), (req, res) => { const { order_id, amount, status, signature } = req.body; // 1) Imzoni tekshiring const expected = crypto .createHash("sha256") .update(`${order_id}${amount}${status}${SALT}`) .digest("hex"); if (expected !== signature) return res.status(403).json({ ok: false }); // 2) Buyurtmani yangilang if (status === "success") { /* ... 'paid' belgilang */ } // 3) 200 qaytaring res.json({ ok: true }); }); app.listen(3000);
Namuna — Telegram bot webhook bot foydalanuvchiga xabar beradi
PHP + Telegram Bot API
<?php // callback.php — to'lov natijasini foydalanuvchiga yuboradi define('BOT_TOKEN', '123456:ABC-DEF...'); $SALT = 'SIZNING_MAXFIY_SALT'; function tg($chat_id, $text) { $url = "https://api.telegram.org/bot" . BOT_TOKEN . "/sendMessage"; $c = curl_init($url); curl_setopt_array($c, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => [ 'chat_id' => $chat_id, 'text' => $text, 'parse_mode' => 'HTML', ], ]); curl_exec($c); curl_close($c); } $data = json_decode(file_get_contents('php://input'), true); $order_id = $data['order_id'] ?? ''; $status = $data['status'] ?? ''; $amount = $data['amount'] ?? 0; // Imzo tekshiruvi $expected = hash('sha256', $order_id . $amount . $status . $SALT); if (!hash_equals($expected, $data['signature'] ?? '')) { http_response_code(403); exit; } // order_id orqali chat_id ni toping (to'lov yaratishda saqlangan) $orders = json_decode(@file_get_contents('orders.json'), true) ?: []; $chat_id = $orders[$order_id] ?? null; if ($chat_id && $status === 'success') { tg($chat_id, "✅ <b>To'lov qabul qilindi!</b>\n" . "🆔 Order: <code>{$order_id}</code>\n" . "💰 Summa: " . number_format($amount, 0, '.', ' ') . " so'm"); } http_response_code(200); echo json_encode(['ok' => true]);
<?php // To'lov YARATGANDA order_id ↔ chat_id bog'lanishini saqlang, // shunda webhook kelganda kimga xabar berishni bilasiz. // 1) /api/v1/create dan order_id keldi (yuqoridagi 2-qadam) $order_id = $resp['order_id']; // 2) Foydalanuvchi chat_id si bilan bog'lab saqlang $orders = json_decode(@file_get_contents('orders.json'), true) ?: []; $orders[$order_id] = $chat_id; file_put_contents('orders.json', json_encode($orders)); // 3) Foydalanuvchiga pay_url tugmasini yuboring tg($chat_id, "To'lash uchun: " . $resp['pay_url']); // 💡 Jiddiy loyihada orders.json o'rniga MySQL jadval ishlating.
Holat (status) qiymatlari webhook'dagi status maydoni
StatusMa'nosiTavsiya etilgan harakat
pendingTo'lov kutilmoqdaHech narsa qilmang — yakuniy webhook'ni kuting.
successTo'lov muvaffaqiyatliBuyurtmani yoping / mahsulotni bering (faqat bir marta).
failedTo'lov amalga oshmadiBuyurtmani bekor qiling, qayta urinishni taklif qiling.
canceledMijoz bekor qildiBuyurtmani yoping (bekor holatda).
Idempotentlik & qayta urinish. Webhook 200 javob olmasa inPAY uni qayta yuboradi. Shu sababli bir order_id uchun mahsulotni faqat bir marta bering — qabul qilishdan oldin buyurtma holatini tekshiring.
Integratsiyada yordam kerakmi?
Kassa, webhook yoki imzo tekshiruvi bo'yicha savollar bo'lsa — texnik jamoamiz Telegram va email orqali yordam beradi.