API hujjatlari
Admin panel →

Tashqi to'lov API

O'zingizning saytingiz yoki ilovangizdan mijozlardan to'lov qabul qiling — Telegram bot yoki kanalga bog'liq bo'lmagan holda. Karta ma'lumotlari hech qachon sizning serveringizga tegmaydi.

Atmos Click Payme
1

API kalit oling

Admin panel → Sotuv → Tashqi API → Kalit yaratish.

2

Buyurtma yarating

POST /orders — summasi va callbackUrl bilan.

3

Mijozni yo'naltiring

Javobdagi checkoutUrlga redirect qiling.

4

Natijani oling

To'lovdan keyin callbackUrlga webhook keladi.

Kirish

Bu — Stripe Checkout / Payme kabi "hosted checkout" modeli: karta ma'lumotlarini siz emas, Subo qabul qiladi va saqlaydi (Atmos tanlanganda), yoki mijoz Click/Payme'ning o'z sahifasida to'laydi (o'sha provayderlar tanlanganda). Ikkala holatda ham sizning integratsiya kodingiz bir xil qoladi.

Barcha so'rovlar https://subo.uz/api/external/v1/ manzili ostida joylashgan. Javoblar va xato xabarlari JSON formatida.

Autentifikatsiya

API kalitingizni Subo admin panelida — Sotuv → Tashqi API bo'limida yaratasiz. Kalit faqat yaratilgan paytda bir marta to'liq ko'rsatiladi, shuning uchun darhol xavfsiz joyga saqlab qo'ying — keyinroq faqat qayta yaratish (eskisini bekor qilib) mumkin.

Har bir so'rovga Authorization headerini qo'shing.

Kalitni frontend/mobil ilova kodida yoki brauzerda saqlamang — faqat backend serveringizdan foydalaning. Oshkor bo'lsa, admin panelda uni bir zumda bekor qilib, yangisini yaratishingiz mumkin.
POST /api/external/v1/orders HTTP/1.1
Host: subo.uz
Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

Ishlash oqimi

  1. Serveringiz POST /orders so'rovini API kaliti bilan yuboradi.
  2. Subo buyurtmani yaratadi va javobda checkoutUrl qaytaradi.
  3. Mijozni shu checkoutUrlga yo'naltirasiz.
  4. Mijoz to'lovni amalga oshiradi — Subo checkout sahifasida (Atmos) yoki Click/Payme sahifasida.
  5. Subo to'lov natijasini callbackUrlingizga webhook orqali yuboradi.
  6. Serveringiz GET /orders/:orderId bilan holatni yakuniy tasdiqlaydi.

Click yoki Payme tanlanganda 3- va 4-qadamlar orasida qo'shimcha bir bosqich bor: mijoz Click/Payme'ning o'z sahifasida to'laydi, ular esa to'g'ridan-to'g'ri Subo bilan (sizdan mustaqil ravishda) gaplashib, natijani tasdiqlaydi. Bu qism butunlay Subo tomonidan boshqariladi — sizga hech qanday qo'shimcha kod yozish shart emas.

To'lov provayderlari

Subo 3 ta to'lov tizimini qo'llab-quvvatlaydi: Atmos, Click va Payme. Har birini admin panelda — Sotuv → Tashqi API → To'lov provayderlari bo'limida alohida sozlaysiz. Bir nechta provayder bir vaqtda faol bo'lishi mumkin.

Buyurtma yaratishda provider maydoni orqali qaysi tizim ishlatilishini tanlaysiz. Ko'rsatilmasa, sozlangan birinchi provayder avtomatik ishlatiladi. Sizning integratsiyangiz kodi provayderdan qat'i nazar o'zgarmaydi.

Provayder Karta kiritiladigan joy Saqlangan karta
Atmos Subo'ning o'z checkout sahifasida Qo'llab-quvvatlanadi (batafsil)
Click Click'ning o'z sahifasida (my.click.uz) Click o'zi boshqaradi
Payme Payme'ning o'z sahifasida (checkout.paycom.uz) Payme o'zi boshqaradi
Click va Payme hisoblaringizni o'zingiz ushbu tizimlarda ro'yxatdan o'tib olishingiz kerak — Subo faqat integratsiyani ta'minlaydi, hisob ochib bermaydi.

Buyurtma yaratish

POST/external/v1/orders

So'rov maydonlari

Maydon Turi Tavsif
amountTiyinintegermajburiySumma tiyinda (1 so'm = 100 tiyin). Min 1000, maks 500 000 000.
providerenumixtiyoriy"ATMOS" / "CLICK" / "PAYME". Ko'rsatilmasa sozlangan birinchi provayder ishlatiladi.
descriptionstringixtiyoriyMijozga ko'rsatiladigan tavsif.
externalReferencestringixtiyoriySizning buyurtma ID'ingiz. Qayta yuborilsa, mavjud buyurtma qaytariladi (idempotentlik).
customerIdstringixtiyoriyMijoz ID'ingiz. Faqat Atmos: karta shu ID'ga saqlanadi (batafsil).
customerNamestringixtiyoriyCheckout sahifasida ko'rsatiladi.
customerContactstringixtiyoriyFaqat ma'lumot uchun.
callbackUrlURLixtiyoriyTo'lov yakunlangach webhook shu manzilga yuboriladi.
returnUrlURLixtiyoriyTo'lovdan keyin qaytariladigan manzil.
Mijozni javobdagi checkoutUrlga yo'naltiring. Havola 30 daqiqa amal qiladi.
POST /api/external/v1/orders HTTP/1.1
Host: subo.uz
Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

// so'rov tanasi
{
  "amountTiyin": 5000000,
  "provider": "CLICK",
  "description": "Frontend kursi — 1-oy",
  "externalReference": "order-1234",
  "customerId": "user-777",
  "customerName": "Alisher Vali",
  "callbackUrl": "https://sizning-saytingiz.uz/webhooks/subo",
  "returnUrl": "https://sizning-saytingiz.uz/thank-you?order=1234"
}

// javob 201
{
  "orderId": "b1e2c3d4-...",
  "status": "PENDING",
  "provider": "CLICK",
  "checkoutUrl": "https://subo.uz/pay/9f8e7d6c5b4a...",
  "externalReference": "order-1234",
  "customerId": "user-777",
  "amountTiyin": "5000000",
  "description": "Frontend kursi — 1-oy",
  "customerName": "Alisher Vali",
  "atmosTransactionId": null,
  "providerTransactionId": null,
  "failureReason": null,
  "paidAt": null,
  "createdAt": "2026-09-12T12:00:00.000Z",
  "expiresAt": "2026-09-12T12:30:00.000Z"
}
curl -X POST https://subo.uz/api/external/v1/orders \
  -H "Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amountTiyin": 5000000,
    "provider": "CLICK",
    "description": "Frontend kursi — 1-oy",
    "externalReference": "order-1234",
    "customerId": "user-777",
    "customerName": "Alisher Vali",
    "callbackUrl": "https://sizning-saytingiz.uz/webhooks/subo",
    "returnUrl": "https://sizning-saytingiz.uz/thank-you?order=1234"
  }'
const res = await fetch('https://subo.uz/api/external/v1/orders', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    amountTiyin: 5000000,
    provider: 'CLICK',
    description: 'Frontend kursi — 1-oy',
    externalReference: 'order-1234',
    customerId: 'user-777',
    customerName: 'Alisher Vali',
    callbackUrl: 'https://sizning-saytingiz.uz/webhooks/subo',
    returnUrl: 'https://sizning-saytingiz.uz/thank-you?order=1234',
  }),
});
const order = await res.json();
// mijozni order.checkoutUrl'ga yo'naltiring

