Dasturchilar uchun

Merchant API

Saytingiz, ilovangiz yoki Telegram botingizni MSavdogar'ga ulang: invoys yarating, xaridorni to'lov sahifasiga yo'naltiring va to'lov natijasini imzolangan webhook orqali darhol oling.

Mundarija
  1. Boshlash
  2. Autentifikatsiya
  3. Invoys yaratish
  4. Invoys holati
  5. Invoyslar ro'yxati
  6. Invoysni bekor qilish
  7. Do'kon ma'lumotlari
  8. Invoys obyekti
  9. Xatolar
  10. Webhooklar
  11. Imzoni tekshirish
  12. Qayta yuborish

Boshlash

Asosiy manzil (base URL)

https://api-beta.msavdogar.uz

Format

JSON · UTF-8 · vaqt ISO 8601 (UTC)

Odatiy to'lov oqimi to'rt qadamdan iborat:

  1. Serveringiz POST /v1/invoices orqali invoys yaratadi va javobdagi pay_url ni oladi.
  2. Xaridor pay_url sahifasiga yo'naltiriladi va Click, bank kartasi yoki balans orqali to'laydi.
  3. To'lov yakunlangach, MSavdogar serveringizga payment.paid webhookini yuboradi.
  4. Ixtiyoriy: buyurtmani yakunlashdan oldin GET /v1/invoices/{number} orqali holatni qayta tekshiring.

Barcha summalar so'mda (UZS) va matn ko'rinishidagi o'nlik son sifatida qaytariladi, masalan "150000.00". So'rovda summani son sifatida yuborishingiz mumkin.

Autentifikatsiya

Har bir so'rov X-Api-Key sarlavhasida API kalitini yuborishi kerak. Kalitni Do'kon panelining API bo'limida yaratasiz; to'liq kalit faqat yaratilgan paytda bir marta ko'rsatiladi.

HTTP sarlavha
X-Api-Key: msk_a1b2c3_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Muqobil ravishda Authorization: Bearer <API kalit> sarlavhasini ishlatishingiz mumkin.

Kalitni maxfiy saqlang

API kalitini faqat serveringizda saqlang. Uni brauzer, mobil ilova yoki ochiq repozitoriyga joylamang. Kalit oshkor bo'lsa, panelda darhol bekor qiling va yangisini yarating.

Limit: har bir kalit uchun daqiqasiga 300 ta so'rov. Limitdan oshganda 429 javobi qaytadi.

Invoys yaratish

POST/v1/invoices

Belgilangan summaga to'lov so'rovi (invoys) yaratadi. Muvaffaqiyatli javob — 201 Created va invoys obyekti.

MaydonTuriTavsif
amount majburiysonTo'lov summasi, UZS. Kamida 1 000 UZS, ko'pi bilan 100 000 000 UZS.
order_idmatn, ≤128Tizimingizdagi buyurtma raqami. Webhookda merchant_order_id sifatida qaytadi.
titlematn, ≤200To'lov sahifasida va chekda ko'rinadigan nom.
commentmatn, ≤300Qo'shimcha izoh.
customer_emailmatn, ≤200Xaridor emaili — PDF chek shu manzilga yuboriladi.
return_urlmatn, ≤512To'lovdan so'ng xaridor qaytariladigan sahifa.
expires_minutessonInvoys amal qilish muddati, daqiqada: 5 – 43200. Standart: 1440 (24 soat).
idempotency_keymatn, ≤128Takroriy so'rovdan himoya: bir xil kalit bilan qayta yuborilgan so'rov yangi invoys yaratmaydi, mavjudini qaytaradi.
cURL
curl -X POST https://api-beta.msavdogar.uz/v1/invoices \
  -H "X-Api-Key: $MSAVDOGAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 150000,
    "order_id": "ORDER-1024",
    "title": "Premium obuna (1 oy)",
    "customer_email": "mijoz@example.com",
    "return_url": "https://example.uz/order/1024",
    "idempotency_key": "order-1024"
  }'

Javob namunasi

201 Created · JSON
{
  "number": "PAY_MYSHOP_7K2M9Q",
  "status": "pending",
  "kind": "api",
  "amount": "150000.00",
  "tip_amount": "0.00",
  "total_amount": "150000.00",
  "currency": "UZS",
  "title": "Premium obuna (1 oy)",
  "comment": null,
  "order_id": "ORDER-1024",
  "fee_percent": null,
  "net_amount": null,
  "pay_url": "https://pay-beta.msavdogar.uz/pay/PAY_MYSHOP_7K2M9Q",
  "created_at": "2026-10-18T09:05:12.481203+00:00",
  "paid_at": null,
  "expires_at": "2026-10-19T09:05:12.481203+00:00",
  "payment_method": null
}

