支付被风控拒绝时 API 返回什么?
两个码,都在订单请求本身上以 HTTP406 返回:
它们是风控决策的直接显现。把两者都当作对该订单的终态——它们是拒绝,不是可重试的传输
失败,也不是你可以等待的审核队列。
D0001 在 Payout、卡和积分充值接口上也存在且含义相同,
所以一个处理程序可以覆盖它;D0002 属于 Payin 接口。
在代码里我如何区分风控拒绝和支付方式拒绝?
取决于你读的是哪个接口,而这正是让人栽跟头的部分。
具体来说,在异步接口上失败以
orderFailedReason 到达,这是一个包含 orderFailedCode 和
orderFailedDescription 的 JSON 值。orderFailedCode 是一个类别,不是你在同步响应上
看到的具体码,而 orderStatus 是普通的已关闭订单状态——没有风控专属的订单状态。
由此得出两条实用规则:
- 收到同步码时记录下来。 它是这一区分唯一可机读的地方。把它持久化到你自己的订单上。
- 不要根据描述字符串做分支。 它是给阅读客服工单的人看的自由文本,不是稳定的接口。
我的支付因为限额被拒绝了。是哪个限额?我能改吗?
限额来自多个地方,并且它们使用与上述风控码不同的码:
其中哪些你可以影响、每日数字如何计算、额度何时释放,见
错误码与限额补充 和
Payin 协议与限额。简短版本:金额范围和上限
来自你账户的设置,所以改变它们是一次沟通,而不是 Portal 设置——有一个例外,见下文。
我可以设置自己的按卡或按用户限制吗?
可以,通过交易限额规则 API,这是唯一由你自己操作的风控相关控制。它只有 API——没有 Portal 页面。端点、请求形态、规则可以基于什么、如何读取或停止规则,见 交易限额规则。 在启用规则之前值得知道的三件事:- 触发的规则会以风控决策拒绝支付——购物者的支付以上述风控码失败,而不是一个独立的 “你的规则触发了”的码。所以在异步接口上你无法把拒绝归因于自己的规则;请自行记录你限制了 什么。
- 规则可以影响已经存在的订单。 风控在购物者实际付款时被咨询,而不是在你创建订单时, 所以在你启用规则之前创建、但在之后付款的订单会按该规则评估。只有已经成功的支付不受影响。
- 它只会增加限制。 没有任何规则方向可以让某张卡或某个用户免于筛查。
3D Secure 何时发生?我能决定吗?
你可以在订单上表达偏好,使用卡信息中的threeDsDecision:
任何其他值都会作为无效卡信息被拒绝。但该字段是偏好,不是开关,有三样东西位于它之上:
- 风控决策。 你的值是风控的一个输入,风控返回实际使用的决策。
- 支付方式能做什么。 决策必须能被支付所走的路径满足。当没有任何路径能满足它时, 订单会失败,而不是静默降级。
- 发卡行。 即使在 3D Secure 支付上,购物者是被挑战还是无交互通过,都是发卡行的 决定,不是我们的,也不是你的。
3DS_FORCE 最好读作”不要跳过这个”,NO_3DS 读作”如果允许就跳过”。
我发了 NO_3DS,购物者仍被要求验证。是我发错了吗?
大概不是。按照上面的顺序,认证步骤仍可能出现,因为风控决策或支付路径要求它。该字段会被
校验,所以一个真正格式错误的值会以无效卡信息错误让请求失败,而不是被忽略——如果你的订单
被接受了,说明该值被理解了。
另一个要排除的情况是作用范围:该字段只对购物者在场的卡、Apple Pay 和 Google Pay
支付有效。在其他任何支付方式上它不起作用。
我可以在订阅续订或其他商户发起的扣款上设置 3D Secure 决策吗?
不可以,这就是为什么它看起来像是被忽略了:该值对商户发起的卡交易会被接受并校验,但不会 应用。订阅续订是商户发起的,所以其上的threeDsDecision 没有效果,也不产生错误。
周期性系列的认证发生在购物者在场的时点——首次支付,或授权设置。见
订阅 和
Tokenization。
挑战如何到达购物者?我自己的前端必须处理什么?
每当需要额外步骤时,订单会以表示需要授权的状态返回,并附带一个描述把购物者送到哪里的orderAction:
如果你使用 Waffo 托管的收银台,这已为你处理——购物者会被带到认证页面并带回。如果你自建
前端,你必须:
- 在创建响应(以及查询)上检测需要授权的状态。
- 解析
orderAction并根据actionType分支。 - 执行整页跳转。不要试图在小框架内进行:认证页面通常拒绝在框架中渲染,购物者会盯着 一个空框。
- 返回时,不要把返回本身当作结果。轮询订单查询,或等待支付通知。
actionData 对需要码、二维码或银行信息的支付方式还能携带什么,见
订单创建字段指南 和
跳转与动作类型。
风控是对每笔交易实时评估的吗?
是。评估发生在支付请求内部,在尝试支付之前,结果立即应用到该订单。没有批处理, 也不会对已经通过的支付进行事后重新评分。 这也解释了一个看起来不一致的模式:购物者的第一笔支付成功、第二笔被拒绝是完全正常的。 每笔支付都在自己的上下文中独立评估——金额、方式、历史、期间发生了什么——所以同一个人 相隔几分钟的两笔支付,结果可能不同。我在 Portal 的哪里能看到被风控拒绝的交易?
按订单查看,而不是作为一个类别:
所以工作流是:在失败分析中找到数量,然后用你自己的记录拉出单个订单。支付列表确实提供的
筛选见
Portal 列表筛选与日期范围。
失败分析告诉我什么?我能下钻到订单吗?
它告诉你多少和为什么,分组为:归因于支付方式侧、客户侧和你这一侧的失败, 每组展开为单个失败描述及其计数和占比。 它不能下钻到订单。面板背后的请求以产品、订阅阶段、国家、支付方式和时间区间为参数—— 从不以订单为参数,响应携带的是计数而不是订单标识。没有任何链接能把失败原因作为筛选带入 支付列表。 面板统计什么、为什么分析数字与列表计数不完全对上,见 Portal 看板与分析。被拒绝的交易会计入我的成功率吗?
会。成功率是成功订单数除以创建订单数,所以每笔创建后被拒绝的订单——无论什么原因, 包括风控——都留在分母中。Portal 在其旁边显示两个更窄的比率:多少已创建订单到达了支付步骤, 以及其中多少成功了。 因为风控拒绝发生在支付步骤,它也落入更窄比率的分母,而不只是总体比率。实际后果: 在创建订单之前预先筛选流量会改善比率;创建之后再拒绝则不会。我能看到自己的拒付率和欺诈报告率吗?
可以,在拒付分析中,它们按卡组织分别报告,而不是一个混合数字,因为各卡组织的定义不同:
注意两个分子都是期间内收到的,而不是”属于期间内所做支付的”——拒付在支付后几个月才
到达,所以该比率是期间度量,不是群组度量。该页面还提供拒付计数和金额、趋势、原因码分布,
以及临近截止时间的案件。数据滞后一天,可选的期间有边界。
每张比率卡片度量什么、报告哪个期间,也见
Portal 看板与分析。针对案件该怎么做见
拒付 和
拒付证据。
欺诈报告和拒付是一回事吗?我能分别查询吗?
它们不是一回事:欺诈报告是发卡行告知卡组织某笔交易是欺诈,它可能到达而之后从未有拒付 跟进——这就是为什么它在上面有自己的比率。 单条欺诈报告可以分别查询,通过 Reported Fraud 列表 API (/api/v1/fraud-report/list,按报告日期、卡组织或单笔订单筛选)。Portal 没有它们的列表
页面——Portal 只在拒付分析中显示汇总。逐字段说明见
原因码与 Reported Fraud。
一笔支付被拒绝了,我认为不该被拒。我能申诉,或把卡加入白名单吗?
两者都没有自助机制——没有申诉端点,没有针对某张卡、某个购物者或某个范围的白名单或 豁免,也没有对应的 Portal 页面。唯一由商户操作的风控控制是限额规则 API,而它只会增加限制。 所以路径是带着订单标识联系你的支持联系人。不要把支付重建为重试循环:对被拒绝的支付工具 反复尝试本身就是一个风控信号。 IP 白名单是另一个功能,确实是自助的——它限制你的哪些服务器可以调用 API,与筛查购物者 无关。见 Portal 自助安全配置。我能在沙箱中测试风控拒绝或 3D Secure 挑战吗?
不能直接测试。沙箱模拟器通过订单金额驱动结果,它能产生的结果是创建、取消和退款路径上的 支付失败、系统错误和未知状态——列于 沙箱模拟器。 其中没有一个会产生风控拒绝码,也没有一个会强制认证挑战。 你可以且应该做的替代方案:- 演练你的处理逻辑,而不是触发条件。 无论哪种原因产生,你处理被拒绝订单和需要授权订单 的代码路径都是一样的,所以模拟一次失败和一次授权步骤,证明你的处理没问题。
- 从第一天起在生产中防御性地处理风控码,因为你无法预演它们。