在UniApp里做微信支付时,不少人会遇到这种情况:后端接口正常、订单也生成了,但一点支付就报错,要么直接调不起微信,要么弹出"商户参数错误"。折腾半天也不知道哪里不对。这篇文章记录一下我遇到的坑和最终的处理方式。
1. 问题描述
在UniApp开发的安卓App中接入微信支付时,按官方文档配置了微信开放平台的应用信息,后端也返回了预支付订单数据,但调用支付时出现以下现象:
{
"errMsg": "requestPayment:fail 商户参数错误",
"errCode": -1,
"code": -1
}
或者直接提示"调起微信支付失败",没有任何详细错误信息。
2. 排查过程
2.1 检查 uni.requestPayment 参数
先确认 uni.requestPayment 的调用方式,微信支付需要传入 provider 和 orderInfo:
uni.requestPayment({
provider: 'wxpay',
orderInfo: orderInfo, // 后端返回的微信支付订单对象
success: function (res) {
console.log('success:' + JSON.stringify(res));
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
}
});
2.2 核对微信开放平台配置
排查了以下配置项:
- 应用包名是否与 manifest.json 中的包名一致
- 应用签名是否使用正确的 MD5 值(注意不是 SHA1)
- 是否已开通微信支付能力
- 商户号、AppID 是否与后端使用的一致
发现很多问题都出在应用签名上——微信要求的是 MD5 签名,且格式为 32 位小写、无冒号。
3. 解决方案揭秘
核心在于:应用签名必须与微信开放平台中配置的签名完全一致,且必须使用 MD5。
3.1 获取正确签名的步骤
- 使用正式签名的 APK(或当前打包使用的 keystore)获取签名
- 在项目根目录执行:
keytool -list -v -keystore your.keystore -alias your_alias
- 取证书指纹中的 MD5 值,去掉冒号,转成 32 位小写字符串
- 将该值填入微信开放平台「应用详情」中的「应用签名」一栏
3.2 完整实现示例
下面是一个带环境判断和错误处理的微信支付封装:
/**
* 启动微信支付流程
* @param orderInfo 微信支付订单对象(包含 appId、partnerId、prepayId、nonceStr、timeStamp、sign 等)
* @param callbacks 回调函数集合
*/
static startWechatPayment(
orderInfo: object,
callbacks: {
onSuccess?: (result: any) => void;
onFail?: (error: any) => void;
} = {}
): void {
const { onSuccess, onFail } = callbacks;
console.log('微信支付订单信息:', orderInfo);
uni.requestPayment({
provider: 'wxpay',
orderInfo: orderInfo,
success: function(result) {
if (onSuccess) onSuccess(result);
},
fail: function(err) {
console.error('微信支付失败:', err);
if (onFail) onFail(err);
// 用户取消不弹错误提示
if (err.errCode !== -2 && err.errCode !== 'cancel') {
uni.showToast({
title: err.errMsg || '支付失败',
icon: 'none'
});
}
}
});
}