uniapp 调用支付接口报支付宝 62009 订单参数错误
结论
支付宝 62009 通常表示传给 uni.requestPayment 的订单参数无法被支付宝客户端正确解析或校验。排查时应先看 orderInfo。它必须是服务端按照支付宝 App 支付规则生成并签名的完整订单字符串,不能直接使用业务参数对象或预下单响应对象,也不要在前端对它执行 JSON.stringify、二次 URL 编码或重新拼接。
正确调用方式
uni.requestPayment({
provider: 'alipay',
orderInfo: orderInfo, // 服务端返回的支付宝 App 支付订单字符串
success(res) {
console.log('支付调用成功', res)
},
fail(err) {
console.error('支付调用失败', err)
}
})
调用前可以先检查数据类型:
console.log(typeof orderInfo)
console.log(orderInfo)
正常情况下,typeof orderInfo 应该是 string。字符串一般会包含 app_id、biz_content、method、sign、sign_type、timestamp 等签名参数。
以下写法容易引发 62009:
// 错误:传入整个接口响应对象
orderInfo: response
// 错误:传入业务参数对象
orderInfo: {
out_trade_no: 'ORDER_001',
total_amount: '0.01'
}
// 错误:对已经签名的订单字符串再次序列化
orderInfo: JSON.stringify(response.data.orderInfo)
// 错误:对完整订单字符串再次编码
orderInfo: encodeURIComponent(response.data.orderInfo)
假设后端返回的数据结构是:
{
"code": 0,
"data": {
"orderInfo": "app_id=...&biz_content=...&sign=..."
}
}
前端需要取出其中真正的订单字符串:
const orderInfo = response.data.data.orderInfo
if (typeof orderInfo !== 'string' || !orderInfo.trim()) {
console.error('支付宝 orderInfo 格式错误')
return
}
uni.requestPayment({
provider: 'alipay',
orderInfo,
success(res) {
console.log(res)
},
fail(err) {
console.error(err)
}
})
服务端需要检查的内容
1. 生成 App 支付参数
uni.requestPayment 调起支付宝客户端时,需要接收支付宝 App 支付订单字符串。服务端应通过支付宝对应的 App 支付接口或 SDK 生成参数。
业务参数通常类似:
{
"out_trade_no": "ORDER_202609090001",
"total_amount": "0.01",
"subject": "测试商品",
"product_code": "QUICK_MSECURITY_PAY"
}
具体字段要以当前接入的支付宝 App 支付文档和服务端 SDK 要求为准。网页支付、手机网站支付、小程序支付等产品生成的参数,不能直接作为 App 支付的 orderInfo。
2. 不要只返回 biz_content
下面的内容只是业务参数,并不是完整的已签名订单:
{
"out_trade_no": "ORDER_202609090001",
"total_amount": "0.01",
"subject": "测试商品"
}
前端不能直接用这些参数调起支付宝支付。服务端还需要组装公共参数、完成签名,再把完整结果返回给前端。
3. 核对签名配置
需要逐项确认:
app_id是否属于当前支付宝应用;- 应用私钥是否与支付宝开放平台配置的应用公钥匹配;
- 服务端使用的是公钥模式还是证书模式,配置是否与 SDK 一致;
sign_type是否与实际使用的签名算法一致;- 沙箱环境与正式环境的应用、密钥和网关是否发生混用;
- 修改密钥或证书后,服务端是否仍在读取旧配置。
签名必须由服务端完成。不要把应用私钥放进 uni-app 前端代码,也不要在客户端重新签名。
4. 检查订单字段
常见问题有:
out_trade_no为空、重复或包含不符合要求的字符;total_amount为空、为0、带有货币符号或小数格式错误;subject为空或超过接口允许的长度;product_code缺失,或者不是 App 支付对应的值;biz_content不是合法 JSON;- 时间戳、字符集或参数格式不符合支付宝接口要求。
金额最好由服务端生成明确的两位小数字符串,例如:
const totalAmount = '10.00'
不要让 JavaScript 的浮点计算直接生成 9.999999999 这类结果。
5. 排查编码和传输变化
支付宝订单字符串中的 sign、biz_content 等字段,通常已经按照 SDK 规则编码。订单字符串从服务端传到前端后,应保持原样。
检查中间环节是否执行过以下操作:
decodeURIComponent(orderInfo)
encodeURIComponent(orderInfo)
JSON.stringify(orderInfo)
orderInfo.replace(/\+/g, ' ')
这些操作都可能改变参与签名的内容。尤其要检查 + 是否被转换为空格、百分号编码是否被二次处理,以及字符串两端是否多出引号。
例如,错误数据可能是:
"app_id=...&method=...&sign=..."
如果最外层的双引号已经成为字符串内容的一部分,支付宝也可能无法正确解析。
推荐的排查顺序
- 确认
provider固定为alipay。 - 确认传入的
orderInfo是非空字符串,不是对象或完整的 HTTP 响应。 - 确认该字符串由服务端的支付宝 App 支付 SDK 生成。
- 确认前端没有序列化、解码、编码或修改订单字符串。
- 在服务端记录支付宝 SDK 生成的原始字符串,并与前端收到的值逐字符比较。
- 核对
app_id、密钥或证书、sign_type和支付环境。 - 使用新的商户订单号重新生成订单,避免旧订单状态造成干扰。
- 查看服务端调用支付宝接口时返回的
code、sub_code和sub_msg。这些信息通常比 uni-app 返回的”未知错误”更具体。
比较订单字符串时,不要在正式日志中完整输出 sign、用户信息等敏感内容。可以记录字符串长度、字段名称和脱敏后的值。
容易混淆的成功回调
uni.requestPayment 进入 success 回调,通常只能说明支付宝客户端返回了支付结果,不能代替服务端确认。最终支付状态应以支付宝异步通知或服务端主动查询的结果为准。
服务端处理支付通知时,还需要:
- 验证支付宝通知签名;
- 校验
app_id、商户订单号和支付金额; - 防止重复处理同一条通知;
- 确认交易成功后,再更新业务订单状态。
如果 orderInfo 的类型和内容都正确,但仍然出现 62009,应先在服务端重新生成一笔订单,再结合支付宝服务端返回的 sub_code 和 sub_msg 排查。只看 uni-app 显示的”未知错误”,通常无法确定具体是哪个字段出了问题。
备注:内容仅供参考。
