支付宝沙箱扫码支付提示被流量海关拦截(ALIN47579)
结论
ALIN47579 通常不是 alipay.trade.precreate 返回的业务错误码,而是支付宝流量安全网关拦截了请求或扫码后的访问链路。此时交易还没有正常进入支付处理阶段,反复生成二维码一般解决不了问题。
在沙箱环境中,应优先检查以下内容:
- 支付接口是否使用了沙箱网关;
- 二维码是否由当前沙箱应用生成;
- 扫码账号是否为对应沙箱环境的买家账号;
app_id、应用私钥和支付宝公钥是否来自同一个沙箱应用;- 是否存在重复请求、异常频率、代理或网络环境干扰;
- 支付宝沙箱服务当时是否发生临时异常。
如果配置没有问题,但所有新生成的二维码仍然稳定出现 ALIN47579,应记录发生时间和请求流水,并提交给支付宝开放平台技术支持进一步确认。仅凭页面上的提示,无法确定具体触发了哪一条内部流量规则。
排查步骤
1. 确认使用沙箱网关
沙箱支付请求应发送到:
https://openapi-sandbox.dl.alipaydev.com/gateway.do
不要混用生产环境网关:
https://openapi.alipay.com/gateway.do
如果通过 SDK 调用,应明确配置沙箱网关,不要依赖不确定的默认值。
2. 检查环境配置是否成套
以下配置必须全部来自同一个沙箱应用:
app_id- 应用私钥
- 支付宝公钥
- 签名算法,例如
RSA2 - 沙箱网关地址
一种常见错误是复制了另一个应用的 app_id,却仍在使用旧应用的密钥。这种混用通常会导致签名失败,也容易干扰后续排查。
还要注意区分以下密钥:
- 应用私钥:商户侧用它生成签名;
- 支付宝公钥:商户侧用它验证支付宝返回的内容;
- 应用公钥:需要上传给支付宝,不能误填到 SDK 的
支付宝公钥配置项中。
3. 确认二维码内容来自接口成功响应
调用 alipay.trade.precreate 后,应先确认响应成功,再使用返回的 qr_code 生成二维码。接口调用失败时,不要继续使用空值、旧值或自行拼接的 URL。
示例逻辑:
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi-sandbox.dl.alipaydev.com/gateway.do",
APP_ID,
APP_PRIVATE_KEY,
"json",
"UTF-8",
ALIPAY_PUBLIC_KEY,
"RSA2"
);
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setOutTradeNo("TEST_" + System.currentTimeMillis());
model.setTotalAmount("0.01");
model.setSubject("沙箱扫码支付测试");
request.setBizModel(model);
AlipayTradePrecreateResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
String qrCode = response.getQrCode();
System.out.println("qr_code = " + qrCode);
} else {
System.err.println("code = " + response.getCode());
System.err.println("sub_code = " + response.getSubCode());
System.err.println("sub_msg = " + response.getSubMsg());
System.err.println("body = " + response.getBody());
}
SDK 的初始化方式可能会随 Java SDK 版本变化,应以当前版本的方法签名为准。无论使用哪个版本,沙箱网关、应用身份和密钥都必须保持一致。
4. 使用沙箱账号和沙箱客户端
扫码时不能混用正式支付宝账号、正式客户端配置和沙箱交易数据。请确认:
- 登录的是开放平台提供的沙箱买家账号;
- 当前客户端支持对应的沙箱测试方式;
- 买家账号没有被锁定,余额或支付条件满足测试要求;
- 商家账号与生成二维码的沙箱应用属于同一套测试环境。
可以退出账号后重新登录,再新建一笔订单测试。不要继续扫描此前保存的旧二维码。
5. 保证订单号唯一
out_trade_no 是商户订单号,在同一商户下应保持唯一。调试时反复提交固定订单号,可能引发重复交易或订单状态冲突。
可以使用以下方式生成订单号:
String outTradeNo = "SANDBOX_" + System.currentTimeMillis();
这种方式只能避免简单的本机重复。并发场景应使用数据库序列、UUID 或其他可以保证唯一性的方案。
6. 降低请求频率并排除网络干扰
流量海关拦截 通常发生在接入层,因此还需要检查请求行为和网络环境:
- 停止循环创建订单或高频刷新二维码;
- 避免多个程序同时使用同一个沙箱应用进行压力测试;
- 暂时关闭抓包代理、VPN、网络加速器或自动重放工具;
- 切换到稳定的普通网络后重新测试;
- 每次测试都创建新的
out_trade_no和二维码; - 不要把沙箱接口用于压力测试。
如果降低请求频率或更换网络后恢复,问题可能与访问特征或网络出口有关,但还不能据此确定具体触发了哪条拦截规则。
7. 区分接口调用失败和扫码后失败
排查前要先确认错误出现在哪个阶段:
- 如果
alipay.trade.precreate调用失败,请检查响应中的code、sub_code、sub_msg和完整响应体; - 如果接口成功返回
qr_code,但扫码后才出现ALIN47579,应重点检查沙箱客户端、买家账号、二维码环境和支付宝侧的扫码链路; - 如果只有某个订单失败,请检查该订单是否过期、重复或状态异常;
- 如果所有账号和所有新订单都失败,则更可能与环境配置、网络出口或沙箱服务异常有关。
不要只保存页面截图。与扫码页面上的提示相比,接口原始响应通常更有助于定位问题。
建议保留的诊断信息
如果问题持续出现,请记录以下信息,再向支付宝开放平台技术支持反馈:
错误码:ALIN47579
发生时间:精确到秒,并注明时区
环境:支付宝沙箱
接口:alipay.trade.precreate
app_id:可提供,私钥不得提供
out_trade_no:商户订单号
接口响应:code、sub_code、sub_msg
请求流水号:响应中存在 trace_id、request_id 等字段时一并提供
扫码账号:提供沙箱账号标识,密码不得提供
网络情况:是否使用代理、VPN 或抓包工具
复现范围:单个订单、单个账号,还是所有新订单均可复现
ALIN47579 对应的内部命中规则通常不会完整提供给调用方,因此不能只根据错误码确定是频控、风险策略还是沙箱链路异常。如果基础配置无误,且等待一段时间、更换网络、重新登录沙箱账号并创建新订单后仍能稳定复现,就需要由支付宝侧结合请求流水定位。
注意事项
- 不要将应用私钥、沙箱账号密码或完整签名参数发布到工单、日志截图或公开页面中。
notify_url无法从公网访问会影响异步通知,但通常不会直接导致扫码页面显示ALIN47579。这两类问题需要分开排查。- 修改密钥后,应同时更新开放平台配置和本地配置。只修改一侧会导致签名或验签失败。
- 沙箱环境可能临时波动,不适合用于性能、并发或稳定性验证。
- 重新安装客户端和清理缓存可以作为补充排查手段,但应先检查网关、账号、应用和密钥是否一致。
备注:内容仅供参考。