Invoys holati

GET/v1/invoices/{number}

Invoysning joriy holatini qaytaradi. Faqat o'z do'koningiz invoyslarini ko'ra olasiz; boshqa invoys uchun 404 qaytadi.

cURL
curl https://api-beta.msavdogar.uz/v1/invoices/PAY_MYSHOP_7K2M9Q \
  -H "X-Api-Key: $MSAVDOGAR_API_KEY"

Invoyslar ro'yxati

GET/v1/invoices?status=paid&limit=50

Eng yangi invoyslar ro'yxati, {"items": [...]} ko'rinishida.

ParametrTavsif
statusIxtiyoriy filtr: pending, paid, cancelled, expired, refunded.
limitNatijalar soni, 1 – 200. Standart: 50.
cURL
curl "https://api-beta.msavdogar.uz/v1/invoices?status=paid&limit=20" \
  -H "X-Api-Key: $MSAVDOGAR_API_KEY"

Invoysni bekor qilish

POST/v1/invoices/{number}/cancel

Hali to'lanmagan (pending) invoysni bekor qiladi va yangilangan invoys obyektini qaytaradi. Boshqa holatdagi invoys uchun 409 qaytadi.

cURL
curl -X POST https://api-beta.msavdogar.uz/v1/invoices/PAY_MYSHOP_7K2M9Q/cancel \
  -H "X-Api-Key: $MSAVDOGAR_API_KEY"

Do'kon ma'lumotlari

GET/v1/me

API kaliti tegishli bo'lgan do'kon va uning hisobidagi mablag'lar holati.

Javob · JSON
{
  "username": "myshop",
  "business_name": "My Shop",
  "kyc_status": "verified",
  "wallet": {
    "held": "450000.00",
    "available": "1250000.00",
    "payout_pending": "0.00"
  }
}
MaydonMa'nosi
wallet.heldYaqinda tushgan, xavfsizlik muddati tugashini kutayotgan mablag'.
wallet.availableYechib olish mumkin bo'lgan mablag'.
wallet.payout_pendingPul yechish so'rovlarida turgan mablag'.
kyc_statusunverified, pending, verified yoki rejected.

Invoys obyekti

MaydonTavsif
numberInvoysning noyob raqami, masalan PAY_MYSHOP_7K2M9Q.
statusHolat (quyidagi jadvalga qarang).
kindInvoys turi; API orqali yaratilganlar uchun api.
amountAsosiy summa.
tip_amountXaridor qo'shgan ixtiyoriy ustama.
total_amountXaridordan yechilgan jami summa (amount + tip_amount).
currencyHar doim UZS.
title, commentInvoys nomi va izohi.
order_idSiz yuborgan buyurtma raqami.
fee_percent, net_amountXizmat haqi foizi va sizga tushadigan sof summa — to'lovdan so'ng to'ldiriladi.
pay_urlXaridor uchun to'lov sahifasi.
created_at, paid_at, expires_atVaqt belgilari (ISO 8601, UTC).
payment_methodclick, card, card_token yoki balance.

Holatlar

HolatMa'nosi
pendingTo'lov kutilmoqda.
paidTo'langan — buyurtmani bajarishingiz mumkin.
cancelledBekor qilingan.
expiredMuddati o'tgan, to'lab bo'lmaydi.
refundedPul xaridorga qaytarilgan.

Xatolar

Xato javoblari standart HTTP kodlari va {"detail": "..."} ko'rinishidagi tana bilan qaytadi.

