SMARTPAY

QRPH代收代付怎么对接?菲律宾统一二维码标准下的收款出款双向接入

我是在马尼拉做本地商户支付接入的,这几年被问得最多的问题之一就是:QRPH到底能不能做代付?很多文章把QRPH写成"扫码收钱"的科普,只讲代收,从来不提代付这条线,结果技术负责人对接到一半才发现,公司真正要的是"一套系统既能收款又能批量出款",而市面上大多数资料对这件事含糊其辞。这篇文章把QRPH作为国家二维码清算标准、同时承载代收(Collection)和代付(Payout)两个方向的底层逻辑讲清楚,包括API怎么设计、签名怎么做、资金清算路径是什么,以及它和GCash原生代收代付到底有什么本质区别。

QRPH不是哪个钱包的功能,是央行牵头的清算标准

很多人把QRPH当成GCash或某个钱包自带的"扫一扫"功能,这个认知是不准确的。QRPH是菲律宾央行(BSP)推动的国家二维码标准,目的是让不同银行、不同电子货币机构(EMI)的App都能识别同一张二维码完成转账或收款。换句话说,QRPH解决的是"跨机构互通"问题——商户生成一张QRPH码,消费者无论用哪家参与机构的App扫码,都能完成支付,不需要商户为每个钱包单独接一套扫码逻辑。

这个"跨机构互通"的属性,恰恰是QRPH能同时支撑代收和代付的关键:代收时,任意参与机构的用户都能向商户的QRPH码付款;代付时,商户发起的出款也能落地到任意参与机构的收款人账户,而不像某个钱包的原生代收代付系统,只能在自己的钱包账户体系内完成资金归集和下发。

QRPH代收与代付的技术路径:同一条清算轨道的两个方向

代收这条路径的核心流程是:商户在后台或通过API生成QRPH二维码(静态码长期有效,适合固定收银台;动态码绑定单笔订单金额和有效期,适合电商下单场景),消费者打开任意参与机构的App扫码确认支付,资金经QRPH清算网络从付款人账户划转,最终进入商户在收单机构开立的结算账户。商户收到异步回调通知后,再做发货或开通服务的后续动作。这一步和此前我们在QRPH收款申请流程里讲过的开通环节是衔接的——开通完成之后,才谈得上代收代付两个方向的接口调用。

代付的技术路径和代收是镜像关系:商户系统调用代付接口,指定收款人的账户标识(可以是钱包账户,也可以是银行账户,只要对方机构是QRPH配套清算网络的参与方),发起出款请求,资金从商户的结算账户出发,经清算网络路由到收款人账户。常见的业务场景包括佣金结算、退款、工资代发、游戏主播分成等。代付通常分单笔和批量两种调用模式:单笔代付适合退款这种即时性要求高的场景,批量代付适合月度佣金结算、批量工资代发这类定时任务,一次提交一个批次文件,系统按批处理并逐条返回状态。批量这块我们在批量代付方案里拆过工资代发和佣金结算的具体文件格式,这里不重复展开。

需要提醒的是,代付不是"发出去就算完成",它和代收一样有完整的状态机——提交成功只代表指令被接受,真正的终态要等清算结果回调,这也是很多团队接代付踩的第一个坑:把"提交成功"当成"钱到账了"。

一套API怎么同时扛起代收和代付

从接口设计角度看,代收和代付虽然资金方向相反,但可以共用同一套商户认证体系和签名机制,只是在业务字段上区分。典型设计是把代收和代付拆成两个独立的endpoint,比如 /api/v1/collect/create 和 /api/v1/payout/create,两者共享商户号、随机数、时间戳、签名这几个基础字段,区别在于代收需要金额、订单号、回调地址,代付还需要额外的收款人账户信息、收款机构代码、出款用途说明。下面是一个代收创建订单的请求示例(字段为示意,实际以服务商文档为准):

curl -X POST https://apix.example.com/api/v1/collect/create \
  -H "Content-Type: application/json" \
  -d '{
    "merid": "M00123456",
    "tno": "ORDER20261003001",
    "amt": "100.00",
    "qr_type": "dynamic",
    "notify_url": "https://merchant.example.com/notify/collect",
    "sign": "9f3a7c1e2b6d4a0f8c5e3b1a7d9f0c2e"
  }'