Buyurtma holatini olish

GET/external/v1/orders/:orderId

Javob yuqoridagi bilan bir xil shaklda, joriy status bilan (PENDING / PAID / FAILED / EXPIRED). To'langanda providerTransactionId to'ldiriladi. Webhook kelgach, holatni shu endpoint orqali qayta tekshirish tavsiya etiladi.

GET /api/external/v1/orders/b1e2c3d4-... HTTP/1.1
Host: subo.uz
Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
curl https://subo.uz/api/external/v1/orders/b1e2c3d4-... \
  -H "Authorization: Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Checkout sahifasi

checkoutUrl — Subo domenida joylashgan, mustaqil to'lov sahifasi (https://subo.uz/pay/<token>). Uni brauzerda yangi oynada oching yoki to'g'ridan-to'g'ri shu manzilga redirect qiling. Sahifa login talab qilmaydi.

Atmos tanlangan bo'lsa: mijoz summani va tavsifni ko'radi → karta raqami + amal qilish muddatini kiritadi → SMS kodni kiritadi → to'lov yakunlanadi.

Click yoki Payme tanlangan bo'lsa: sahifa mijozni darhol o'sha provayderning o'z to'lov sahifasiga yo'naltiradi.

Karta raqami va SMS kodi (Atmos holatida) faqat Subo serveriga yuboriladi. Sizning serveringiz bu ma'lumotlarni hech qachon ko'rmaydi.

