PAYATHON 2026

Node.js alipay-sdk 调用 alipay.trade.app.pay 返回 302

支付老李

结论

这不是支付宝 App 支付的正常响应,也不是需要客户端继续访问的支付跳转。

调用 alipay.trade.app.pay 时,如果收到 HTTP 302,并且 Location 中出现:

http://openapi.alipay.com/none?...

通常是支付宝网关地址配置有误,或者请求路径丢失。最常见的原因是网关只配置了 https://openapi.alipay.com,缺少 /gateway.do。支付宝网关路由请求时得到异常路径 /none,而 alipay-sdk 不会将该重定向视为成功响应,因此抛出:

[AlipaySdk]HTTP 请求错误

遇到这种情况,应先检查 SDK 的网关配置,不要手动跟随 302。

检查支付宝网关地址

生产环境的网关通常应配置为:

https://openapi.alipay.com/gateway.do

沙箱环境使用:

https://openapi-sandbox.dl.alipaydev.com/gateway.do

不要写成:

https://openapi.alipay.com

生产应用和沙箱网关也不能混用。

不同版本的 alipay-sdk 可能使用不同的配置字段,具体应以当前安装版本的类型定义或说明为准。常见配置如下:

import AlipaySdk from 'alipay-sdk';

const alipayClient = new AlipaySdk({
  appId: process.env.ALIPAY_APP_ID,
  privateKey: process.env.ALIPAY_APP_PRIVATE_KEY,
  alipayPublicKey: process.env.ALIPAY_PUBLIC_KEY,
  signType: 'RSA2',
  gateway: 'https://openapi.alipay.com/gateway.do',
  timeout: 10000
});

需要确认最终请求地址确实包含 /gateway.do。如果项目使用了环境变量、配置中心或二次封装,还要检查网关地址是否被覆盖为空值、undefined、none,或者只剩域名。

推荐的调用方式

const orderString = await alipayClient.exec('alipay.trade.app.pay', {
  notifyUrl: 'https://example.com/api/alipay/notify',

  bizContent: {
    outTradeNo: order._id.toString(),
    totalAmount: '99.00',
    subject: `****${product.title}`,
    productCode: 'QUICK_MSECURITY_PAY'
  },

  needEncrypt: false
});

正常情况下,服务端会得到一段用于调起支付宝 App SDK 的已签名订单字符串,并将它原样返回给 Android 或 iOS 客户端。

alipay.trade.app.pay 不是网页支付接口,所以不能把这里的 302 Location 返回给 App,也不能将其作为浏览器支付地址。网页支付应使用对应的 alipay.trade.page.pay 或 alipay.trade.wap.pay 接口。

仍然报错时的排查顺序

1. 确认实际请求地址

查看异常中的 requestUrls 或 SDK 调试日志,确认请求目标是:

https://openapi.alipay.com/gateway.do

如果请求经过反向代理、API 网关或自建 HTTP 客户端,还要确认这些组件没有删除 /gateway.do,也没有将 HTTPS 改成 HTTP。

2. 确认环境完全匹配

以下配置必须属于同一环境:

  • appId
  • 应用私钥
  • 支付宝公钥
  • 支付宝网关
  • 应用授权及签约状态

生产应用不能使用沙箱网关,沙箱应用也不能直接调用生产网关。

3. 检查密钥配置

privateKey 应填写应用私钥,alipayPublicKey 应填写支付宝公钥,不能误填应用公钥。

如果密钥来自环境变量,需要恢复真实换行:

const privateKey = process.env.ALIPAY_APP_PRIVATE_KEY?.replace(/\\n/g, '\n');
const alipayPublicKey = process.env.ALIPAY_PUBLIC_KEY?.replace(/\\n/g, '\n');

密钥或签名错误通常会返回支付宝业务错误码,而不是触发 /none 重定向,但这部分配置仍需检查。

4. 检查业务参数

totalAmount 建议使用字符串,并明确保留两位小数:

totalAmount: '99.00'

不要直接依赖 JavaScript 浮点数计算支付金额。更稳妥的方式是在系统内部以整数分保存金额,提交前再转换为元。

outTradeNo 必须在商户侧保持唯一,subject 不能为空。App 支付建议明确传入:

productCode: 'QUICK_MSECURITY_PAY'

5. 检查 AES 加密配置

如果应用没有启用接口内容加密,可以保留:

needEncrypt: false

如果支付宝开放平台中已启用 AES 加密,则需要按照当前 SDK 的要求配置 AES 密钥并启用加密。AES 配置不一致通常会产生明确的验签或解密错误,因此不是此次 302 的首要排查方向。

不要通过跟随 302 解决

Location 中的 alipay_exterface_invoke_assign_target、invoke_id 等参数是支付宝网关的内部路由信息,业务代码不应解析、保存或重新签名这些参数。

即使 HTTP 客户端支持自动重定向,也不建议以此绕过问题。应修复初始网关地址和 SDK 配置,让请求直接发送到 /gateway.do。如果网关地址正确后仍然收到 302,需要记录 trace_id、invoke_id、请求时间以及脱敏后的实际请求 URL,再通过支付宝开放平台技术支持继续定位。

备注:内容仅供参考。