PAYATHON 2026

支付宝沙箱支付登录后点击下一步无反应

支付阿杰

结论

后端能生成支付 URL,说明参数组装和签名流程基本执行成功,但不代表沙箱收银台一定能正常登录。

“点击下一步无反应”和”余额为 0、没有充值按钮”通常是两个不同的问题:

  1. 登录页无响应时,先确认支付 URL 是否指向沙箱网关、登录账号是否为沙箱买家账号,再查看浏览器控制台和网络请求中的报错。
  2. 充值和提现通常不在支付收银台操作。沙箱余额需要到支付宝开放平台的沙箱账号管理页面维护。如果控制台中没有充值入口,原因可能是控制台改版、账号权限限制或沙箱能力调整,修改 NestJS 支付代码无法解决。

如果请求参数正确,更换浏览器和网络后仍无法登录,而且点击按钮时没有发出任何请求,问题很可能出在支付宝沙箱页面。请保留请求时间、app_id、支付 URL 中的关键参数和浏览器报错,并提交给支付宝开放平台技术支持。

先核对沙箱环境

支付请求必须发送到沙箱网关:

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

不要混用以下正式环境信息:

  • 正式应用 app_id
  • 正式应用密钥
  • 正式支付宝买家账号
  • 正式网关 https://openapi.alipay.com/gateway.do

沙箱应用、沙箱密钥和沙箱买家账号必须来自同一个开放平台沙箱环境。沙箱商家账号不能代替沙箱买家账号登录收银台。

可以直接检查生成 URL 的域名:

const payUrl = await createPayUrl();
const parsedUrl = new URL(payUrl);

console.log({
  origin: parsedUrl.origin,
  appId: parsedUrl.searchParams.get('app_id'),
  method: parsedUrl.searchParams.get('method'),
  signType: parsedUrl.searchParams.get('sign_type'),
});

至少应满足以下条件:

origin    = https://openapi-sandbox.dl.alipaydev.com
method    = alipay.trade.page.pay
sign_type = RSA2

不要在日志中输出完整 URL。支付 URL 中含有签名和业务参数,不适合公开或长期保存。

Node.js/NestJS 配置示例

以下示例使用常见的 alipay-sdk 调用方式。不同版本的 SDK 在字段命名上可能略有差异,请以项目实际安装版本的类型定义和文档为准。

import AlipaySdk from 'alipay-sdk';

const alipaySdk = new AlipaySdk({
  appId: process.env.ALIPAY_APP_ID!,
  privateKey: process.env.ALIPAY_PRIVATE_KEY!,
  alipayPublicKey: process.env.ALIPAY_PUBLIC_KEY!,
  gateway: 'https://openapi-sandbox.dl.alipaydev.com/gateway.do',
  signType: 'RSA2',
  charset: 'utf-8',
});

生成电脑网站支付 URL:

import { Injectable } from '@nestjs/common';
import { randomUUID } from 'node:crypto';

@Injectable()
export class AlipayService {
  async createPagePayUrl(): Promise<string> {
    const outTradeNo = randomUUID().replaceAll('-', '');

    return alipaySdk.exec(
      'alipay.trade.page.pay',
      {
        notifyUrl: 'https://example.com/payment/alipay/notify',
        returnUrl: 'https://example.com/payment/alipay/return',
        bizContent: {
          out_trade_no: outTradeNo,
          product_code: 'FAST_INSTANT_TRADE_PAY',
          total_amount: '0.01',
          subject: '沙箱支付测试',
        },
      },
      {
        method: 'GET',
      },
    );
  }
}

需要重点检查:

  • total_amount 应使用字符串形式,例如 '0.01'。
  • 每次测试都应使用唯一的 out_trade_no。
  • product_code 应为 FAST_INSTANT_TRADE_PAY。
  • 不要填反私钥和支付宝公钥。
  • 普通公钥模式不能与证书模式混用。
  • 不要对 SDK 返回的完整 URL 再执行 encodeURIComponent()。
  • 不要截断生成的 URL 后再复制到浏览器。
  • 不要缓存或重复使用支付链接。出现问题时,重新生成一笔订单。

如果使用证书模式,应按当前 SDK 的证书配置方式提供应用公钥证书、支付宝公钥证书和支付宝根证书,不要同时套用普通公钥模式的配置。

排查”下一步”没有反应

1. 确认使用沙箱买家账号

登录收银台时,应输入开放平台沙箱账号页面提供的买家账号和登录密码。