Saqlangan karta (takroriy mijoz)

Faqat Atmos provayderi uchun. Agar buyurtma yaratishda customerId yuborsangiz va mijoz to'lovni muvaffaqiyatli yakunlasa, uning kartasi (Atmos token sifatida, shifrlangan holda) shu customerIdga bog'lab saqlanadi.

Keyingi safar bir xil customerId bilan yangi buyurtma yaratsangiz, checkout sahifasi kartani qayta kiritishni so'ramaydi — mijozga saqlangan karta ko'rsatiladi va u faqat bitta tugma bosib to'laydi.

Karta raqamining o'zi hech qachon sizga qaytarilmaydi — faqat maskalangan (oxirgi 4 raqam) ko'rinishda mijozning o'ziga ko'rsatiladi. Bu tizimingizni PCI DSS talablaridan ozod qiladi.

Webhook

Buyurtma yakunlangach (muvaffaqiyatli yoki muvaffaqiyatsiz), agar callbackUrl berilgan bo'lsa, o'sha manzilga POST so'rovi yuboriladi — provayderdan qat'i nazar bir xil shaklda. event qiymati order.paid yoki order.failed bo'ladi.

Muhim: webhook'ni faqat "signal" sifatida ishlating. Kelgach, GET /orders/:orderIdni chaqirib holatni rasmiy manbadan tasdiqlang. Yetkazib berish 5 marta (eksponensial kutish bilan) qayta urinadi.
POST https://sizning-saytingiz.uz/webhooks/subo HTTP/1.1
Content-Type: application/json

{
  "event": "order.paid",
  "orderId": "b1e2c3d4-...",
  "externalReference": "order-1234",
  "amountTiyin": "5000000",
  "status": "PAID",
  "paidAt": "2026-09-12T12:05:32.000Z",
  "sandbox": false
}
app.post('/webhooks/subo', async (req, res) => {
  const { orderId } = req.body;

  // Ishonchli manbadan tasdiqlang — tanaga to'g'ridan-to'g'ri ishonmang.
  const order = await fetch(
    `https://subo.uz/api/external/v1/orders/${orderId}`,
    { headers: { Authorization: 'Bearer sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' } }
  ).then((r) => r.json());

  if (order.status === 'PAID') {
    // ... obunani faollashtiring / buyurtmani yakunlang ...
  }

  res.sendStatus(200); // muhim: aks holda qayta urinib turadi
});

Xatoliklar

