ASL RAQAM Connect: hamkorlar uchun qo‘llanma
API versiyasi: v1 · Hujjat versiyasi: 0.9.2, 14.10.2026 (dastlabki)
Bu hujjat onlayn-kassalar (E-POS), TSD va hisob tizimlari dasturchilari uchun. Ular markirovka kodlarini
tekshirishni ASL RAQAM Connect orqali ulaydi. To‘liq spetsifikatsiya OpenAPI 3.1 formatida:
openapi.yaml. Endpoint va maydon nomlari, xato kodlari — ruscha qo‘llanma bilan bir xil.
Holat. API v1 tayyor va ASL BELGISI emulyatorida avtomatik testlardan o‘tadi. Ishchi va test manzillari ulanishda beriladi: hujjatda ishchi nom
https://connect.aslraqam.uzko‘rsatilgan. Hali ishlab chiqilayotgan imkoniyatlar «Keyinroq qo‘shiladi» bo‘limida.
Mundarija
- Connect nima qiladi
- 5 qadamda boshlash
- API ning umumiy qoidalari
- Merchantni ulash
- Kodlarni tekshirish:
POST /check - Verdiktlar
- Kassa hodisalari:
POST /events - Qoldiqlar, kodlar, nomuvofiqliklar
- Sinxronlash
- Inventarizatsiya
- Vebhuklar
- Foydalanish va tariflash
- Xatolar va limitlar
- Sinov muhiti: test kodlari
- Kod misollari
- Keyinroq qo‘shiladi
- O‘zgarishlar jurnali
1. Connect nima qiladi
Kassa markirovka kodini skanerlaydi, Connect esa soniyaning bir qismida tovarni sotish mumkinmi yoki yo‘qmi va nima uchunligini aytadi.
- Sotuvdan oldin tekshiruv. Kod do‘kon balansidami? Muomaladami? Avval sotilmaganmi? Qadoq kodi
emasmi? Javobda rang (🟢 🟡 🔴 ⚪),
can_sellbelgisi va kassir uchun o‘zbek va rus tilidagi tayyor matn keladi. - Do‘kon kodlari lederi. Connect do‘konning kaliti bilan ASL BELGISI dan uning balansidagi barcha kodlarni yuklab oladi va har kecha yangilaydi. Tekshiruvlarning ko‘pchiligiga lederdan javob beriladi: tez va ASL ga yuk tushmaydi.
- Harakat hisobi. Kassa sotuv, qaytarish, qabul, hisobdan chiqarish va ko‘chirish haqida xabar beradi. Connect kodlar bo‘yicha qoldiqni yuritadi va nomuvofiqliklarni topadi, masalan «o‘z balansidan sotilmagan» yoki «ikki marta sotilgan».
- TSD bilan inventarizatsiya. Javondagi skan balans bilan solishtiriladi, Connect kamomad va begona kodlarni topadi.
Kassa ASL BELGISI bilan bevosita ishlamaydi: kalitlar, limitlar, qayta urinishlar va ASL nosozliklarini Connect o‘z zimmasiga oladi.
Kassa / TSD ──HTTPS──▶ ASL RAQAM Connect ──▶ ASL BELGISI (do‘kon kaliti)
▲ │
└──── vebhuklar ◀────────┘
Asosiy qoida: kassa Connect sababli savdoni hech qachon to‘xtatmaydi. Agar Connect 3 soniyada javob bermasa yoki 5xx qaytarsa, kassa sotadi va sotuv hodisasini keyinroq yuboradi (3.6).
2. 5 qadamda boshlash
Misollarda sinov muhiti va test kaliti ck_test_… ishlatiladi. Sinov muhiti oldindan tayyorlangan kodlari
bor ASL emulyatorida ishlaydi (14-bo‘lim).
export CONNECT=https://sandbox.connect.aslraqam.uz/api/v1 # manzil ulanishda beriladi
export KEY=ck_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1-qadam. Kirishni tekshiring.
curl -s $CONNECT/health
# {"status":"ok"}
2-qadam. Do‘konni (merchantni) STIR bo‘yicha ro‘yxatdan o‘tkazing.
curl -s -X POST $CONNECT/merchants \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"tin": "300000001", "name": "«Baraka» do‘koni"}'
3-qadam. Markirovkalanadigan tovarlar katalogini (GTIN) yuboring.
curl -s -X PUT $CONNECT/merchants/300000001/catalog \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"mode": "replace", "items": [{"gtin": "04780012345677", "name": "Suv 0,5 l"}]}'
4-qadam. ASL BELGISI ni ulang: do‘konning API kalitini va roziligini yuboring.
curl -s -X PUT $CONNECT/merchants/300000001/asl-key \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"key": "<do‘konning ASL API kaliti>",
"consent": {"accepted": true, "version": "2026-10-v1", "user": "Direktor A. Karimov"}}'
# {"status":"active","organization":"…","product_groups":["14"],"expires_on":"2027-06-30T23:59:59+00:00","key_last4":"0001"}
Shundan so‘ng Connect balansni birinchi marta sinxronlashni boshlaydi. U tugagach, sync.completed
vebhuki keladi.
5-qadam. Kodni kassada tekshiring.
curl -s -X POST $CONNECT/check \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
--max-time 3 \
-d '{"merchant_tin": "300000001", "store_id": "store-01", "context": "SALE",
"codes": ["010478001234567721OKOKOK00001"]}'
{
"request_id": "01a13a69-0dcb-793f-9de1-319ece312fb9",
"results": [{
"index": 0,
"ki": "010478001234567721OKOKOK00001",
"verdict": "OK", "color": "green", "can_sell": true,
"served_from": "ledger", "stale": false,
"message": {"ru": "Можно продавать", "uz": "Sotish mumkin"},
"hint": {"ru": "", "uz": ""},
"product": {"gtin": "04780012345677"},
"package": null,
"asl": {"status": "INTRODUCED"},
"details": {},
"billable": false
}],
"summary": {"total": 1, "green": 1, "yellow": 0, "red": 0, "grey": 0, "can_sell_all": true},
"connection": {"status": "active"}
}
Sotuvdan keyin SALE hodisasini yuboring (7-bo‘lim). Shu bilan eng
kichik integratsiya tayyor.
3. API ning umumiy qoidalari
3.1. Manzil va protokol
| Ishchi | https://connect.aslraqam.uz/api/v1 (ishchi nom) |
| Sinov muhiti | https://sandbox.connect.aslraqam.uz/api/v1 (ishchi nom) |
| Protokol | faqat HTTPS, TLS 1.2+ |
| Format | JSON, UTF-8 |
| Vaqt | ISO 8601, vaqt zonasi bilan; UTC tavsiya etiladi: 2026-10-14T09:15:00Z |
| Pul | tiyinda, butun son (1 so‘m = 100 tiyin) |
3.2. Avtorizatsiya
Authorization: Bearer ck_live_… # ishchi kalit
Authorization: Bearer ck_test_… # test kalit
- Kalit berilganda bir marta ko‘rsatiladi. Biz faqat uning xeshini saqlaymiz va kalitni tiklay olmaymiz. Yo‘qotsangiz, yangisini beramiz, eskisini bekor qilamiz.
- Kalitga huquqlar (scope) va ruxsat etilgan IP manzillar cheklovini qo‘yish mumkin.
- Uzilishsiz almashtirish uchun hamkorda bir vaqtda ikkita amaldagi kalit bo‘lishi mumkin.
- Kalit hamkor serverida saqlanadi. Uni hech qachon brauzerga yoki kassirning mobil ilovasiga bermang.
| Huquq (scope) | Nimaga ruxsat beradi |
|---|---|
merchants:write |
merchantlar, nuqtalar, katalog, ASL kalitini ro‘yxatga olish va o‘zgartirish; nomuvofiqliklarni yopish |
checks:write |
POST /check |
events:write |
POST /events, hodisalarni bekor qilish |
reports:read |
merchantlar, qoldiqlar, kodlar, nomuvofiqliklar, sinxronlash va inventarizatsiyani o‘qish |
sync:write |
sinxronlashni qo‘lda boshlash |
inventory:write |
inventarizatsiya |
webhooks:write |
vebhuklarni boshqarish |
usage:read |
foydalanish statistikasi |
3.3. Merchant va nuqtalar
- Merchant STIR orqali aniqlanadi: yo‘lda
/merchants/{tin}/…,/checkva/eventsda esamerchant_tinmaydonida. STIR 9 xonali (yuridik shaxs) yoki 14 xonali (YaTT ning JShShIR) bo‘ladi. - Begona yoki ro‘yxatdan o‘tmagan STIR uchun 404
MERCHANT_NOT_FOUNDqaytadi, 403 emas: shunday qilib kim ulanganligi oshkor bo‘lmaydi. store_id— nuqtaning sizning tizimingizdagi ID si, 64 belgigacha bo‘lgan satr. Nuqtani oldindan ro‘yxatga olish shart emas: birinchi marta tilga olinganda u avtomatik yaratiladi. Nomi va manziliniPUT /merchants/{tin}/stores/{store_id}orqali berish mumkin.
3.4. Idempotentlik
- Barcha POST/PUT/PATCH/DELETE so‘rovlari uchun noyob qiymatli (UUID tavsiya etiladi)
Idempotency-Keysarlavhasi majburiy. Istisno —/check: unda sarlavha ixtiyoriy, lekin tavsiya etiladi. - Kalit 24 soat saqlanadi.
- Xuddi shu kalit va xuddi shu tana bilan qayta yuborilgan so‘rov o‘sha javobni
Idempotent-Replayed: truesarlavhasi bilan qaytaradi. Aloqa uzilgandan keyin so‘rovni xavfsiz qaytarish mumkin. - Xuddi shu kalit boshqa tana bilan kelsa — 409
IDEMPOTENCY_CONFLICT. Birinchi so‘rov hali bajarilayotgan bo‘lsa ham shu javob keladi (details.in_progress: true). - So‘rov xato bilan tugasa, kalit bo‘shaydi va so‘rovni o‘sha kalit bilan qaytarish mumkin.
Kassa hodisalari uchun yaxshi amaliyot — kalitni chek ma’lumotlaridan yasash, masalan
sale-{terminal_id}-{external_ref}. Shunda oflayn navbatdan qayta yuborilganda dublikat paydo bo‘lmaydi.
3.5. Kuzatuv, til, moslik
X-Request-Id: siz yuborsangiz, javobda qaytadi; yubormasangiz, server o‘zinikini yaratadi. U har bir javob va har bir xatoda bor. Qo‘llab-quvvatlash xizmatiga yozganda shu ID ni ko‘rsating.Accept-Language: ru | uzxatolardagimessagemaydoni tilini tanlaydi. O‘zbekcha matn har doimmessage_uzda keladi. Tekshiruv natijalarida doim ikkala til bor.- Noma’lum maydonlarni e’tiborsiz qoldiring. Yangi maydonlar versiya o‘zgarmasdan qo‘shiladi.
- Mos kelmaydigan o‘zgarishlar faqat
/v2da chiqadi; shundan keyin/v1yana 6 oy ishlaydi.
3.6. Taymautlar va fail-open (majburiy)
| Qoida | Qiymat |
|---|---|
/check javobini kutish |
3 soniya |
| Taymaut, 5xx yoki tarmoq yo‘q bo‘lsa | sotishga ruxsat bering va hodisani mahalliy navbatga saqlang |
| Navbatdagi hodisani qachon yuborish | aloqa tiklanganda, o‘sha Idempotency-Key bilan |
| Qancha eski hodisalar qabul qilinadi | 30 kungacha; 7 kundan eskisi late belgisi bilan qabul qilinadi |
ASL BELGISI nosozliklari /check da xatoga olib kelmaydi. ASL ishlamasa, Connect 200 bilan
UNKNOWN verdiktini (⚪, can_sell: true) yoki stale: true belgili leder javobini qaytaradi.
5xx xatolari faqat Connect ning o‘zi nosoz bo‘lganda bo‘lishi mumkin.
3.7. Sahifalash
Ro‘yxatlar {"items": [...], "next_cursor": "…"} qaytaradi. Keyingi sahifa ?cursor=<next_cursor>
bilan so‘raladi; limit 1000 dan oshmaydi (sukut bo‘yicha 100). next_cursor: null — ro‘yxat oxiri.
4. Merchantni ulash
4.1. Tartib
POST /merchantsmerchantni ro‘yxatga oladi, holatipending.PUT /merchants/{tin}/catalogdo‘kon sotadigan markirovkalanadigan GTIN lar ro‘yxatini yuboradi. Katalogni ulangandan keyin ham yuborish mumkin: yangi GTIN lar avtomatik yuklanadi.PUT /merchants/{tin}/asl-keydo‘konning ASL API kalitini va roziligini yuboradi. Connect kalitni tekshiradi (10 soniyagacha), shifrlangan holda saqlaydi va birinchi sinxronlashni boshlaydi.merchant.connectedvebhuki darhol keladi,sync.completedesa balans yuklangandan keyin.
4.2. Do‘konning ASL kaliti
Do‘kon API kalitini ASL BELGISI shaxsiy kabinetida yaratadi. Kalit foydalanuvchisida «Kuzatuvchi» roli «Markirovka kodlari» imtiyozi bilan bo‘lishi kerak.
PUT /merchants/300000001/asl-key
{
"key": "<ASL API kaliti>",
"rotation_mode": "manual",
"consent": {"accepted": true, "version": "2026-10-v1", "user": "Direktor A. Karimov"}
}
| Maydon | Majb. | Tavsif |
|---|---|---|
key |
ha | ASL BELGISI API kaliti. Bir marta yuboriladi; uni o‘zingizda saqlamang |
consent.accepted |
ha | true: do‘kon Connect uning nomidan ASL ga murojaat qilishiga rozi |
consent.version |
ha | do‘konga ko‘rsatilgan rozilik matni versiyasi |
consent.user |
yo‘q | rozilikni kim bergan |
rotation_mode |
yo‘q | manual (sukut): yangi kalitni hamkor yuboradi. auto va resign ERI orqali kirish ishga tushganda kerak bo‘ladi (16-bo‘lim) |
Connect nimani tekshiradi: kalit formati, merchant STIR iga tegishliligi, rollar (ASL ga sinov so‘rovi), tashkilot va tovar guruhlari. Javob:
{"status": "active", "organization": "«Baraka» MChJ", "product_groups": ["14"],
"expires_on": "2027-06-30T23:59:59+00:00", "key_last4": "0001"}
Ulanish xatolari (HTTP 422):
| Kod | Do‘konga nima deyish kerak |
|---|---|
ASL_KEY_INVALID |
kalit noto‘g‘ri, bekor qilingan yoki muddati o‘tgan: ASL kabinetida yangisini yarating |
ASL_KEY_WRONG_TIN |
kalit boshqa tashkilotga tegishli |
ASL_INSUFFICIENT_ROLES |
«Kuzatuvchi» roli («Markirovka kodlari» imtiyozi bilan) yetishmaydi |
ASL_UNAVAILABLE (503) |
ASL BELGISI vaqtincha ishlamayapti, keyinroq urinib ko‘ring |
RATE_LIMITED (429) |
bir sutkada 10 tadan ko‘p ulanish urinishi |
Ishlab turgan merchantning yangi kaliti tekshiruvdan o‘tmasa, Connect eski kalit bilan ishlashda davom etadi.
4.3. Ulanish holati
GET /merchants/{tin}/connection:
{"status": "active", "method": "manual", "key_last4": "0001",
"expires_on": "2027-06-30T23:59:59+00:00", "key_expires_in_days": 259,
"last_checked_at": "2026-10-14T12:34:57Z", "check_status": "ok", "missing_roles": [],
"rotation_mode": "manual", "product_groups": ["14"], "consent_version": "2026-10-v1",
"edo_status": null}
status |
Ma’nosi |
|---|---|
pending |
ro‘yxatdan o‘tgan, kalit hali yuborilmagan |
active |
ishlayapti |
key_expiring |
kalit muddati 14 kun ichida tugaydi: do‘kondan yangisini yaratishni so‘rang |
key_invalid |
kalit bekor qilingan yoki muddati o‘tgan, tekshiruv faqat leder bo‘yicha ishlaydi |
wrong_tin, insufficient_roles |
kalit to‘g‘ri kelmaydi (4.2 ga qarang) |
suspended |
operator tomonidan to‘xtatilgan |
disconnected |
merchant uzilgan |
Kalit muddati tugashi haqidagi eslatmalar merchant.connection.expiring vebhuki bilan 14, 7, 3 va 1
kun oldin keladi.
4.4. Merchant sozlamalari
PATCH /merchants/{tin}:
{"name": "«Baraka» do‘koni", "policy": "strict",
"policy_overrides": {"NOT_INTRODUCED": "block", "PACKAGE_CODE": "warn"}}
policy:soft(sukut) yokistrict. Qat’iy rejimda 🟡 verdiktlarcan_sell: falseberadi.null— hamkorning sukut bo‘yicha sozlamasi.policy_overrides: muayyan verdiktga munosabat,allow,warnyokiblock. Sabab bo‘yicha aniqlashtirish mumkin:"NOT_ON_BALANCE:INVOICE_NOT_SIGNED": "warn". Ustuvorlik tartibi: sabab verdiktdan muhimroq, merchant sozlamasi hamkor sozlamasidan muhimroq.- 🔴 verdiktlarni
allowga o‘tkazib bo‘lmaydi: bunday so‘rov 400 qaytaradi.
4.5. Uzish
DELETE /merchants/{tin}: ASL kaliti darhol o‘chiriladi, leder ma’lumotlari hisobotlar uchun 90 kun
saqlanadi.
4.6. Merchant uchun vidjet: sessiya
Ulash, qoldiqlar, nomuvofiqliklar va inventarizatsiya ekranlarini kassa interfeysiga vidjet sifatida joylash mumkin (vidjetning o‘zi ishlab chiqilmoqda, sessiyalar API si allaqachon ishlaydi).
- Sizning serveringiz bir martalik token so‘raydi (
widget:issuehuquqi):
POST /widget/sessions
{"merchant_tin": "300000001", "store_id": "store-01", "locale": "uz",
"user": {"id": "u-17", "name": "Aziz", "role": "owner"},
"scopes": ["connect", "reports", "inventory", "settings"]}
→ 201 {"token": "wt_…", "url": "https://connect.aslraqam.uz/widget/", "expires_at": "…"}
- Token 15 daqiqa yashaydi va bir marta almashtiriladi. Uni iframe ga sahifa manzilida emas,
postMessageorqali bering: manzillar loglarga tushadi. - Vidjet tokenni o‘zi sessiyaga almashtiradi (
POST /widget/exchange) va uni faqat xotirada saqlaydi. Sessiya bitta merchant bilan cheklangan: begona STIR — 404.
scopes |
Nimani ochadi | Kimga |
|---|---|---|
connect |
ASL ni ulash | faqat owner |
settings |
rejim, override lar, uzish | faqat owner |
reports |
umumiy ko‘rinish, qoldiqlar, kodlar, nomuvofiqliklar, sinxronlash; nomuvofiqlikni faqat owner yopa oladi |
hammaga |
inventory |
inventarizatsiya | hammaga |
invoices |
ESF (Didox ulangandan keyin) | hammaga |
Kod tekshiruvi vidjetda doim ochiq. Hamkor kaliti brauzerga hech qachon tushmaydi.
5. Kodlarni tekshirish: POST /check
5.1. So‘rov
{
"merchant_tin": "300000001",
"store_id": "store-01",
"context": "SALE",
"receipt_draft_id": "draft-1001",
"codes": ["010478001234567721OKOKOK00001"],
"options": {"verify_authenticity": "off"}
}
| Maydon | Majb. | Tavsif |
|---|---|---|
merchant_tin |
ha | merchant STIR i |
store_id |
ha | nuqtaning sizning tizimingizdagi ID si |
context |
ha | SALE, RETURN, RECEIVE, INVENTORY, INFO |
codes |
ha | 1–100 ta kod, istalgan ko‘rinishda |
receipt_draft_id |
yo‘q | chek qoralamasi ID si: bir chekda bitta kod qayta skanerlanishini ushlaydi |
options.verify_authenticity |
yo‘q | off (sukut), async, sync: kripto-dum bo‘yicha haqiqiylik tekshiruvi |
Kodlarni skanerdan kelganicha yuborish mumkin: GS belgilari (\u001d), qavslar (01)…(21)…,
]d2 prefiksi, kripto-dum bilan. Connect kodni o‘zi KI ga (GTIN va seriya raqami) keltiradi. Kripto-dum
faqat haqiqiylikni tekshirish uchun ishlatiladi, hech qayerda saqlanmaydi va hech qachon
qaytarilmaydi.
5.2. Kontekstlar
context |
Qachon | Xususiyatlari |
|---|---|---|
SALE |
tovarni chekka urish | asosiy kontekst |
RETURN |
xaridordan qaytarish | «shu do‘kon sotgan» — OK; sotilmagan kod — RETURN_NOT_SOLD |
RECEIVE |
tovarni qabul qilish | qadoq kodi tarkibiga ochiladi (package.children), ichidagilar «mavjud» deb belgilanadi |
INVENTORY |
inventarizatsiya | qadoq tarkibini qaytaradi |
INFO |
kod haqida ma’lumot, masalan tovar kartochkasida | hech narsani o‘zgartirmaydi |
5.3. Javob
Har bir kirish kodiga results[] da bitta element mos keladi, tartib o‘sha.
| Maydon | Tavsif |
|---|---|
index |
kodning kirish massividagi o‘rni |
ki |
normallashtirilgan KI yoki kod tanilmasa null |
verdict |
verdikt (6-bo‘lim) |
color |
green / yellow / red / grey |
can_sell |
rejim va override larni hisobga olgan tavsiya |
served_from |
ledger — lederdan, live — ASL ga jonli so‘rov, cache, fallback — ASL vaqtida javob bermadi, input — kirish ma’lumotida xato |
stale |
true: ASL ishlamagani sababli eskirgan ma’lumot bo‘yicha javob |
message |
{"ru", "uz"} — kassir ekrani uchun qisqa matn, 40 belgigacha |
hint |
{"ru", "uz"} — nima qilish kerakligi haqida maslahat |
product |
{"gtin"} |
package |
qadoq kodi uchun: type, children_count; children[] faqat RECEIVE, INVENTORY, INFO da |
asl |
{"status"} — kodning ASL dagi holati (INTRODUCED, WITHDRAWN…) |
details |
aniqlashtirishlar: withdrawal_reason, sold_elsewhere, problem (kod nega tanilmadi), reason (NOT_ON_BALANCE uchun) |
billable |
shu kod tariflanganmi |
summary |
total, green, yellow, red, grey, can_sell_all |
connection.status |
merchantning ulanish holati: kassa ogohlantirish ko‘rsatishi mumkin, masalan «kalit muddati tugayapti» |
Misol: RECEIVE kontekstida qadoq kodi.
{
"index": 0, "ki": "00467800123456BOX00001",
"verdict": "OK", "color": "green", "can_sell": true, "served_from": "live",
"package": {"type": "BOX_LV_1", "children_count": 3,
"children": ["010478001234567721CHILD000001", "010478001234567721CHILD000002",
"010478001234567721CHILD000003"]},
"asl": {"status": "INTRODUCED"}
}
5.4. Kassada qanday ko‘rsatish kerak
messageni yirik,hintni uning ostida maydaroq ko‘rsating. Tilni kassa sozlamasidan oling.- Rangni
colordan, «chekka urish yoki yo‘q» qarorinican_selldan oling. can_sell— tavsiya. Kassa 🟡 ni katta kassir tasdig‘i bilan o‘tkazib yuborishi mumkin. Tovar tavsiyaga qarshi sotilgan bo‘lsa, buni sotuv hodisasiningitems[].overridemaydonida yuboring (7-bo‘lim).- ⚪ (
UNKNOWN,NOT_CONNECTED,SERVICE_SUSPENDED) doim sotishga ruxsat beradi.
5.5. Qancha kutish kerak
Lederdan javob o‘nlab millisekundda keladi. ASL ga jonli so‘rov 1,5 soniya bilan cheklangan. ASL
ulgurmasa, Connect leder bo‘yicha javob (stale) yoki UNKNOWN qaytaradi va tekshiruvni fonda
tugatadi. Fonda kod 🔴 bo‘lib chiqsa, check.updated vebhuki keladi.
6. Verdiktlar
| Verdikt | Rang | can_sell yumshoq / qat’iy |
Qachon | Kassirga matn (UZ) |
|---|---|---|---|---|
OK |
🟢 | ha / ha | kod do‘kon balansida, muomalada, sotilmagan | Sotish mumkin |
NOT_ON_BALANCE |
🟡 | ha / yo‘q | kod muomalada, lekin boshqa ishtirokchida: yetkazib beruvchi kodlarni o‘tkazmagan | Kod balansingizda emas |
NOT_INTRODUCED |
🟡 | ha / yo‘q | do‘kon kodi, lekin muomalaga kiritilmagan | Kod muomalada emas |
PACKAGE_CODE |
🟡 | ha / yo‘q | tovar birligi emas, qadoq kodi skanerlangan | Bu qadoq kodi |
IN_OUTGOING_INVOICE |
🟡 | ha / yo‘q | kod xaridorga chiquvchi ESF da (Didox ulangandan keyin) | Kod chiquvchi ESFda |
RETURN_NOT_SOLD |
🟡 | ha / yo‘q | faqat RETURN: kod sotilmagan |
Kod sotilmagan |
SOLD_LOCALLY |
🔴 | yo‘q / yo‘q | kassa hodisalari bo‘yicha shu do‘konda allaqachon sotilgan | Sizda allaqachon sotilgan |
ALREADY_SOLD |
🔴 | yo‘q / yo‘q | ASL da sotuv bilan muomaladan chiqarilgan | Kod avval sotilgan |
WITHDRAWN |
🔴 | yo‘q / yo‘q | boshqa sabab bilan muomaladan chiqarilgan | Muomaladan chiqarilgan |
WRITTEN_OFF |
🔴 | yo‘q / yo‘q | hisobdan chiqarilgan | Kod hisobdan chiqarilgan |
NOT_FOUND |
🔴 | yo‘q / yo‘q | kod ASL da yo‘q | Kod topilmadi |
NOT_AUTHENTIC |
🔴 | yo‘q / yo‘q | haqiqiylik tekshiruvidan o‘tmadi | Kod haqiqiy emas |
INVALID_FORMAT |
🔴 | yo‘q / yo‘q | kod shikastlangan yoki noto‘g‘ri o‘qilgan | Kod noto‘g‘ri o‘qildi |
DUPLICATE_IN_REQUEST |
🔴 | yo‘q / yo‘q | kod so‘rovda yoki chek qoralamasida allaqachon bor | Chekda allaqachon bor |
UNKNOWN |
⚪ | ha / ha | tekshirib bo‘lmadi: ASL ishlamayapti, taymaut | Tekshiruv mavjud emas |
NOT_CONNECTED |
⚪ | ha / ha | merchant ulanmagan yoki kalit yaroqsiz, lederda ma’lumot yo‘q | Tekshiruv ulanmagan |
SERVICE_SUSPENDED |
⚪ | ha / ha | hamkor kirishi to‘xtatilgan | Tekshiruv to‘xtatilgan |
Ikkala tildagi to‘liq matnlar va maslahatlar /check javobida (message va hint) keladi, ularni
o‘zingizda saqlash shart emas.
NOT_ON_BALANCE sabablari (details.reason) Didox ulangandan keyin paydo bo‘ladi:
INVOICE_NOT_SIGNED, INVOICE_SIGNED_PENDING, INVOICE_SIGNED_STUCK, INVOICE_REJECTED, NO_INVOICE.
Didox siz bu maydon bo‘lmaydi.
7. Kassa hodisalari: POST /events
Kassa markirovkalangan tovar bilan har bir amal haqida xabar beradi. Shu ma’lumotlar bo‘yicha Connect qoldiqni yuritadi va nomuvofiqliklarni topadi.
{
"merchant_tin": "300000001",
"store_id": "store-01",
"type": "SALE",
"external_ref": "CHK-000123",
"fiscal_sign": "123456789012",
"terminal_id": "POS-1",
"occurred_at": "2026-10-14T09:15:00Z",
"items": [{"code": "010478001234567721OKOKOK00001", "price_tiyin": 450000}]
}
| Maydon | Majb. | Tavsif |
|---|---|---|
type |
ha | SALE, RETURN, RECEIVE, WRITE_OFF, MOVE, INVENTORY_ADJUST |
external_ref |
ha | sizdagi chek yoki hujjat raqami |
occurred_at |
ha | kassadagi amal vaqti, vaqt zonasi bilan; 30 kundan eski va kelajakda bo‘lmasin |
fiscal_sign, terminal_id |
yo‘q | fiskal belgi va kassa raqami |
to_store_id |
MOVE uchun |
qabul qiluvchi nuqta |
reason |
WRITE_OFF uchun |
DAMAGE, EXPIRED, LOSS, OTHER — faqat mahalliy hisob uchun, ASL ga yuborilmaydi |
items[] |
ha | 1–1000 ta pozitsiya |
items[].code |
ha | istalgan ko‘rinishdagi kod |
items[].quantity, items[].unit |
yo‘q | sukut 1 va pcs; vaznli tovarlar uchun kg, l |
items[].price_tiyin |
yo‘q | birlik narxi |
items[].override |
yo‘q | verdiktga qarshi sotilgan: {"verdict", "reason", "approved_by"} |
Javob 201:
{"event_id": 2, "accepted_items": 1, "rejected_items": [],
"warnings": [{"index": 0, "warning": "SOLD_WITH_RED_VERDICT", "verdict": "ALREADY_SOLD"}],
"late": false}
- Hodisa har doim qabul qilinadi, verdiktlar yomon bo‘lsa ham: kassa amalni allaqachon bajargan. Connect faktni qayd etadi va kerak bo‘lsa nomuvofiqlik ochadi.
rejected_items[]— qabul qilinmagan pozitsiyalar (INVALID_FORMAT,DUPLICATE_IN_EVENT,INVALID_QUANTITY,INVALID_UNIT,INVALID_ITEM). Qolganlari qabul qilingan.warnings[]:SOLD_WITH_RED_VERDICT(🔴 verdiktli kod sotilgan),SOLD_TWICE(qaytarishsiz ikkinchiSALE).- Oflayn kassalar hodisalari kechikib va tartibsiz kelishi mumkin. Connect ularni
occurred_attartibida qo‘llaydi.
Hodisani bekor qilish (bekor qilingan chek): POST /events/{event_id}/reverse. Takroriy bekor qilish
xato bermaydi va o‘sha natijani qaytaradi.
{"event_id": 1, "reversed": true, "reversed_at": "2026-10-14T12:34:57Z", "restored": 1}
8. Qoldiqlar, kodlar, nomuvofiqliklar
| Metod | Nima qaytaradi |
|---|---|
GET /merchants/{tin}/stock?store_id=>in= |
har bir GTIN bo‘yicha: on_balance (ASL balansida va muomalada), in_stock_local (hodisalar bo‘yicha mavjud), sold_30d, open_discrepancies, last_sync_at |
GET /merchants/{tin}/codes?gtin=&owned=&state=&store_id= |
lederdagi kodlar |
GET /merchants/{tin}/codes/{kod} |
kod kartochkasi: ASL ma’lumotlari, mahalliy holat, oxirgi 20 hodisa, ochiq nomuvofiqliklar |
GET /merchants/{tin}/discrepancies?type=&status=&severity=&store_id= |
nomuvofiqliklar |
PATCH /merchants/{tin}/discrepancies/{id} |
yopish: {"status": "resolved" \| "ignored", "comment": "…"} |
Faylga yuklab olish. stock, codes va discrepancies da format=csv|xlsx parametri bor:
filtrlar hisobga olingan barcha sahifalar bitta faylda keladi (100 000 qatorgacha; ko‘p bo‘lsa —
422 EXPORT_TOO_LARGE, filtrni toraytiring). CSV — BOM li UTF-8 va ; ajratgich, Excel da sozlashsiz
ochiladi.
curl -s -H "Authorization: Bearer $KEY" -o stock.xlsx "$CONNECT/merchants/300000001/stock?format=xlsx"
Qoldiqlar misoli:
{"items": [{"gtin": "04780012345677", "name": "Suv 0,5 l", "on_balance": 5, "in_stock_local": 4,
"sold_30d": 1, "open_discrepancies": 0, "last_sync_at": "2026-10-14T12:34:57Z"}],
"next_cursor": null}
Nomuvofiqlik turlari
| Kod | Nomi | Muhimlik | Do‘kon nima qilishi kerak |
|---|---|---|---|
D1 |
O‘z balansidan sotilmagan | yuqori | yetkazib beruvchidan kodli ESF so‘rash; jarima xavfi bor |
D2 |
Balansda 180 kundan ortiq harakatsiz turibdi | past | inventarizatsiya o‘tkazish |
D3 |
Kassada sotuvsiz balansdan chiqib ketgan | o‘rta | tekshirish: boshqa kassada sotilgan, berilgan, hisobdan chiqarilgan |
D4 |
Ikki marta sotilgan | yuqori | cheklarni tekshirish |
D5 |
Sotuv 72 soatda ASL ga yetib bormagan | yuqori | chekning OFD ga yuborilishini tekshirish |
D6 |
Inventarizatsiyada kamomad | o‘rta | tovarni topish yoki hisobdan chiqarish |
D7 |
Javonda begona kod | yuqori | yetkazib beruvchidan kodlarni o‘tkazishni so‘rash |
Sharti yo‘qolganda nomuvofiqlik avtomatik yopiladi, masalan yetkazib beruvchi kodlarni o‘tkazganda.
Yuqori muhimlikdagi yangi nomuvofiqlik discrepancy.created vebhuki bilan keladi.
9. Sinxronlash
Connect do‘kon balansini ASL dan o‘zi yuklaydi: ulanganda to‘liq, keyin har kecha (harakatli GTIN lar har kuni, qolganlari haftada bir). Katalogdagi yangi GTIN lar kunduzi yuklanadi.
Qo‘lda ishga tushirish — merchant uchun soatiga 1 martadan ko‘p emas:
POST /merchants/{tin}/sync {"gtins": ["04780012345677"]} ← ixtiyoriy; maydonsiz — barcha GTIN lar
→ 202 {"sync_job_id": "01a13a68-…"}
GET /sync-jobs/{id}
→ {"id": "…", "kind": "manual", "status": "done", "gtins_total": 1, "gtins_done": 1,
"codes_upserted": 6, "codes_left_balance": 3, "discrepancies_found": 2, "error": null}
status: queued, running, done, partial (GTIN larning bir qismi yuklanmadi), failed. Bir
soatdan oldin qayta ishga tushirish details.retry_at bilan 429 qaytaradi. Tugagach sync.completed
(birinchi va qo‘lda sinxronlash uchun) yoki sync.failed (har qanday turi uchun) vebhuki keladi.
10. Inventarizatsiya
1. POST /merchants/{tin}/inventory-sessions {"store_id": "store-01", "scope": "all"}
(yoki "scope": {"gtins": ["04780012345677"]})
→ 201 {"id": "<session_id>", "status": "open"}
2. POST /inventory-sessions/{id}/scans {"codes": [...1000 tagacha...], "device_id": "TSD-7"}
skanni bekor qilish: {"void": ["<ki>", ...]}
3. POST /inventory-sessions/{id}/finish {"apply": false}
4. GET /inventory-sessions/{id} hisobot istalgan vaqtda
- Qadoq kodi tarkibiga ochiladi, ichidagi kodlar topilgan deb belgilanadi.
- Bitta kodning qayta skani takrorlanmaydi.
- Hisobot:
{"session_id": "…", "applied": false, "found_on_balance": 3,
"shortage": ["…"], "shortage_count": 2,
"foreign": ["010478001234567721FOREIGN0001"], "foreign_count": 1,
"found_but_sold": [], "unknown_store_codes": 1,
"by_gtin": [{"gtin": "04780012345677", "expected": 5, "found": 3}]}
- Kamomad
D6nomuvofiqligini, begona kodlarD7ni ochadi. apply: truebo‘lsa, topilgan kodlar «mavjud», topilmaganlari «kamomad» holatiga o‘tadi.- Tugagach
inventory.finishedvebhuki keladi. - Excel dagi hisobot:
GET /inventory-sessions/{id}?format=xlsx— «Сводка», «По GTIN», «Недостача», «Чужие коды», «Продано, но найдено» varaqlari.
11. Vebhuklar
11.1. Obuna
POST /webhooks {"url": "https://pos.example.uz/hooks/connect",
"events": ["merchant.connected", "sync.completed", "discrepancy.created", "check.updated"]}
→ 201 {"id": "…", "secret": "…"} ← sir bir marta ko‘rsatiladi (so‘rov takrorlansa — secret: null)
GET /webhooks
DELETE /webhooks/{id}
POST /webhooks/{id}/test ← webhook.test sinov hodisasi
Manzil HTTPS bo‘lishi shart.
11.2. Hodisalar
| Hodisa | Qachon |
|---|---|
merchant.connected |
ASL kaliti tekshirildi, merchant ulandi |
merchant.connection.expiring |
ASL kaliti tugashiga 14, 7, 3, 1 kun qoldi |
merchant.connection.failed |
kalit muddati o‘tgan yoki bekor qilingan, begona STIR, rollar yetishmaydi |
sync.completed / sync.failed |
sinxronlash tugadi |
discrepancy.created |
yuqori muhimlikdagi yangi nomuvofiqlik |
discrepancy.resolved |
nomuvofiqlik yopildi |
check.updated |
kassaga javobdan keyin fondagi tekshiruv kod verdiktini 🔴 ga o‘zgartirdi |
inventory.finished |
inventarizatsiya tugadi |
billing.period.closed |
oylik hisob tuzildi |
edo.*, invoice.* |
Didox va ESF hodisalari (Didox ulangandan keyin) |
11.3. Format
POST /hooks/connect HTTP/1.1
Content-Type: application/json
X-Connect-Signature: t=1760445325,v1=5f2b…
X-Connect-Event: merchant.connected
X-Connect-Delivery: 01a13a69-…
{"id": "evt_01a13a690cf578b8", "type": "merchant.connected",
"created_at": "2026-10-14T12:35:25Z", "api_version": "v1", "merchant_tin": "300000001",
"data": {"organization": "«Baraka» MChJ", "product_groups": ["14"], "expires_on": "2027-06-30T23:59:59+00:00"}}
11.4. Imzoni tekshirish (majburiy)
v1 = HMAC-SHA256(secret, "<t>." + so‘rovning xom tanasi), o‘n oltilik ko‘rinishda. 5 daqiqadan eski
xabarlarni rad eting. Imzoni qayta seriyalangan JSON bo‘yicha emas, xom tana bo‘yicha hisoblang.
import hashlib, hmac, time
def verify(secret: str, header: str, body: bytes, tolerance: int = 300) -> bool:
try:
parts = dict(p.split("=", 1) for p in header.split(","))
ts = int(parts["t"])
except (ValueError, KeyError):
return False
if abs(time.time() - ts) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{ts}.".encode() + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))
PHP va Node.js misollari 15-bo‘limda.
11.5. Yetkazish
- Serveringiz 10 soniya ichida 2xx bilan javob berishi kerak. Og‘ir ishlovni asinxron bajaring.
- Qayta urinishlar: 1 daq, 5 daq, 15 daq, 1 soat, 3 soat, 6 soat, 12 soat, 24 soatdan keyin; so‘ng
yetkazish
failedholatini oladi. - Manzil 3 kun davomida hodisalarni qabul qilmasa, u o‘chiriladi va biz siz bilan bog‘lanamiz.
- Kafolat «kamida bir marta»: dublikatlarni
idbo‘yicha tashlab yuboring. Hodisalar tartibi kafolatlanmaydi,created_atga tayaning.
12. Foydalanish va tariflash
GET /usage?date_from=2026-10-01&date_to=2026-10-31 (davr 92 kungacha):
{"items": [{"day": "2026-10-14", "merchant_tin": "300000001", "store_id": "store-01",
"checks_total": 14, "checks_billable": 9, "events_total": 1}],
"totals": {"checks_total": 14, "checks_billable": 9, "events_total": 1, "active_stores": 1}}
Nima tariflanmaydi:
- ck_test_ test kaliti bilan so‘rovlar;
- INVALID_FORMAT, DUPLICATE_IN_REQUEST, UNKNOWN, NOT_CONNECTED, SERVICE_SUSPENDED verdiktlari;
- o‘sha nuqtada o‘sha kodni 10 daqiqa ichida qayta tekshirish.
Tarif shartlari (faol nuqta uchun abonent to‘lovi, tekshiruvlar kvotasi, BHM) shartnomada belgilanadi. Joriy kun ma’lumotlari so‘rov paytida yangilanadi.
13. Xatolar va limitlar
13.1. Xato formati
{"error": {"code": "MERCHANT_NOT_FOUND", "message": "Мерчант не найден",
"message_uz": "Merchant topilmadi",
"request_id": "01a13a69-0f6e-78d2-b7b7-05a7e9b6c832", "details": {}}}
| HTTP | Kod | Qachon |
|---|---|---|
| 400 | VALIDATION_ERROR |
maydonlar noto‘g‘ri; details.fields — aynan qaysilari |
| 401 | UNAUTHORIZED |
kalit yo‘q, noto‘g‘ri yoki bekor qilingan |
| 403 | FORBIDDEN_SCOPE |
kalitda kerakli huquq yo‘q (details.required) |
| 403 | PARTNER_SUSPENDED |
hamkor kirishi to‘xtatilgan; /check bunda ishlaydi va SERVICE_SUSPENDED qaytaradi |
| 403 | IP_NOT_ALLOWED |
ruxsat etilmagan IP dan so‘rov |
| 404 | NOT_FOUND, MERCHANT_NOT_FOUND |
|
| 409 | IDEMPOTENCY_CONFLICT |
idempotentlik kaliti boshqa tana bilan ishlatilgan |
| 409 | MERCHANT_EXISTS |
merchant allaqachon ro‘yxatdan o‘tgan |
| 413 | PAYLOAD_TOO_LARGE |
tana /check uchun 256 KB dan, qolganlari uchun 5 MB dan katta |
| 422 | TOO_MANY_CODES |
/check da 100 tadan ko‘p kod |
| 422 | MERCHANT_NOT_READY |
amal uchun ASL kaliti kerak |
| 422 | EXPORT_TOO_LARGE |
yuklab olishda 100 000 dan ortiq qator — filtrni toraytiring |
| 422 | ASL_KEY_INVALID, ASL_KEY_WRONG_TIN, ASL_INSUFFICIENT_ROLES |
4.2 ga qarang |
| 429 | RATE_LIMITED |
limit oshdi; Retry-After soniya kuting |
| 500 | INTERNAL_ERROR |
Connect nosozligi: bizga request_id ni yuboring |
| 503 | ASL_UNAVAILABLE |
faqat kalit ulanayotganda |
13.2. Limitlar
| Nima | Sukut bo‘yicha limit |
|---|---|
| Bitta kalitning barcha so‘rovlari | soniyasiga 100 ta, qisqa muddatda 200 tagacha |
Bitta merchant bo‘yicha /check |
soniyasiga 20 ta |
Bitta /check dagi kodlar |
100 |
| Bitta hodisadagi pozitsiyalar | 1000 |
| Bitta inventarizatsiya so‘rovidagi skanlar | 1000 |
| Qo‘lda sinxronlash | merchant uchun soatiga 1 marta |
| ASL kalitini ulash urinishlari | merchant uchun sutkasiga 10 ta |
Limitlar hamkor uchun alohida sozlanadi. Har bir javobda X-RateLimit-Limit, X-RateLimit-Remaining,
X-RateLimit-Reset sarlavhalari bor.
14. Sinov muhiti: test kodlari
Sinov muhitida Connect ASL BELGISI emulyatori bilan ishlaydi. Test merchanti — STIR 300000001,
test GTIN — 04780012345677. Sinov muhiti uchun ASL API kaliti hamkor kaliti bilan birga beriladi.
SALE kontekstidagi verdiktlar:
| Kod | Verdikt |
|---|---|
010478001234567721OKOKOK00001 |
OK 🟢 |
010478001234567721FOREIGN0001 |
NOT_ON_BALANCE 🟡 |
010478001234567721NOTINTR0001 |
NOT_INTRODUCED 🟡 |
00467800123456BOX00001 |
PACKAGE_CODE 🟡 (RECEIVE da — OK va 3 ta ichki kod) |
010478001234567721SOLD0000001 |
ALREADY_SOLD 🔴, shu do‘kon sotgan |
010478001234567721ELSEWH00001 |
ALREADY_SOLD 🔴, boshqa ishtirokchi sotgan (details.sold_elsewhere) |
010478001234567721WDRAWN00001 |
WITHDRAWN 🔴 |
010478001234567721WOFF0000001 |
WRITTEN_OFF 🔴 |
010478001234567721MISSING0001 |
NOT_FOUND 🔴 |
not-a-code |
INVALID_FORMAT 🔴 |
| bitta so‘rovda ikki marta kelgan istalgan kod | ikkinchisi — DUPLICATE_IN_REQUEST 🔴 |
Jadval har safar hujjat yig‘ilganda avtomatik test bilan tekshiriladi.
15. Kod misollari
15.1. Python: fail-open bilan tekshiruv
import uuid
import httpx
CONNECT = "https://connect.aslraqam.uz/api/v1"
client = httpx.Client(base_url=CONNECT, headers={"Authorization": "Bearer ck_live_…"},
timeout=httpx.Timeout(3.0))
def check(tin: str, store: str, codes: list[str], draft_id: str) -> dict | None:
"""None — Connect ishlamayapti: sotamiz (fail-open)."""
try:
r = client.post("/check", json={"merchant_tin": tin, "store_id": store, "context": "SALE",
"receipt_draft_id": draft_id, "codes": codes})
if r.status_code == 200:
return r.json()
if r.status_code >= 500 or r.status_code == 429:
return None
r.raise_for_status() # 4xx — integratsiya xatosi, uni tuzatish kerak
except httpx.TransportError: # taymaut, tarmoq yo‘q
return None
def send_sale(tin: str, store: str, receipt_no: str, terminal: str, occurred_at: str, items: list[dict]):
# Kalit chek ma’lumotlaridan: oflayn navbatdan qayta yuborish dublikat yaratmaydi
key = f"sale-{terminal}-{receipt_no}"
r = client.post("/events", headers={"Idempotency-Key": key}, json={
"merchant_tin": tin, "store_id": store, "type": "SALE", "external_ref": receipt_no,
"terminal_id": terminal, "occurred_at": occurred_at, "items": items}, timeout=10)
r.raise_for_status()
return r.json()
15.2. PHP: tekshiruv
<?php
function connect_check(string $tin, string $store, array $codes): ?array {
$ch = curl_init('https://connect.aslraqam.uz/api/v1/check');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT_MS => 3000, // 3 soniyadan keyin fail-open
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CONNECT_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'merchant_tin' => $tin, 'store_id' => $store, 'context' => 'SALE', 'codes' => $codes,
]),
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($body === false || $code >= 500 || $code == 429) {
return null; // sotamiz, hodisani keyin yuboramiz
}
return json_decode($body, true);
}
// Vebhuk imzosini tekshirish
function connect_verify(string $secret, string $header, string $rawBody, int $tolerance = 300): bool {
$parts = [];
foreach (explode(',', $header) as $p) {
[$k, $v] = array_pad(explode('=', $p, 2), 2, '');
$parts[$k] = $v;
}
if (!isset($parts['t'], $parts['v1']) || abs(time() - (int)$parts['t']) > $tolerance) {
return false;
}
$expected = hash_hmac('sha256', $parts['t'] . '.' . $rawBody, $secret);
return hash_equals($expected, $parts['v1']);
}
// $raw = file_get_contents('php://input');
// connect_verify($secret, $_SERVER['HTTP_X_CONNECT_SIGNATURE'] ?? '', $raw);
15.3. JavaScript (Node.js 18+)
const CONNECT = "https://connect.aslraqam.uz/api/v1";
export async function check(tin, store, codes) {
try {
const r = await fetch(`${CONNECT}/check`, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.CONNECT_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ merchant_tin: tin, store_id: store, context: "SALE", codes }),
signal: AbortSignal.timeout(3000), // 3 soniyadan keyin fail-open
});
if (r.status >= 500 || r.status === 429) return null;
if (!r.ok) throw new Error(`Connect ${r.status}: ${await r.text()}`);
return await r.json();
} catch (e) {
if (e.name === "TimeoutError" || e.name === "TypeError") return null; // taymaut / tarmoq
throw e;
}
}
// Vebhuk imzosini tekshirish (express: app.post(path, express.raw({type: "application/json"}), …))
import crypto from "node:crypto";
export function verify(secret, header, rawBody, tolerance = 300) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
const ts = Number(parts.t);
if (!ts || Math.abs(Date.now() / 1000 - ts) > tolerance) return false;
const expected = crypto.createHmac("sha256", secret).update(`${ts}.`).update(rawBody).digest("hex");
const got = Buffer.from(parts.v1 || "", "utf8");
const exp = Buffer.from(expected, "utf8");
return got.length === exp.length && crypto.timingSafeEqual(got, exp);
}
15.4. Ishga tushirishdan oldingi tekshiruv ro‘yxati
- [ ]
/checktaymauti 3 soniya; taymaut, 5xx yoki 429 da sotishga ruxsat beriladi. - [ ] Hodisalar oflayn navbati,
Idempotency-Keychek ma’lumotlaridan yasaladi. - [ ]
occurred_atvaqt zonasi bilan; 30 kundan eski hodisalar qabul qilinmaydi. - [ ] Chekda bitta kodning qayta skanini ushlash uchun
receipt_draft_idyuboriladi. - [ ] Bekor qilingan chek
/events/{id}/reverseorqali bekor qilinadi. - [ ] 🟡/🔴 ga qarshi sotuv
items[].overrideda yuboriladi. - [ ] Vebhuklar: imzo xom tana bo‘yicha tekshiriladi, dublikatlar
idbo‘yicha tashlanadi, 10 soniyada 2xx javob. - [ ] Javoblardagi noma’lum maydonlar e’tiborsiz qoldiriladi.
- [ ]
ck_live_kalitlari faqat serverda saqlanadi; do‘konning ASL kaliti sizda saqlanmaydi. - [ ] Loglarda
X-Request-Idbor.
16. Keyinroq qo‘shiladi
| Imkoniyat | Holat |
|---|---|
| Do‘konni qo‘lda kalitsiz, ERI (E-IMZO) bilan kirib ulash | ishlab chiqilmoqda, ASL dan ma’lumot kutilmoqda |
Didox: kiruvchi va chiquvchi ESF, NOT_ON_BALANCE sabablari, /edo va /invoices metodlari |
ishlab chiqilmoqda |
| Merchant uchun o‘rnatiladigan vidjet (interfeys; sessiyalar API si tayyor — 4.6) | ishlab chiqilmoqda |
| Hamkor kabineti: kalitlar, vebhuklar jurnali, qayta yuborish | ishlab chiqilmoqda |
Bu jadvaldagi metodlar /v1 ga mavjudlarini o‘zgartirmasdan qo‘shiladi.
17. O‘zgarishlar jurnali
| Sana | Versiya | O‘zgarishlar |
|---|---|---|
| 14.10.2026 | 0.9.2 | Vidjet sessiyalari: POST /widget/sessions, /widget/exchange (4.6) |
| 14.10.2026 | 0.9.1 | Qoldiqlar, kodlar, nomuvofiqliklar uchun format=csv\|xlsx; inventarizatsiya hisoboti XLSX da; o‘zbekcha qo‘llanma |
| 14.10.2026 | 0.9 | Hujjatning birinchi versiyasi: API v1 (merchantlar, ASL kaliti, /check, /events, hisobotlar, sinxronlash, inventarizatsiya, vebhuklar, foydalanish) |
Qo‘llab-quvvatlash: murojaat qilganda javobdagi X-Request-Id ni ilova qiling.
Texnik yordam kontaktlari ulanishda beriladi.