注意区分:

  • 登录密码:用于登录沙箱账号。
  • 支付密码:用于确认支付。
  • 商家账号:用于模拟收款方,不能作为买家完成自己的订单。
  • 正式支付宝账号:不能登录沙箱收银台。

建议手动输入账号和密码,并暂时关闭密码管理器和浏览器自动填充。有时输入框看起来已经有内容,但页面脚本并未收到正常的输入事件。

2. 查看浏览器开发者工具

按 F12 打开开发者工具,分别检查 Console 和 Network。

点击”下一步”后,可以根据具体表现排查:

  • 完全没有网络请求:通常是页面 JavaScript 报错、按钮未通过前端校验、浏览器扩展拦截,或者沙箱页面本身出现异常。
  • 请求被浏览器阻止:检查第三方 Cookie、内容拦截、隐私保护、代理和安全软件。
  • 返回 4xx 或 5xx:记录请求地址、响应内容和发生时间。
  • 页面提示签名或参数错误:重新检查 app_id、密钥、网关和签名模式。
  • 页面长时间处于等待状态:更换网络并关闭代理后重试。

无痕模式不一定更兼容。有些浏览器会在无痕模式下采用更严格的 Cookie 和跨站跟踪限制。可以分别尝试:

  • 使用普通窗口;
  • 更换 Chrome、Edge 等浏览器;
  • 允许当前站点使用 Cookie;
  • 禁用广告拦截和脚本拦截扩展;
  • 关闭代理或 VPN;
  • 清除支付宝沙箱相关的站点数据,然后重新打开页面;
  • 更换网络环境。

3. 检查链接是否被二次处理

一个常见错误是再次编码完整 URL:

// 不推荐:会破坏完整支付 URL 的查询参数结构
return encodeURIComponent(payUrl);

应该直接跳转:

return res.redirect(payUrl);

也可以由接口返回:

return {
  payUrl,
};

前端直接赋值:

window.location.href = response.payUrl;

通过 JSON 返回时,JSON 序列化会自行处理字符串转义,无需额外编码整个 URL。

4. 检查系统时间

签名请求中的时间参数对环境时间有要求。如果开发机或服务器的时间偏差较大,可能导致请求过期或校验失败。

检查服务器的时区和当前时间,并确保系统已启用时间同步。NestJS 中的请求时间应交给 SDK 正常处理,不要自行拼接已经过期的 timestamp。

余额为 0 和没有充值按钮

支付收银台用于选择付款方式和确认支付,不是沙箱账户管理页面。因此,收银台中没有”充值”和”提现”按钮,并不代表支付代码配置有误。

进入支付宝开放平台对应应用的沙箱环境,在沙箱账号或买家账号管理入口中查看是否可以调整沙箱余额。控制台界面和入口名称可能会随时间变化。

如果当前沙箱控制台确实没有余额维护入口,请依次确认:

  1. 当前登录的是创建该沙箱应用的开放平台账号。
  2. 当前打开的是沙箱环境,而不是正式应用页面。
  3. 使用的是沙箱买家账号,而不是沙箱商家账号。
  4. 应用已经开通当前测试所需的支付能力。
  5. 控制台中是否有余额初始化、充值或重置沙箱数据的入口。

如果以上条件都已满足,后台仍然没有相关入口,需要联系支付宝开放平台支持,确认当前沙箱账户的余额维护方式。不要用真实支付宝向沙箱账号转账,正式环境和沙箱环境互不相通。

建议的最小验证流程

可以按以下顺序测试,尽量排除业务代码的干扰:

  1. 使用沙箱 app_id、沙箱密钥和沙箱网关。
  2. 创建一笔金额为 0.01 元的新订单。
  3. 确保 out_trade_no 从未使用过。
  4. 将 SDK 原始返回的 URL 直接粘贴到普通浏览器窗口。
  5. 使用沙箱买家账号和登录密码。
  6. 打开开发者工具,观察点击”下一步”后的请求和错误。
  7. 更换浏览器、网络和沙箱买家账号进行交叉验证。

如果多个浏览器、多个网络和不同沙箱买家账号都遇到相同问题,而且点击按钮时没有发出任何业务请求,继续修改 NestJS 签名代码通常没有意义。此时应整理以下信息并提交给技术支持:

  • 问题发生的准确时间;
  • 沙箱应用 app_id;
  • 接口名称 alipay.trade.page.pay;
  • 浏览器及版本;
  • Console 错误截图;
  • Network 中失败请求的状态码和响应;
  • 脱敏后的请求参数;
  • 支付页面截图。

不要提交应用私钥、完整签名、登录密码或支付密码。

备注:内容仅供参考。