JSAPI支付和小程序支付是否都需要升级?
支付老李
结论
是否需要同时升级,要看这里的”升级”具体涉及什么:
- 如果调整的是服务端下单、签名、证书或回调验签能力,而 JSAPI 支付和小程序支付共用这些能力,通常需要同时检查并升级两个场景。
- 如果调整的是前端支付调起接口,则要分别处理。公众号网页通常使用
WeixinJSBridge或wx.chooseWXPay,小程序使用wx.requestPayment,两者不能直接替换。 - 如果业务只开通并使用了一种支付场景,只需升级实际使用的部分。
因此,不能只根据”JSAPI 支付”和”小程序支付”这两个名称判断是否要同时升级。还要核对升级通知涉及的接口版本、商户号、应用 appid 和具体支付链路。
为什么要分别确认
JSAPI 支付和小程序支付的服务端流程相近,一般包括:
- 服务端创建支付订单。
- 微信支付返回预支付标识。
- 服务端生成调起支付所需的签名参数。
- 前端调起支付。
- 服务端接收并验证支付结果通知。
不过,两者的运行环境并不相同:
- JSAPI 支付运行在微信内网页中,通常使用公众号
appid,用户的支付标识是该appid下的openid。 - 小程序支付运行在小程序中,使用小程序
appid,并通过wx.requestPayment调起支付。 - 同一个用户在不同
appid下的openid通常不同,不能混用。 - 两种场景可以共用商户号和后端代码,但应用配置、授权流程和前端调用方式仍要分别验证。
即使一次后端升级覆盖了大部分公共逻辑,两个支付入口也需要分别测试。
建议的升级步骤
1. 明确升级范围
先核对升级要求涉及哪些内容,例如:
- 下单 API;
- 请求签名算法;
- API 证书或平台证书;
- APIv3 密钥;
- 支付回调解密与验签;
- 前端 JS SDK;
- 商户平台中的应用授权或
appid绑定关系。
如果升级通知中没有明确说明接口名称、版本或具体改动,应先向支付服务商或微信支付技术支持确认,不要只根据支付方式名称直接改造。
2. 盘点两个场景的实际配置
分别记录 JSAPI 支付和小程序支付使用的:
- 商户号
mchid; - 应用
appid; - 下单接口;
- 用户
openid获取方式; - 回调地址;
- 签名和验签实现;
- 前端调起接口。
还要确认两个场景是否共用同一个支付服务。如果共用,公共模块升级后可能同时影响两条链路。
3. 升级服务端公共能力
如果升级涉及支付 API、签名或回调,先改造服务端公共模块,再根据不同支付场景传入正确的 appid、openid 和订单信息。
下面只展示结构示例。接口地址、字段和签名方式应以当前接入版本的官方文档为准:
async function createPayment({ scene, appid, openid, orderNo, amount }) {
if (!["JSAPI", "MINIPROGRAM"].includes(scene)) {
throw new Error("Unsupported payment scene");
}
if (!appid || !openid || !orderNo) {
throw new Error("Missing required payment parameters");
}
const requestBody = {
appid,
mchid: process.env.WECHAT_PAY_MCHID,
description: "订单支付",
out_trade_no: orderNo,
notify_url: process.env.WECHAT_PAY_NOTIFY_URL,
amount: {
total: amount,
currency: "CNY"
},
payer: {
openid
}
};
// 在此调用与当前接入版本匹配的微信支付下单接口。
// 请求签名、证书处理及返回值校验不能省略。
return callWechatPayApi(requestBody);
}
商户私钥、APIv3 密钥和其他商户级敏感信息不能保存在客户端。支付参数应由服务端生成。
4. 分别适配前端调用
小程序支付通常通过 wx.requestPayment 调起:
wx.requestPayment({
timeStamp: payment.timeStamp,
nonceStr: payment.nonceStr,
package: payment.package,
signType: payment.signType,
paySign: payment.paySign,
success() {
// 前端成功仅表示支付调起流程返回成功,
// 最终支付状态仍应由服务端查询或支付通知确认。
},
fail(error) {
console.error("requestPayment failed", error);
}
});
微信内网页使用 WeixinJSBridge 时,可以采用类似方式:
function invokeJsapiPayment(payment) {
WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: payment.appId,
timeStamp: payment.timeStamp,
nonceStr: payment.nonceStr,
package: payment.package,
signType: payment.signType,
paySign: payment.paySign
},
function (result) {
if (result.err_msg === "get_brand_wcpay_request:ok") {
// 不要只依赖该结果更新订单状态,
// 应由服务端确认实际支付结果。
}
}
);
}
字段名和大小写必须与服务端返回值及当前接口要求一致。例如,timeStamp 通常以字符串形式传递,实际仍要以所用接口和 SDK 的文档为准。
5. 分场景回归测试
至少要分别验证:
- JSAPI 支付正常完成、取消和失败;
- 小程序支付正常完成、取消和失败;
- 不同
appid对应的openid是否正确; - 支付回调能否正常验签或解密;
- 重复回调是否具备幂等处理;
- 主动查询结果与本地订单状态是否一致;
- 退款、关单等关联能力是否受到升级影响。
注意事项
- 不要把公众号的
openid用于小程序支付,也不要把小程序的openid用于公众号支付。 - 前端返回支付成功不能作为最终入账依据,应以服务端收到的有效支付通知或主动查询结果为准。
- 如果两个场景共用回调地址,需要根据订单信息识别来源,并保证验签、解密和幂等逻辑一致。
- 升级签名或证书机制时,要同步检查下单、查单、退款、关单和回调处理,不能只修改下单接口。
- 正式切换前应保留回退方案,并分别在公众号和小程序的真实环境中完成验证。
总的来说,共用的服务端支付能力可能只需改造一次,但 JSAPI 支付和小程序支付仍是两个独立入口。是否都要升级,应根据实际升级范围判断,相关配置和回归测试也要分别完成。
备注:内容仅供参考。