KodSabab
401API kaliti berilmagan, noto'g'ri yoki bekor qilingan.
400So'rov ma'lumotlari noto'g'ri, yoki to'lov jarayonida xatolik (message maydonida o'zbek tilida tushuntirish).
404Buyurtma yoki checkout havolasi topilmadi.
{
  "statusCode": 400,
  "message": "Karta balansida mablag' yetarli emas",
  "error": "Bad Request"
}

Sandbox muhiti

Integratsiyani haqiqiy to'lovlarsiz sinash uchun sotuvchidan Sandbox turidagi API kaliti so'rang — u sk_test_ bilan boshlanadi. Bu kalit bilan yaratilgan buyurtmalar hech qanday to'lov tizimiga (Click, Payme, Atmos) bormaydi, haqiqiy pul yechilmaydi va ular sotuvchining daromad statistikasiga kirmaydi.

So'rovlar, javoblar va webhook'lar production bilan bir xil — faqat checkout sahifasida karta formasi o'rniga natijani o'zingiz tanlaydigan ikki tugma chiqadi:

  • To'lov muvaffaqiyatli (test) — buyurtma PAID holatiga o'tadi va order.paid webhooki yuboriladi.
  • To'lov xato (test) — buyurtma FAILED holatiga o'tadi va order.failed webhooki yuboriladi.
Muhim: sandbox webhook'ida "sandbox": true keladi. Production ishlovchingiz shu maydon bo'yicha test hodisalarini ajratib tashlashi mumkin. Tayyor bo'lgach sotuvchidan production kaliti (sk_) so'raysiz — kodingizda faqat kalitni almashtirasiz, boshqa hech narsa o'zgarmaydi.
POST https://sizning-saytingiz.uz/webhooks/subo HTTP/1.1
Content-Type: application/json

{
  "event": "order.paid",
  "orderId": "b1e2c3d4-...",
  "externalReference": "order-1234",
  "amountTiyin": "4900000",
  "status": "PAID",
  "paidAt": "2026-09-25T13:40:11.000Z",
  "sandbox": true
}

Atmos test kartalari

Atmos test rejimida quyidagi test kartalaridan foydalaning (SMS kodi hammasi uchun 111111):

Karta raqamiAmal qilish muddati
8600 4907 4431 334710/24
8600 3329 1424 939009/25
8600 4929 9340 748110/24
9860 0901 0143 190705/25

Click va Payme uchun test kartalar o'sha tizimlarning o'z hujjatlarida beriladi.

Cheklovlar

  • Checkout havolasi yaratilgandan keyin 30 daqiqa amal qiladi.
  • Summa: minimal 1 000 tiyin (10 so'm), maksimal 500 000 000 tiyin (5 000 000 so'm).
  • Har bir admin hisobida bir vaqtning o'zida 3 tagacha faol API kaliti bo'lishi mumkin (masalan alohida Sandbox va Production kalitlari).

Savol-javob

Click/Payme'ning callback'larini o'zim yozishim kerakmi?

Yo'q. Bularning barchasi Subo tomonida avtomatik boshqariladi. Siz faqat POST /orders chaqirasiz va o'z callbackUrlingizda oddiy JSON qabul qilasiz.

Bir vaqtning o'zida Atmos, Click va Payme'dan barchasini ishlata olamanmi?

Ha. Har birini alohida sozlaysiz, so'ng har bir buyurtmada provider maydoni orqali tanlaysiz.

Webhook kelmasa nima qilishim kerak?

GET /orders/:orderIdni davriy ravishda chaqirib, "kutilayotgan" buyurtmalar holatini o'zingiz tekshirib turishingiz mumkin.

Test qanday amalga oshiriladi?

Atmos uchun — sandbox rejimda yuqoridagi test kartalar bilan. Click/Payme uchun — ularning o'zlaridan test hisob so'rab, shu ma'lumotlar bilan sozlang.