https://sdk.hesap.uz/v1

Hesap SDK

Mijozni o'z tizimingizdan Hesap'da ro'yxatdan o'tkazing, shablon asosida shartnoma tuzing va mijozga uni saytingiz ichida imzolating. Mijoz Hesap'ga kirmaydi va saytingizni tark etmaydi.

Base URL
https://sdk.hesap.uz/v1
Autentifikatsiya
Authorization: Bearer …
OpenAPI spec
sdk.hesap.uz/api-docs
Format
JSON, UTF-8

Tezkor boshlash

Server tomonidagi so'rovlar Authorization: Bearer token bilan ishlaydi. Tokenni appId va appSecret evaziga olasiz. Iframe esa tokensiz ochiladi — unga imzolash sessiyasi ruxsat beradi.

  1. Token olingPOST /auth/token — appId va appSecret evaziga 1 soatlik token beriladi.
  2. Mijozni ro'yxatdan o'tkazingPOST /clients — PINFL, F.I.Sh., telefon va pasport ma'lumotlari. Takror chaqirish xavfsiz.
  3. Shartnoma tuzingPOST /contracts — shablon, taraflar, summa va to'lov jadvali.
  4. Imzolash sessiyasini ochingPOST /contracts/{id}/sign-sessions — javobda iframe uchun url qaytadi.
  5. Iframe'ni ko'rsatingMijoz shartnomani o'qiydi va SMS kodi, MyID yoki E-IMZO bilan imzolaydi.
  6. Natijani olingIframe'dan SIGNED xabari keladi, serveringizga CONTRACT_SIGNED webhook yuboriladi.
To'liq oqim
# 0. Token → {"accessToken":"sdkt_…","tokenType":"Bearer","expiresIn":3600}
TOKEN=$(curl -s -X POST https://sdk.hesap.uz/v1/auth/token \
  -H "Content-Type: application/json" \
  -d "{\"appId\":\"$HESAP_APP_ID\",\"appSecret\":\"$HESAP_APP_SECRET\"}" | jq -r .accessToken)

# 1. Mijoz
curl -X POST https://sdk.hesap.uz/v1/clients \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"in":"31234567890123","firstName":"Aziz","lastName":"Karimov","phone":"998901234567","passport":"AA1234567"}'

# 2. Shartnoma → {"id":"9b3f7c21-..."}
curl -X POST https://sdk.hesap.uz/v1/contracts \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"templateId":"0f0c1f2e-8a41-4d02-9d55-2f7c1b6f9a30","buyerIn":"31234567890123","price":12500000,"currency":"UZS"}'

# 3. Imzolash sessiyasi → {"url":"https://sdk.hesap.uz/sign/…"}
curl -X POST https://sdk.hesap.uz/v1/contracts/9b3f7c21-.../sign-sessions \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"signerIn":"31234567890123","parentOrigin":"https://shop.example.uz"}'

Autentifikatsiya

Hesap sizga ikkita qiymat beradi: appId (ochiq identifikator) va appSecret (maxfiy). Ularni Hesap administratori hamkorlik kelishuvi asosida beradi. appSecret faqat bir marta ko'rsatiladi — uni serverda, maxfiy sozlamalarda saqlang, brauzer yoki mobil ilova kodiga qo'shmang.

Har bir so'rovdan oldin secret yubormaysiz: avval POST /auth/token bilan 1 soatlik token olasiz, keyin uni Authorization: Bearer <accessToken> headerida yuborasiz. Token muddati tugasa yoki 401 kelsa, yangi token olib so'rovni takrorlang.

Shartnomalar ilova egasi nomidan tuziladi: taraflardan biri ilova egasi bo'lishi kerak. Bo'sh qoldirilgan taraf o'rniga ilova egasi qo'yiladi.

HuquqNimaga ruxsat beradi
CLIENTS_WRITEMijozni ro'yxatdan o'tkazish
CLIENTS_READMijozni PINFL/STIR bo'yicha tekshirish
TEMPLATES_READShablonlar va ularning maydonlari
CONTRACTS_WRITEShartnoma tuzish
CONTRACTS_READShartnoma holati va PDF
CONTRACTS_SIGNImzolash sessiyasini ochish va holatini ko'rish

