第三方应用小程序模板如何正确对接支付?
结论
第三方应用的小程序模板不能直接作为支付经营主体,也不能把某个商户申请的 JSAPI 支付能力统一关联到所有模板实例。
每个通过模板生成的小程序,都应以对应的实际经营商户为支付主体。商户需要签约并开通“小程序支付”,再授权第三方应用调用支付接口。服务端通过 app_auth_token 代表该商户创建交易,并在创建订单时传入当前商户小程序的 AppId。小程序端再通过 my.tradePay 唤起支付。
“当面付”生成的二维码只适用于扫码支付,不能替代小程序支付。开发者工具能扫码,不代表这笔订单可以在真机小程序中通过 my.tradePay 完成支付。
为什么会出现这两个错误
“经营主体类型非小程序应用”
这个错误通常说明支付能力申请或关联到了错误的应用类型。常见原因有:
- JSAPI/小程序支付能力申请在第三方应用或模板应用下。
- 关联的支付商户不是当前小程序的实际经营主体。
- 当前小程序 AppId尚未完成支付产品签约或商户关联。
- 服务商代调用时,没有正确携带商户授权信息或实际经营小程序的 AppId。
第三方应用负责模板开发、实例化和接口代调用,但它本身不是商户的小程序支付主体。
“该交易只支持在小程序内支付”
关闭 JSAPI 后改用当面付,通常会通过 alipay.trade.precreate 获得二维码。这类订单属于扫码支付场景。
真机中的 my.tradePay 需要传入适用于小程序支付的交易号。如果传入当面付订单、二维码内容或其他支付场景生成的交易,就会因为支付场景不匹配而提示唤起方式不正确。
正确的配置关系
各方关系应按下面的方式配置:
第三方应用
├─ 负责开发和发布小程序模板
├─ 获得商户应用授权,取得 app_auth_token
└─ 代商户调用 alipay.trade.create
商户小程序实例
├─ 拥有独立的小程序 AppId
├─ 关联实际经营商户
├─ 由该商户开通小程序支付能力
└─ 使用 my.tradePay 唤起支付
模板 AppId、第三方应用 AppId和商户小程序实例 AppId是不同的概念,不能混用。
接入步骤
1. 为每个商户生成或绑定独立的小程序实例
模板上架或实例化后,需要取得当前商户小程序的 AppId,并在业务系统中建立清晰的映射关系:
merchant_id -> mini_app_id -> app_auth_token -> seller_id
创建订单时,应根据当前小程序实例找到对应商户,不能固定使用其他商户的账号。
2. 由实际收款商户开通小程序支付
支付产品应开通在实际收款商户名下,并按平台要求与该商户经营的小程序建立关系。
需要确认以下内容:
- 小程序主体与收款商户之间的关系符合平台审核要求。
- 商户已经完成小程序支付产品签约。
- 商户已经授权第三方应用调用所需的支付接口。
- 授权仍然有效,且
app_auth_token属于当前商户。 - 当前小程序 AppId不是模板 AppId或第三方应用 AppId。
控制台入口和产品名称可能随开放平台版本变化,请以商户后台当前显示的小程序支付签约及授权页面为准。
3. 服务端使用 alipay.trade.create 创建小程序交易
供 my.tradePay 使用的订单不能通过 alipay.trade.precreate 创建。
采用服务商代调用模式时,通常由第三方应用使用自己的应用私钥签名,并在公共请求参数中携带当前商户的 app_auth_token。业务参数还应标明实际经营的小程序 AppId。
下面是协议层面的示意代码,具体参数应按照所用 SDK 的字段模型传递:
const bizContent = {
out_trade_no: "ORDER_202609130001",
total_amount: "0.01",
subject: "测试商品",
buyer_id: buyerUserId,
product_code: "JSAPI_PAY",
// 当前商户实际经营的小程序 AppId
op_app_id: merchantMiniAppId
};
const result = await alipaySdk.exec("alipay.trade.create", {
bizContent,
// 当前收款商户授权第三方应用后获得的令牌
appAuthToken: merchantAppAuthToken
});
const tradeNo = result.tradeNo;
不同语言或 SDK 版本对字段名的转换方式可能不同。例如,协议字段是 app_auth_token、biz_content 和 op_app_id,在 SDK 中可能采用驼峰命名。请以实际使用的 SDK 文档和请求日志为准。
app_auth_token 是公共请求参数,不应放入 biz_content。使用服务商模式时,还要确认请求中的第三方应用 AppId、签名证书或密钥都属于同一个第三方应用。
4. 将支付宝交易号返回给小程序
后端创建交易成功后,只需向小程序返回必要的交易信息:
{
"tradeNO": "202609132200..."
}
不要向小程序返回私钥、app_auth_token 或完整的支付宝签名配置。
5. 小程序端调用 my.tradePay
my.tradePay({
tradeNO: order.tradeNO,
success: (res) => {
console.log("支付结果", res);
// 前端结果仅用于交互展示,最终状态仍需向服务端查询
},
fail: (err) => {
console.error("支付唤起失败", err);
}
});
支付完成后,服务端应通过支付宝异步通知或主动查询接口确认最终交易状态,不能只根据前端回调将订单修改为已支付。
用户身份也必须匹配
如果 alipay.trade.create 要求提供 buyer_id,应通过当前小程序内的用户授权流程取得授权码,再由服务端换取对应的用户标识。
需要避免以下情况:
- 使用其他应用环境中缓存的用户标识。
- 直接把用户授权码当作
buyer_id。 - 在不同小程序 AppId之间复用未经确认可以通用的用户标识。
- 在前端伪造或自行拼接买家身份。
具体使用 buyer_id,还是开放平台当前支持的其他用户标识字段,应以所用接口的最新参数说明为准。
排查时重点核对
真机支付失败时,可以逐项检查:
- 下单接口是否为
alipay.trade.create,而不是alipay.trade.precreate。 product_code是否使用小程序支付要求的值,例如JSAPI_PAY。op_app_id是否为当前商户的小程序实例 AppId。app_auth_token是否属于当前收款商户,而且仍在有效期内。- 收款商户是否已经签约小程序支付。
- 第三方应用是否获得代调用支付接口所需的授权。
tradeNO是否来自本次alipay.trade.create的响应。- 真机运行的小程序 AppId是否与创建交易时声明的小程序 AppId一致。
- 是否误用了其他商户的支付配置、商户号、授权令牌或订单。
- 验证异步通知签名时,是否使用支付宝公钥或对应证书,而不是商户应用公钥。
注意事项
- 模板可以复用代码,但支付签约、商户授权和资金结算关系不能直接复用。
- 多个商户不能共用同一个商户的
app_auth_token。 - 不要在小程序前端保存第三方应用私钥或商户授权令牌。
- 开发者工具对扫码、授权和支付环境的模拟能力有限,最终仍需使用真实的小程序 AppId和真机环境验收。
- 沙箱、开发版、体验版和正式版支持的能力可能不同。支付功能是否可用,应以开放平台对应环境的实际配置为准。
- 如果商户主体与小程序主体不一致,能否关联取决于平台支持的经营关系和审核材料,无法通过代码绕过。
核心原则是:第三方应用代调用,实际商户收款,由实际经营的小程序 AppId限定支付场景,并在真机端通过 my.tradePay 支付。
备注:内容仅供参考。