披露:本文包含联盟链接。如您通过链接购买,我们可能获得佣金,且您无需承担额外费用。

测试结账流程,意味着要模拟用户点击“支付”到后端确认“资金到账”之间发生的一切——拒付、风控检查、退款、乱序触发的 Webhook——而全程不能真正扣款。支付处理商发布沙盒环境和公开的测试卡号,正是为此而生。本指南介绍 Stripe、PayPal、Braintree、Adyen 和 Square 提供的测试卡与沙盒工具,以及如何将它们与虚拟账单数据结合使用的工作流。

“测试卡”到底是什么

测试卡是支付处理商在沙盒中保留的一个 16 位 PAN(主账号)。这个卡号能通过 Luhn 校验,看起来像真实的 Visa 或 Mastercard,并会触发特定的处理商响应——成功、拒付、余额不足、过期等——而永远不会路由到真实发卡行。多数处理商会在文档中发布一组公开的测试卡;请使用这些卡号而不是自己编造,因为末四位通常被编码为特定的拒付原因码。

Stripe——最完整的沙盒

Stripe 是测试基础设施的黄金标准。其沙盒(“测试模式”)接受以 pk_test_sk_test_ 开头的可发布密钥和秘密测试密钥,因此每个 API 调用都有测试对应版本,每个 Webhook 都可以通过 Stripe CLI 镜像到本地。

必备 Stripe 测试卡

卡号品牌结果
4242 4242 4242 4242Visa支付成功
4000 0027 6000 3184Visa拒付——附带欺诈拦截标记
4000 0000 0000 0002Visa通用拒付
4000 0000 0000 9995Visa余额不足
4000 0000 0000 0069Visa卡片过期
4000 0082 6000 3178Visa需要 3DS 验证
5555 5555 5555 4444Mastercard支付成功
3782 822463 10005Amex支付成功(Amex 测试卡,15 位)

Stripe CLI:在本地重放 Webhook

杀手级功能是 Stripe CLI,它能把测试模式的实时事件转发到你本地的 Webhook 端点:

stripe login
stripe listen --forward-to http://localhost:8080/webhooks/stripe

这一条命令,就是“我测试了顺利路径”和“我测试了完整的顺利路径——包括那条更新我数据库的 Webhook”之间的区别。还可以手动触发特定事件:

stripe trigger payment_intent.succeeded
stripe trigger invoice.payment_failed
stripe trigger charge.refunded

PayPal——沙盒账户与虚拟卡

PayPal 提供了一个“沙盒”环境,你可以在开发者控制台创建独立的沙盒买家账户和商户账户。至少创建一个沙盒企业账户(商户)和一个个人账户(买家)。

沙盒测试卡——在 PayPal 沙盒内用于游客结账——包括以下公开卡号:

  • Visa:4032035728984848(有效期填任意未来日期,CVV 123)
  • Mastercard:5425233430109242
  • Amex:374245455400126

这些卡仅在 PayPal 沙盒内有效;在其他任何地方使用都会得到通用拒付。PayPal 沙盒像 Stripe 那样支持丰富的拒付场景——要测试 PayPal 拒付,请使用开发者控制台中的 reviewer 工具,给你的沙盒账户附加一个“负面测试”标记,强制下一笔交易失败。

Braintree——沙盒卡

Braintree(PayPal 旗下公司)在初始化时区分沙盒密钥与生产密钥,并发布了一套按特定响应码划分的测试卡:

卡号结果
4111 1111 1111 1111批准
5105 1051 0510 5100批准(Mastercard)
4000 1111 1111 1115处理商拒付——卡类型未启用
5000 1111 1111 1114处理商拒付——被发卡行拒付
4000 1111 1111 1112处理商拒付——已拦截

Braintree 还允许你通过设置特定的街道地址或 CVV 值来控制 AVS 和 CVV 响应——这在测试高级风控和卡片验证路径时非常有用。

Adyen 和 Square

Adyen 提供测试账户,每个卡号都有可预测的结果,拒付原因码也非常出色。常用测试卡包括 4111 1111 1111 1111(Visa,已授权)和 5101 1800 0000 0007(Mastercard)。Adyen 响应对象上的“test”前缀让审计工作变得简单。

Square 发布了沙盒卡,如 4111 1111 1111 1111(Visa 扣款成功)和 5105 1051 0510 5100(Mastercard 拒付)。Square 沙盒允许你创建沙盒客户并将卡片存档。

最佳实践:测试每一条拒付路径

