沙箱app支付提示商户支付宝账号暂不支持收款
结论
出现“该商户支付宝账号暂不支持收款”,通常不是因为 alipay.trade.app.pay 缺少某个可选参数。这说明订单已经进入支付宝收银台,但系统在校验收款方时发现,当前商户、应用或支付环境不满足收款条件。
在沙箱环境中,常见原因包括:
- 请求被发送到了正式网关,或者混用了正式环境和沙箱环境的配置。
app_id、应用私钥、应用证书和支付宝根证书并非来自同一个沙箱应用。- 付款时登录的不是沙箱买家账号,或者误用沙箱商家账号付款。
- 沙箱应用未开通“手机网站支付/APP 支付”能力、能力状态异常,或者沙箱账号数据已经失效。
- 使用了过期订单或重复的
out_trade_no,也可能是请求时间与当前时间相差过大。 - 测试金额触发了沙箱限制。具体限额可能随沙箱规则调整,应以当前沙箱控制台和接口返回为准。
从现有参数来看,biz_content 已包含 out_trade_no、total_amount 和 subject,满足接口的基本必传要求。不过,仅凭这段支付参数还无法判断具体原因,需要结合服务端生成订单时的同步响应、支付宝收银台日志和沙箱控制台状态继续排查。
优先检查支付环境
沙箱请求必须发送到沙箱网关:
https://openapi-sandbox.dl.alipaydev.com/gateway.do
不能使用正式环境网关:
https://openapi.alipay.com/gateway.do
下面这些配置必须全部来自同一个沙箱应用:
app_id- 应用私钥
- 应用公钥证书
- 支付宝公钥证书
- 支付宝根证书
app_cert_snalipay_root_cert_sn
不要把正式应用的证书或密钥用于沙箱,也不要混用不同沙箱应用的证书。证书序列号通常由 SDK 根据证书文件计算,不建议手动填写,更不要复制其他环境中的值。
检查沙箱账号
付款时,需要在沙箱版支付宝客户端中登录沙箱控制台提供的买家账号。
逐项确认以下内容:
- 登录的是沙箱买家账号,不是沙箱商家账号。
- 没有用真实支付宝账号测试沙箱订单。
- 买家账号状态正常,沙箱余额充足。
- 收款方是当前
app_id绑定的沙箱商家账号。 - 沙箱客户端、沙箱账号和沙箱网关属于同一套环境。
如果账号长期未使用,或者沙箱控制台近期重置过数据,可以重新获取沙箱买家账号并登录,然后创建一笔新订单测试。
查看接口同步响应
服务端调用 alipay.trade.app.pay 后,不能只把订单字符串返回给客户端,还应记录同步响应中的这些字段:
codemsgsub_codesub_msgbodyout_trade_no
示例:
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("sandbox_" + System.currentTimeMillis());
model.setTotalAmount("0.01");
model.setSubject("沙箱支付测试");
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
request.setNotifyUrl("https://example.com/alipay/notify");
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
System.out.println("code=" + response.getCode());
System.out.println("msg=" + response.getMsg());
System.out.println("subCode=" + response.getSubCode());
System.out.println("subMsg=" + response.getSubMsg());
System.out.println("body=" + response.getBody());
if (!response.isSuccess()) {
throw new IllegalStateException(
"生成支付宝订单失败:" + response.getSubCode() + " / " + response.getSubMsg()
);
}
String orderInfo = response.getBody();
alipayClient 必须使用沙箱网关,并配置当前沙箱应用对应的密钥或证书。支付宝 Java SDK 不同版本的初始化方式可能不同,应以项目实际使用的 SDK 接口为准。
部分 SDK 或接口场景可能会默认处理 product_code,但 APP 支付仍建议明确传入:
QUICK_MSECURITY_PAY
这样可以明确请求用途,也方便排查 SDK 版本或参数组装造成的差异。
使用最小订单重新测试
先将业务参数缩减为一笔全新的最小金额订单:
{
"out_trade_no": "sandbox_新的唯一订单号",
"total_amount": "0.01",
"subject": "沙箱支付测试",
"product_code": "QUICK_MSECURITY_PAY"
}
测试时注意:
- 每次都要生成新的
out_trade_no。已经支付、关闭,或者创建失败后状态不明的订单号不能重复使用。 timestamp必须是当前时间,不要重复提交历史订单字符串。total_amount建议使用保留两位小数的字符串,例如"0.01"或"2689.00"。- 如果
0.01可以支付,但2689.00无法支付,再检查沙箱余额、单笔金额限制和风控限制。 - App 端应直接使用服务端返回的完整
orderInfo调起支付,不要再次解析、拼接、排序或编码。
Android 端示例:
PayTask payTask = new PayTask(activity);
Map<String, String> result = payTask.payV2(orderInfo, true);
String resultStatus = result.get("resultStatus");
String memo = result.get("memo");
String resultData = result.get("result");
同时记录 resultStatus、memo 和 result。页面上的提示只是面向用户的文案,服务端同步响应和客户端支付结果通常能提供更多排查线索。
检查应用支付能力
进入支付宝开放平台的沙箱应用配置,确认以下内容:
- 当前应用可以调用
alipay.trade.app.pay。 - APP 支付能力处于可测试状态。
- 应用密钥或证书没有被重新生成、替换或失效。
- 服务端使用的
app_id与控制台当前打开的沙箱应用一致。
如果配置看起来没有问题,但所有新订单都提示无法收款,可以重新生成沙箱密钥或证书,并更新服务端配置。更新后需要重启应用,防止程序继续从缓存或旧配置文件中读取密钥。
回调地址不是该提示的直接原因
参数中的回调地址是:
http://www.cdinput.com:9213/app/notify/alipay
notify_url 无法访问,通常不会直接导致收银台显示“商户账号暂不支持收款”,因为支付结果通知发生在交易处理过程中或完成之后。不过,回调地址仍需满足以下条件:
- 支付宝服务器可以通过公网访问该地址。
- 域名、端口和路径确实可用。
- 防火墙没有拦截支付宝请求。
- 接口支持
POST。 - 生产环境优先使用 HTTPS。
- 回调处理完成后,按照接口要求返回成功响应。
参数中还需注意的问题
给出的参数时间是:
timestamp=2022-11-07 14:46:15
如果现在仍用这段完整参数发起调用,时间戳、签名和订单号都已经失效,必须重新生成请求。签名覆盖请求参数,因此修改 timestamp、biz_content 或其他参与签名的字段后,都要重新签名。
完整支付请求中的 sign 虽然不是商户私钥,但也不应公开记录或长期复用。日志可以保留 app_id、out_trade_no、错误码和响应摘要,签名内容应脱敏。
推荐排查顺序
- 确认使用的是沙箱网关。
- 确认
app_id、私钥和所有证书都属于同一个沙箱应用。 - 确认应用具备 APP 支付能力。
- 使用沙箱买家账号登录沙箱版支付宝。
- 生成新的
out_trade_no,用0.01元重新测试。 - 明确传入
product_code=QUICK_MSECURITY_PAY。 - 记录
alipay.trade.app.pay的同步响应和客户端payV2的返回结果。 - 如果配置均正确但仍无法收款,重置沙箱账号,或者重新配置沙箱密钥和证书后再试。
如果接口同步响应中已经包含明确的 sub_code 和 sub_msg,应优先根据这两个字段排查。只有收银台文案而没有接口日志,无法准确判断问题来自账号状态、环境混用还是支付能力异常。
备注:内容仅供参考。