Ilovaga barcha shablonlar yoki faqat tanlanganlari ruxsat etiladi. Ruxsat berilmagan shablon bilan ishlashga urinish 403 qaytaradi.

appSecret sizib chiqsa — darhol Hesap administratoriga xabar bering. Yangi secret berilgan zahoti eskisi va u bilan olingan barcha tokenlar ishlamay qoladi.

Umumiy qoidalar

  • Identifikatorin: jismoniy shaxs uchun 14 xonali PINFL, yuridik shaxs uchun 9 xonali STIR.
  • Sanalar — ISO 8601, UTC: 2026-10-18T00:00:00Z. Pasport va tug'ilgan sana: YYYY-MM-DD.
  • Telefon — mamlakat kodi bilan, faqat raqamlar: 998901234567 (+, bo'sh joy va chiziqcha olib tashlanadi).
  • ValyutaUZS, USD, RUB.
  • Xato javobida doim message maydoni bo'ladi — uni foydalanuvchiga ko'rsatish mumkin.

Endpointlar

POST

/auth/token

ochiq

appId va appSecret evaziga access token olish. Boshqa hamma so'rovlar shu token bilan ishlaydi.

MaydonTuriIzoh
appId majburiystringapp_…
appSecret majburiystringsks_…
200 OK
{
  "accessToken": "sdkt_Qm9v7Lx2…",
  "tokenType": "Bearer",
  "expiresIn": 3600
}

appId yoki appSecret noto'g'ri bo'lsa 401 qaytadi (qaysi biri noto'g'ri ekani aytilmaydi). Ilova bekor qilingan yoki muddati o'tgan bo'lsa 403.

POST

/clients

CLIENTS_WRITE

Mijozni ro'yxatdan o'tkazish.

Takror chaqirish xavfsiz. Shu in bilan mijoz allaqachon bo'lsa, yangi yozuv ochilmaydi: mavjud mijozning faqat bo'sh maydonlari to'ldiriladi va o'sha mijoz qaytadi. Hesap'dagi (masalan OneID orqali tasdiqlangan) ma'lumot qayta yozilmaydi.

MaydonTuriIzoh
in majburiystringPINFL (14) yoki STIR (9)
typestringCLIENT (standart) yoki COMPANY
firstName, lastNamestringJismoniy shaxs uchun majburiy
midNamestringOtasining ismi
phonestringJismoniy shaxs uchun majburiy — imzolash SMS kodi shu raqamga boradi
legalNamestringYuridik shaxs uchun majburiy — tashkilotning to'liq nomi
passportstringSeriya va raqam: AA1234567
passportIssuedBystringPasportni bergan organ
passportIssueDate, passportExpiryDatestringYYYY-MM-DD
birthdaystringYYYY-MM-DD
isManbooleanJinsi: true — erkak
address, emailstring
So'rov
{
  "in": "31234567890123",
  "firstName": "Aziz",
  "lastName": "Karimov",
  "midName": "Olimovich",
  "phone": "998901234567",
  "passport": "AA1234567",
  "passportIssuedBy": "Toshkent sh. Yunusobod IIB",
  "passportIssueDate": "2019-05-14",
  "passportExpiryDate": "2029-05-13",
  "birthday": "1990-03-12",
  "isMan": true,
  "address": "Toshkent sh., Yunusobod t., 4-kvartal"
}
200 OK
{
  "id": "7f3a0c55-1b2e-4d7a-9c0e-5e2d8a1b3c44",
  "in": "31234567890123",
  "firstName": "Aziz",
  "lastName": "Karimov",
  "midName": "Olimovich",
  "legalName": null,
  "type": "CLIENT",
  "phone": "998901234567",
  "verified": false
}
verified: false — siz yuborgan ma'lumot saqlanadi, lekin Hesap uchun tasdiq hisoblanmaydi. Shaxs imzolash paytida (MyID yoki E-IMZO) yoki Hesap'ga OneID bilan kirganda tasdiqlanadi.
GET

/clients/{in}

CLIENTS_READ

Mijoz Hesap'da bormi va shaxsi tasdiqlanganmi. Javob POST /clients bilan bir xil, topilmasa 404.

GET

/templates

TEMPLATES_READ

Ilovaga ruxsat etilgan shablonlar. Javobdagi tasdiqlash turlari shartnoma qanday imzolanishini oldindan ko'rsatadi.

200 OK
[
  {
    "id": "0f0c1f2e-8a41-4d02-9d55-2f7c1b6f9a30",
    "nameUz": "Oldi-sotdi shartnomasi (muddatli to'lov)",
    "nameRu": "Договор купли-продажи (рассрочка)",
    "nameEn": "Sales contract (installments)",
    "individualVerificationType": "OTP_SMS",
    "legalVerificationType": "E_IMZO",
    "productEnabled": true,
    "productRequired": false,
    "paymentScheduleEnabled": true,
    "witnessCount": 0
  }
]
GET

/templates/{templateId}/fields

TEMPLATES_READ

Shablonning to'ldiriladigan maydonlari. Shartnomadagi values massivini shular bo'yicha yig'asiz: har bir maydonning idsi templateFieldId ga, keyNamei keyName ga tushadi.

POST

/contracts

CONTRACTS_WRITE

Shablon asosida shartnoma tuzish. Shartnoma raqami avtomatik beriladi, holati — CREATED (ikkala taraf imzosi kutiladi).

MaydonTuriIzoh
templateId majburiyuuidIlovaga ruxsat etilgan shablon
buyerIn, sellerInstringTaraflar. Bittasi ilova egasi bo'lishi kerak; bo'sh qolgani o'rniga ilova egasi qo'yiladi
pricenumberShartnoma summasi
currencystringUZS / USD / RUB
initialPaymentnumberBoshlang'ich to'lov
deliveryAtdatetimeYetkazib berish sanasi
valuesarrayShablon maydonlari: { templateFieldId, keyName, value, position }
paymentsarrayTo'lov jadvali: { amount, paymentDate }
productsarrayMahsulotlar (shablonda yoqilgan bo'lsa)
witnessIdsarrayGuvohlar (Hesap foydalanuvchi id'lari)
So'rov
{
  "templateId": "0f0c1f2e-8a41-4d02-9d55-2f7c1b6f9a30",
  "buyerIn": "31234567890123",
  "price": 12500000,
  "currency": "UZS",
  "values": [
    { "templateFieldId": "7c1d0a55-3b21-4f88-9a0e-1d2b3c4d5e6f", "keyName": "product_name",
      "value": "Samsung Galaxy S25", "position": 1 }
  ],
  "payments": [
    { "amount": 4166667, "paymentDate": "2026-10-18T00:00:00Z" },
    { "amount": 4166667, "paymentDate": "2026-11-18T00:00:00Z" },
    { "amount": 4166666, "paymentDate": "2026-12-18T00:00:00Z" }
  ]
}
200 OK
{ "id": "9b3f7c21-55ad-4e10-8b6e-0c4a91f2d773" }
GET

/contracts/{id}

CONTRACTS_READ

Shartnoma va uning holati. Asosiy maydonlar: status, buyerStatus, sellerStatus, number, price, taraflar va values.

GET

/contracts/{id}/pdf

CONTRACTS_READ

Shartnoma PDF'i (application/pdf). Tilni ?lang=uz|ru|en bilan tanlang.

POST

/contracts/{id}/sign-sessions

CONTRACTS_SIGN

Bitta tarafni imzolash uchun sessiya ochish. Har bir taraf uchun alohida sessiya oching.

MaydonTuriIzoh
signerIn majburiystringKim imzolaydi — shartnomaning buyerIn yoki sellerIn qiymati
langstringIframe tili: uz (standart), ru, en
parentOriginstringIframe joylashadigan sayt, masalan https://shop.example.uz. Berilsa iframe'ni faqat shu sayt ko'rsata oladi va hodisalar faqat shu saytga yuboriladi. Production'da albatta bering.
redirectUrlstringImzodan keyin «Davom etish» tugmasi ochadigan sahifa
200 OK
{
  "id": "5b0f6c1e-4e7a-4a8b-9d7e-2f1c0a9b8d33",
  "url": "https://sdk.hesap.uz/sign/Qx7fK2…",
  "method": "OTP_SMS",
  "expiresAt": "2026-09-18T11:19:02Z",
  "status": "PENDING"
}
GET

/sign-sessions/{id}

CONTRACTS_SIGN

Sessiya holati: PENDING, SIGNED, REJECTED yoki EXPIRED. Faqat o'z ilovangiz ochgan sessiyalar ko'rinadi.

Iframe

Sessiya javobidagi urlni sahifangizga joylang. Saytingiz HTTPS'da bo'lishi kerak.

HTML
<iframe
  id="hesap-sign"
  src="https://sdk.hesap.uz/sign/Qx7fK2…"
  allow="camera"
  style="width:100%; max-width:520px; height:640px; border:0">
</iframe>

allow="camera" — MyID/AbleID bilan yuzni tasdiqlash uchun. Tasdiqlash yangi oynada ochiladi, shuning uchun brauzerning popup blokerini hisobga oling.

Imzolash usullari

Usulni shablon belgilaydi, siz tanlamaysiz. Sessiya javobidagi method qaysi usul ekanini ko'rsatadi.

methodMijoz nima qiladi
OTP_SMSTelefoniga kelgan 5 xonali kodni kiritadi. 5 marta noto'g'ri kiritilsa sessiya yopiladi.
MY_IDYangi oynada MyID orqali yuzini tasdiqlaydi.
ABLE_IDYangi oynada AbleID orqali yuzini tasdiqlaydi.
E_IMZOKompyuterdagi E-IMZO kaliti bilan imzolaydi. Yuridik shaxslar uchun odatiy usul.
Shablonda tasdiqsiz imzo sozlangan bo'lsa ham, SDK orqali imzolashda tasdiq so'raladi: jismoniy shaxsdan SMS kodi, yuridik shaxsdan E-IMZO.

Iframe hodisalari

Iframe sahifangizga postMessage orqali xabar yuboradi. event.originni albatta tekshiring.

JavaScript
window.addEventListener("message", (event) => {
  if (event.origin !== "https://sdk.hesap.uz") return;
  const msg = event.data;
  if (!msg || msg.source !== "hesap-sdk") return;

  switch (msg.type) {
    case "READY":    /* oyna yuklandi; msg.method */ break;
    case "RESIZE":   document.getElementById("hesap-sign").style.height = msg.height + "px"; break;
    case "SIGNED":   /* imzolandi — serverda tekshiring */ break;
    case "REJECTED": /* mijoz rad etdi */ break;
    case "ERROR":    /* sessiya yaroqsiz; msg.message */ break;
  }
});
typeQachonQo'shimcha maydonlar
READYOyna yuklandi va shartnoma ko'rsatildimethod
RESIZEOyna balandligi o'zgardiheight (px)
SIGNEDMijoz imzoladisessionId, contractId
REJECTEDMijoz rad etdi
ERRORSessiya yopilgan, muddati o'tgan yoki topilmadi
Brauzer xabari — faqat interfeys uchun signal. Buyurtmani tasdiqlashdan oldin serveringizda GET /sign-sessions/{id} yoki GET /contracts/{id} bilan tekshiring yoki webhook'ni kuting.

Webhook

Ilovaga webhook manzili biriktirilgan bo'lsa, Hesap hodisalarni shu manzilga POST qiladi. Qaysi hodisalarni olishni ilova yaratilganda belgilanadi; hech biri tanlanmasa hammasi keladi.

HodisaQachon
CONTRACT_CREATEDShartnoma tuzildi
CONTRACT_SIGNEDTaraflardan biri imzoladi
CONTRACT_ACTIVEIkkala taraf imzoladi — shartnoma kuchga kirdi
CONTRACT_REJECTEDTaraf rad etdi
CONTRACT_CANCELLEDYaratuvchi bekor qildi
PAYMENT_ACCEPTEDTo'lov tasdiqlandi
Webhook tanasi
{
  "event": "CONTRACT_SIGNED",
  "contractId": "9b3f7c21-55ad-4e10-8b6e-0c4a91f2d773",
  "contractNumber": "260918-0042",
  "status": "CREATED",
  "templateId": "0f0c1f2e-8a41-4d02-9d55-2f7c1b6f9a30",
  "buyerIn": "31234567890123",
  "sellerIn": "301234567",
  "creatorIn": "301234567",
  "actorIn": "31234567890123",
  "amount": 12500000,
  "currency": "UZS",
  "occurredAt": "2026-09-18T11:06:41Z"
}
HeaderMa'nosi
X-Hesap-EventHodisa turi
X-Hesap-DeliveryYetkazish id'si — bir hodisani ikki marta qayta ishlamaslik uchun saqlang
X-Hesap-Signaturesha256=<hex> — tananing HMAC-SHA256 imzosi (webhook secret bilan; ilova yaratilganda beriladi)

Imzoni tekshirish

Imzo xom tana ustidan hisoblanadi — JSON'ni parse qilishdan oldin tekshiring.

verify
const crypto = require("crypto");

function verify(rawBody, signature, secret) {
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(signature || "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Javob 10 soniya ichida 2xx bo'lishi kerak. Aks holda Hesap 3 marta qayta urinadi, keyin hodisa tashlab yuboriladi — muhim holatlarni vaqti-vaqti bilan GET /contracts/{id} orqali solishtirib turing.

Xatolar

KodSabab
400Maydon noto'g'ri: PINFL 14 xonali emas, signerIn taraf emas, shartnoma CREATED holatida emas, SMS kodi noto'g'ri
401Token yo'q, noto'g'ri yoki muddati tugagan — yangi token oling; /auth/token'da — appId yoki appSecret noto'g'ri
403Huquq yetishmaydi, shablon ruxsat etilmagan, shartnoma ilova egasiga tegishli emas, ilova bekor qilingan; iframe'da — sessiya yopilgan yoki muddati o'tgan
404Mijoz, shartnoma yoki sessiya topilmadi
503Ichki xizmat vaqtincha javob bermadi — birozdan keyin qayta urining
Xato javobi
{
  "code": 403,
  "status": "403 Forbidden",
  "message": "Bu shablon ilovaga ruxsat etilmagan",
  "timestamp": "18 sentabr 2026 y., 16:04:02 UTC+5"
}

Holatlar

MaydonQiymatlar
Shartnoma statusCREATED imzo kutilmoqda · ACTIVE kuchga kirdi · COMPLETED yakunlandi · REJECTED rad etildi · CANCELLED bekor qilindi
buyerStatus, sellerStatusPENDING · ACCEPTED · REJECTED
Sessiya statusPENDING · SIGNED · REJECTED · EXPIRED
Mijoz typeCLIENT jismoniy · COMPANY yuridik

Ishga tushirishdan oldin

  • appSecret va token faqat serverda saqlanadi, brauzer yoki mobil ilova kodiga tushmaydi.
  • Token keshlanadi va 401 kelganda yangilanadi — har so'rov oldidan yangi token olinmaydi.
  • Har bir sessiyaga parentOrigin berilgan.
  • Iframe hodisalarida event.origin tekshiriladi.
  • Buyurtma SIGNED xabari bilan emas, server tekshiruvi yoki webhook bilan tasdiqlanadi.
  • Webhook imzosi xom tana ustida tekshiriladi, X-Hesap-Delivery takrorlanishiga qarshi saqlanadi.
  • Muddati o'tgan sessiya uchun yangi sessiya ochish yo'li bor.