跳到正文
PayHub开发者文档

测试指南

测试环境与生产环境如何隔离、用哪些测试场景、如何测试收银台、退款、Webhook 与幂等,以及 33 条商户自测清单。

最后更新于 2026-10-15 · 契约 v1.0.0

测试环境说明

项目测试环境(test)生产环境(live)
API 地址https://api.payhub.example(与生产相同)同左
环境由什么决定测试 API Key生产 API Key
Key 前缀sk_test_sk_live_
能访问的数据只有测试对象;查询生产对象返回 404只有生产对象
上游选定上游的沙箱账户正式上游账户
卡只接受沙箱测试卡真实卡
资金不产生真实资金真实扣款、结算、打款
Webhook测试环境单独的端点与签名密钥生产端点与签名密钥
费率未单独配置测试费率时为 0,不计费;需要演练计费时联系平台配置测试费率按合同配置的生产费率
退款审核默认自动批准(不设金额上限,仍需通过资金与风控校验);需要演练人工审核时联系平台改为人工审核默认人工审核
结算与打款按测试结算条款生成结算单(未单独配置时为 T+1 自然日、每日结算、结算手续费 0);审核与打款由平台演练,不发生真实打款,不使用你的收款账户真实
商户后台标识橙色“测试”徽章与横幅绿色“生产”徽章
何时可用商户开通后平台完成开通检查并激活生产后
  • 测试 Key 查询生产对象返回 404;生产 Key 不能把交易发到测试上游。
  • 测试数据在生产停用后不会被删除;测试对象只能在测试环境查询。

警告

只能使用沙箱测试卡。禁止在测试环境、工单、聊天、截图中使用或传播真实卡数据。测试环境不产生真实资金。

准备工作

  1. 测试 API Key 及所需权限范围:创建测试 Key(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)。
  2. 测试环境的 Webhook 端点与签名密钥:配置 Webhook(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)。
  3. 登记回跳地址(测试环境可登记 http://localhost):回跳地址(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)。
  4. 公网可达的 HTTPS 测试地址:用公开测试端点或受控隧道把本地服务暴露出去;平台不会访问内网或本机地址。

测试卡与场景

表中的占位符是场景标识:实际卡号、有效期规则与 CVC 取自选定上游的沙箱资料,只在商户后台登录后展示(查看测试卡取值(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者))。公开文档不发布任何测试卡取值。

#场景场景标识其他输入预期 API 结果预期事件对应 AC
C1直接成功(无需 3DS)<UPSTREAM_TEST_CARD_SUCCESS>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)任一未来有效期、<TEST_CVC>201 succeeded,captured_amount = amountpayment.succeededAC-008、AC-010
C23DS 免交互通过<UPSTREAM_TEST_CARD_3DS_FRICTIONLESS>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)同上201 succeeded,可能不经过 requires_actionpayment.succeeded(可能没有 payment.requires_action)AC-008
C33DS 挑战后成功<UPSTREAM_TEST_CARD_3DS_CHALLENGE>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)测试认证页选择“通过”201 requires_action → 认证后 succeededpayment.requires_action、payment.succeededAC-009、AC-011
C43DS 认证失败<UPSTREAM_TEST_CARD_3DS_FAIL>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)测试认证页选择“失败”requires_action → failed(authentication_failed)payment.failed—
C53DS 成功但发卡行拒绝<UPSTREAM_TEST_CARD_3DS_THEN_DECLINE>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)认证通过requires_action → failed(card_declined),认证结果为成功payment.failedAC-012
C6发卡行拒绝<UPSTREAM_TEST_CARD_DECLINED>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)—failed(card_declined)payment.failed—
C7拒绝后换卡成功<UPSTREAM_TEST_CARD_SUCCESS>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)先做 C6,再用新幂等键 confirm 成功卡同一 Payment,attempt_count=2,succeededpayment.failed、payment.succeeded(version 递增)AC-026
C8卡信息错误<UPSTREAM_TEST_CARD_INCORRECT_DATA>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)—failed(incorrect_card_data)payment.failed—
C9超时 / 结果未知后成功(暂不支持模拟)—(暂不支持模拟)自测方法见表下说明生产中的表现:202 processing + needs_query → 稍后 succeededpayment.succeededAC-019
C10超时 / 结果未知后失败(暂不支持模拟)—(暂不支持模拟)自测方法见表下说明生产中的表现:202 processing → 稍后 failedpayment.failed—
C11上游重复回调(暂不支持模拟)—(暂不支持模拟)自测方法见表下说明生产中的表现:succeeded只有一个 payment.succeeded 事件 ID(可能被投递多次)AC-021(商户侧对应点)
C12卡品牌不支持<UPSTREAM_TEST_CARD_UNSUPPORTED_BRAND>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)—422 card_brand_not_supported无—
C13退款将失败<UPSTREAM_TEST_CARD_REFUND_FAILS>登录商户后台查看(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者)支付成功后发起退款支付 succeeded;退款 processing → failedrefund.failed—

