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.
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
| Maydon | Turi | Majburiy | Izoh |
|---|---|---|---|
| amount | number | Ha | To'lov summasi (so'm). Minimal 1000. |
| user_id | int | Ha | Kassa egasining kabinetdagi user_id'si. |
| callback_url | string | Tavsiya | Webhook qabul qiladigan manzilingiz. Bo'sh bo'lsa kassaning standart webhook_url'i ishlatiladi. |
| description | string | Yo'q | To'lov izohi (chek va webhook'da ko'rinadi). |
| payment_method | string | Yo'q | '' (mijoz tanlaydi), yoki click / payme. |
| phone | string | Yo'q | Mijoz 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
| Status | Ma'nosi | Tavsiya etilgan harakat |
|---|---|---|
| pending | To'lov kutilmoqda | Hech narsa qilmang — yakuniy webhook'ni kuting. |
| success | To'lov muvaffaqiyatli | Buyurtmani yoping / mahsulotni bering (faqat bir marta). |
| failed | To'lov amalga oshmadi | Buyurtmani bekor qiling, qayta urinishni taklif qiling. |
| canceled | Mijoz bekor qildi | Buyurtmani 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.