RouteNest 的 Pro 月付页出现了三种结果:荷兰买家用 EUR 打开桌面结账,能看到 iDEAL 和银行卡;美国买家用 USD,只看到银行卡和钱包;同一位美国买家改从受限的 App 内 WebView 打开,钱包按钮又不见了。为什么不同用户看到的支付方式不一样?因为每种方式都要分别满足当前账户、这笔订单、买家设备和页面设置,换掉其中一个条件,结果就可能不同。

排查的目标不是让所有人看到同一排按钮,而是找出目标方式在哪一步消失:服务端从未返回、被本次订单排除、浏览器不能显示、按钮藏进“更多”,还是买家点击以后才失败。结账页面本身还没确定时,先完成托管、嵌入与自建结账的选择。RouteNest 和三位买家都是合成案例,不对应真实商户。

后台已经打开,为什么买家还是看不到

后台把某种支付方式设为启用,只表示它可以进入后续判断。它要出现在当前页面,还得继续满足账户环境、订单条件、买家设备和本次页面设置。

要核对的地方这次真正使用的条件可能在这里被排除通过以后仍不能证明什么
账户与环境服务商、商户主体、账户能力、关联账户、sandbox 或 live、启用配置当前账户未开通、测试与正式配置不同、关联账户没有资格买家的设备一定能显示
这笔订单Product、Price、最终金额、币种、买家国家、一次性付款或订阅地区、币种、金额或付款用途不符合要求钱包和浏览器已经就绪
买家设备Web 或 App、设备、浏览器、钱包、HTTPS、域名、iframe 或 WebView当前设备无法显示按钮,或无法完成外部付款动作买家提交后一定能支付成功
本次页面设置单笔允许或排除、展示规则、排列顺序、渠道健康和明确存在的商户策略原本可用的方式被隐藏、后移或暂时移除消失原因一定与买家风险有关
支付方式依次核对账户环境、订单条件、买家设备和本次页面设置,最后得到当前买家能看到的选项
后台启用只通过了第一步。按钮最终是否出现,还要看这笔订单和买家当前使用的设备。

Stripe 的动态支付方式文档(在新标签页打开)列出的条件包括 Dashboard 设置、账户注册国家、币种、含税费和折扣的最终金额、买家国家、API 能力、单笔排除、展示规则和实验。Connect 使用 Direct Charges 或 on_behalf_of 时,可用方式还可能由关联账户的设置决定。Adyen 的 /paymentMethods 接口(在新标签页打开)会根据金额、国家和币种返回方式,channelallowedPaymentMethodsblockedPaymentMethods 还能继续限制结果。Airwallex 的支付方式目录(在新标签页打开)则同时列出买家地区、商户地区、呈现币种、支持功能和接入方式。三家字段不同,但都不能只靠服务商的全球目录回答当前页面会显示什么。

按钮的位置也会变化。Stripe 当前会按相关性排列合格的支付方式,规则和实验可以改变顺序;Express Checkout 空间不足时,还会把部分按钮放进溢出菜单。方式从首屏移到“更多”不等于被关闭,服务端没返回和前端没放在首屏也不是同一个问题。

先让两次测试只差一个条件

两次测试如果同时换了 Price、税费、优惠、币种、买家国家和浏览器,列表不同也无法定位原因。先复制同一笔测试购买,保持内部购买编号、商户账户、环境、Price、最终金额、币种和付款用途不变,再只改一个待验证条件。查地区就只改服务端采用的买家国家,查钱包就只换设备或浏览器。

地区测试不能只开 VPN。“买家在荷兰”可能来自服务端提交的国家、账单地址、账户资料或服务商自己的信号,IP 只是其中可能的一项。要先确认当前接入究竟把哪个国家值传给服务商、缺值时怎样处理。没有传国家,只能说明这次请求缺少信息,不能直接断言该买家不受支持。

每次测试至少要能还原这些事实:购买编号、sandbox 或 live、商户或关联账户、Price、最终金额和币种、一次性或订阅用途、服务端实际采用的买家国家,以及接口返回了哪些支付方式。浏览器型号与版本、设备、WebView、页面域名和钱包状态用于解释客户端差异。API Secret、完整付款资料、钱包令牌和可帮助绕过风控的细节不能写进日志或支持工单。

地区、币种、金额和付款用途要一起核对

“用户在荷兰”可能指 IP 位于荷兰、账户资料写着荷兰、账单地址在荷兰,也可能只是服务端向支付服务商提交了 countryCode=NL。这些值没有跨服务商通用的优先级。商户系统应明确本次使用的国家值来自哪里,并把采用的值和来源写进诊断记录;不要允许前端任意参数覆盖订单中的国家事实。

商户账户地区决定商户是否有资格开通某种方式,买家地区决定付款人是否在服务范围内,币种和最终金额决定这笔交易是否满足该方式的要求。Stripe 的支付方式支持表(在新标签页打开)把 Business location、Customer country 和 Currencies 分开列出;Adyen 的官方排障说明(在新标签页打开)也明确指出,请求中的 countryCode 会影响本地方式,Klarna 等特定方式还要求买家国家与币种匹配。

