iFragment

Vebxuklar

Buyurtma va akkaunt hodisalari, HMAC-SHA256 imzosi, qayta yuborish.

Vebxuk bu har bir hodisada Project'ingiz URL manziliga yuboriladigan POST so'rov. Endpoint va imzo siri kabinetda sozlanadi; sir faqat bir marta ko'rsatiladi.

Hodisalar

typeQachon
order.succeededbuyurtma bajarildi
order.failedbuyurtma bajarilmadi, balansdagi blok olib tashlandi
order.needs_reviewnatija noma'lum, buyurtmani qo'llab-quvvatlash xizmati tekshirmoqda
supplier_account.health_changedSupplier Account'ingiz holati o'zgardi (OWN rejimi)

Format

POST /ifragment/webhook HTTP/1.1
Content-Type: application/json
X-IFragment-Signature: t=1790000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
{
  "id": "0199a1b2-7c3d-7e4f-8a9b-0c1d2e3f4a5b",
  "type": "order.succeeded",
  "createdAt": "2026-09-26T10:15:30.000Z",
  "data": {
    "id": "0199a1b2-6f00-7abc-9def-112233445566",
    "externalId": "1042",
    "product": "STARS",
    "quantity": 500,
    "months": null,
    "username": "durov",
    "recipientName": "Pavel Durov",
    "status": "SUCCEEDED",
    "price": "8.25",
    "currency": "USD",
    "failure": null,
    "createdAt": "2026-09-26T10:15:02.000Z",
    "sentAt": "2026-09-26T10:15:05.000Z",
    "completedAt": "2026-09-26T10:15:30.000Z"
  }
}

supplier_account.health_changed hodisasida data ichida akkaunt keladi:

{
  "accountId": "0199a1b2-1111-7abc-9def-112233445566",
  "label": "Main wallet",
  "previousHealth": "HEALTHY",
  "health": "DEGRADED",
  "reasons": ["LOW_BALANCE"],
  "changedAt": "2026-09-26T10:20:00.000Z"
}
  • id bu hodisa id'si, qayta yuborishlarda u o'zgarmaydi. Qayta ishlangan id larni saqlang va dublikatlarni o'tkazib yuboring: yetkazish "kamida bir marta" tamoyili bo'yicha ishlaydi.
  • data ichida buyurtma obyekti (GET /v1/orders/{id} dagi kabi) yoki supplier_account.health_changed uchun akkaunt bo'ladi. order.failed da sabab data.failure.code ichida.
  • Hodisalar tartibsiz kelishi mumkin; data.status ga tayaning, shubha bo'lsa, buyurtmani API orqali so'rang.

Javob

10 soniya ichida istalgan 2xx bilan javob bering, javob tanasi o'qilmaydi. Uzoq davom etadigan ishlovni javobdan keyin bajaring (navbat, fon vazifasi).

Qayta yuborish

Javob 2xx bo'lmasa, taymaut yoki ulanish xatosi bo'lsa, yetkazish eksponensial kechikish bilan takrorlanadi: jami taxminan 24 soat ichida 12 urinish. Shundan so'ng yetkazish FAILED deb belgilanadi; uni kabinetdan qo'lda qayta yuborish mumkin.

Imzoni tekshirish

X-IFragment-Signature: t=<unix>,v1=<hex>, bunda v1 = hex(HMAC-SHA256(secret, "<t>.<rawBody>")):

  1. sarlavhani t va v1 ga ajrating;
  2. t + "." + so'rovning xom tanasi satridan HMAC-SHA256 hisoblang, ya'ni JSON parse qilinishidan oldin kelgan baytlarning o'zidan;
  3. natijani v1 bilan doimiy vaqtda solishtiring;
  4. agar t joriy vaqtdan 5 daqiqadan ko'proq farq qilsa, so'rovni rad eting (qayta yuborish hujumidan himoya).
import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyIFragmentSignature(rawBody: string, header: string, secret: string, toleranceSec = 300): boolean {
  const parts = Object.fromEntries(header.split(',').map((part) => part.split('=', 2) as [string, string]));
  const timestamp = Number(parts.t);
  if (!parts.v1 || !Number.isInteger(timestamp) || Math.abs(Date.now() / 1000 - timestamp) > toleranceSec) {
    return false;
  }
  const expected = createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest();
  const received = Buffer.from(parts.v1, 'hex');
  return received.length === expected.length && timingSafeEqual(received, expected);
}

// Express: parse qilingan JSON emas, xom tanani oling.
app.post('/ifragment/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const raw = req.body.toString('utf8');
  if (!verifyIFragmentSignature(raw, req.get('X-IFragment-Signature') ?? '', process.env.IFRAGMENT_WEBHOOK_SECRET!)) {
    return res.sendStatus(401);
  }
  const event = JSON.parse(raw);
  res.sendStatus(200);
  queue.add(event); // javobdan keyin ishlov berish
});

Ko'p uchraydigan xato: imzoni qayta seriyalangan JSON'dan (JSON.stringify(req.body)) hisoblash. Maydonlar tartibi va bo'shliqlar farq qilishi mumkin, natijada imzo mos kelmaydi. Doim xom tanadan foydalaning.

Ushbu sahifada