
Lyft 自建模拟支付服务商,应对大规模支付测试需求
来源标题:Beyond Test Cards: A Fake Payment Provider for Testing at Scale
Lyft 构建了一个模拟支付服务商,可按需模拟任意支付处理商行为,解决标准测试卡在复杂支付流程中的局限。标准测试卡只能让所有支付动作全部成功或全部失败,而真实场景常出现授权成功、捕获失败等混合结果。Lyft 每年处理数十亿美元支付,该方案用于在大规模下验证支付系统的可靠性与正确性。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
软件开发 金融科技 压力测试 基础设施 超越测试卡:用于大规模测试的模拟支付服务商 Jay Patel 15 分钟阅读· 4 天前
图片由 Google Gemini 生成,2026 作者:Savelii Kolesnikov、Jay Patel、Ivanna Sivak Lyft 每年处理数十亿美元的支付,且这一交易量仍在持续增长。Agentic 编程大幅加速了功能开发,但这也让一个无法仓促应对的环节变得更加关键:确保关键支付系统达到最高标准的可靠性与正确性。 每个支付平台最终都会撞上同一堵墙。单元测试覆盖业务规则,集成测试验证边界,压力测试推动上游极限,但标准测试在请求到达第三方处理商的那一刻就停止了。 处理商的测试卡是为简单流程设计的:一张卡要么通过所有支付操作——从授权到请款再到退款——要么全部失败。而真实的支付流程往往是一步失败、其余步骤成功。 本文将解释测试卡为何失效,以及我们如何构建自己的模拟支付服务商,按需模拟任意处理商行为。与典型的 mock 不同,它可以安全地运行在生产环境中,因此我们能够对支付栈进行压力测试,并在真实乘客之前,先在模拟乘客上试验新的工作流。 与在电商网站或你喜爱的流媒体平台上购买产品不同,Lyft 作为一家网约车公司,在支付方面面临一系列独特的挑战。我们可以在叫车请求时对卡片进行预授权,但最终扣款金额并不总是与最初的预授权金额一致。我们可以使用处理商提供的测试卡;然而,这些卡要么让所有扣款操作(授权、增量授权、请款、直接扣款、退款等)全部成功,要么全部失败。当我们想测试以下场景时,就会撞墙: 上述场景没有一个是奇特的。这些正是我们的重试与兜底代码所针对的路径,而在生产环境之前,它们很难被触发。 这些限制让我们在整个公司层面都付出了代价。没有真实的失败路径,验证我们自己的重试与兜底逻辑就很困难。任何涉及中间支付失败的环节都难以验证。我们的端到端验收测试只能覆盖全部成功或全部失败,永远无法覆盖中间状态。而且,由于测试卡被束缚在处理商的沙箱中,我们的模拟行程压力测试框架不得不完全绕过支付流程。这一点我们稍后会再谈。 上述每一项代价都指向同一个根因:横亘在我们与信心之间的东西,位于处理商的 API 之后,处于我们无法控制的发布周期中。第一反应是请处理商自己来解决——更好的沙箱、更多的测试卡、更多的场景。这无法规模化。我们与多家处理商合作,每家的沙箱覆盖范围各不相同,而沙箱本身并不是为了模拟我们的重试与兜底逻辑而构建的。那样我们将维护的是一张兼容性矩阵,而不是一套测试套件,每家处理商一列。 我们没有继续绕开提供给我们的沙箱,而是决定完全掌控自己的测试环境,构建自己的解决方案——一个专为满足网约车测试复杂需求而设计的模拟支付服务商。 这个一直让我们头疼的限制,最终反而救了我们。与多家处理商合作迫使你把它们全部隐藏在一个接口之后,而接口是我们自己可以实现的东西。 它们是不同的公司,有不同的 API 和各自的怪癖。把这些全部剥离后,它们做的事情其实就那么几件。Token 化。授权。增量授权。请款。扣款。退款。撤销。 因此,添加一个模拟服务商很容易描述。实现这些方法。将部分用户路由到它。完成。 而这确实就是设计的大部分内容。路由器解析出一个服务商并调用它。服务商层之上的任何代码都不知道这个服务商从不打开 socket。因为每个处理商的响应都已被转换为同一种内部表示,模拟服务商不必模仿任何处理商的 API。它只需要产生我们平台已经理解的结果。这条边界是双向的。由于模拟服务商位于服务商接口之后,它永远不会执行与各处理商通信的代码:构建请求、解析响应,以及将它们的错误映射为我们的错误。这些路径仍然依赖处理商的沙箱,而用录制与回放来弥合这一差距是我们接下来的任务。 容易描述并不等于容易构建。将这个理念付诸实践需要解决三个关键问题: ◾ 访问控制:谁被允许访问模拟服务商? ◾ 状态持久化:模拟服务商在多次调用之间如何保存其场景行为? ◾ 场景建模:该测试行为实际上是如何定义和配置的? 与模拟支付服务商相关的一切都留在一个被隔离的测试用户组内。在我们的系统中,他们被称为 simulatedusers。模拟低价值 Token(LVT)由我们生成,并且仅对模拟测试账户接受。 路由规则:模拟服务商仅对模拟用户成为候选 注意图中没有包含什么。路由器没有测试模式,也没有特殊分支。它只有规则,而对于真实乘客,模拟服务商从一开始就不会成为候选。我们各服务中的多重独立检查确保模拟支付方式只能被内部模拟测试账户使用。 一个并非真实的处理商仍然必须记住它打算如何表现。我们现在正在复现哪个场景?下一个操作应该做什么?每个操作返回什么? 这就是状态,而状态必须有地方存放。有三个地方可以放它。 ◾ 一个新服务。对于这个里程碑而言,所需基础设施过多。更糟的是,它会引入一条生产环境并不存在的数据路径。那样我们测试的将是一个并不存在的系统。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。