KodSabab
400So'rov bajarilmadi, masalan summa ruxsat etilgan chegaradan tashqarida.
401API kaliti yuborilmagan yoki noto'g'ri.
403Do'kon faol emas.
404Invoys topilmadi yoki boshqa do'konga tegishli.
409Invoys holati amalga ruxsat bermaydi (masalan, to'langan invoysni bekor qilish).
422Maydonlar talablarga mos emas (turi, uzunligi yoki qiymati).
429So'rovlar limiti oshib ketdi — birozdan so'ng qayta urining.
5xxVaqtinchalik nosozlik. idempotency_key bilan xavfsiz qayta urinishingiz mumkin.

Webhooklar

Do'kon panelida webhook manzili (faqat ochiq https:// manzil) va maxfiy kalitni sozlang. Har bir hodisada MSavdogar shu manzilga POST so'rov yuboradi.

HodisaQachon yuboriladi
payment.paidInvoys muvaffaqiyatli to'langanda.
payment.refundedTo'lov xaridorga qaytarilganda.

Sarlavhalar

SarlavhaQiymat
X-MSavdogar-EventHodisa nomi, masalan payment.paid.
X-MSavdogar-TimestampYuborilgan vaqt, Unix soniyalarda.
X-MSavdogar-SignatureHMAC-SHA256(secret, timestamp + "." + body), hex ko'rinishida.
X-MSavdogar-DeliveryYetkazishning noyob ID raqami — takroriy qayta ishlashdan himoya uchun.
Content-Typeapplication/json

payment.paid namunasi

POST · JSON
{
  "event": "payment.paid",
  "created_at": "2026-10-18T09:07:41.102938+00:00",
  "data": {
    "invoice": "PAY_MYSHOP_7K2M9Q",
    "kind": "api",
    "status": "paid",
    "amount": "150000.00",
    "tip_amount": "5000.00",
    "total_amount": "155000.00",
    "currency": "UZS",
    "fee_percent": "5",
    "net_amount": "147500.00",
    "merchant_order_id": "ORDER-1024",
    "title": "Premium obuna (1 oy)",
    "comment": null,
    "paid_at": "2026-10-18T09:07:40.877120+00:00",
    "payment_method": "click"
  }
}

payment.refunded namunasi

POST · JSON
{
  "event": "payment.refunded",
  "created_at": "2026-10-19T11:20:03.554210+00:00",
  "data": {
    "invoice": "PAY_MYSHOP_7K2M9Q",
    "amount": "155000.00",
    "reason": "Xaridor so'rovi bo'yicha"
  }
}

Imzoni tekshirish

Imzo so'rovning xom tanasi (raw body) bo'yicha hisoblanadi — JSON'ni qayta formatlamasdan, kelgan baytlarni ishlating. Shuningdek, eski so'rovlar qayta yuborilishining oldini olish uchun vaqt belgisini tekshiring (masalan, 5 daqiqadan eski so'rovlarni rad eting).

Python (FastAPI)
import hashlib
import hmac
import os
import time

from fastapi import FastAPI, HTTPException, Request

app = FastAPI()
WEBHOOK_SECRET = os.environ["MSAVDOGAR_WEBHOOK_SECRET"].encode()


@app.post("/msavdogar/webhook")
async def msavdogar_webhook(request: Request):
    raw_body = await request.body()
    timestamp = request.headers.get("X-MSavdogar-Timestamp", "")
    signature = request.headers.get("X-MSavdogar-Signature", "")

    expected = hmac.new(WEBHOOK_SECRET, timestamp.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, signature):
        raise HTTPException(status_code=400, detail="invalid signature")
    if not timestamp.isdigit() or abs(time.time() - int(timestamp)) > 300:
        raise HTTPException(status_code=400, detail="stale request")

    event = await request.json()
    if event["event"] == "payment.paid":
        data = event["data"]
        # Idempotent bo'ling: bir hodisa bir necha marta kelishi mumkin
        mark_order_paid(data["merchant_order_id"], data["invoice"])
    return {"ok": True}

Javob va qayta yuborish

  • Serveringiz 15 soniya ichida istalgan 2xx kodi bilan javob berishi kerak. Og'ir ishlarni javobdan keyin, fonda bajaring.
  • Javob kelmasa yoki 2xx bo'lmasa, yetkazish 1 daqiqa, 5 daqiqa, 15 daqiqa, 1 soat va 6 soatdan so'ng qayta urinib ko'riladi.
  • Yo'naltirishlar (3xx) kuzatilmaydi — webhook manzili to'g'ridan-to'g'ri ishlovchi manzil bo'lsin.
  • Bir hodisa bir necha marta kelishi mumkin. X-MSavdogar-Delivery yoki invoice raqami bo'yicha takroriy ishlovni oldini oling.
  • Yetkazishlar tarixi va oxirgi xatolar Do'kon panelining webhook bo'limida ko'rinadi.

Integratsiya bo'yicha savolingiz bormi?

Qo'llab-quvvatlash xizmatiga yozing — dasturchilarimiz yordam beradi.

Murojaat yuborish