ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

外贸电商支付测试卡号全攻略:从Luhn算法到3DS验证

外贸电商支付测试卡号全攻略:从Luhn算法到3DS验证 做外贸电商这几年几乎每个项目都逃不过支付环节的联调测试。有一回我接了个独立站项目前端下单流程全跑通了结果在沙盒环境里随便填了一张看起来像真的的卡号网关直接返回card.declined排查了半天才发现问题根本不在代码而是卡号压根不是网关认可的测试卡。那之后我就养成了一个习惯每次开工先把测试卡号体系理清楚分门别类整理成文档团队里谁需要直接抄作业。这篇就把我积累的外贸电商支付测试卡号知识一次性说透。1. 为什么外贸电商离不开一组正确的测试信用卡号很多刚接触跨境支付开发的同事会问一个问题为什么不能直接拿自己的真实信用卡去测答案其实很现实四个字安全、成本。真实卡号一旦进了测试环境就会触碰支付行业的合规红线。PCI DSS支付卡行业数据安全标准对卡数据的存储、传输、展示有严格规定测试环境往往不具备完整的安全审计能力真实卡号出现在日志里就是严重事故。更别提真实卡号每次测试都会产生真实扣款哪怕随后退款也涉及清算手续费和资金占用测个十几单就是几百美金的流水财务那边迟早找你喝茶。测试卡号的价值在于它们走的是支付服务商也就是俗称的收单机构或网关的沙盒环境卡号本身是合法公开的由卡组织或网关官方发布专门用于模拟交易。你拿它去测网关会走完一次完整的支付链路——验卡、鉴权、扣款、回调——但不会产生真实资金流动也不会碰真实银行系统。整条链路里所有参与方都知道这是一场演习但代码里每一个分支、每一个回调状态都是真实的。所以测试卡号不是随便填几个数字就能替代的。它有几个硬性要求必须通过卡组织的校验算法Luhn算法否则前端卡校验那关就过不去必须是支付网关沙盒环境认得的卡BIN卡号前6位否则网关直接拒绝必须能模拟不同业务场景成功、余额不足、风险拦截、需要3DS验证等否则你测不出完整的异常分支搞清楚这三条后面所有操作都不会发怵。2. 测试卡号背后的基础卡BIN、Luhn算法与沙盒环境2.1 卡BIN决定了网关如何识别你的卡卡BINBank Identification Number是卡号的前6位用来标识发卡行和卡组织。比如 Visa 的 BIN 通常以4开头MasterCard 以51到55或2221到2720开头American Express 以34或37开头。网关拿到卡号后第一件事就是解析BIN判断卡组织、卡类型信用卡/借记卡、发卡国家然后路由到对应的清算网络。测试卡号的设计思路就是沿用真实卡组织分配的BIN段但后面的账号部分用一个公开的测试序列。这样网关可以正常识别卡组织又因为沙盒环境专门放行了这些特定卡号所以不会真的向卡组织发起扣款清算。理解这一点对你排查问题特别有用。比如你填了一张4111111111111111如果网关报错说卡组织不被支持那大概率不是卡号的问题而是你的网关账户没有开启对应卡组织的收单权限。这种情况在开通PayPal、Stripe、Adyen等账户时经常遇到需要单独在后台勾选。2.2 Luhn算法卡号能不能过前端校验靠它Luhn算法也叫模10算法是卡组织通用的卡号校验规则用来检查卡号是否合法。很多前端表单在提交前就会用这个算法预校验不符合的直接标红。你手工造一个卡号如果过不了Luhn连第一道校验都过不去。算法本身不复杂从卡号右边第一位开始校验位每隔一位乘以2如果乘完大于9就减9然后把所有数字相加结果必须能被10整除。我通常给新人这样解释把卡号当成一组数字隔一个翻倍一次翻倍后超过9的就拆开相加最后整个和要凑成10的倍数。为了省事大多数项目里都有现成的 JavaScript 或 Python 校验函数不需要自己一遍遍笔算。但要注意一个细节Luhn通过不代表网关会接受它只是最基础的格式校验。网关沙盒还会检查这个卡号是否是它预设的测试卡号查不到对应记录就返回card.declined或invalid_number。所以我一直强调测试卡号一定要从网关官方文档里取不要自己发明。2.3 沙盒模式与测试卡的配合方式沙盒Sandbox是支付服务商提供的模拟环境和真实的线上生产环境Production完全隔离。你在沙盒里创建的商户账户、配置的密钥、接入的API地址都是独立的测试卡号只在这个环境里有效。这里有个特别容易踩的坑沙盒环境和生产环境的API地址不同密钥也不同。很多人代码里环境变量没切干净拿着沙盒的密钥打到生产环境或者反过来结果就是要么扣了真钱、要么沙盒里永远报认证失败。我的建议是验收代码时把环境变量检查作为常规动作确认gateway_base_url、api_key这些配置和当前测试环境一一对应。多花两分钟能省下后面一整天的排查时间。3. 主流支付服务商的测试卡号清单与适用场景先放结论不同的支付服务商测试卡号体系会有细微差别。有的是全行业通用的例如4111111111111111这张卡几乎所有网关都认有的则是自家沙盒专门定制的。下面按我常用的场景逐一列。3.1 Stripe场景覆盖最全的一套测试卡Stripe 的测试卡号体系是我个人认为最好用的因为每个场景对应一张独立卡号想测什么直接查表不用自己琢磨。我做独立站最常用的几张场景卡号备注普通成功支付4242 4242 4242 4242Visa任何金额、任何有效期的将来日期、任意CVC都能成功MasterCard成功支付5555 5555 5555 4444MasterCard同样任意后续信息可用Amex成功支付3782 822463 10005注意Amex卡号格式是15位CVC是4位余额不足被拒绝4000 0000 0000 0002返回card_declined理由是insufficient_funds被风控拦截4000 0000 0000 0069Stripe的风控规则直接拒绝不返回具体银行原因需要3DS验证4000 0000 0000 3220金额小于2000针对日元时是2000円Stripe会要求3D Secure验证始终需要3DS验证4000 0000 0000 9995任何金额都必须走3DS适合专门测试验证流程还有一张特别有用的卡号4000 0025 0000 3155它专门用来模拟银行卡借记卡交易可以测出你的系统有没有正确处理卡类型是借记卡的逻辑。Stripe测试卡的通用规则有效期填一个未来的任意月份和年份都可以CVC填任意三位数Amex除外就能过。如果你想测试卡号过期expired_card填一个已经过去的月份/年份即可。3.2 PayPal / Braintree必须要用沙盒账号配套测试Braintree 是 PayPal 旗下的支付服务商很多外贸B2B站用的是它。Braintree 的测试卡号大部分和 Stripe 通用4111111111111111、5555555555554444在 Braintree 沙盒里同样有效。但有个不同点Braintree 更强调沙盒买家账号的概念推荐你创建一个沙盒买家账号在付款时登录买家账号支付这样可以顺带测 PayPal 钱包支付的完整流程。Braintree 沙盒测试卡号有几个特殊规则金额为0.01和0.02这类极小金额可能触发拒绝响应理由随机用来测网关异常聚合如果你想模拟发卡行拒绝processor_declinedBraintree 提供了专门的卡号4000111111111115想模拟处理器被拒后的重试逻辑可以先用上面这张卡触发拒绝然后等5分钟再用正常卡重试观察你的系统有没有软化失败soft decline重试机制我之前在 Braintree 项目里就靠这些卡号把退款、拒付Chargeback、撤销Void几套流程都覆盖了省了很多事。3.3 Adyen测试卡号按测试套餐走Adyen 的企业级客户用得多它的沙盒有一套按卡组织分类的测试卡清单。常用的是Visa4917610000000000MasterCard5577000000000007Amex378282246310005银联UnionPay6250947000000016Adyen 的特点是有几种测试套餐每种套餐模拟不同国家的清算规则和风险规则。比如欧洲地区用force 3DS套餐可以强制每次交易都走3DS验证适合欧元区的合规测试。你想模拟韩国发的卡、日本发的卡也有对应的BIN段专用测试卡。需要注意Adyen 沙盒里并不是所有测试卡都支持退款部分卡号只在授权Authorization阶段有效退款Refund阶段会报错。我建议你在进入退款测试前先在 Adyen 后台翻一下当前测试环境的支持矩阵省得代码写完了发现跑不通。3.4 VISA和MasterCard官方公布的测试Bin段如果你用的是自建收单或者一些小型网关可能没有上面这些大厂的沙盒支持。这时候可以退到底层用卡组织官方公开的测试卡BIN段。这些BIN段是面向开发者验证卡BIN识别能力的通常配合网关的模拟器使用。Visa 官方常用的测试BIN有411111、401288、422222等段MasterCard 则用511111、555555、222300段。在这些BIN段后面补上满足Luhn算法的账号数字就能得到一张结构完全合规的测试卡号。但我必须提醒一句这些卡号只能用于卡号格式校验、BIN识别这类前端或本地的逻辑测试不要指望它们能在支付网关的沙盒里通过交易。原因前面说了网关沙盒只放行自己预设的卡号列表卡组织官方BIN段对于网关来说仍然可能是未知卡。3.5 一张表看懂什么时候用哪类测试卡我把常见场景和适配卡号做个汇总方便直接对照测试目标推荐卡号服务商适配基础成功交易4111 1111 1111 1111 / 4242 4242 4242 4242Stripe、Braintree、多数网关通用MasterCard成功交易5555 5555 5555 4444Stripe、Braintree3DS验证流程4000 0000 0000 3220 / 4000 0000 0000 9995Stripe其他平台查对应文档余额不足4000 0000 0000 0002Stripe、Braintree被银行拒绝4000 0000 0000 0002 / 4000 0000 0000 0004不同网关有不同卡号触发风控4000 0000 0000 0069仅Stripe卡号格式校验自造Luhn合法卡号前端/本地逻辑响应码递增测试4000 0000 0000 0010 / ...0018Stripe递减卡模拟发卡行多种拒因拿最后一行说明一下Stripe 提供过一组卡号后三位从010到018每张卡对应一种拒付原因码。测的时候可以写一个自动化脚本逐张提交验证你的订单系统对这些错误码的文案、日志、重试处理是否符合预期。4. 从卡号填写到回调验证一次完整的支付测试流程有了卡号怎么把一趟支付测试跑完整这里我拆一下步骤每一步都标注容易出错的地方。4.1 第一步确认网关沙盒配置拿到项目第一件事先确认网关的测试模式配置。以 Stripe 为例你的 API 密钥如果是sk_test_开头说明当前走的是沙盒sk_live_开头则是生产环境。Braintree 的沙盒地址是api.sandbox.braintreegateway.comAdyen 是checkout-test.adyen.com。我习惯在代码里加一段启动日志把当前环境标签清晰地打出来防止环境混淆。日志示例import os gateway_env os.getenv(GATEWAY_ENV, sandbox) if gateway_env sandbox: print(f[PAYMENT] Running against SANDBOX, base: {sandbox_base_url}) else: print(f[PAYMENT] Running against PRODUCTION, base: {prod_base_url})如果连这个都不确认后面所有测试结果都可能无效。4.2 第二步从前端到后端的完整支付提交用测试卡号在测试页面提交一次订单完整链路应包含前端把卡号交给支付组件如Stripe Elements或Braintree Drop-in由组件生成一个payment_method/payment_method_nonce你的服务器不直接接触卡号原文服务器用这个payment_method创建交易create/charge/sale网关返回交易状态succeeded/requires_3ds/declined/requires_capture预授权如果是requires_3ds把返回的client_secret或3ds_url交给前端拉起验证Modal完成3DS验证后再次确认或获取最终状态触发Webhook回调更新订单状态和库存很多新人容易在第二步就出错把卡号直接POST到自己的服务器再转交网关。这样做不但多一次卡数据触碰也不符合支付组件产品的设计意图容易引发安全审计问题。4.3 第三步用3DS测试卡跑一遍完整鉴权以 Stripe 的4000 0000 0000 3220这张卡为例它在沙盒里可以弹出一个模拟的3DS验证页页面上有一个Complete authentication按钮点一下就表示验证成功。如果你想模拟用户中途关闭验证页直接切走即可网关会在几秒后把这个交易标记为requires_3ds超时或失败。这一步测试的重点是你的订单系统能不能在用户完成3DS之前不默认扣款成功、不释放库存我见过有的项目在PaymentIntent创建后、3DS还没验证前就更新订单为已支付导致用户取消验证后订单状态错乱。正确做法是只有收到payment_intent.succeeded事件或状态变成succeeded之后才更新业务库。4.4 第四步验证回调到底准不准Webhook回调是支付流程的最后一环也是最容易出bug的地方。测试时要注意以下几点沙盒环境里可以手动触发回调事件。Stripe的Dashboard在测试支付详情页可以直接重发WebhookBraintree也可以在沙盒后台查看交易详情里重发通知校验回调签名。Stripe用stripe-signature头校验事件是否来自网关Braintree和Adyen也有各自的签名校验机制测试重复回调。你的Webhook处理逻辑必须保证同一条回调处理多次不会产生重复发货或重复退款这叫幂等性。用同一个事件ID去重是基本的实现手段我在 Adyen 项目里踩过一次很尴尬的坑测试环境重发回调后订单状态被重置回待支付因为我的回调处理器没有做事件去重和顺序判断。后来在事件表里加了event_id唯一索引并增加order_state_machine状态流转校验才算彻底解决。4.5 第五步退款与拒付模拟退款测试相对直接在沙盒后台或通过API对已成功的交易发起退款观察返回状态。注意有些卡组织如Amex在部分网关的沙盒中对部分退款支持的粒度不同有的只能全额退有的支持多次部分退。这个在你选型网关时就该确认否则后面业务设计会受限。拒付Chargeback的模拟更头疼。部分网关会在沙盒后台提供一个模拟拒付的入口Stripe是直接发一封通知邮件并不会真实发起卡组织拒付流程。Adyen的沙盒则可以直接在后台的交易详情里触发一个CHARGEBACK状态。测拒付时重点看两条业务链路一是订单自动退款二是风控名单自动拉黑。5. 测试过程中最容易栽的几个坑5.1 填了测试卡号前端校验通过了网关却报错这种问题多半是网关沙盒不认这张卡。前面说了4111111111111111这种通用卡在大多数网关沙盒都有放行但反过来Stripe的4000 0000 0000 0002拿到别的网关去测大概率报card declined。因为各家的沙盒只放行自家文档里列出的卡号。解决办法就是去当前网关的官方文档页搜test card numbers把该平台支持的卡号清单拉下来直接复制文档里的卡号不要自己猜。5.2 3DS页面弹不出来有的项目在沙盒里提交测试卡预期应该弹出3DS验证界面结果直接返回成功了。这时候先看两个地方检查你的 PaymentIntent 创建时是否传了payment_method_types部分网关需要你把card类型显式传进去检查金额。Stripe 的4000 0000 0000 3220在金额小于一定阈值时不会强制3DS这是为了模拟真实场景中的免密小额支付规则。把金额调大通常大于3000再试就会弹出来了还有一点尽量别忽略3DS的验证结果要透过网关API在下一次 PaymentIntent 状态查询或 Webhook 事件里确认不要只依赖前端跳转后的URL参数。5.3 AVS与CVC校验结果被忽略AVS地址验证系统和CVC校验是网关返回给商户的额外风险信号分别表示卡账单地址是否匹配和CVC是否匹配。测试卡号沙盒里通常都能通过但有的网关允许你在沙盒后台配置AVS校验的强度模拟不同国家的账单地址匹配失败场景。我之前在 Braintree 项目里遇到过生产环境客户反馈部分美国用户的交易被风控拒绝排查后发现在沙盒测试时忽略了AVS响应码生产环境里网关把AVS mismatch视为高风险直接拦截。后来在测试阶段就专门建了一批AVS不匹配的沙盒地址做回归才把这块逻辑补齐。5.4 测试卡号的有效期和CVC太随意虽然测试卡对有效期和CVC大多不敏感但你要遵守一条底线有效期不要填过去的日期除非你明确要测过期卡场景。CVC也不要填000部分网关沙盒会把它视为弱校验返回的风险分更高可能触发自己的风控规则。如果你确实要测卡号过期或CVC错误分支先确认有没有专门的测试卡号没有的话再靠填过去日期和特殊CVC来模拟。不要反过来把正常的成功测试都建立在过期错误CVC之上那样测出来的结果不具备参考性。6. 测试完成之后卡号文档怎么沉淀最后讲讲文档沉淀这件事。我每个外贸电商项目都会维护一份TEST_CARDS.md放在代码仓库的docs目录下格式大致如下# Test Cards Gateway: Stripe Environment: sandbox Updated: 2024-06-15 ## 成功场景 - Visa: 4242 4242 4242 4242 - MasterCard: 5555 5555 5555 4444 ## 失败场景 - 余额不足: 4000 0000 0000 0002 - 风控拒绝: 4000 0000 0000 0069 ## 3DS场景 - 小额3DS: 4000 0000 0000 3220 - 强制3DS: 4000 0000 0000 9995 ## 注意事项 - 测试卡只在sandbox环境有效 - 有效期填未来CVC填任意三位 - Amex的CVC是4位这份文档要跟网关账户、沙盒地址、密钥权限放一起管理。新同事入职或者换网关时第一件事就是翻这份文档配合沙盒账号把支付链路跑一遍通常半小时就能把环境摸熟。关于测试卡号有一个我个人的习惯值得分享每次在真实生产环境上线前我会用沙盒卡号把从用户提交订单、到支付成功、再到Webhook回调、最后订单完结整条链路完整跑一遍记录每一步耗时。如果有超过3秒的环节就要排查是不是回调事件处理有阻塞。支付这件事不可能靠填真卡试一试来验证逻辑靠的一定是这些公开测试卡号搭出来的沙盒演练。如果看完这篇你所在的网关平台和文里这些不太一样做法也一样先翻官方文档找test card再按成功、失败、3DS、退款四类场景各选一张卡最后写进文档里沉淀下来。这套方法能在任何一家支付服务商面前都通用。
返回列表