A公司开放平台和App支付如何付款至B公司商家支付宝?
明确结论
不能直接用 A 公司的支付宝开放平台应用和商户签约关系,将 App 支付订单的收款账户指定为 B 公司的商家支付宝。
App 支付的收款方由以下信息共同确定:
- 接口调用所使用的应用身份;
- 商户签约关系;
- 签名私钥对应的商户或服务商;
- 服务商代调用时使用的商户授权令牌。
alipay.trade.app.pay 没有可供调用方任意填写 B 公司支付宝账号的“收款账户”参数。
如果订单需要由 B 公司直接收款,通常有两种合规方案:
- B 公司自行创建开放平台应用并签约 App 支付,由 A 公司的 App 后端调用 B 公司的支付配置。
- A 公司作为服务商接入支付宝的服务商代调用模式。B 公司完成签约和授权后,A 公司使用 B 公司的授权信息创建订单。
具体采用哪种模式,需要根据双方的业务关系、支付宝当前开放的能力和签约审核结果确定。
为什么不能直接指定 B 公司收款
App 支付不是普通的支付宝账户转账。创建交易时,支付宝会根据调用方身份和签约关系确定收款商户。
常见的 App 支付请求包含:
app_id
method=alipay.trade.app.pay
biz_content
sign
其中,biz_content 通常包含订单号、金额、商品说明等业务信息,但没有可供调用方随意指定商家支付宝登录账号的字段。例如:
{
"out_trade_no": "ORDER_202609090001",
"total_amount": "99.00",
"subject": "商品订单"
}
即使将 B 公司的支付宝账号写入订单扩展字段、商品描述或其他与收款无关的参数,也不会改变实际收款方。
A 公司的应用私钥、支付宝公钥、应用密钥等配置也不能交给 B 公司共用。如果应用身份、商户主体和支付签约关系不一致,可能出现验签失败、权限不足、交易归属错误或结算异常。
方案一:由 B 公司作为直接收款商户
如果 A 公司的 App 只是交易入口,商品或服务实际由 B 公司提供,较为清晰的处理方式是由 B 公司完成支付接入。
大致步骤如下:
- B 公司在支付宝开放平台创建或关联应用。
- B 公司使用自己的商户主体申请并签约 App 支付能力。
- B 公司配置应用公钥、支付宝公钥、异步通知地址等信息。
- A 公司的业务服务器根据订单归属,调用 B 公司对应的支付配置。
- 客户端收到服务端生成的支付参数后,调用支付宝 App SDK。
- 支付宝将异步通知发送到约定地址,服务端验签后更新订单状态。
服务端生成支付订单的 Java 示例:
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
bCompanyAppId,
bCompanyPrivateKey,
"json",
"UTF-8",
alipayPublicKey,
"RSA2"
);
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setNotifyUrl("https://example.com/alipay/notify");
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("ORDER_202609090001");
model.setTotalAmount("99.00");
model.setSubject("商品订单");
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
AlipayTradeAppPayResponse response =
alipayClient.sdkExecute(request);
if (response.isSuccess()) {
String orderString = response.getBody();
// 将 orderString 原样返回给 App,由支付宝 App SDK 发起支付
} else {
// 记录错误码和错误信息,不要向客户端泄露私钥等敏感配置
}
这里的 bCompanyAppId、bCompanyPrivateKey 和相应公钥配置都必须属于 B 公司实际签约使用的应用,不能继续使用 A 公司的商户配置,让 B 公司以此收款。
方案二:A 公司作为服务商代 B 公司调用
如果 A 公司运营的是一个为多个商户提供交易能力的平台,可以考虑服务商模式。通常需要经过以下流程:
- A 公司申请相应的服务商或第三方应用能力。
- B 公司以商户身份完成所需产品的签约。
- B 公司授权 A 公司的第三方应用。
- A 公司保存授权结果中的商户标识和授权令牌。
- 为 B 公司创建订单时,A 公司携带对应的
app_auth_token。 - 支付、查询、退款和关闭交易时,始终使用同一商户的授权上下文。
示意代码如下:
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setNotifyUrl("https://example.com/alipay/notify");
// 仅适用于已开通服务商代调用能力,且 B 公司已经完成有效授权的场景
request.putOtherTextParam("app_auth_token", bCompanyAppAuthToken);
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("B_ORDER_202609090001");
model.setTotalAmount("99.00");
model.setSubject("B公司商品订单");
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
AlipayTradeAppPayResponse response =
alipayClient.sdkExecute(request);
这段代码只展示授权代调用的基本结构。app_auth_token 是否适用于具体接口、B 公司需要签约哪些产品,以及资金如何结算,都应以实际的开放平台应用类型和支付宝当前接口文档为准。仅添加一个 app_auth_token,不能绕过签约、授权或审核要求。
支付完成后的处理
不能只根据 App 客户端的返回值判断支付结果。客户端结果可能被篡改,也可能因网络中断而丢失。
服务端收到异步通知后,至少需要完成以下检查:
- 使用支付宝公钥验证通知签名;
- 检查
app_id是否属于预期应用; - 检查
out_trade_no是否存在,以及该订单是否已处理; - 检查
total_amount是否与本地订单金额一致; - 检查通知中的收款主体或商户信息是否符合订单归属;
- 确认交易状态后再更新订单;
- 对重复通知进行幂等处理。
不要只看到 trade_status 显示成功就立即发货,也不要直接信任客户端提交的支付结果。
不建议采用“先收款再转账”
还有一种容易想到的方式,即由 A 公司先收款,再将资金转给 B 公司。这并不等于让 App 支付直接付给 B 公司,而是两次独立的资金行为:
- 消费者向 A 公司付款;
- A 公司再向 B 公司付款或结算。
这种设计改变了交易和资金链路,可能涉及分账、结算、退款、发票、税务及平台合规等问题。普通转账接口也不能代替商户收款或平台分账能力。
如果业务模式本身就是平台代收后按规则结算,应评估支付宝提供的分账或平台型产品,不应使用个人转账或普通转账接口模拟结算。能否使用相关能力,需要根据商户类型和实际签约结果确认。
注意事项
- 私钥只能保存在服务端,不能放入 App 安装包。
- 不要让客户端自行传入
app_id、商户号或授权令牌来决定收款方。 - A、B 两套支付配置应在服务端按商户维度隔离。
- 订单号应全局唯一,至少要避免 A、B 公司之间出现重复。
- 退款、查询和关单必须使用原交易所属商户的配置或授权上下文。
- B 公司的授权失效后,应停止为其创建新订单,并提示其重新授权。
- 沙箱环境的账号、网关和密钥不能用于生产环境。
- 收款主体应与商品提供方、订单协议和页面展示一致,避免消费者付款时看到的商户名称与实际业务不符。
如果要让消费者付款后,资金直接进入 B 公司的商家支付宝,就需要让 B 公司成为该笔交易对应的签约商户,或者由 B 公司通过支付宝支持的服务商机制正式授权 A 公司代为调用。不能在 A 公司的 App 支付请求中直接填写 B 公司的支付宝账号来实现这一目的。
备注:内容仅供参考。
