Skip to content

Webhook 回调

订单支付、发货、Profile 状态或退款完成时,会向你在 API 凭证里配置的 callback URL 发送 POST 请求。验签规则与调用 Open API 时完全一致

三个要点:

  1. 对外只有 3 种 eventType(见下表)。
  2. 每次推送的是整单快照(与 查单 结构相同),不是增量 patch。
  3. 想知道「这次具体变了什么」,优先看 changeHints,再对照 orderStatus / deliveryStatus / items[].profiles[]

配置回调地址

方式一: 管理后台 → API 凭证 → 填写回调 URL

方式二: 调用接口 POST /open-api/v1/webhook/set

json
{ "callbackUrl": "https://your-server.com/openapi/callback" }

事件类型

eventType何时推送
ORDER_PAID余额扣款成功,订单进入履约
DELIVERY_UPDATED发货进度或 Profile 状态有变化(见 常见场景)。仅在该订单确有变更时推送
REFUND_COMPLETED退款已入账(含同步退款与异步退款完成)

发货、安装、激活、用量更新等变化都使用 DELIVERY_UPDATED,不会另发 ESIM_STATUSDATA_USAGE 等事件名。请根据 payload 字段与 changeHints 判断细节。


推荐处理流程

text
收到 POST → 验签 → 快速返回 HTTP 200 → 异步处理业务

若 eventType == DELIVERY_UPDATED:
  1. 读取 changeHints,按类型更新 UI / 本地状态
  2. 用整单 payload 覆盖本地订单快照(便于对账)

若 eventType == ORDER_PAID:
  标记已支付,等待后续 DELIVERY_UPDATED

若 eventType == REFUND_COMPLETED:
  标记退款完成,更新退款金额

幂等: 同一 orderNo + eventType 可能因重试重复投递,请按此组合去重。


如何读懂 changeHints

Webhook Body 是全量订单快照changeHints 表示「相对该订单、同类型事件的上一次成功投递」发生了哪些变化:

  • 首次 DELIVERY_UPDATED,或没有历史快照时,按「相对空快照」推断(例如首次出现 iccidICCID_READY)。
  • 一次推送可含多个 hint。
  • 重试投递时 changeHints 与首次相同。

发货与安装

changeHints含义建议动作
ICCID_READY首次出现 ICCID展示卡号、引导安装
QR_CODE_READY首次出现安装二维码 URL展示 QR
ACTIVATION_CODE_READY首次出现 SM-DP+ 激活码展示 LPA 串

订单与子项状态

changeHints含义建议动作
DELIVERY_STATUS_CHANGED主单 deliveryStatus 变化更新发货进度
ORDER_STATUS_CHANGED主单 orderStatus 变化更新订单状态
ITEM_STATUS_CHANGED子项 itemStatus 变化更新子单状态
PROFILE_LIFECYCLE_CHANGEDProfile lifecycleStatus 变化更新单卡生命周期
ESIM_STATUS_CHANGEDProfile esimStatus 变化记录 eSIM 状态(补充字段)
SMDP_STATUS_CHANGEDProfile smdpStatus 变化记录安装过程状态(补充字段)

套餐与用量

changeHints含义建议动作
PLAN_USE_STARTEDplanUseStatus 变为 STARTED标记套餐已开始使用
PLAN_USE_ENDEDplanUseStatus 变为 ENDED标记套餐已结束
USAGE_UPDATED流量相关字段变化更新用量展示;实时用量可另调 profile/usage

退款与其他

changeHints含义建议动作
PROFILE_CANCELLEDProfile cancelled 变为 true标记卡已取消
REFUND_AMOUNT_UPDATED累计退款额增加更新退款金额
ORDER_PAID配合 ORDER_PAID 事件标记已支付
REFUND_COMPLETED配合 REFUND_COMPLETED 事件标记退款完成
ORDER_SNAPSHOT_SYNC有推送但未命中更细规则用 payload 全量覆盖本地快照

状态字段取值

判断业务阶段时,优先使用 lifecycleStatuschangeHintsesimStatus / smdpStatus 为渠道相关原始值,不同套餐可能不同,仅作补充参考。

主单 deliveryStatus

含义
PENDING未发货
PARTIAL部分 Profile 已就绪
DELIVERED全部 Profile 已就绪
FAILED发货失败

主单 orderStatus(常用)

含义
PAID已支付,待履约
FULFILLING履约中
COMPLETED订单完成
REFUNDING退款处理中(通常不单独推 Webhook,以查单为准)
REFUNDED已退款