这套字段设计的好处是,代收和代付可以共享同一个风控引擎和同一套对账系统——因为它们本质上都是"一次资金在清算网络里的单向移动",只是方向不同、涉及的账户角色不同。两个接口常用字段的区别大致如下:

字段代收接口(Collect)代付接口(Payout)
商户号 merid必填必填
订单号 tno必填,全局唯一必填,全局唯一
金额 amt必填必填
收款人账户标识不需要,由付款人扫码主动发起必填,钱包账号或银行账号+机构代码
码类型 qr_type静态码/动态码二选一不适用
回调地址 notify_url必填必填
签名 sign必填必填

签名验签与异步回调,代收代付共同的生命线

不管是代收还是代付,安全性几乎都压在签名机制和回调验证这两件事上。常见做法是对请求参数按字典序排序后拼接,加上商户密钥,做一次哈希,生成的签名随请求一起提交,服务端用同样的规则重新计算并比对,防止参数被篡改。

代付的回调要比代收复杂一些,因为代付的状态机通常有"受理中、处理中、成功、失败、退回"多种状态,不像代收基本只有"成功、失败"两种终态——这是因为代付涉及跨机构清算,中途可能因为收款账户信息有误、对方机构暂时不可用等原因进入"退回"状态,商户系统要能正确处理这种中间态,不能把"受理成功"直接等同于"钱到账了"。下面是一个用Node.js构造代付请求签名、并处理异步回调验签的示意代码:

const crypto = require('crypto');

// 构造代付请求签名
function buildPayoutSign(params, merchantKey) {
  const sortedKeys = Object.keys(params).sort();
  const raw = sortedKeys.map(k => `${k}=${params[k]}`).join('&') + `&key=${merchantKey}`;
  return crypto.createHash('sha256').update(raw, 'utf8').digest('hex');
}

const payoutParams = {
  merid: 'M00123456',
  tno: 'PAYOUT20261003007',
  amt: '100.00',
  acc_no: '09171234567',
  bank_code: 'GXCHPHM2XXX',
  purpose: 'commission_settlement',
  notify_url: 'https://merchant.example.com/notify/payout'
};

payoutParams.sign = buildPayoutSign(payoutParams, process.env.MERCHANT_KEY);

// 验证异步回调签名,防止伪造通知
function verifyCallback(body, merchantKey) {
  const { sign, ...rest } = body;
  const expected = buildPayoutSign(rest, merchantKey);
  return expected === sign;
}

资金清算路径:谁来结算,钱走的是哪条线

从商户视角看,一次QRPH代收或代付,资金实际上要经过几层角色:商户 → 收单/代付服务商 → QRPH清算网络(由BSP统一调度规则) → 参与机构(银行或EMI钱包) → 最终的付款人或收款人账户。商户能感知到的只是"发起请求—收到回调",但中间的跨机构清算、资金调度,全部压在持牌服务商身上。

这也是为什么选支付服务商之前,要先确认对方到底持不持牌——BSP的OPS(运营支付系统牌照)和EMI(电子货币机构牌照)是菲律宾支付领域两张关键牌照,直接决定了一家机构有没有资格合法地做资金归集、清算和代付这类业务。

结算周期上,代收这一侧常见的是D0(当日)或T+1等不同窗口,具体取决于服务商和清算机构之间的协议;代付这一侧因为涉及出款到外部账户,清算确认的时间点往往比代收更依赖对方机构的处理速度。商户在设计资金计划时,建议把代收到账和代付出账分开排期,不要假设两者的结算窗口是对称的。

QRPH代收代付 vs GCash代收代付,差在哪

把QRPH和GCash原生代收代付放在一起看,本质区别是"标准归属"不同:GCash的原生代收代付是GCash自己的钱包生态内的系统,收款人和付款人理论上都要在GCash体系内完成资金归集和下发(代付目标账户可以路由到其他银行或钱包,但发起端始终锚定在GCash这一个App);QRPH是跨机构的国家标准,任何参与机构的用户都能扫同一张码完成代收,代付的落地账户也不局限于某一个钱包。

做选型判断时,如果商户的客户群高度集中在某一个钱包的重度用户,原生直连在体验上(比如免跳转、App内一步确认)可能更顺;如果商户要覆盖多个钱包、多家银行的用户,QRPH的跨机构覆盖面是它的核心价值。几个主流方案放在一起对比大致如下:

