Webhooks

Khi app ở chế độ HIOBuy warehouse fulfillment, HIOBuy đẩy sự kiện vòng đời fulfillment tới endpoint HTTPS của bạn. Cấu hình tại Developer Portal → Webhooks . Gửi bất đồng bộ; phản hồi Public API không chờ server webhook.

Điều kiện tiên quyết: Ủy quyền kênh → chế độ fulfillment = HIOBuy warehouse. Self chỉ xem intro; không tạo/bật Endpoint.

Tổng quan {#overview}

Hạng mụcGiá trị
Vận chuyểnPOST JSON tới endpoint của bạn
Timeout10 giây
Thành côngHTTP 2xx
Secret kýwhsec_… (chỉ hiện một lần khi tạo / xoay vòng)
Header chữ kýHioBuy-Signature
Header ID sự kiệnHioBuy-Event-Id
User-AgentHioBuy-Webhooks/1.0
Retrytối đa 5 lần: ngay, rồi 1m / 5m / 30m / 2h
Sự kiện testPortal Send test → livemode: false, tiền tố id evt_test_

Đăng ký, xoay secret, lịch sử gửi và retry thủ công là chỉ portal (auth phiên). v1 không có Public /v1/webhooks/*.

Danh mục sự kiện {#events}

Đăng ký theo endpoint. Cần ≥ 1 sự kiện.

NhómLoại sự kiệnKhi nào
Mua hàngprocurement.failedMua hàng kho thất bại
Mua hàngprocurement.out_of_stockSKU hết hàng khi mua
Khopackage.receivedKiện nội địa đã nhập kho
Khopackage.exceptionNgoại lệ nhập kho (data.exception_type)
Gom hàngconsolidation.completedGom hàng hoàn tất
Vận chuyểnshipment.createdTạo vận đơn quốc tế
Vận chuyểnshipment.ready_for_paymentĐóng gói và tính phí hoàn tất; có thể thanh toán
Vận chuyểnshipment.dispatchedĐã giao cho carrier
Vận chuyểnshipment.deliveredĐã giao người nhận
Vận chuyểnshipment.exceptionNgoại lệ xuất kho (data.exception_type)
Tài khoảnbalance.lowSố dư ví kho dưới ngưỡng

Push live warehouse→developer đang mở dần; hãy dùng Send test trên portal để kiểm tra receiver.

Envelope công khai {#envelope}

Mỗi body gửi là JSON:

{
  "id": "evt_01HXYZ…",
  "type": "package.received",
  "created_at": "2026-08-16T04:00:00.000Z",
  "livemode": true,
  "app_id": "app_…",
  "data": {
    "package_id": "pkg_…",
    "order_id": "ord_…",
    "status": "received"
  }
}
TrườngKiểuMô tả
idstringID sự kiện công khai (evt_… live, evt_test_… test)
typestringLoại trong catalog
created_atstringTimestamp ISO-8601
livemodebooleanfalse với test portal
app_idstringApp ID của bạn
dataobjectPayload sự kiện (không có trường nội bộ kho)

Ví dụ data {#data-shapes}

Giống mẫu test portal; live dùng cùng khóa.

procurement.failed

{
  "order_id": "ord_…",
  "status": "failed",
  "reason": "supplier_rejected"
}

package.exception

{
  "package_id": "pkg_…",
  "order_id": "ord_…",
  "status": "exception",
  "exception_type": "DAMAGED"
}

shipment.ready_for_payment

{
  "shipment_id": "115",
  "order_sn": "JIYUNRI1349",
  "external_shipment_id": "MY-INTL-ORDER-001",
  "previous_status": "PENDING",
  "status": "WAIT_PAYMENT",
  "amount_due": {
    "amount": 10200,
    "currency": "CNY"
  },
  "source_packages": [
    {
      "package_id": "pkg_…",
      "external_order_id": "STORE-ORDER-10086"
    }
  ],
  "occurred_at": "2026-09-09T16:20:00.000Z"
}

shipment.dispatched

{
  "shipment_id": "shp_…",
  "tracking_number": "…",
  "status": "dispatched"
}

balance.low

{
  "available_amount": 12.5,
  "currency": "USD",
  "threshold": 50
}

Gửi HTTP {#delivery}

POST /your/webhook-path HTTP/1.1
Host: your-server.example
Content-Type: application/json
User-Agent: HioBuy-Webhooks/1.0
HioBuy-Event-Id: evt_01HXYZ…
HioBuy-Signature: t=1723780800,v1=abcdef0123456789…
  • Production bắt buộc HTTPS. Ngoài production có thể dùng http://localhost / tunnel.
  • Trả 2xx trong 10s. Mã khác hoặc lỗi mạng sẽ retry.
  • Gửi at-least-once. Dedup theo id (và tùy chọn HioBuy-Event-Id).

Xác minh chữ ký {#signature}

  1. Đọc HioBuy-Signature (t=<unix_seconds>,v1=<hex_hmac>).
  2. Tạo chuỗi ký: "{t}.{raw_body}", raw_body là body gốc nhận được (JSON UTF-8).
  3. Tính HMAC-SHA256(secret, signed_payload) rồi hex.
  4. So sánh với v1 theo thời gian hằng.
  5. Từ chối nếu |now - t| quá lớn (dung sai khuyến nghị: 5 phút).

Node.js ví dụ

import crypto from "node:crypto";
 
function verifyHioBuySignature(rawBody, signatureHeader, secret, toleranceSec = 300) {
  const match = /^t=(\d+),v1=([0-9a-f]+)$/i.exec(signatureHeader || "");
  if (!match) return false;
 
  const t = Number(match[1]);
  const expected = match[2].toLowerCase();
  if (!Number.isFinite(t)) return false;
  if (Math.abs(Math.floor(Date.now() / 1000) - t) > toleranceSec) return false;
 
  const signed = `${t}.${rawBody}`;
  const digest = crypto
    .createHmac("sha256", secret)
    .update(signed, "utf8")
    .digest("hex");
 
  const a = Buffer.from(digest, "utf8");
  const b = Buffer.from(expected, "utf8");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Chỉ lưu whsec_… trên server. Portal hiện mask (6 ký tự cuối). Sau khi xoay, cập nhật server trước lần gửi tiếp theo.

Retry & trạng thái {#retries}

Lần thửĐộ trễ sau lần thất bại trước
1Ngay (vào queue)
21 phút
35 phút
430 phút
52 giờ

Sau lần thất bại cuối: failed. Có thể Retry now trong chi tiết portal.

Trạng thái: pending · success · retrying · failed.

Quy trình portal {#portal}

  1. Đặt app sang warehouse fulfillment trong Channel Auth / setup.
  2. Mở Webhooks  → Add endpoint.
  3. Nhập URL HTTPS, mô tả tùy chọn và sự kiện.
  4. Sao chép secret ngay khi hiện (một lần).
  5. Dùng Send test event và xem deliveries / attempts.
  6. Xoay secret, tắt hoặc xóa khi cần.

Giới hạn & lưu trữ {#limits}

Giới hạnGiá trị
Payload≤ 64 KB
body phản hồi lưu trong attempt≤ 4 KB
lưu events / deliveries~30 ngày
Attempt~14 ngày

Liên quan

Get Support

Need integration help? Contact Developer Support at support@hiobuy.com · Response within 1–2 business days

Email support