金额要使用税费、折扣和数量计算后的最终值,而不是价目表上的起始价。Stripe 当前也用包含税费和折扣的最终金额判断可用方式,不同方式还可能有自己的最低或最高金额。

付款用途同样会直接排除方式。保存付款工具供以后使用、手动捕获、一次性购买和订阅首付,需要的能力并不相同。某种方式能完成一次性付款,不代表它支持当前订阅;Stripe 文档还明确列出,有些方式不支持 setup_future_usage,有些方式不支持 capture_method: manual

钱包按钮还要看设备、浏览器和域名

Apple Pay 和 Google Pay 通过账户与订单检查后,仍要由当前浏览器判断能不能显示。Stripe 对 Express Checkout(在新标签页打开) 的要求包括:支付方式已启用,当前浏览器和币种受支持;在默认行为下,Google Pay 等钱包还会受买家是否已设置钱包影响。Stripe 同时说明,即使把钱包配置为 always,也不能强迫它出现在不支持的平台或币种中。

钱包页面必须使用 HTTPS,实际显示按钮的域名还要在测试环境和正式环境分别注册。www.example.comcheckout.example.com 和测试子域名是不同主机名;iframe 与顶层页面来源不同时,还要按浏览器和服务商要求确认两个域名及 allow="payment"。Stripe 的钱包测试说明(在新标签页打开)还列出浏览器的钱包检测权限、私密窗口、设备兼容性、生物识别和地区条件。

App 内 WebView 也不能按普通浏览器推断。Stripe 当前对不同钱包给出的 WebView 支持并不相同:有些方式完全不支持,有些方式要求宿主 App 提供 Payment Request 能力,还有些方式不能依赖弹窗。如果 SDK 提供可用方式事件,就以事件返回的结果为准;当前环境不满足条件,就显示银行卡或其他可用选项,不能自己画一个无法完成付款的钱包按钮。

接口里出现 card,也不等于页面必须同时显示 Apple Pay 和 Google Pay。钱包可以建立在卡支付能力之上,再由 SDK 根据设备、浏览器和钱包状态决定是否显示。服务端允许卡支付与客户端能显示哪个钱包,要分开检查。

按钮换了顺序,不等于支付方式消失

某种方式具备基本使用条件,只回答“这笔交易能不能尝试”。页面还可能按金额、买家位置、商户规则、实验或渠道健康调整顺序,甚至暂时隐藏它。买家已经点下支付后,服务商或发卡行仍可能要求认证或拒绝付款。这三种情况分别发生在显示前、排版时和提交后,不能只看一张截图就归因于风险或渠道故障。

如果商户自己的系统会在展示前根据地区政策、历史失败或渠道健康调整按钮,应保存规则版本、采用的输入、调整前后的方式和不暴露内部阈值的原因码。买家只需要知道下一步能做什么,例如选择另一种当前可用的方式或联系支持;不应看到内部阈值、命中特征和可用于规避控制的细节。

方式已经出现,提交以后才收到风险、认证或渠道拒绝,就应沿原 Payment 和 Attempt 查看统一失败类别、非敏感服务商引用、Webhook 或查单结果。把提交失败倒推成“这个按钮本来就不该显示”,可能让系统错误地隐藏一个对其他买家仍然可用的方式。

为什么三位买家看到的支付方式不一样

RouteNest 使用嵌入式结账销售 Pro 月付。三组数据都是合成推演,只说明条件怎样改变页面,不代表任何真实账户已开通这些方式。

本次购买为什么留下这些方式页面显示这次结果能说明什么
荷兰买家,NL,EUR,桌面 Web,订阅首付;当前账户和流程已开通 iDEAL账户、买家地区、EUR 和付款用途都满足要求,浏览器也能完成银行跳转iDEAL 与银行卡;钱包是否出现另看设备iDEAL 对这组条件可用,不代表 USD、其他国家或另一种订阅流程也可用
美国买家,US,USD,受支持的普通浏览器,钱包已在该设备中设置并通过可用性检查iDEAL 因买家地区或币种退出,银行卡和当前钱包通过检查银行卡和钱包,顺序可能变化列表不同来自这笔订单和设备,不是荷兰买家拥有特殊账户权限
同一位美国买家、同一笔 USD 购买,改用缺少所需能力的 App 内 WebView服务端返回的方式没有变化,钱包在当前 WebView 中不可用银行卡仍可输入,钱包按钮不出现应修复宿主能力或改用受支持浏览器,不能改国家或强制显示按钮

比较第二组和第三组时,只换客户端;商户账户、Product、Price、金额、币种和付款用途都保持不变。若第二组同时改成一次性购买,第三组又换到 live 账户,就无法判断差异来自用途、环境还是 WebView。多截几张页面图不能弥补条件混在一起。

