如何代第三方用户接受在线付款并收取佣金?
明确结论
这类系统应采用“平台支付”或“Marketplace Payments”模式。不要先把全部款项收进网站自有账户,再由网站私下转账给第三方。
应选择具备以下能力的支付服务商:
- 为工作者、商家等第三方创建和管理收款账户;
- 对第三方进行身份认证和合规审核;
- 接收客户付款;
- 从每笔交易中扣除平台佣金;
- 将剩余资金结算给第三方;
- 处理退款、拒付、余额不足和账户限制。
常见方案有 Stripe Connect、Adyen for Platforms、PayPal Commerce Platform、Mangopay,以及在部分地区可用的 Checkout.com、Airwallex 等平台型产品。能否使用这些产品,要看平台主体注册地、第三方用户所在地、交易币种、业务类型和资金流设计。
普通支付网关的收款接口不等于平台支付。普通商户账户通常只能收取平台自己的销售收入,未必允许平台长期代第三方收款和分账。
推荐的资金流
假设客户支付 100.00 元,平台佣金率为 10%:
客户支付: 100.00
平台佣金: 10.00
第三方应得: 90.00
业务流程可以设计为:
第三方入驻并完成身份认证
↓
客户创建订单
↓
支付服务商接受付款
↓
平台确认服务已经交付
↓
扣除佣金并向第三方结算
↓
处理退款、拒付和账务对账
资金最好由持牌支付机构按照平台规则分账和结算。平台数据库只记录订单、佣金和结算状态,不能充当真正的资金账户。
选择哪种支付模式
平台型支付产品一般提供以下几种模式,不同服务商的名称可能不同。
直接向第三方账户收款
付款直接进入第三方的关联账户,平台通过类似 application_fee 的机制收取佣金。
这种模式通常有以下特点:
- 交易与第三方账户的关系较直接;
- 平台通常可以自动收取手续费;
- 第三方往往承担更多退款或拒付责任;
- 适合只撮合交易、不深度控制资金流的平台。
平台收款后自动拆分
付款由平台发起,支付服务商再按规则把资金分配给一个或多个第三方账户。
这种模式适用于以下情况:
- 一个订单需要向多个服务者付款;
- 平台需要统一控制订单和结算时机;
- 需要从总金额中扣除固定金额或一定比例的佣金;
- 需要保留运费、税费或其他平台费用。
“平台发起付款”不代表客户资金可以长期存放在平台自己的银行账户中。实际资金仍应由合规的支付服务商托管和结算。
先收款,满足条件后再转账
部分服务商允许先完成客户付款,等到服务交付、验收或退款期结束后,再向第三方执行 transfer 或 payout。
这种模式与自由职业平台的资金流比较接近,但接入前必须确认:
- 服务商允许延迟多久;
- 等待期间由谁持有资金;
- 这种安排是否构成托管或类似 escrow 的受监管业务;
- 发生退款或拒付时由谁承担损失。
不能只根据接口名称认定某项功能属于“托管”。真正的 escrow 往往涉及额外牌照和法律要求。
可考虑的支付服务商
Stripe Connect
Stripe Connect 是常见的平台支付方案,支持关联账户、身份验证、平台佣金、转账和结算。
它适合需要完整 API、Webhook 和账户体系的平台。常见概念包括:
- Connected Account
- PaymentIntent
application_fee_amount- Transfer
- Payout
- Account Link
Stripe 的国家和地区支持范围、账户类型及责任划分可能发生调整。接入前应根据平台和收款人的注册地,核对官方提供的可用性信息。
Adyen for Platforms
Adyen for Platforms 面向 Marketplace、SaaS 平台和按需服务平台,支持用户入驻、账户审核、资金拆分和结算。
它较常用于交易规模较大或覆盖多个国家和地区的平台。具体的接入门槛、商务条件和产品开放范围,通常需要向其销售或合规团队确认。
PayPal Commerce Platform
PayPal Commerce Platform 支持多方交易、商家入驻和平台佣金。对于已有较多 PayPal 用户的业务,它会比较方便,但各个市场开放的功能并不完全相同。
接入前应确认:
- 第三方商家所在国家或地区是否受支持;
- 是否能在同一订单中收取平台费用;
- 退款、争议和负余额由谁负责;
- 平台是否需要额外审批。
Mangopay
Mangopay 主要服务于 Marketplace 和平台型业务,提供钱包、用户验证、收付款与结算能力,在欧洲市场较为常见。
如果业务涉及欧盟客户、平台钱包或较复杂的资金分配,可以把它列入候选方案。最终是否适用,仍取决于业务所在地、交易类型和合规审核结果。
其他服务商
Checkout.com、Airwallex 等服务商也可能提供平台收款、分账或关联账户产品,但不一定会向所有国家、行业和不同规模的客户开放全部功能。
如果平台主要在中国境内经营,应向具有相应资质的支付机构咨询电商平台分账、二级商户入网等产品,不能直接照搬境外 Marketplace 的账户结构。
基于 Stripe Connect 的示例
下面是一个简化示例。客户支付 100.00 USD,平台收取 10.00 USD,其余款项归关联账户。示例只展示核心结构,生产环境还需要加入身份认证、幂等控制、Webhook 验签和异常处理。
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const paymentIntent = await stripe.paymentIntents.create({
amount: 10000,
currency: "usd",
automatic_payment_methods: {
enabled: true
},
application_fee_amount: 1000,
transfer_data: {
destination: "acct_CONNECTED_ACCOUNT_ID"
},
metadata: {
order_id: "order_12345"
}
}, {
idempotencyKey: "pay_order_12345"
});
console.log(paymentIntent.client_secret);
金额以最小货币单位表示:
10000 cents = 100.00 USD
1000 cents = 10.00 USD
佣金也可以由服务端计算:
function calculateCommission(amount, rateBasisPoints) {
return Math.round(amount * rateBasisPoints / 10000);
}
const amount = 10000;
const commission = calculateCommission(amount, 1000); // 10%
const sellerAmount = amount - commission;
使用基点可以避免直接以浮点小数表示费率:
10000 basis points = 100%
1000 basis points = 10%
250 basis points = 2.5%
佣金必须在服务端计算。不要接受浏览器直接提交的 application_fee_amount、收款账户 ID 或最终支付金额,否则攻击者可能篡改这些参数。
第三方用户入驻
平台不能只保存第三方的银行卡号,再自行向其打款。通常要先通过支付服务商为第三方创建关联账户,并引导对方完成身份认证。
概念性示例如下:
const account = await stripe.accounts.create({
type: "express",
country: "US",
email: "worker@example.com",
capabilities: {
transfers: {
requested: true
}
}
});
const accountLink = await stripe.accountLinks.create({
account: account.id,
refresh_url: "https://example.com/onboarding/refresh",
return_url: "https://example.com/onboarding/complete",
type: "account_onboarding"
});
console.log(accountLink.url);
这里的 country、账户类型和能力要根据实际业务选择,并非所有组合都可用。不能替用户伪造身份资料,也不能绕过支付服务商要求的 KYC 或企业认证流程。
平台数据库可以保存服务商返回的账户标识:
user_id: 789
provider: stripe
connected_account: acct_xxx
onboarding_status: pending
charges_enabled: false
payouts_enabled: false
创建订单前,至少要检查第三方账户是否已经具备必要的收款或结算能力。
必须通过 Webhook 确认支付
浏览器跳转到“支付成功”页面,并不代表款项已经最终支付成功。付款可能仍在处理中,也可能在之后失败。
订单状态应通过经过验签的 Webhook 更新:
app.post(
"/webhooks/stripe",
express.raw({ type: "application/json" }),
async (req, res) => {
let event;
try {
event = stripe.webhooks.constructEvent(
req.body,
req.headers["stripe-signature"],
process.env.STRIPE_WEBHOOK_SECRET
);
} catch {
return res.status(400).send("Invalid signature");
}
if (event.type === "payment_intent.succeeded") {
const paymentIntent = event.data.object;
await markOrderAsPaid({
orderId: paymentIntent.metadata.order_id,
paymentIntentId: paymentIntent.id
});
}
if (event.type === "payment_intent.payment_failed") {
const paymentIntent = event.data.object;
await markOrderAsPaymentFailed({
orderId: paymentIntent.metadata.order_id
});
}
res.sendStatus(200);
}
);
Webhook 可能重复发送,也不一定按照业务预期的顺序到达。处理逻辑必须具备幂等性,例如为 event.id 建立唯一约束,并校验订单的状态转换。
账务系统不能只保存一个余额字段
平台至少要分别记录:
- 客户支付总额;
- 平台佣金;
- 支付处理费;
- 第三方应得金额;
- 已退款金额;
- 已转账金额;
- 已结算金额;
- 拒付及相关费用;
- 币种和汇率;
- 支付服务商的交易标识。
建议使用不能随意覆盖的账务流水,不要反复修改 seller.balance:
entry_type amount
customer_payment +10000
platform_commission -1000
seller_receivable +9000
seller_transfer -9000
所有金额都应以整数形式的最小货币单位保存。每条流水还要关联订单 ID、支付 ID、第三方账户 ID 和幂等键。
以下状态也要明确区分:
created
payment_pending
paid
service_in_progress
eligible_for_transfer
transferred
paid_out
refunded
disputed
cancelled
transferred 只表示资金已经分配到第三方账户。paid_out 才可能表示支付服务商已开始向第三方的银行账户结算。具体含义要以服务商对事件和状态的定义为准。
退款与拒付怎么处理
开发前必须明确退款和拒付由谁负责,否则平台很容易出现负余额。
例如,客户支付 100.00,平台已经收取 10.00 佣金,并向工作者分配 90.00。如果之后发生全额退款,需要确定:
- 平台佣金是否退回;
- 已转给工作者的资金能否撤回;
- 支付处理费是否退还;
- 工作者余额不足时由谁垫付;
- 跨币种退款产生的汇率损失由谁承担。
退款接口通常允许申请退回平台费用。某些资金流还可以同时撤销对应转账,但具体参数取决于所选的支付模式,不能假定所有交易都能自动追回。
拒付比普通退款更复杂。平台即使已经向第三方结算,客户仍可能通过发卡行发起争议。因此需要考虑:
- 设置合理的结算等待期;
- 为高风险用户设置准备金;
- 保存合同、聊天、交付记录和验收凭证;
- 限制新用户的单笔金额和提现速度;
- 监听 dispute、refund、transfer 和 payout 相关事件;
- 在服务协议中明确负余额和追偿规则。
合规问题比支付接口更重要
这类业务涉及 KYC、AML、制裁筛查、税务、消费者保护和资金托管等问题。如果平台自行长期持有客户资金、维护可提现余额,或允许用户之间转账,可能触及支付牌照、电子货币或托管监管要求。
平台上线前应明确:
- 谁是法律意义上的卖方或服务提供者;
- 客户是向平台购买,还是向第三方购买;
- 发票或收据由谁开具;
- 谁负责退款、争议和服务未交付问题;
- 平台能否延迟结算,最长可以延迟多久;
- 是否允许第三方账户出现负余额;
- 平台是否需要收集或申报第三方的税务信息;
- 业务所在地是否允许采用当前的资金流。
如果业务覆盖多个国家或地区,还要分别核对各地规则。支付服务商同意开户,不代表整个商业模式一定符合所有法律和税务要求。
安全与工程注意事项
生产系统还应采取以下措施:
- 使用支付服务商托管的支付页面或安全组件,避免服务器直接接触银行卡信息;
- Secret Key 只存放在服务端;
- 验证每个 Webhook 的签名;
- 为创建支付、退款和转账设置幂等键;
- 不信任前端传来的金额、币种、佣金和账户 ID;
- 在数据库事务中更新订单和账务流水;
- 定期使用服务商的结算报表对账;
- 保存支付和账务审计日志;
- 对提现账户变更、高额交易和异常交易频率加强风控;
- 不在日志中记录完整卡号、身份证件、银行账户等敏感信息;
- 使用异步任务处理通知、对账和可重试操作。
平台接触信用卡信息的范围也会影响其 PCI DSS 责任。使用服务商托管的页面或官方前端组件,通常能减少平台直接接触卡数据的情况,但不会自动免除全部安全义务。
实际选型建议
联系支付服务商前,先整理一份具体的业务说明:
平台主体注册地:
客户所在国家或地区:
第三方所在国家或地区:
预计月交易额:
平均客单价:
支持币种:
佣金计算方式:
是否延迟结算:
最长延迟时间:
是否存在数字钱包余额:
退款责任方:
拒付责任方:
交易涉及的商品或服务:
选型时重点比较:
- 是否支持相关国家、币种和行业;
- 第三方入驻和身份认证体验;
- 分账、延迟转账及多方付款能力;
- 退款与拒付责任;
- 结算周期和最低结算金额;
- 支付费、平台账户费、换汇费和提现费;
- Webhook、报表和对账能力;
- 风险准备金及账户冻结规则;
- API 文档、技术支持和商务准入门槛。
初创 Marketplace 通常可以先评估 Stripe Connect、PayPal Commerce Platform,或当地持牌机构的平台分账产品。交易规模较大、覆盖多个市场或资金结构复杂时,再考虑 Adyen for Platforms 等企业级方案。
基本原则是让具备相应能力的支付服务商负责第三方账户、资金分配和结算,由平台负责订单、佣金规则、风险控制和账务核对。这样可以控制开发成本,也能避免普通网站在无意间变成未经许可的资金托管系统。
备注:内容仅供参考。
