PAYATHON 2026

支付宝 Android SDK Demo 返回“系统繁忙”及授权参数获取问题

支付阿杰

排查结论

系统繁忙,请稍后再试通常是支付宝客户端显示的兜底提示,并不代表支付宝服务确实繁忙。结合当前配置,问题更可能出在沙箱环境、应用身份或订单签名没有完全匹配。

可以按以下几项逐一检查。

1. 沙箱钱包与包可见性配置

沙箱测试需要安装并使用支付宝开放平台提供的沙箱版支付宝,常见包名是:

com.eg.android.AlipayGphoneRC

正式版支付宝的包名通常是:

com.eg.android.AlipayGphone

如果设备上只有正式版支付宝,沙箱订单通常无法正常完成。香港版钱包和大陆支付宝沙箱支付不属于同一条测试链路,一般不用加入。

Android 11 及以上版本可以在 AndroidManifest.xml 的 <manifest> 节点下声明包可见性:

<queries>
    <package android:name="com.eg.android.AlipayGphoneRC" />
    <package android:name="com.eg.android.AlipayGphone" />
</queries>

<queries> 只能解决应用查询和钱包拉起问题,不能决定订单使用沙箱还是正式环境。实际环境由服务端网关、应用配置、签名密钥和 SDK 环境设置共同决定。

2. APPID、网关和密钥必须属于同一个沙箱应用

以下信息必须来自同一个支付宝沙箱应用:

  • APPID
  • 应用私钥
  • 支付宝公钥
  • 沙箱网关
  • 沙箱买家账号
  • 沙箱版支付宝客户端

服务端请求应使用开放平台控制台当前提供的沙箱网关,常见地址是:

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

不要混用正式环境和沙箱环境的 APPID、支付宝公钥或网关,也不要弄反密钥的用途:

  • 应用私钥:商户服务端用它为请求或订单签名。
  • 支付宝公钥:商户服务端用它验证支付宝返回结果和异步通知。
  • 应用公钥:上传到支付宝开放平台,用于生成或匹配支付宝公钥配置。

如果应用采用公钥证书模式,还需要使用配套的应用证书、支付宝公钥证书和支付宝根证书,不能再按照普通公钥模式拼装参数。

3. 不要在 Android 客户端生成正式支付签名

Android 客户端只需要向业务服务端请求订单,再把服务端返回的完整订单字符串原样交给支付宝 SDK:

PayTask payTask = new PayTask(activity);
Map<String, String> result = payTask.payV2(orderInfo, true);

推荐的调用链路如下:

Android 客户端
    → 业务服务端创建订单并签名
    → 服务端返回完整 orderInfo
    → 客户端调用 payV2
    → 支付宝异步通知业务服务端
    → 服务端验签并更新订单状态

不要把应用私钥硬编码或打包进 APK。即使测试时能够支付,私钥也很容易被反编译提取,攻击者可能借此伪造订单请求。

如果当前 Demo 在本地拼接 app_id、biz_content、timestamp,并使用应用私钥签名,应尽快改为由服务端下单。

4. 检查支付 SDK 的沙箱环境设置

部分版本的支付宝 SDK 需要显式切换到沙箱环境,例如在调用支付前设置沙箱模式:

EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);

不同 SDK 版本使用的类名和支持方式可能不同,应以当前接入版本的官方说明为准。不要自行替换支付宝客户端包名、网关域名或 SDK 内部常量来”模拟”沙箱。

切换环境后,建议清除应用并重新打开,同时清理之前生成的旧订单。正式环境创建的订单不能直接交给沙箱钱包支付,沙箱订单也不能用于正式环境。

5. 核对服务端生成的订单参数

调用 alipay.trade.app.pay 时,至少需要检查:

  • app_id 是否为当前沙箱应用的 APPID。
  • method 是否为 alipay.trade.app.pay。
  • sign_type 是否与控制台配置一致,通常使用 RSA2。
  • charset 是否为 utf-8。
  • timestamp 和服务器时间是否准确。
  • out_trade_no 是否唯一。
  • total_amount 是否为合法的两位小数金额。
  • product_code 是否为 QUICK_MSECURITY_PAY。
  • 签名是否包含全部应签参数,签名完成后是否又修改了订单内容。
  • 客户端是否原样传递完整订单字符串,没有再次进行 URL 编码、截断或重新排序。

还要查看 payV2 返回的完整结果,不要只显示”系统繁忙”:

String resultStatus = result.get("resultStatus");
String memo = result.get("memo");
String rawResult = result.get("result");

常见状态包括:

  • 9000:支付成功,但最终结果仍应以服务端异步通知和主动查询为准。
  • 6001:用户取消。
  • 8000:正在处理或结果未知,需要由服务端查询。
  • 其他状态:结合 memo、完整返回内容和支付宝服务端日志排查。

如果服务端下单接口已经返回 sub_code 或 sub_msg,应先处理对应错误。客户端显示的”系统繁忙”往往只是对实际错误的二次包装。

PID 和 target_id 应该填写什么

PID

pid 是支付宝分配给商户或开发者的合作伙伴身份标识,也称支付宝用户 ID。通常可以在支付宝开放平台或商家平台的账号信息中找到,常见形式是一串以 2088 开头的数字。

它不是以下内容:

  • APPID
  • 登录手机号
  • 支付宝登录邮箱
  • 商户订单号
  • 应用公钥编号

如果授权 Demo 要求填写 PID,应填写当前沙箱应用所属沙箱商户账号对应的 PID。不要将正式商户 PID 与沙箱 APPID 混用。

target_id

target_id 是商户为本次授权请求生成的唯一业务标识,用于区分不同的授权请求。它不是支付宝分配的固定值,也不是用户的支付宝账号。

可以由服务端生成,例如:

auth_20260908_a83f17c29d4b

生成时需要注意:

  • 在商户系统内保持唯一。
  • 每次发起新的授权流程时使用新值。
  • 只使用安全、稳定的字母和数字组合。
  • 长度符合当前授权接口文档的限制。
  • 最好由服务端生成并记录,以便关联授权结果并防止重放。

PID、APPID、应用私钥和授权产品配置也必须属于同一个应用环境。授权信息同样应由服务端签名,客户端只负责调用授权 SDK,不应保存应用私钥。

建议的最短排查顺序

先确认手机已安装并登录沙箱版支付宝,再确认 APPID、沙箱网关和密钥全部来自同一个沙箱应用。接着检查服务端 alipay.trade.app.pay 的原始响应,最后记录客户端 payV2 返回的 resultStatus、memo 和完整 result。

如果服务端尚未成功生成完整且已签名的 orderInfo,应先修复服务端配置。如果服务端下单正常,但客户端无法拉起钱包,再检查 SDK 版本、沙箱环境设置和 Android 11 的 <queries> 配置。

备注:内容仅供参考。