XD-OP-11 · DOC

上线检查清单(Go-Live Checklist)

上线前逐条核对签名、回跳、通知、退款、密钥轮换与监控;mock 全绿不等于生产可用,最后用一笔真实小额订单跑通。

小豆支付开放平台是面向已有自有系统的商家的支付接入服务:通过服务器对服务器的接口,把支付宝与微信收款接进商家自己的系统,并以签名事件通知回传支付状态;资金由持牌支付公司收付结算。个人也能申请:主体类型选「个人」,身份证 + 本人银行卡即可完成商户进件。央行持牌机构清算,安全可靠的个人和企业支付接口。

平台不提供沙箱/测试应用/回调模拟器(见 接入指南 · 联调支持边界)。所以上线前请逐条自检本清单——每一条都能在你自己的环境里验证,不需要平台配合。全部打勾前不要接真实流量。

A. 凭证与签名

  • A1 RSA2 golden 向量自检:用一个固定的请求(固定 METHOD/路径/query/时间戳/nonce/requestId/Content-Type/body),确认你算出的规范串与 undefined(在公开仓与「下载接入包」内;不在「下载文档包」内)参考实现逐字节一致(含空 query 的空行)。
  • A2 关键归一化逐条验证:URL 路径解码一次、query 按 RFC3986 重编码并按键名排序、Content-Type 小写去 ; 参数、body 哈希取原始字节。响应验签侧同样要归一化(响应头通常是 application/json; charset=utf-8,参与签名的是 application/json)。
  • A3 私钥纪律:私钥只在你自己的服务器/密钥服务;不在浏览器、不在仓库、不在日志(grep 一遍构建产物与日志配置)。
  • A4 时钟:服务器开启 NTP,与标准时间偏差在容许窗口内(否则会出现「偶发 401」)。
  • A5 nonce 唯一性:nonce 由高质量随机源生成且每次请求都不同(含重试)。
  • A6 响应验签:对带 X-XD-Response-* 四头的响应做 XD-Response-v1 验签,且平台公钥来自固定文档页/门户,不是从响应里取。鉴权链之前的拒绝(来源 IP 403、请求体门卫 400/413、六头形态 400、验签失败 401、nonce 重放 409)不带这四个头——代码要按「四头齐备才验」处理,别把缺头当篡改丢弃(平台签名密钥不可用时的 503 也不带四头)。参考实现见 undefined(含 --golden 自检,不需要密钥;在公开仓与「下载接入包」内;不在「下载文档包」内)。
  • A7 平台公钥入库:把 接入指南 · 平台公钥与指纹 的公钥按 kid 存进你方配置(不是每次请求去拉),并本地算一遍指纹与该页公示值逐字符比对。

B. 下单与幂等

  • B1 requestId 幂等:重试(超时/5xx)复用同一个 requestId 与同一请求体;有代码级保证,不是靠人记得。
  • B2 业务幂等:outTradeNo 由你自己的订单系统生成且稳定;重试不换号。
  • B3 409 处理:收到 409 时的动作是「先查单」,不是换号重下单(写进你的错误处理代码,别只写在文档里)。
  • B4 严格请求体:带请求体的两个端点(创建订单/创建退款)请求体不存在 schema 外字段(多传字段会被 400 拒);所有 POST 都带 Content-Type: application/json(含「无请求体」的重拉起/关单——它们可以不带请求体,但不能不带这个头)。
  • B5 tradeScope 申报:按你申报的经营范围正确传参;双申报应用记得必填。

C. 收款材料与终端

  • C1 收款材料只从响应取:qrCode/payUrl 都直接用响应原值,不拼接、不改写、不转发第三方。
  • C2 官方码防呆复检:渲染 qrCode 之前校验前缀,非法值不渲染、不报错、不打印(回退 payUrl 中转链)。
  • C3 过期语义:理解「查询接口 qrCode/payUrl 恒空」「重拉起才换新码」,代码里没有拿旧码长期展示的分支。
  • C4 App 宿主内:自有 App 用系统浏览器打开收银链,没有 WebView 内嵌收银页的路径。
  • C5 终端矩阵自测:用 demo 的终端预览(只在公开仓提供,不在门户下载包内)或真机走一遍 PC / 手机微信外 / 手机微信内三种形态,确认与矩阵一致;先确认你要用的通道与交易形态已放行(未放行的组合下单返回 422,属正常拒绝,不要试探)。
  • C6 微信外文案:若你在自己页面复述引导文案,与逐字文案一致(不要把「复制链接并打开微信」改成别的说法,也不要承诺「点一下就到支付面板」)。