下面这份清单覆盖了大多数团队容易遗忘的失败面:

  • 使用有效卡片成功扣款
  • 通用处理商拒付
  • 余额不足
  • 卡片过期
  • 需要 3DS 的场景(验证挑战弹窗出现且挑战完成成功;验证取消——每条路径都重要)
  • 卡片存档后,通过已保存的令牌稍后扣款
  • 全额退款与部分退款
  • 对已被拒付(争议)的扣款发起退款(追回路径)
  • Webhook 到达两次——验证你的处理器是幂等的
  • Webhook 在数据库写入之前到达(Stripe 称之为“事件 ID 领先于状态”的罕见乱序情况)

幂等的 Webhook 处理器是底线,不容妥协。使用事件 ID 作为你的幂等键。如果你发现自己在处理器里写出 if (!exists) { insert } else { skip }——恭喜你,你已经写出了幂等性。下次重构时千万别把它弄丢了。

将测试卡与虚拟账单数据配对使用

一次成功的沙盒扣款还依赖于 AVS(地址验证系统)——发卡行会核对邮编和街道号是否与卡片档案一致。大多数沙盒卡的测试环境会忽略 AVS 结果,但要测试你表单的错误路径(例如邮编错误触发错误提示),你需要稳定但明显虚构的账单数据。

这正是 USA Data Tools 地址生成器的用武之地:

curl "https://vic999.com/us-address/api/v1/address?count=20" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o fixtures/billing-addresses.json
  • 真实的地址让你能断言表单接受每一种邮编到州的组合。
  • 按州生成的数据对测试扣款前的销售税明细行无价。
  • 免税州生成器让你能验证特拉华、蒙大拿、新罕布什尔和俄勒冈的零税结账。

把生成的账单地址、Stripe 的需要 3DS 测试卡和一个生成的购买金额组合起来,你就得到了一个完全可复现的结账测试场景,一次性覆盖 AVS、税费和 3DS。

幂等性——悄无声息的结账杀手

真实世界的支付事故往往长这样:用户点击支付,请求在第 28 秒超时,用户再次点击支付——然后被扣了两次款。每个支付 API 都支持幂等键;请务必使用:

// Stripe 示例:传入幂等键
const paymentIntent = await stripe.paymentIntents.create({
  amount: 1999,
  currency: "usd",
  customer: customerId,
}, {
  idempotencyKey: `order_${orderId}_pay`,
});

同一客户端的重复调用(或恐慌用户连点 50 次)只会产生一次扣款。构建一个端到端测试:重复发送支付请求,断言只存在一笔扣款;这一个测试就能预防约 30% 的真实生产支付事故。

Webhook 重放:抓住罕见但致命的 Bug

Stripe 允许你在控制台重放任意 Webhook。保存 payment_intent.id,12 小时后点击“Resend”,验证你的处理器是否处理得当——很多真实 Bug 只在这种场景下才会浮现。结合生成的订单 ID 和地址,你就拥有了一个完全可复现的夹具,能精确触发你想要的路径。

CI 集成

使用独立的沙盒密钥,把你的拒付矩阵接入每晚运行的 CI:

- name: Checkout decline matrix
  run: npx playwright test checkout-declines
  env:
    STRIPE_SECRET_KEY: ${{ secrets.STRIPE_TEST_SECRET_KEY }}
    STRIPE_PUBLISHABLE_KEY: ${{ secrets.STRIPE_TEST_PUBLISHABLE_KEY }}
    BILLING_FIXTURES_URL: https://vic999.com/us-address/api/v1/address?count=50

矩阵全绿的那个夜晚,就是可以发布的夜晚。

在支付场景中使用测试数据生成器

  • 用于 AVS 路径的真实账单地址
  • 用于订单确认短信路径的电话号码
  • 用于企业账户 KYB 的 EIN(使用 EIN 生成器
  • 用于个人 KYC 的 SSN 格式夹具(使用保留区段的 SSN 测试格式

总结

测试支付流程并不复杂——但需要全面。处理商的沙盒覆盖了扣款侧;生成的虚拟数据覆盖了表单与 AVS 侧;幂等键模式加上重放驱动的 Webhook 测试,则覆盖了那些最终会演变成 3 万美元退款的隐性失败。先写出上面的拒付矩阵,用 Stripe CLI 接入本地 Webhook,再用地址生成器生成虚拟账单记录。矩阵全绿的第一晚,你的结账流程就不再是黑盒。