02-支付消费
消费是 PayLater 的主要用信场景,由外部商户/场景调起,用户用 PayLater 额度完成支付,之后按账单还款。
"消费是 PayLater 的**主要用信场景**:外部商户/场景调起,用户用 PayLater 额度完成支付,并在后续按账单还款。"
积分抵扣采取积分先抵、剩余走 PayLater 的方式;被积分抵掉的部分不产生借据、不收费。
"①是否用积分抵扣(**积分先抵、剩余走 PayLater**,抵掉的部分不产生借据、不收费)"
分期档位由定价引擎按用户与该笔金额实时试算,不是固定的 1/3/6/12,默认选中第一档。
"档位由定价引擎按"这个用户 × 这笔金额"实时试算,不是固定的 1/3/6/12。默认选中第一档。"
每笔 PL 支付都要经过后端决策引擎(反欺诈引擎+刷脸引擎):放行则直接支付,判定可疑则下发挑战、加验一次人脸后再放行。
"**每笔 PL 支付都要过后端决策引擎(反欺诈引擎 + 刷脸引擎)**——放行则直接支付;判定可疑则下发挑战,用户被**加验一次人脸**后再放行。"
支付结果有三种状态:成功、失败、处理中(处理中表示后台仍在处理,稍后以账单为准),页面最多等约 20 秒。
"页面最多等约 20 秒,给出三种结果之一——**成功 / 失败 / 处理中**(后台仍在处理,稍后以账单为准)"
SDK 关闭回宿主时支付结果不随关闭动作回传,商户须靠自己的订单查询确认收款,这是接入契约的一部分。
"**支付结果不随关闭动作回传**,商户靠自己的订单查询确认收款——这是接入契约的一部分"
消费支付的准入对象为已开通 PayLater 的用户;额度是否足够由交易时后台判定,前端不预检。
"已开通 PayLater 的用户;**额度够不够由交易时后台判定**,前端不预检"
每次展示分期试算都实时调用定价引擎,价格与期限均由引擎返回,无本地档位/费率表;常见 1/3/6/12,最长可到 36,随用户资质、金额与时点变化。
"**每次展示试算都实时调用定价引擎,价格与期限均由引擎返回**(PM 确认 2026-07-16,无本地档位/费率表;常见 1/3/6/12,最长可到 36),随用户资质与金额、时点变化"
费用为两费结构:service fee 是首月一次性额外服务费仅首月收,admin fee 是每月收的月费;付款页每档仅展示 admin fee 百分比,service fee 不在付款页单独列示。
"**两费结构(PM 2026-07-16 复核)**:**service fee**(首月一次性额外服务费,仅首月收,如 PL 交易分期首月)+ **admin fee**(月费,每月收)。付款页每档仅展示 admin fee 百分比,**service fee 不在付款页单独列示**"
支付确认流程内不选优惠券;立减(SMP)、免息等优惠在收单侧/营销侧生效,用户在此步感知不到券。
"**支付确认流程内不选券**;立减(SMP)、免息等优惠在收单侧/营销侧生效,用户在这一步感知不到券"
身份验证中 PIN 必验;PL 支付经过反欺诈引擎与刷脸引擎两个决策引擎,判定可疑时加验人脸。
"PIN 必验;**PL 支付过两个决策引擎:反欺诈引擎 + 刷脸引擎**(引擎矩阵见下),判定可疑时加验人脸"
CL(取现 Instant Cash)产品线的决策引擎组合为反欺诈引擎 + 刷脸引擎 + 首借引擎 + 复借引擎。
"| **CL(取现 Instant Cash)** | 反欺诈引擎 + 刷脸引擎 + **首借引擎 + 复借引擎**"
决策引擎为串行过闸,逐个引擎依次通过才放行,任一引擎可下发挑战或拒绝。
"**引擎为串行过闸**(PM 确认 2026-07-16):逐个引擎依次通过才放行,任一引擎可下发挑战或拒绝。"
DBDP 单笔单批不走决策引擎,而是字段强控,直接读用户 riskCode 上的 DBDP 标签硬拦截。
"DBDP 单笔单批**不走引擎,是字段强控**(直接读用户 riskCode 上的 DBDP 标签硬拦截,见 03 篇)"
从首页进入的用户会被提前拦截(冻结/逾期/邮箱未验证给弹窗),但从商户深链直达的用户没有前置检查,会走到输完 PIN 才被后台拒绝。
"从首页进入的用户会被提前拦截(冻结/逾期/邮箱未验证给明确弹窗),但**从商户深链直达的用户没有前置检查**,会一路走到输完 PIN 才被后台拒绝"
通用消费付款由商户带订单调起(scene=PAY_LATER_PAY),流程为拉订单详情→选分期+是否用积分→密码验证→结果页回调商户,分期试算用 coreTransTryLoan(LOAN_CODE=9012),由本仓 H5 承载。
"商户带订单调起(`query.scene=PAY_LATER_PAY`)→ 拉订单详情 → 选分期 + 是否用积分 → 密码验证 → 结果页回调商户。分期试算 `coreTransTryLoan`(LOAN_CODE=9012),落地 `service/payment/Index.vue`"
QRIS 主扫有两种形态:固定金额(动态码,金额随码带出不可改)和用户输入金额(静态码,扫后自输金额)。
"主扫分**两种形态:固定金额(动态码,金额随码带出不可改)/ 用户输入金额(静态码,扫后自输金额)**"
首页 QRIS 入口由 showQrisEnter 控制显隐(isSubprimeUser && cashLimitRate==='0'),非次级用户不显示该入口;显示后在 availableLimit<2000 时置灰。
"首页 QRIS 入口整体由 `showQrisEnter` 控制显隐(`home/Index.vue:697-698` = `isSubprimeUser && cashLimitRate==='0'`),非次级用户根本不显示该入口;显示后在 `availableLimit<2000` 时**置灰**"
QRIS 入口在本仓,但 QRIS 收单/展示页非本仓承载,由原生/外部 H5 承载。
"**QRIS 收单/展示页非本仓承载**,由原生/外部 H5 承载"
Merchant CPM(付款码)、Billpayment(账单代付)、Indomaret 等渠道本前端 SDK 未承载,由原生/外部 H5/后端承载。
"**本前端 SDK 未承载**,由原生/外部 H5/后端承载"
线上 VISA/VDC(虚拟借记卡)发放虚拟借记卡号用于线上/绑卡支付,背后用 PayLater 额度,余额不足时由 VDC Auto top-up 自动补足。
"**线上 VISA / VDC(虚拟借记卡)** | 发放虚拟借记卡号,用于线上/绑卡支付,背后用 PayLater 额度;余额不足时由 VDC Auto top-up 自动补足"
分期可选档位不由前端固定为 1/3/6/12,而是由后端 coreTransTryLoan 返回的 LOAN_LIST 驱动渲染(mock 实际含 18/24/36 等档)。
"分期可选档位不由前端固定为 `1/3/6/12`,而是由后端 `coreTransTryLoan` 返回的 `LOAN_LIST` 驱动渲染"
当 query.scene 等于 PAY_LATER_PAY 时,分发到消费付款入口,落地 service/payment/Index.vue。
"`query.scene === PAY_LATER_PAY`(消费付款入口,落地 `service/payment/Index.vue`)"
scene=ALLO_PAY 被映射到路由名 SERVICE_PAYMENT,但该路由名从未注册,故 ALLO_PAY 会导航到不存在的路由。
"`scene=ALLO_PAY` 在本仓**无已注册落地页**——`App.vue:363-364` 把 ALLO_PAY 映射到路由名 `SERVICE_PAYMENT`,而该路由名从未在任何 router 注册(router 只注册了 `PAY_LATER_SERVICE_PAYMENT`),故 ALLO_PAY 会导航到不存在的路由"
消费付款的试算接口为 coreTransTryLoan,消费场景 LOAN_CODE 取值 9012。
"**试算接口**:`coreTransTryLoan`,消费场景 `LOAN_CODE=9012`"
账户准入校验 checkAccountBeforeWithdrawAndPay:邮箱未验证、blockCode 冻结、逾期等情形会拦截支付/取现。
"**账户准入**:`checkAccountBeforeWithdrawAndPay()`(`utils/view.js:389`)——邮箱未验证 / blockCode 冻结 / 逾期等会拦截"
账户准入校验仅由首页内发起的支付/取现入口调用;商户深链直达 payment/Index.vue 不经过该校验,绕过守卫。
"该校验仅由**首页内发起的支付/取现入口**调用(`home/Home.vue:1275`、`home/HomeV2.vue:898`、`home/AppGuidedTour.vue:169`);商户深链直达的 `payment/Index.vue` 不经过它(`App.vue:366-367` 直接跳 `payment/Index.vue`,绕过守卫)"
付款结果:成功进入 COMMON_RESULT 页并触发外部回调;失败则给出错误提示可重试。
"**结果**:成功 → `COMMON_RESULT` 页 + 外部回调;失败 → 错误提示可重试"
付款页提供积分抵扣开关 use_allo_points,开与关分别走两套分期试算,是否用积分会影响分期试算结果。
"**积分抵扣开关 `use_allo_points`**:付款页提供积分抵扣开关,开/关分别走两套分期试算(`payment/Index.vue:9-12,148-216`)。是否用积分会影响分期试算结果"
付款页提交走组合支付接口 coreTransPayUnionPay,返回三态结果。
"**提交=组合支付 `coreTransPayUnionPay`**:提交走组合支付接口,含三态结果(`Index.vue:230-342`)"
使用 PL 的支付必过支付反欺诈引擎;引擎判定可疑时接口返回 0004(NEED_FACE)加 faceScanAppNo,触发 COMMON_FACE 刷脸验证,通过后回到结果轮询。
"使用 PL 的支付**必过支付反欺诈引擎**,引擎判定可疑时接口返回 `0004`(NEED_FACE)+ `faceScanAppNo` → 触发 `COMMON_FACE` 刷脸验证,通过后续回结果轮询"
组合支付返回 PENDING 时进入轮询,按轮询结果落定为成功或失败。
"**PENDING 轮询**:返回 PENDING 时进入轮询,按轮询结果落定成功/失败"
QRIS 主扫固定金额(动态码)形态:商户按订单生成动态二维码,金额随码带出,用户扫码后不可改金额,直接进支付确认。
"**固定金额**(动态码) | 商户按订单生成动态二维码,金额随码带出,用户扫码后**不可改金额**,直接进支付确认"
QRIS 主扫用户输入金额(静态码)形态:商户张贴静态收款码,用户扫码后自行输入支付金额再确认。
"**用户输入金额**(静态码) | 商户张贴静态收款码,用户扫码后**自行输入支付金额**再确认"
QRIS 主扫两种形态进入支付确认后共用同一套 PL 选项、分期与低价展示逻辑,低价感知各条对两种形态均适用。
"两种形态进入支付确认后共用同一套 PL 选项/分期/低价展示逻辑(下方"低价感知"各条对两种形态均适用)"
第三种交互为被扫(CPM 付款码):用户出示付款码由商户扫。
"另有第三种交互 = **被扫(CPM 付款码)**:用户出示付款码由商户扫"
QRIS 支付限额来自监管规定,对两种主扫形态与被扫一体适用,产品/营销不可配置调整。
"QRIS 支付限额来自**监管规定**,对两种主扫形态与被扫一体适用,产品/营销不可配置调整"
QRIS 单日(Per Day)限额为 Rp 100.000.000。
"**单日(Per Day)** | Rp 100.000.000"
生成 QRIS 码有金额上限、超上限不可生成,其校验来源是监管红线,不是可调的运营参数。
"这解释了「生成 QRIS 码有金额上限、超上限不可生成」(《QRIS被扫流程优化0428》)的校验来源——**监管红线,不是可调的运营参数**"
用户选择钱包支付时判断 PL 是否有低价权益,有则展示 0% interest 标识。
"**0% interest 展示条件**:用户选择钱包支付时,判断 PL 是否有低价权益,**有则展示 0% interest** 标识"
读取试算接口,若用户有 0 利率权益,则在 PL 选项处展示当前 0 利率的剩余可用额度及其适用期数。
"读取试算接口,若用户有 0 利率权益,则在 PL 选项处展示用户当前 **0 利率的剩余可用额度** 及其适用期数"
选择 PL 选项时默认只展示前两个期数选项,点击展开更多才出现全部期数;如果只有两个期数则不展示展开/隐藏按钮。
"**期数默认收起**:选择 PL 选项时,**默认只展示前两个期数选项**,点击"展开更多"时再出现全部期数;如果只有两个期数则不展示展开/隐藏按钮"
limit up 会员在有效期内,展示会员的还款提额比例,取值基于 Market code 第 3~4 位(前端直读整数,如 06=6%)。
"在有效期内 → 展示会员的还款提额比例,取值**基于 Market code 第 3~4 位**(前端直读整数,`06`=6%"
支付结果页弹窗按是否有效会员用对应比例计算后,展示按时还款后可提额的额度金额。
"**支付结果页弹窗**同样按"是否有效会员"用对应比例计算后,展示"按时还款后可提额的额度金额""
用户勾选立减权益支付但最终订单金额超过权益门槛无法使用权益时,以 toast 提示告知用户,5 秒后消失,toast 文案可配置。
"**立减权益超门槛 toast**:用户勾选了立减权益支付,但最终订单金额**超过权益门槛**导致无法使用权益时,以 toast 提示告知用户(**5 秒后消失**),**toast 文案可配置**"
CPM 的 PL 期数选项按从小到大排序。
"**CPM 期数排序**:CPM 的 PL 期数选项按**从小到大**排序(原为从大到小)"
立减权益在 Indomaret/CPM 场景以优惠券(coupon)形式应用,记账上立减部分计入 Payment Discount CPM Expense(如购买 5.4K 商品立减 3.4K,PL 实际放款 2K)。
"立减权益在 Indomaret/CPM 场景以**优惠券(coupon)**形式应用,记账上立减部分计入 `Payment Discount CPM Expense`(如购买 5.4K 商品立减 3.4K,PL 实际放款 2K)"
支用交易在后端按产品线经过不同的决策引擎组合,引擎本体全部在后端,前端只能看到"放行/挑战"结果
"支用交易在后端按产品线过不同的**决策引擎组合**,引擎本体全部在后端,前端只见"放行/挑战"结果"
前端 SDK 本仓的 QRIS 仅为跳转原生的入口按钮,QRIS 支付页低价/免息/会员提额比例展示在本仓无承载页
"本仓 QRIS 仅为跳原生的入口按钮,**整节"QRIS 支付页低价/免息/会员提额比例展示"在本仓无承载页**"
QRIS 支付页对贷款用户做低价感知优化,用户在选择支付方式与分期时即可看到 0% 利率权益与会员提额能力
"QRIS 支付页对贷款用户做了"低价感知"优化,让用户在选择支付方式与分期时即可看到 0% 利率权益与会员提额能力"
CPM / Indomaret 收单链路及其立减权益展示在本前端 SDK 仓中无承载页,由原生/外部 H5/后端承载。
"CPM / Indomaret 收单链路与其立减权益展示在本仓无承载页,由原生/外部 H5/后端承载"
低价权益/立减/0% 免息叠加的展示与计算逻辑在本前端 SDK 仓无承载页,由原生/外部 H5/后端承载。
"低价权益/立减/0% 免息叠加的展示与计算逻辑在本仓无承载页"
低价权益从优惠券形式解耦为额度属性,目的是为用户发放低价权益后对应额度的低价可在全支付场景自动生效,无需逐个支付场景页面改造。
"低价权益从"优惠券形式"解耦为额度属性"
低价权益与贷款利率优惠券可同时使用叠加,利率券基于低价权益的价格计算;如原始利率5%、低价利率3%叠加7折利率券,若支用额度属于低价额度则按3%×0.7=2.1%执行。
"低价权益与贷款利率优惠券可同时使用,且利率券基于低价权益的价格计算"
VDC Auto top-up 相关功能(开通入口、T&C、激活、限额等)在本前端 SDK 内无任何代码,不实现,由原生/外部 H5/后端承载。
"VDC Auto top-up 整节在本仓 SDK 中全仓 grep 零命中(无开通入口、T&C、激活、限额等任何前端代码),由原生/外部 H5/后端承载"
VDC(虚拟借记卡)支付以 Allo Prime 钱包为主资金源、PayLater 额度为辅资金源。
"VDC(虚拟借记卡)支付以 **Allo Prime 钱包为主资金源、PayLater 额度为辅资金源**"
当 Prime 钱包余额不足时,由 PayLater 自动放款到钱包补足差额,使 VDC 交易无摩擦成功。
"当钱包余额不足时,由 PayLater 自动放款到钱包补足差额,使 VDC 交易无摩擦成功"
VDC Auto top-up 激活时先判断是否已开通 PL 账户:未开通则弹窗引导申请 PL;已开通则弹窗展示每日 PL 支付限额上限值。
"激活时判断是否已开通 PL 账户"
已开通 PL 账户时弹窗展示每日 PL 支付限额上限值,默认期数为1期,调用定价引擎试算接口展示该1期(默认传入100K)对应的 admin fee 价格。
"展示每日 PL 支付限额上限值,**默认期数 1 期**,调用定价引擎试算接口展示该 1 期(默认传入 100K)对应的 admin fee 价格"
T&C 页首个勾选框默认选中,第二个勾选框需用户主动勾选,勾选后继续按钮高亮,点击进入验 PIN。
"**首个勾选框默认选中,第二个勾选框需用户主动勾选**,勾选后"继续"按钮高亮"
VDC Auto top-up 入口激活状态取值:从未激活=New、当前激活中=Active、曾激活已关闭=Inactive。
"**从未激活=New / 当前激活中=Active / 曾激活已关闭=Inactive**"
VDC Auto top-up 自动失效机制:以 VDC 最新一次支付时间加90天为失效点,连续90天不再使用 VDC 支付(任何支付含钱包支付)则自动关闭此功能。
"通过 **VDC 最新一次支付时间 + 90 天后自动失效**,即连续 90 天不再使用 VDC 支付(任何支付,包括钱包支付)则自动关闭此功能"
自动放款的 Instant Cash 每日上限默认 2 Mio(Rp3.000.000 为可调上限),且不得超过用户的 VDC limit。
"自动放款的 Instant Cash **每日上限默认 2 Mio(Rp3.000.000 为可调上限)**,且**不得超过用户的 VDC limit**"
Instant Cash 限额默认值规则:VDC limit≥2 Mio 时默认2 Mio;VDC limit<2 Mio 时默认等于 VDC limit。
"VDC limit ≥ 2 Mio → Instant Cash 限额默认 2 Mio;VDC limit < 2 Mio → Instant Cash 限额默认等于 VDC limit"
订单金额小于等于 prime 余额时,直接按现有流程处理,仅扣 prime。
"订单金额 ≤ prime 余额 → 直接按现有流程处理(仅扣 prime)"
订单金额大于 prime 余额时判断是否已激活自动充值:未激活则支付失败并触发 push(PL 用户与非 PL 用户两份模版)。
"订单金额 > prime 余额 → 判断是否已激活自动充值:未激活 → **支付失败**并触发 push"
已激活时检查(订单金额−prime余额)是否大于每日剩余 PL 支付上限:大于则支付失败;否则判断可用额度是否足够,足够则差额部分由 PL 额度支付并触发 PL 支付的 RIPLAY 邮件,不足则支付失败。
"已激活 → 检查(订单金额 − prime 余额)是否大于"每日剩余 PL 支付上限":大于 → 支付失败;否则判断当前可用额度是否足够"
实际调用 PL 消费接口时,先支付到用户 prime 账户,再由 prime 账户支付给外部。
"实际调用 PL 消费接口,先支付到用户 **prime 账户**,再由 prime 账户支付给外部"
VDC 因余额不足支付失败时,若 prime 账户余额不足以撤销该笔 PL 支付订单则按撤销失败处理;余额足够则完成 PL 支付撤销。
"VDC 因余额不足支付失败时,若 prime 账户余额不足以撤销该笔 PL 支付订单,则按撤销失败处理;足够则完成 PL 支付撤销"
深链分发中 ALLO_PAY 映射到 SERVICE_PAYMENT(钱包支付),但该路由未注册,导航必失败。
"`ALLO_PAY` → `SERVICE_PAYMENT`(钱包支付,**路由未注册,导航必失败**"
拉订单接口返回的 totalAmt 缺失时,toast "order error" 并 closeSDK() 退出,以防外部传入金额与后台不一致。
"`totalAmt` 缺失 → toast "order error" → `closeSDK()` 退出(防外部传入金额与后台不一致)"
页面第一步并发拉订单与积分余额(amsCardpointQueryPointBal 返回 avlScoreAmount 可用积分)。
"并发拉订单 + 积分余额 `amsCardpointQueryPointBal`(返回 `avlScoreAmount` 可用积分)"
用积分档试算时 AMOUNT = 订单总额 − 积分,即积分先抵扣,分期只对剩余部分试算。
"用积分档:`AMOUNT = total − 积分`(积分先抵扣,分期只对剩余部分试算)"
use_allo_points 开关默认开启,只切换展示哪套试算结果,不重新请求试算接口。
"`use_allo_points` 开关(默认开)**只切换展示哪套结果,不重新请求**"
选档时后端 LOAN_LIST 按返回顺序渲染,前端不排序,默认选中首档。
"后端 `LOAN_LIST` 按返回顺序渲染(前端不排序),**默认选首档**"
分期档位无免息档特殊标识,0% 只表现为 "0% admin fee" 文本。
"**无免息档特殊标识**——0% 只表现为 "0% admin fee" 文本"
消费支付的 PIN 验密只是门禁,验密 session 不进支付接口;与取现不同,取现的 session 随 coreTransApplyLoan 上送。
"PIN 校验只是门禁,**验密 session 不进支付接口**(与取现不同——取现的 session 随 `coreTransApplyLoan` 上送)"
组合支付 coreTransPayUnionPay 入参 totalAmt 须等于积分、钱包、PL 三者之和。
"`totalAmt`(须 = 积分 + 钱包 + PL 三者之和)"
组合支付 PAYMENT_STATUS 三态:0000 成功进入轮询确认;0004 需刷脸,刷脸成功回轮询、失败进失败页;异常进失败页。
"`0000` 成功 → 轮询确认;`0004` 需刷脸 → `COMMON_FACE`(scene=LOAN),**刷脸成功后续回轮询**、失败进失败页;异常 → 失败页"
轮询 coreTransPayUnionPayQuery 2s 间隔最多 10 次:0000 成功页、0002 失败页、第 10 次仍 0003 进「Processing」处理中页。
"2s 间隔 × 最多 10 次;`0000`→成功页、`0002`→失败页、第 10 次仍 `0003`→「Processing」处理中页"
成功/失败/处理中三个结果页按钮均为无参 closeSDK(),SDK 只关闭返回宿主不回传状态/金额参数,商户须自行查单确认结果。
"成功/失败/处理中三个结果页的按钮都是**无参 `closeSDK()`**——SDK 只关闭返回宿主,不回传任何状态/金额参数,**商户须自行查单确认结果**"
支付失败不可页内重试,失败页唯一按钮回宿主,用户需从商户侧重新发起。
"**失败不可页内重试**:失败页唯一按钮回宿主,用户需从商户侧重新发起"
payment 页无任何前置准入,不校验可用额度/账户状态/单笔限额,唯一门禁是 PIN,额度是否足够完全由后端 coreTransPayUnionPay 判定。
"**payment 页无任何前置准入**:不调 `checkAccountBeforeWithdrawAndPay`、不校验可用额度/账户状态/单笔限额,唯一门禁是 PIN"
消费支付前端流程不含券逻辑,提交无 couponId,立减券/免息券的应用不在本前端流程(SMP 立减在收单侧)。
"**消费支付流程不含券逻辑**:`service/payment/` 目录 grep coupon/免息零业务命中,提交无 couponId——立减券/免息券的应用不在本前端流程(SMP 立减在收单侧)"
「用 PayLater 支付」引导页三个出口,先 checkBeforePay()(含 checkAccount 与额度>0)再 closeSDK({params}) code=103 带目标地址跳转。
"三个出口,先 `checkBeforePay()`(含 checkAccount + 额度>0)再 `closeSDK({params})`(code=103 带目标地址)"
消费交易详情的 Repay 按钮仅在交易 SUCCESSFUL 且有未还期时出现,点击进入提前还款流 EARLY_REPAYMENT。
"**Repay 按钮**仅交易 SUCCESSFUL 且有未还期时出现 → 提前还款流(`EARLY_REPAYMENT`)"
消费交易详情页 query 契约为 type(S/T)、orderId(BIZ_SEQ_NO)、partnerOrderId(MER_BIZ_NO)、receiptId(可选),缺参不请求。
"query 契约 `type(S/T)/orderId(BIZ_SEQ_NO)/partnerOrderId(MER_BIZ_NO)/receiptId(可选)`,缺参不请求"