D. 终态与事件

  • D1 终态判据:全代码库搜一遍,确认没有任何地方把「收银页回跳 / 页面状态 / 用户点击」当作支付成功。
  • D2 事件验签:XD-Webhook-v1 用原始字节算哈希验签;验签失败不落账。
  • D3 eventId 去重:eventId 建唯一索引,且去重行与业务写在同一事务;重复投递直接丢弃但仍回 success。
  • D4 响应体:成功时返回 2xx 且响应体字节正好是 success(无 JSON 包装、无多余空白)。
  • D5 乱序兼容:用订单/退款状态机判新旧(事件体里的 stateVersion 当前恒为 0,不要用它),不假设事件按序到达。
  • D6 查单补偿:有一条定时/触发式的查单补偿任务(事件丢失、长期未收敛时兜底)。
  • D7 UNKNOWN 不判死:订单/退款为 UNKNOWN 时不重新下单、不重新发起退款、不给买家提示失败。
  • D8 回调地址:notifyUrl 是绝对 HTTPS、公网可达、host 属于你已申报的域名(归属验证可选、不影响生效)、path 非裸 /;本地/内网地址不上线;已在门户「应用配置变更」提交并已生效(未配置或校验未通过=平台不会产生任何事件);接口能承受重复投递。

E. 退款与对账

  • E1 退款幂等:outRefundNo 稳定;UNKNOWN 的退款不换号重试。
  • E2 累计上限:有本地校验「累计退款 ≤ 实付」,且以平台状态为准。
  • E3 每单投影入账:入账使用每单的 feeProjection(含 ruleVersion),代码里没有硬编码费率表。
  • E4 每日对账:有一个日对账任务,覆盖「平台成功/我未成功」「我成功/平台未成功」「金额不一致」三类差异。

F. 安全与运维

  • F1 IP 白名单:你的生产出口 IP 已在门户白名单内(含灾备/多可用区出口);来源 IP 校验默认开启,可在门户自助关闭(不建议——关闭后任何来源都能用你的密钥调用)。
  • F2 日志脱敏:日志里没有私钥、完整签名材料、完整请求体、买家个人信息;排障只留 requestId。
  • F3 浏览器侧:承载收款材料的页面不引入第三方 CDN/统计/字体,不把材料地址写进 localStorage/sessionStorage/Cookie。
  • F4 returnUrl:只用于展示与轮询,不带交付内容、不带 token。
  • F5 退避策略:429/503 走指数退避且有上限;422(通道未放行)不重试。
  • F6 告警:对 401(签名异常)、403(来源/状态)、502、事件投递失败率配告警。

G. 上线动作

  • G1 首单计划:安排一次真实小额首单,明确谁盯、看什么指标(订单状态、事件到达、结算视图)。
  • G2 陪跑申请:如需平台协助,通过官网反馈渠道提交首单计划(不承诺 SLA)。
  • G3 回滚预案:明确「关掉下单入口」的开关位置与话术(不要用改配置/改代码的方式紧急止血)。
  • G4 材料留档:本次接入的签名 golden 向量、事件验签测试结果、终端矩阵自测记录留档(用于后续变更比对)。
  • G5 域名归属(建议项,非准入):申报清单里的每个域名建议都完成一次归属验证(见 接入指南 · 域名归属验证);未验证不影响开通,但验证后归属更明确。

下列准入前提是你自己要办好的(不是平台代劳):签署开放平台协议与合规报送同意书、出口 IP 白名单(或你已明确决定关闭来源校验)、notifyUrl 已提交并已生效;平台侧只管应用状态、商家状态与通道放行。若上线后发现新增下单被拒类错误,先看 错误码与排障 的 403 组。

内容源:open-platform/docs/11-go-live-checklist.md · 最后更新 2026-10-12 下载本文 .md 在 GitHub 查看