验证公钥
获取并缓存 Anyway 的 Ed25519 公钥:publicKey 是带前缀的原始公钥表示,keys 是等价的 JWKS 表示。投递信封遵循 Standard Webhooks,并使用非对称 Ed25519(v1a)签名。如果密钥轮换后验证开始失败,请刷新缓存公钥。
事件
当前事件包括:
端点未选择任何事件时,会订阅全部受支持事件,因此未选择事件的现有端点也会开始收到
refund.* 事件。
对不处理的事件类型请返回 2xx,或明确选择需要的事件。只有验证通过的 order.paid 才能触发履约。
周期末取消会通过 subscription.updated 报告;在 subscription.ended 之前,请使用
cancelAtPeriodEnd 和 currentPeriodEnd 表示计划取消状态。收到 fullyRefunded: true 的
refund.succeeded 时,请收回被退款订单授予的权益。部分退款(fullyRefunded: false)由你自己的
策略决定,多数商户会保留权益。
投递请求头与签名内容
签名覆盖以下精确字节序列:
验证 Ed25519 签名
载荷
签名后的信封包含type、RFC 3339 timestamp、apiVersion、端点身份,以及与事件类型对应的
data.order 或 data.subscription。退款事件同时包含 data.refund 和被退款订单 data.order。
订单和订阅事件使用相同的 product 结构。例如,临时产品返回:
product.id。名称只用于展示,不能作为权益标识。如果产品 ID 和名称都不存在,订单事件返回 product: null,订阅事件则省略 product。
重要订单字段包括:
如果付款链接包含
merchant_reference=PUR_456&user_id=USR_123&source=web,订单事件会返回
相同的值:
merchantMetadata 在内的完整原始请求体。签名验证只能证明载荷由
Anyway 投递,并不会让最初对买家可见的查询参数变成可用于授权的可信数据。
不要只根据 merchantMetadata、买家备注、电子邮箱或 URL 参数授权访问。请将订单、金额、币种、产品和关联值与你的服务端记录核对。
订阅载荷
订阅事件使用data.subscription。重要字段包括:
merchantReference 和 merchantMetadata 属于订单载荷,不是 data.subscription 的字段。
需要首笔结账上下文时,请使用 subscriptionId 查询相关订单。
退款载荷
每笔退款最终只会发送一个事件:- 支付渠道确认款项已退回后发送
refund.succeeded。同一订单分两次退款会发送两个事件,各自带有 不同的refundId。 - 退款在 Anyway 审核中被拒绝,或处理时未能完成,发送
refund.failed,没有退回任何款项。
data.order 与订单事件中的订单对象相同,可用 orderId、merchantReference 或
subscriptionId 与你自己的记录匹配。
data.order.status 反映退款完成时的订单状态,全额退款后可能仍显示 PAID。请根据退款字段,
而不是订单状态,决定收回哪些权益。
投递行为
- 持久化加入队列后快速返回
2xx。 - 每次尝试的超时时间为 10 秒。
- 网络错误、
408、429和5xx会重试。 3xx,以及除408、429之外的永久性4xx不会重试。- 最多投递 12 次,指数退避最长一小时。
429和503的Retry-After会被采用,最长一小时。- 投递至少一次,事件也可能乱序到达。
webhook-id 作为投递幂等键。不要让迟到的待处理(Pending)事件把本地
已支付(Paid)订单回退,也不要让更早的订阅更新覆盖较新的生命周期状态。