说明:C9 ~ C11 暂不支持模拟

测试环境不提供上游模拟器,上游沙箱通常无法触发上游超时与重复回调。自测方法:

  1. 结果未知(C9、C10):用单元测试或模拟服务把 202 processing + needs_query 响应(创建支付的 processingNeedsQuery 示例)交给你的代码,确认显示“正在确认”、不重扣,之后按查询或事件处理;再把客户端超时设为 100 毫秒发起 C1 支付,用同一个键重试或按订单号查询,确认只得到一个 Payment。
  2. 重复回调(C11):按下面 Webhook 测试的第 6 步(超时重投)与第 8 步(平台人工重发同一事件)让同一事件 ID 再次到达,确认只处理一次;用“发送测试事件”核对接收、验签与按事件 ID 存档。

部分上游用特定金额触发场景,触发规则与测试卡取值一起在商户后台展示;失败原因码以失败原因码为准。每笔测试支付的状态、尝试与事件都可以在 支付订单(在新标签页打开商户后台)(测试环境) 中查看。

托管收银台测试

场景操作预期AC
无需 3DS创建会话 → 打开 checkout_url → 用 C1 卡支付结果页成功、回到 return_url;查询与 Webhook 均为 succeededAC-010
需要 3DS用 C3 卡在收银台支付收银台内完成认证;你的服务端密钥不出现在浏览器AC-011
两个标签页同时提交同一 checkout_url 开两个标签页同时点击支付只产生一笔在途尝试AC-024
会话过期创建会话后不操作,等待超过 expires_at页面不再接受新提交;若此前有在途支付,结果仍会确认AC-025
点击返回商户在收银台点“返回商户”跳到 cancel_url;你的页面先查询状态,不直接标记“已取消”—
已成功订单再创建会话对已支付订单再次创建会话200 + status=completed 只读会话—
USD 与 JPY分别为 USD 10000 与 JPY 10000 创建会话收银台显示 USD 100.00 与 JPY 10,000AC-028

退款测试

基于一笔 USD 10000 的成功支付:

场景操作预期AC
部分退款退 4000201 processing(测试环境默认自动批准)→ succeeded;支付 refund_status=partialAC-031
多次部分退款再退 6000(新的退款号与幂等键)累计 10000,refund_status=full,支付状态仍为 succeededAC-031、AC-030
全额退款显式传 amount 等于可退金额成功后原支付成功事实保留AC-030
超过可退本金已退 4000 后再申请 8000422 refund_amount_exceedsAC-032
并发超额同时发起两笔 6000(不同退款号)只受理符合额度的一笔,另一笔 422AC-032
资金不足请平台为你配置非零测试费率后,刚支付完成就全额退款422 insufficient_refund_funds,message 给出差额,不生成退款单AC-034
同一退款号重复换幂等键、同一 merchant_refund_no不创建第二笔(409 refund_no_conflict)—
退款超时客户端超时后用同一个键重试返回同一笔退款,不创建第二笔AC-033
退款失败用 C13 卡支付后退款refund.failed,资金占用解除—
只读 Key 退款用只有 refunds:read 的 Key 创建退款403 forbiddenAC-003