先确认它在哪一步消失

依次确认服务端是否返回目标方式、本次设置是否保留、客户端能否显示、按钮是否藏在更多菜单,以及提交后是否失败
先找出按钮在哪一步消失,再查看那一步的输入和结果;不要只凭买家一句“没有这个按钮”猜渠道故障。
买家看到什么先查哪里能定位问题的信息处理方式
服务端从未返回目标方式账户、环境和这笔订单实际账户、sandbox 或 live、最终金额与币种、买家国家、付款用途、启用配置和可取得的排除原因修正错误输入或配置后,用同一购买编号重新请求
服务端原本返回,经过商户设置后消失或排到后面展示规则、路由或渠道健康设置规则与配置版本、调整前后的方式、通用原因码和发生时间只有证据证明误配时才改设置;正常排除就给买家其他方式
服务端返回了目标方式,前端却没显示SDK、浏览器、域名或钱包环境SDK 的可用方式事件、浏览器版本、当前域名、HTTPS、钱包和 WebView 能力修复域名注册或客户端环境;仍不支持时不要强制显示
按钮藏在“更多”或折叠区域页面布局与动态排序容器宽度、溢出菜单、折叠状态、遮挡和键盘焦点让入口可发现、可聚焦;不要把位置变化报成不可用
按钮能选,提交后失败付款执行、认证或风险处理原 Payment/Attempt、统一失败类别、非敏感渠道引用、Webhook 或查单结果继续处理原付款,不要因为提交失败而改写该方式的显示条件
页面没有任何付款方式账户、订单或商户设置每一步还剩多少方式、第一次变成空列表的位置、配置版本和已知原因暂停创建付款,至少恢复一种完整可用的方式后再开放结账

“当前交易没有 iDEAL”“页面没有 iDEAL 按钮”和“点了 iDEAL 但没有付成”是三种问题。第一种先查服务端返回,第二种查浏览器与布局,第三种查原付款。支持工单应保留买家的原始现象,不要先改写成笼统的“渠道不可用”。

支付服务商不一定给出每个被排除方式的原因。有些接口只返回当前能用的方式,此时“响应里没有 iDEAL”只是已知现象,不是已经找到根因。商户自己的过滤可以记录输入、方式在哪一步减少和稳定原因码;服务商内部过滤则先保留请求标识与非敏感条件,再用单变量测试、官方排障工具或支持渠道确认。仍拿不到依据时,应记录“服务商未返回,原因未确认”,不能根据 IP、画像或一次失败编造解释。Stripe 提供的缺失支付方式排障工具(在新标签页打开)就是这类入口。

换一种方式前,先确认上一笔有没有开始

买家还没有创建付款、没有跳去银行,也没有向服务商提交请求时,目标方式如果不符合条件,可以直接显示其他可用选项。Product、Price、应付金额和购买编号继续沿用,买家只是换一种付款工具,不需要另建订单。

一旦已经创建 Payment、发起外部跳转或把请求交给服务商,超时、断连和回跳丢失都可能让结果暂时未知。此时换一家服务商重新扣款,并不能取消第一笔动作。先用原 Payment、幂等键、Webhook 或服务端查单确认它最终成功、失败还是仍在处理中。只有确认原付款失败、取消或没有产生扣款,且当前还有其他可用方式时,才能为同一购买编号创建新的 Attempt。

页面文案也要对应真实状态。“此方式当前不可用,可以改用银行卡”适合付款尚未开始或已经明确失败;“正在确认上一笔付款,请勿重复支付”适合结果未知。把两种情况都写成“请重试”,会把一次界面恢复变成重复扣款风险。

哪些变化会让原来的结果失效

一次测试通过,只能说明当时那组条件成立。更换商户主体或关联账户会改变账户资格;从 sandbox 切到 live 会改变启用项、域名注册和密钥;新 Price 会改变币种、金额与订阅用途;手动捕获、保存付款工具供后续使用或新的促销会改变所需能力;换域名、iframe、SDK、浏览器或 WebView 会改变钱包显示;服务商支持范围、展示规则和渠道状态也会继续变化。

发生这些变化后,保留一笔条件明确的测试购买,按顺序确认:服务端返回了什么,本次设置删掉或移动了什么,SDK 在当前浏览器报告什么,买家提交后又产生了哪一个付款对象。荷兰 EUR 显示 iDEAL、美国浏览器显示钱包、受限 WebView 不显示钱包,只要都能由各自条件解释,就不需要强行改成同一列表。只有相同条件重复测试仍得到无法解释的不同结果,才继续查配置传播、SDK 回归或运行故障。

能解释每位买家为什么看到这些支付方式后,下一步才是把这套配置从沙箱切到正式环境:重新核对 live 密钥、Price、Webhook、域名和返回地址,并使用服务商允许的方式完成第一笔真实订单。需要长期设计“向买家显示哪些方式”和“选中后交给哪家服务商”时,再把支付方式发现与渠道路由拆成两个独立决定。