维度QRPHGCash原生代收代付InstaPayPesoNet
标准归属BSP国家二维码标准,跨机构GCash自有生态BSP跨行即时转账清算网络BSP跨行批量清算网络
代收方式静态/动态二维码,任意参与机构可扫GCash App内原生唤醒不直接提供代收二维码,偏重账户间转账不直接提供代收二维码
代付覆盖范围可路由到参与机构的钱包或银行账户发起端锚定GCash,目标账户可路由出去银行与钱包账户均可覆盖,偏实时以银行账户为主,偏批量定时
典型适用场景多钱包多银行覆盖的收银台、跨机构代付GCash重度用户群的收银台即时到账需求强的单笔代付批量工资代发、定时结算

关于QRPH具体的开通条件和材料准备,我们在QRPH API接入与验签流程里有更完整的接口字段拆解。

从接入到首笔代收代付跑通,实际会踩的几个点

理论讲完,落地阶段几个常见的坑值得提前知道:

  • 沙盒环境和生产环境的参与机构覆盖范围可能不完全一致,测试阶段测通的收款人账户,上线后未必能覆盖所有真实用户的钱包或银行;
  • 代付的收款人账户信息(账号、机构代码)如果格式校验不严,容易在清算环节被退回,排错成本比代收高;
  • 回调超时和重试机制要设计好,代付尤其容易因为跨机构清算延迟导致商户系统提前判断"失败"而重复发起,造成重复代付的风险;
  • 代收和代付的对账口径要分开记录,不要混在一张流水表里,否则月底核对现金流会非常痛苦。

开通环节具体要准备什么材料、走哪些审核步骤,可以参考QRPH商户接入Checklist;遇到代收到账异常,可以按QRPH收款没到账排查清单里的步骤定位,是签名问题、回调丢失还是清算延迟。

常见问题

QRPH一个商户号能同时做代收和代付吗?

可以。代收和代付在接口层面是两个独立的endpoint,但共用同一套商户认证体系,商户只需要在服务商后台把两个方向的权限都开通,不需要为代付单独注册一个商户号。

QRPH代付有没有单笔限额?

有,限额由服务商和清算机构的风控规则决定,具体额度以服务商提供的商户协议为准,这里不便给出统一数字——不同商户的资质、交易历史、合规评级都会影响实际可用的限额。

QRPH代付和InstaPay代付是同一回事吗?

不完全是。QRPH本身是二维码标准,代付时资金的清算路由很多场景下会借助InstaPay这类跨行即时转账网络完成最后一段落地,两者是协作关系,不是替代关系。

QRPH代付失败了,钱会不会自动退回商户账户?

正常流程下,代付如果最终状态是失败或退回,资金会退回到发起方账户,但退回有处理时间窗口,商户系统应该以回调通知里的终态为准,而不是提交成功就当作完成。

QRPH动态码和静态码,代收代付场景分别怎么选?

代收场景里,固定收银台适合用静态码,电商下单这种需要绑定具体订单金额和有效期的场景适合用动态码;代付不涉及二维码,是接口直接发起,这个问题主要只影响代收这一侧。

用QRPH做代付,一定要给对方一个QRPH专属账户吗?

不需要。代付的收款人账户可以是参与机构体系下的钱包账户,也可以是银行账户,只要对方机构是QRPH配套清算网络的参与方,不要求收款人专门持有某种"QRPH账户"。

QRPH代收代付的对账,怎么和D0结算对齐?

代收和代付各自会产生独立的交易流水,对账时建议按日切分,把当天的代收入账、代付出账、服务商结算到账三条流水分别核对,再和D0或T+1的结算周期对齐,避免把代付出账误记进代收对账表。

无论是代收还是代付,只要涉及资金归集和跨机构清算,背后的服务商就必须持有BSP认可的OPS或EMI牌照——这不是可选项,而是能不能合法做这件事的前提。

如果你的团队正在评估QRPH代收代付的接入方案,或者已经在对接但卡在签名、回调、清算路径这几个环节,可以直接找我们聊具体场景——Telegram:t.me/LouisSMARTPAY(@LouisSMARTPAY),邮箱:[email protected]。

相关推荐