注意:测试环境的资金与审核

  • 刚完成的支付资金处于待结算;平台可在上游支持时占用本支付自身的待结算净额。测试费率默认 0,全额退款通常不会出现资金差额;配置了非零测试费率时,原支付手续费默认不退,全额退款会差一个手续费——例如支付 100.00、手续费 3.50 时差 3.50。这是正确行为:可以先做部分退款,或联系平台在测试环境登记补款后用同一退款号与金额重新提交。
  • 测试环境退款默认自动批准,创建后直接进入 processing;需要演练人工审核时,联系平台在测试环境把你的商户改为人工审核,之后退款停留在 pending_review,由平台运营审批。

Webhook 测试

  1. 准备公网可达的 HTTPS 测试地址:使用公开测试端点或受控隧道把本地服务暴露出去;平台不会访问内网或本机地址。
  2. 在商户后台(测试环境)配置端点、订阅事件(需二次认证);测试签名密钥只在创建端点时显示一次,立即写入你的测试环境配置(遗失时轮换)。
  3. 点击“发送测试事件”:投递记录显示成功(2xx);你的日志显示验签通过并按事件 ID 存档。测试事件带 X-Pay-Test-Event: true,只投递 1 次、不重试,不产生真实支付、退款或分录。
  4. 篡改测试:用 Webhook 测试向量验证你的验签函数——改动请求体后必须拒绝(AC-059)。
  5. 失败重试:让端点临时返回 500,再用 C1 卡完成一笔测试支付,观察该 payment.succeeded 事件在首次投递后 1 分钟、5 分钟的重试——事件 ID 相同、投递 ID 与签名时间不同;恢复后返回 2xx,确认能被接受并去重(AC-060)。测试事件不重试,所以这一步用真实的测试支付事件。
  6. 超时去重:让端点等 6 秒才返回 200(超过 5 秒),平台判定超时并重投;确认业务只执行一次。
  7. 乱序:用 C7 场景观察 payment.failed 与 payment.succeeded 的 version,确认你的逻辑按 version 处理。
  8. 最终失败(可选,完整周期约 48 小时):端点持续失败,8 次后进入失败列表并收到邮件通知;用 GET /v1/events/{event_id} 补齐,或请平台人工重发(事件 ID 不变,可同时验证重复投递只处理一次,AC-061)。
  9. 内网地址:尝试把端点配置为内网或 localhost 地址,应被拒绝(AC-062)。

投递结果在 事件投递记录(在新标签页打开商户后台)(测试环境;需要所有者、管理员或开发者) 查看。

Webhook 失败重试测试
Webhook 失败重试测试

幂等与异常测试

场景操作预期AC
同键顺序重复同一个键创建支付 10 次同一个 Payment,只扣一次AC-014
同键并发50 个并发请求使用同一个键只有一个执行,其他返回同一对象或 409 operation_in_progressAC-015
同键不同金额同一个键改金额再提交409 idempotency_conflictAC-016
换键同订单号新键 + 同一订单号不产生第二个 PaymentAC-017
同键重试换卡同一个键重试但换成另一张测试卡复用原操作,不用新卡扣款AC-018
处理中用新键 confirmC3 场景停在 requires_action 时用新键 confirm409 payment_in_progressAC-027
网络超时后同键重试客户端超时设为 100 毫秒发起 C1 支付,再用同一个键重试得到同一 Payment,只扣一次AC-069
取消可能已提交的支付C3 场景 requires_action 时调用取消202 或保持原状态;只有上游确认安全取消后才会变成 canceledAC-029
环境隔离生产开通后,用生产 Key 查询测试支付号(或反之)404AC-002
只读 Key 写操作用只有 payments:read 的 Key 创建支付403 forbiddenAC-003
推荐的测试顺序
推荐的测试顺序

商户自测用例清单

勾选状态只保存在本机。“怎么测”会定位到上面对应的场景行。

已完成 0 / 33

