Skip to content

Webhooks

The platform sends POST requests to your callback URL on key events. Signing is identical to inbound Open API calls.

Configuration

  • Admin console: API credentials → callback URL
  • Or API: POST /open-api/v1/webhook/set
json
{ "callbackUrl": "https://your-server.com/openapi/callback" }

Event types

Partner-facing Webhooks expose only 3 eventType values (unlike eSIM Access / Billion inbound notifyType). Many fulfillment/profile changes are aggregated into DELIVERY_UPDATED. The payload matches Query Order; inspect orderStatus, deliveryStatus, and items[].profiles[] for the actual change.

eventTypeDescription
ORDER_PAIDBalance payment succeeded; fulfillment started
DELIVERY_UPDATEDDelivery or profile state changed (see triggers below). Sent only when that order actually changed
REFUND_COMPLETEDRefund credited (sync or async Billion after-sale complete)

Interpreting DELIVERY_UPDATED

The webhook body is a full order snapshot (same as query), not a delta. Use changeHints first:

  • Computed by diffing against the last successfully delivered snapshot for the same orderNo + eventType
  • First push or no history: inferred vs empty baseline (e.g. new iccidICCID_READY)
  • Multiple hints may appear in one delivery
  • Retries reuse the same hints

See the Chinese Webhook guide for the full changeHints and status enum tables (English summary below).

changeHintsMeaning
ICCID_READY / QR_CODE_READY / ACTIVATION_CODE_READYFirst time iccid / QR / activation code appears
DELIVERY_STATUS_CHANGED / ORDER_STATUS_CHANGED / ITEM_STATUS_CHANGEDOrder-level status changed
PROFILE_LIFECYCLE_CHANGEDProfile lifecycleStatus changed (PENDINGDELIVEREDACTIVATINGACTIVATEDCANCELLED)
PLAN_USE_STARTED / PLAN_USE_ENDEDPlan usage started / ended
USAGE_UPDATEDCached usage bytes changed
PROFILE_CANCELLEDProfile cancelled
ORDER_SNAPSHOT_SYNCPush with no finer rule matched — refresh full snapshot

Prefer lifecycleStatus over raw esimStatus / smdpStatus (supplier-specific strings).

DELIVERY_UPDATED triggers (platform internal)

These platform-side changes all emit DELIVERY_UPDATED (there is no separate ESIM_STATUS, DATA_USAGE, etc.):

ScenarioTypical payload changes
ICCID / QR / activation code readyitems[].iccid, qrCodeUrl, activationCode; deliveryStatusPARTIAL / DELIVERED
eSIM install / statusitems[].profiles[].esimStatus, smdpStatus
Plan usage start / enditems[].profiles[].planUseStatus, planUseStartTime, planUseEndTime
Data / validity alertsitems[].profiles[].dataUsageBytes, remainDataBytes, usagePercent
Activation / lifecycleitems[].profiles[].activated, lifecycleStatus
Profile updates during refund rejectionitems[].profiles[].cancelled; credit still via REFUND_COMPLETED

Not sent as separate events

Expected scenarioNotes
REFUNDING in progressRefund API may return REFUNDING; no webhook until credited — poll query or wait for REFUND_COMPLETED
Top-up approvedAccount flow; not order webhooks
Payment failed at order timeNo order row; no webhook

Delivery policy

  • Events are order-scoped; the platform presents a unified order/profile model
  • Only actual state changes for that order are pushed; no change means no webhook
  • Supported profile fields may vary by package; rely on items[].profiles[] in the payload

Request format

Headers match inbound API (platform signs with your AppSecret).

Delivery / profile update example:

json
{
  "eventType": "DELIVERY_UPDATED",
  "transactionId": "your-transaction-id",
  "orderNo": "ORD20260101001",
  "orderId": 123456,
  "payStatus": "PAID",
  "deliveryStatus": "DELIVERED",
  "orderStatus": "COMPLETED",
  "currency": "USD",
  "changeHints": ["ICCID_READY", "DELIVERY_STATUS_CHANGED"],
  "items": [
    {
      "itemNo": "ITEM001",
      "iccid": "8901234567890123456",
      "profiles": [
        {
          "iccid": "8901234567890123456",
          "esimStatus": "IN_USE",
          "planUseStatus": "STARTED"
        }
      ]
    }
  ]
}

Refund completed example:

json
{
  "eventType": "REFUND_COMPLETED",
  "transactionId": "your-transaction-id",
  "orderNo": "ORD20260101001",
  "orderId": 123456,
  "payStatus": "REFUNDED",
  "orderStatus": "REFUNDED",
  "refundAmount": 3.50,
  "currency": "USD",
  "items": []
}

See WebhookCallbackPayload in OpenAPI Spec.

Retries

Failed deliveries are retried with backoff. Your endpoint should be idempotent on orderNo + eventType.

eSIM Dealer Open API v1