支付宝支付遇到code 40004商户协议状态非正常怎么办?
结论
code 40004 表示支付宝已收到请求,但业务处理失败。“商户协议状态非正常”表示当前收款商户与支付宝签订的支付产品协议不可用。
这通常与二维码生成代码无关。先登录支付宝商家平台,检查对应产品是否已经签约并生效、商户账号是否受限,以及请求中的商户身份是否正确。协议恢复后,再次发起支付请求。
常见原因
支付产品尚未签约或未生效
调用当面付接口生成二维码,通常需要先开通对应的支付产品。产品仍在审核、签约流程尚未完成或协议还未生效,都可能引发该错误。
例如,调用:
alipay.trade.precreate
需要确认当前商户已经具备当面付相关能力。创建支付宝开放平台应用,不等于商户完成了支付产品签约。
商户协议已失效或被暂停
主体资料过期、风控限制、账户异常、协议到期或平台审核等情况,都可能导致商户协议暂停。仅凭 code 40004 无法判断具体原因,需要结合响应中的 sub_code 和 sub_msg,并以商家平台显示的状态为准。
使用了错误的商户身份
常见情况包括:
- 应用绑定的商户与实际签约商户不一致;
- 服务商代商户调用时传错了
app_auth_token; app_auth_token已失效,或对应的商户授权已取消;- 应用或密钥由其他支付宝账号创建;
- 更换商户后,系统仍在使用旧配置。
沙箱与生产环境混用
沙箱账号、沙箱网关和生产账号不能混用。使用生产商户配置请求沙箱网关,或使用沙箱应用信息请求生产网关,都可能造成身份或协议校验异常。
处理步骤
1. 保存完整的支付宝响应
除了 code 和 msg,还要记录:
code
msg
sub_code
sub_msg
request_id
定位问题时,sub_code 和 sub_msg 往往比 code 40004 更有用。日志中不要写入应用私钥、AES 密钥或完整的授权令牌。
2. 检查支付产品状态
使用实际收款商户的账号登录支付宝商家平台,逐项检查:
- 对应支付产品是否已经签约;
- 协议是否已经生效;
- 协议是否被暂停、关闭或限制;
- 商户主体资料是否需要补充;
- 商户账户是否有待处理通知。
如果产品仍在审核,需要等待审核完成。协议已暂停时,应按照平台提示补充资料或申请恢复。
3. 核对应用和商户关系
确认以下信息来自同一套生产配置:
app_id- 支付宝公钥或支付宝证书
- 应用私钥
- 支付网关
- 签约商户账号
- 服务商模式下的
app_auth_token
普通商户直接调用时,通常无须传入 app_auth_token。服务商代商户调用时,要确认授权令牌属于实际收款商户,而且授权仍然有效。
4. 确认调用环境
生产环境通常使用:
https://openapi.alipay.com/gateway.do
沙箱环境必须使用对应的沙箱应用、账号、密钥和网关。不能只替换网关地址,却继续使用另一个环境的商户资料。
5. 重新发起请求
协议恢复正常后,重新调用接口生成二维码。排查时可先使用最少的必要参数,减少无关业务参数的干扰。
如果平台显示协议正常,但接口仍然返回相同错误,可向支付宝技术支持提供以下信息:
app_id- 接口名称
- 请求时间
request_idsub_codesub_msg- 商户账号或商户 PID
不要在公开渠道提供应用私钥、支付密码或完整的 app_auth_token。
Java 调用示例
以下以 alipay.trade.precreate 为例。不同版本的 SDK 可能使用不同的类名和构造方式,请以项目实际安装的支付宝 SDK 为准。
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.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("ORDER_202609130001");
model.setTotalAmount("0.01");
model.setSubject("支付测试");
request.setBizModel(model);
AlipayTradePrecreateResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
System.out.println("二维码地址:" + response.getQrCode());
} else {
System.err.println("code: " + response.getCode());
System.err.println("msg: " + response.getMsg());
System.err.println("sub_code: " + response.getSubCode());
System.err.println("sub_msg: " + response.getSubMsg());
}
只有服务商代商户调用时,才需要根据实际授权关系传入 app_auth_token:
AlipayTradePrecreateResponse response =
alipayClient.execute(request, APP_AUTH_TOKEN);
如果这时出现“商户协议状态非正常”,需要检查服务商应用权限、商户授权状态和被代调用商户的产品协议,不能只看服务商自己的签约状态。
注意事项
40004是业务失败码,不表示 HTTP 状态码是40004。- 修改签名算法或重新生成订单号,通常不能解决协议状态异常。
- 支付能力必须开通在实际收款主体名下。应用审核通过,不表示支付协议已经生效。
- 协议恢复后,原支付请求不一定会自动成功,需要重新调用接口。
- 如果完整响应中包含更具体的
sub_code,应优先根据该字段排查。 - 平台后台入口和产品名称可能发生调整。找不到协议状态时,可以通过商家平台的产品签约、账户中心或客服入口查询。
备注:内容仅供参考。