子项 itemStatus

含义
PENDING待发码
DELIVERED已发码
ACTIVATING激活中
ACTIVATED已激活
FAILED失败
REFUNDED已退款

Profile lifecycleStatus(推荐)

含义
PENDING待发码
DELIVERED已发码(含 iccid / qr)
ACTIVATING安装或激活进行中
ACTIVATED已激活
CANCELLED已取消

DELIVERY_UPDATED 常见场景

场景payload 中常见变化
ICCID / 二维码 / 激活码就绪items[].iccidqrCodeUrlactivationCodedeliveryStatus 可能变为 PARTIAL / DELIVERED
Profile 安装或 eSIM 状态变更items[].profiles[].esimStatussmdpStatus
套餐开始使用或结束items[].profiles[].planUseStatusplanUseStartTimeplanUseEndTime
流量或有效期更新items[].profiles[].dataUsageBytesremainDataBytesusagePercent
Profile 激活或生命周期变化items[].profiles[].activatedlifecycleStatus
退款审核拒绝等导致 Profile 回写items[].profiles[].cancelled 等;退款入账另见 REFUND_COMPLETED

不会单独推送的情况

场景说明
退款处理中(REFUNDING退款接口可能返回 REFUNDING入账前不会推 Webhook,请查单或等待 REFUND_COMPLETED
账户充值审核通过走账户流程,不在订单 Webhook 范围内
下单支付失败未落单,无 Webhook

推送规则

  • 订单维度推送;仅在该订单实际发生变更时发送,无变更则不推。
  • 不同套餐支持的 Profile 字段可能不同,以 payload 中 items[].profiles[] 实际返回为准。

请求格式

Header 与入站 Open API 一致(使用同一 AppKey 对应的 AppSecret 签名)。

ORDER_PAID 示例

json
{
  "eventType": "ORDER_PAID",
  "transactionId": "your-transaction-id",
  "orderNo": "ORD20260101001",
  "orderId": 123456,
  "payStatus": "PAID",
  "deliveryStatus": "PENDING",
  "orderStatus": "PAID",
  "currency": "USD",
  "items": [
    {
      "itemNo": "2075463266738958341",
      "packageCode": "PKG001",
      "quantity": 1,
      "itemStatus": "PAID"
    }
  ]
}

DELIVERY_UPDATED 示例

json
{
  "eventType": "DELIVERY_UPDATED",
  "transactionId": "your-transaction-id",
  "orderNo": "ORD20260101001",
  "orderId": 123456,
  "payStatus": "PAID",
  "deliveryStatus": "DELIVERED",
  "orderStatus": "COMPLETED",
  "currency": "USD",
  "changeHints": ["ICCID_READY", "QR_CODE_READY", "DELIVERY_STATUS_CHANGED", "PROFILE_LIFECYCLE_CHANGED"],
  "items": [
    {
      "itemNo": "2075463266738958341",
      "packageCode": "PKG001",
      "quantity": 1,
      "itemStatus": "DELIVERED",
      "profiles": [
        {
          "profileId": "2075464693179805698",
          "iccid": "8901234567890123456",
          "esimTranNo": "26071006120045",
          "qrCodeUrl": "https://cdn.example.com/qr/xxx.png",
          "activationCode": "LPA:1$rsp-eu.simlessly.com$...",
          "esimStatus": "IN_USE",
          "lifecycleStatus": "ACTIVATED",
          "planUseStatus": "STARTED",
          "dataUsageBytes": 524288000
        }
      ]
    }
  ]
}

REFUND_COMPLETED 示例

json
{
  "eventType": "REFUND_COMPLETED",
  "transactionId": "your-transaction-id",
  "orderNo": "ORD20260101001",
  "orderId": 123456,
  "payStatus": "REFUNDED",
  "deliveryStatus": "DELIVERED",
  "orderStatus": "REFUNDED",
  "refundAmount": 3.50,
  "currency": "USD",
  "items": [
    {
      "itemNo": "ITEM001",
      "packageCode": "PKG001",
      "quantity": 1,
      "itemStatus": "REFUNDED"
    }
  ]
}

完整字段定义见 OpenAPI Schema 中的 WebhookCallbackPayload


重试与接入建议

投递失败会自动重试(默认最多 8 次,指数退避)。

  1. 先验签,再处理业务逻辑
  2. 尽快返回 HTTP 200,耗时操作放异步队列
  3. orderNo + eventType幂等,并保存整单快照便于对账

eSIM Dealer Open API v1