Kartaga tushgan pulni saytingiz o'zi taniydi
Mijoz Humo yoki Uzcard kartangizga istalgan ilovadan pul o'tkazadi. Har bir to'lovga noyob summa beriladi, shu summa bilan kelgan kirim bir necha soniyada tasdiqlanadi va saytingizga xabar boradi.
Mijoz aynan shu summani o'tkazadi. Oxirgi raqamlar to'lovni shu buyurtmaga bog'laydi.
Qanday ishlaydi
- Saytingiz to'lov yaratadiBuyurtma summasi va ID sini API ga yuborasiz.
- Tizim noyob summa va karta beradiMasalan 50 000 o'rniga 50 003 so'm. Bir vaqtda ochiq to'lovlar summasi hech qachon takrorlanmaydi.
- Mijoz kartaga o'tkazadiClick, Payme, Uzum, Paynet yoki bank ilovasi orqali — farqi yo'q.
- Bank xabari o'qiladiKartangiz ulangan Telegram akkaunt yoki SMS telefoni orqali kirim summasi aniqlanadi.
- Saytingizga webhook keladi
invoice.paid— buyurtmani "to'landi" qilasiz.
Tez boshlash
- Botga kiring@TolovTekshiruvchiBot da
/start— akkaunt va sinov muddati darhol ochiladi. - Karta qo'shing va tasdiqlash manbasini ulang«💳 Kartalar» bo'limida karta, keyin «🤖 Telegram ulash» yoki «📱 SMS qurilma».
- Tayyor kodni oling«📘 Hujjat» → «📦 Tayyor kod». Kalitlaringiz yozilgan
AvtoTolov.php,pay.php,webhook.phpkeladi. PHP bo'lmasa — quyidagi Node.js yoki Python misollaridan foydalaning. - Webhook manzilini kiriting«🔗 Webhook» bo'limida
https://saytingiz.uz/webhook.phpva «🧪 Test yuborish». - Kichik summa bilan sinangTo'lov yarating, aynan
pay_amountni o'tkazing va webhook kelganini tekshiring.
Avtorizatsiya
Har bir so'rovga API kalitni sarlavhada yuboring. Kalit botdagi «🔑 API kalit» bo'limida.
X-Api-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# yoki
Authorization: Bearer ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAsosiy manzil: https://avtotasdiq.uz/api/v1. Barcha javoblar JSON, muvaffaqiyatli bo'lsa "ok": true.
Kalitni faqat serveringizda saqlang — brauzer yoki mobil ilova kodiga qo'ymang. Kalit oshkor bo'lsa, botda «♻️ Kalitlarni yangilash» ni bosing.
To'lov yaratish
| Maydon | Turi | Tavsif |
|---|---|---|
amount majburiy | butun son | Buyurtma summasi, so'mda. 1 000 – 50 000 000. |
order_id majburiy | satr | Sizdagi buyurtma ID si, 100 belgigacha. Har bir buyurtma uchun noyob. |
description | satr | To'lov sahifasida ko'rinadigan izoh. |
return_url | URL | To'lovdan keyin mijoz qaytadigan sahifa. |
card_type | satr | Faqat shu turdagi kartani berish: humo, uzcard, visa, mastercard. |
ttl | soniya | Amal qilish muddati, 120 – 3600. Standart 900. |
require 'AvtoTolov.php'; // botdagi «📦 Tayyor kod» dan
$at = new AvtoTolov();
$invoice = $at->createInvoice(50000, 'order-123', [
'description' => 'UC 660',
'return_url' => 'https://sayt.uz/success',
]);
header('Location: ' . $invoice['pay_url']);const res = await fetch('https://avtotasdiq.uz/api/v1/invoices', {
method: 'POST',
headers: { 'X-Api-Key': process.env.AVTOTOLOV_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: 50000, order_id: 'order-123', return_url: 'https://sayt.uz/success' }),
});
const { ok, invoice, error } = await res.json();
if (!ok) throw new Error(error.message);
// invoice.pay_url ga yo'naltiringimport os, requests
r = requests.post('https://avtotasdiq.uz/api/v1/invoices',
headers={'X-Api-Key': os.environ['AVTOTOLOV_KEY']},
json={'amount': 50000, 'order_id': 'order-123', 'return_url': 'https://sayt.uz/success'},
timeout=15)
data = r.json()
if not data['ok']:
raise Exception(data['error']['message'])
invoice = data['invoice'] # invoice['pay_url'] ga yo'naltiringcurl -X POST https://avtotasdiq.uz/api/v1/invoices \
-H "X-Api-Key: ak_..." \
-H "Content-Type: application/json" \
-d '{"amount":50000,"order_id":"order-123","return_url":"https://sayt.uz/success"}'Javob — 201
{
"ok": true,
"invoice": {
"id": "inv_3f9a1c0d2b7e4a5f6c81",
"order_id": "order-123",
"status": "pending",
"amount": 50000,
"pay_amount": 50003,
"card": { "type": "humo", "number": "9860 1234 5678 9012", "holder": "ALISHER K." },
"description": "UC 660",
"pay_url": "https://avtotasdiq.uz/pay/?id=inv_3f9a1c0d2b7e4a5f6c81",
"return_url": "https://sayt.uz/success",
"late": false,
"created_at": "2026-10-09T12:00:00+05:00",
"expires_at": "2026-10-09T12:15:00+05:00",
"paid_at": null
}
}Shu order_id bilan ochiq to'lov bo'lsa, yangisi yaratilmaydi — o'sha qaytariladi. Shuning uchun so'rovni xavfsiz takrorlash mumkin.
Holatni olish
Javob to'lov yaratishdagi kabi invoice obyekti. Webhook kelmay qolsa, shu bilan tekshirib turing.
Bekor qilish
Faqat pending holatdagi to'lov bekor qilinadi. Uning noyob summasi boshqa to'lovlar uchun bo'shaydi.
Do'kon holati
{
"ok": true,
"shop": {
"id": 12,
"name": "Mening do'konim",
"webhook_url": "https://sayt.uz/webhook.php",
"subscription_active": true,
"subscription_until": "2026-11-09T12:00:00+05:00"
}
}Holatlar
| status | Ma'nosi |
|---|---|
pending | To'lov kutilmoqda. |
paid | Pul tushdi va tasdiqlandi. Muddati o'tgandan keyin 10 daqiqa ichida kelsa ham tasdiqlanadi va "late": true bo'ladi. |
expired | Muddat ichida to'lov kelmadi. |
cancelled | Siz bekor qildingiz. |
To'lov sahifasi
Eng oson yo'l — mijozni pay_url ga yo'naltirish. Sahifada karta raqami, aniq summa, nusxalash tugmalari va taymer bor; pul tushishi bilan sahifa o'zi yangilanadi va return_url ga qaytaradi.
O'z dizayningizda ko'rsatmoqchi bo'lsangiz, card.number va pay_amount ni chiqaring va mijozga aynan shu summani o'tkazish kerakligini aniq yozing.
Webhook
To'lov tasdiqlanganda (invoice.paid) va muddati o'tganda (invoice.expired) botda kiritgan manzilingizga POST so'rov keladi.
POST https://sayt.uz/webhook.php
Content-Type: application/json
X-Event: invoice.paid
X-Signature: 5d41402abc4b2a76b9719d911017c592...
{
"event": "invoice.paid",
"invoice": { "id": "inv_...", "order_id": "order-123", "status": "paid",
"amount": 50000, "pay_amount": 50003, "paid_at": "2026-10-09T12:03:41+05:00", ... },
"sent_at": "2026-10-09T12:03:42+05:00"
}Javob sifatida 2xx qaytaring. Aks holda so'rov qayta yuboriladi: 1, 2, 5, 10, 30 daqiqa, 1, 3, 6 soatdan keyin. Shu sababli bir xil webhook bir necha marta kelishi mumkin — buyurtma allaqachon to'langan bo'lsa, qayta ishlamang.
Imzoni tekshirish
X-Signature = so'rov tanasining HMAC-SHA256 imzosi (hex), kalit sifatida botdagi webhook secret ishlatiladi. Imzosi mos kelmagan so'rovni rad eting — aks holda istalgan odam saytingizga "to'landi" deb yozishi mumkin.
require 'AvtoTolov.php';
$data = (new AvtoTolov())->readWebhook(); // imzoni o'zi tekshiradi
if (!$data) { http_response_code(401); exit; }
if ($data['event'] === 'invoice.paid') {
$orderId = $data['invoice']['order_id'];
// buyurtma allaqachon to'langan bo'lsa — o'tkazib yuboring
// aks holda "to'landi" qiling
}
echo 'ok';import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const expected = crypto.createHmac('sha256', process.env.AVTOTOLOV_SECRET)
.update(req.body).digest('hex');
const got = req.get('X-Signature') || '';
if (got.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) {
return res.sendStatus(401);
}
const data = JSON.parse(req.body);
if (data.event === 'invoice.paid') {
// data.invoice.order_id buyurtmasini "to'landi" qiling (takror kelsa e'tiborsiz qoldiring)
}
res.send('ok');
});import hmac, hashlib, json, os
from flask import Flask, request, abort
app = Flask(__name__)
@app.post('/webhook')
def webhook():
body = request.get_data()
expected = hmac.new(os.environ['AVTOTOLOV_SECRET'].encode(), body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, request.headers.get('X-Signature', '')):
abort(401)
data = json.loads(body)
if data['event'] == 'invoice.paid':
pass # data['invoice']['order_id'] ni "to'landi" qiling (takror kelsa e'tiborsiz qoldiring)
return 'ok'Xato kodlari
{ "ok": false, "error": { "code": "no_card", "message": "Faol karta yo'q..." } }| HTTP | code | Nima qilish kerak |
|---|---|---|
| 401 | unauthorized | API kalitni tekshiring. |
| 402 | subscription_expired | Botda «💎 Obuna» orqali uzaytiring. |
| 403 | blocked | Admin bilan bog'laning. |
| 404 | not_found | To'lov ID si yoki manzil noto'g'ri. |
| 409 | no_card | Botda faol karta qo'shing. |
| 409 | order_exists | Bu order_id allaqachon to'langan yoki yopilgan — yangi ID bering. |
| 422 | bad_amount, bad_order_id, bad_card_type | Maydon qiymatini tuzating. |
| 429 | busy | Shu summa atrofida ochiq to'lovlar juda ko'p. Bir ozdan keyin qayta urining. |
Muhim qoidalar
- Summani har doim o'z bazangizdagi buyurtmadan oling, foydalanuvchi yuborgan qiymatdan emas.
- Buyurtmani faqat imzosi tekshirilgan webhook yoki API dagi
status: paidasosida yoping. To'lov sahifasidan qaytish (return_url) to'lov qilinganini bildirmaydi. - Webhook da
invoice.amountbuyurtma summasiga tengligini tekshiring. - Mijoz boshqa summa o'tkazsa, to'lov avtomatik tasdiqlanmaydi — botga "mos kelmagan kirim" xabari keladi, uni qo'lda hal qilasiz.