Z Zise Developers English
卡发行 › Webhook

3DS 验证码

发卡上游把 3DS / OTP 验证码回调给我方时发送。

事件类型

事件什么时候发
card.3ds.received卡片 3DS / OTP 验证码已收到

投递约定

事件体只带 ID 与状态

没有金额、没有资产代码、没有卡号的任何片段、没有风控原因。这不是省字节 —— webhook 端点是你的服务,我方没有办法保证它的传输与存储; 而 GET /v1/<资源>/{id} 那条路径上有 API Key、scope、 代理会员三层校验。要详情就拿 data.id 回查, 别指望从事件体里读出金额来记账。

逐条

card.3ds.received 卡片 3DS / OTP 验证码已收到
什么时候发

发卡上游把 3DS / OTP 验证码回调给我方、并成功落库到 card_3ds_events 之后。目前生产者只有两条:WAS 与 INT。data.id 直接就是公开卡资源 ID(crd_<id>),拿它回查仍走 GET /v1/cards/{id};真正给你展示验证码的,是事件体里受控附带的三个字段:

  • otp_code:给用户手输的短码;
  • expires_at:这条码的失效时间(上游有给才会带值)。
  • application_id:若这张卡来自申请单,会带公开格式的 cap_<id>,方便你直接关联自己那笔开卡申请;没有申请单来源的卡则不带这个字段。

⚠ 事件体不会暴露我方内部 event_key,也不会告诉你上游 provider 是谁;商户侧应该只依赖自己已经持有的会员/卡/申请单坐标做关联。⚠ 这条事件与 card.status.updated 不是一回事:收到验证码并不等于卡状态发生变化;尤其 WAS 会在收到激活码后继续尝试自动激活,成不成要看后续 card.activated或卡状态回查,别把这条事件当成“激活成功”。

事件体
{
  "event_id": "evt_8dc2a13d65904ef29c5ea2f2fe7a1dc2",
  "event_type": "card.3ds.received",
  "created_at": "2026-09-07T11:38:19Z",
  "merchant_id": "acme",
  "livemode": true,
  "data": {
    "object": "card",
    "id": "crd_e70b3d41-5a28-4c96-91f0-6b2a8c05d7e3",
    "external_member_id": "u_88123",
    "status": "received",
    "status_version": 13,
    "application_id": "cap_3882c371-572f-4d5a-af08-f61fc0964de9",
    "otp_code": "54695634",
    "expires_at": "2026-09-07T11:38:19.549Z"
  }
}

验签

验签方式与所有事件一致,见 Webhook 概览; 可以用签名调试器逐字符比对签名串。