PAYATHON 2026

客户端接入支付宝支付提示“系统繁忙,请稍候再试”

支付小周

结论

支付宝页面显示“系统繁忙,请稍候再试”时,仅凭这条通用提示和 PID 无法判断具体原因。调用 alipay.wap.create.direct.pay.by.user 时,建议先检查产品权限、请求参数、签名方式、调用流程和商户账号状态。

这是支付宝旧版手机网站支付接口。如果项目刚接入,或者支付宝调整过商户可用产品,需要先确认该 PID 是否仍有相应的签约权限。原生客户端不应自行拼装请求,更不能保存商户私钥。支付请求应由服务端生成,再交给浏览器或 WebView 跳转。

常见原因

1. 未签约或接口权限不匹配

商户账号可能没有开通手机网站支付,或者已签约产品与所调用的接口不一致。PID 正确并不代表它有权调用:

alipay.wap.create.direct.pay.by.user

请在支付宝商家平台中核对:

  • 对应产品是否已经签约并生效;
  • 签约主体、PID 和当前商户账号是否一致;
  • 接口是否已停用、迁移或停止接受新接入;
  • 是否需要改用开放平台当前提供的手机网站支付或 App 支付接口。

如果是原生 App,还要确认业务需要的究竟是 App 支付还是手机网站支付。

2. 请求参数缺失或格式错误

旧版接口通常要求提交完整的公共参数和业务参数。下面这些问题都有可能被前端统一显示为“系统繁忙”:

  • partner 填写错误;
  • seller_id 与签约账号不一致;
  • service 拼写错误;
  • out_trade_no 为空、重复或含有不支持的字符;
  • total_fee 格式不正确;
  • notify_url 或 return_url 不是合法 URL;
  • _input_charset 与实际编码不一致;
  • 缺少 payment_type、subject 等必填参数;
  • 参数签名后又被修改;
  • 不应参与签名的空值参数被加入了签名。

可以先记录服务端最终发出的完整参数集合,但必须隐藏商户密钥、用户隐私和完整支付凭证。

3. 签名计算错误

签名错误是旧版支付宝接口调用失败的常见原因。计算签名时通常需要:

  1. 排除 sign、sign_type;
  2. 排除值为空的参数;
  3. 按参数名进行字典序排序;
  4. 使用未经 URL 编码的原始参数值拼接;
  5. 按签约方式计算签名;
  6. 最后对请求参数进行 URL 编码。

下面的代码只展示旧版 MD5 签名的基本过程。当前商户能否使用这种方式,仍应以实际签约配置为准:

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class AlipayLegacySign {

    public static String sign(Map<String, String> requestParams, String md5Key)
            throws Exception {
        Map<String, String> sorted = new TreeMap<>();

        for (Map.Entry<String, String> entry : requestParams.entrySet()) {
            String name = entry.getKey();
            String value = entry.getValue();

            if ("sign".equals(name) || "sign_type".equals(name)) {
                continue;
            }
            if (value == null || value.isEmpty()) {
                continue;
            }

            sorted.put(name, value);
        }

        String content = sorted.entrySet()
                .stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&"));

        return md5(content + md5Key);
    }

    private static String md5(String value) throws Exception {
        MessageDigest digest = MessageDigest.getInstance("MD5");
        byte[] bytes = digest.digest(value.getBytes(StandardCharsets.UTF_8));

        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b & 0xff));
        }
        return result.toString();
    }
}

还要注意以下几点:

  • MD5 密钥不能保存在客户端;
  • 签名前不要对参数值进行 URL 编码;
  • 签名完成后不能再修改参数;
  • 参数编码必须与 _input_charset 一致;
  • 如果签约配置使用 RSA 或 RSA2,不能直接套用上面的 MD5 示例;
  • 不要混用新版开放平台 SDK 和旧版 PID/Key 接口的签名规则。

建议的排查步骤

第一步:确认实际调用链路

先确认客户端通过什么方式发起支付。正常链路应为:

客户端 → 商户服务端生成支付请求 → 返回支付 URL 或表单 → 浏览器/WebView 跳转支付宝

如果客户端保存了密钥并自行计算签名,应立即改为服务端签名。这既便于记录请求和响应,也能防止密钥泄露。

第二步:保存完整的服务端日志

日志至少应包含:

  • 请求时间;
  • 请求网关地址;
  • service;
  • partner 和 seller_id;
  • out_trade_no;
  • _input_charset;
  • sign_type;
  • 签名前的待签名字符串;
  • 支付宝返回的原始响应或跳转地址;
  • HTTP 状态码;
  • 支付宝返回的错误码、sub_code、sub_msg 或 request ID。

密钥、签名原文、手机号和身份证号等敏感信息必须脱敏。客户端页面上的“系统繁忙”无法提供足够的定位依据,排查时真正有用的是服务端原始响应和支付宝侧请求标识。

第三步:核对参数和签名

针对同一笔请求逐项检查:

  • 参数名是否完全正确;
  • 参数中是否含有多余空格、换行或不可见字符;
  • 签名前后的字符编码是否一致;
  • 金额是否采用合法的十进制格式;
  • out_trade_no 是否唯一;
  • URL 是否被重复编码;
  • 签名参数的排序是否正确;
  • 所用密钥是否属于当前 PID;
  • 测试环境与正式环境的账号、网关和密钥是否发生混用。

第四步:检查商户产品状态

登录对应的商户账号,检查 PID 2088141122714984 所属账号的签约情况和产品状态。PID 只是商户识别信息,不能单独用来判断接口权限。

如果后台找不到 alipay.wap.create.direct.pay.by.user 对应的产品,或者产品已经迁移,应根据开放平台当前文档改用合适的接口。迁移时不能只替换接口名,网关地址、应用身份、签名算法和参数结构通常也要随之调整。

第五步:取得支付宝侧的明确错误信息

如果请求参数、签名和签约状态都没有明显问题,可以向支付宝技术支持提供:

  • PID;
  • 问题发生的准确时间;
  • out_trade_no;
  • 服务端原始响应;
  • 支付宝返回的 request ID 或错误码;
  • 已脱敏的请求参数;
  • 问题能否稳定复现。

是否存在风控拦截、账号状态异常、产品权限问题或短时服务异常,只能通过支付宝侧日志确认。

注意事项

不要反复重试同一个失败请求。重复提交可能让订单状态难以判断,也可能触发限流或风控。再次发起支付前,应先查询订单状态,再按照业务规则决定继续支付,还是生成新的商户订单号。

页面显示“系统繁忙”并不等于支付宝服务出现故障。参数校验失败、签名错误、产品未签约或账号受限,都可能触发同一条通用提示。排查应以服务端原始返回、错误码和支付宝侧请求日志为准。

备注:内容仅供参考。