支付 0/7收银台 0/5幂等 0/8退款 0/5Webhook 0/5权限与隔离 0/3

  • 支付

    MT-01无需 3DS 的直接支付成功,并只履约一次支付 · 对应 AC AC-008 ·
  • MT-023DS 挑战:整页跳转认证地址,return_url 页面以服务端查询为准支付 · 对应 AC AC-009 ·
  • MT-033DS 成功但发卡行拒绝:不履约,提示换卡支付 · 对应 AC AC-012 ·
  • MT-04拒绝后换卡:用新幂等键 confirm,沿用同一 Payment支付 · 对应 AC AC-026 ·
  • MT-05结果未知(202):显示“正在确认”,不重扣,最终按通知或查询处理支付 · 对应 AC AC-019 ·
  • MT-06USD 与 JPY 金额按最小货币单位换算正确支付 · 对应 AC AC-028 ·
  • MT-07手动给 return_url 加 ?status=succeeded 之类的参数不会触发履约支付 · 对应 AC AC-013
  • 收银台

    MT-08收银台无需 3DS 支付成功,页面、查询、通知结果一致收银台 · 对应 AC AC-010 ·
  • MT-09收银台 3DS 支付成功收银台 · 对应 AC AC-011 ·
  • MT-10两个标签页同时提交只产生一笔在途尝试收银台 · 对应 AC AC-024 ·
  • MT-11会话过期时不把订单判为失败收银台 · 对应 AC AC-025 ·
  • MT-12点击返回商户后先查询,不直接标记已取消收银台 · 对应 AC 商户侧对应点 ·
  • 幂等

    MT-13同键重复提交 10 次只有一个 Payment幂等 · 对应 AC AC-014 ·
  • MT-14同键并发只有一个执行幂等 · 对应 AC AC-015 ·
  • MT-15同键不同金额收到 409 并触发告警幂等 · 对应 AC AC-016 ·
  • MT-16换键同订单号不产生第二个 Payment幂等 · 对应 AC AC-017 ·
  • MT-17同键重试换卡不会用新卡扣款幂等 · 对应 AC AC-018 ·
  • MT-18处理中用新键 confirm 被拒,不新扣款幂等 · 对应 AC AC-027 ·
  • MT-195xx / 超时后同键重试或查单;代码中不存在“换键重扣”的路径幂等 · 对应 AC AC-069 ·
  • MT-20取消可能已提交的支付时,以 canceled 结果为准幂等 · 对应 AC AC-029 ·
  • 退款

    MT-21全额退款显式传金额退款 · 对应 AC AC-030 ·
  • MT-22多次部分退款累计与 refund_status 正确退款 · 对应 AC AC-031 ·
  • MT-23超额退款被拒并正确提示退款 · 对应 AC AC-032 ·
  • MT-24退款超时后同键重试不产生第二笔退款 · 对应 AC AC-033 ·
  • MT-25资金不足时向操作人展示差额,不自动缩减金额退款 · 对应 AC AC-034 ·
  • Webhook

    MT-26篡改请求体后验签失败,不执行业务Webhook · 对应 AC AC-059 ·
  • MT-27旧事件以新签名时间重投时被接受并按事件 ID 去重Webhook · 对应 AC AC-060 ·
  • MT-28端点失败后按计划重试;恢复后能补齐遗漏事件Webhook · 对应 AC AC-061 ·
  • MT-29内网或本机地址无法配置为端点Webhook · 对应 AC AC-062 ·
  • MT-30乱序事件按 version 处理,旧事件不覆盖新状态Webhook · 对应 AC AC-022(商户侧对应点) ·
  • 权限与隔离

    MT-31测试 Key 与生产 Key 互相访问不到对方的对象权限与隔离 · 对应 AC AC-002 ·
  • MT-32只读 Key 无法创建退款权限与隔离 · 对应 AC AC-003 ·
  • MT-33你的日志、错误上报中不出现卡号、CVC、API Key、签名密钥、认证链接权限与隔离 · 对应 AC AC-064(商户侧对应点)

从测试到生产

项目测试生产需要重新做的事
API Key测试 Key所有者或管理员在生产环境创建(需二次认证),按最小权限范围
Webhook测试端点与密钥配置生产端点,保存生产签名密钥
回跳地址测试地址登记生产域名下的地址
卡沙箱测试卡真实卡;不要在生产使用测试卡
退款默认自动批准(可请平台改为人工审核演练)默认人工审核
下一步—按上线检查清单逐项确认
这页有帮助吗?