PAYATHON 2026

支付宝沙箱手机网站支付提示商户合作协议已到期

支付小周

结论

出现”商户合作协议已到期”,通常不是支付代码或签名算法的问题,而是沙箱商家账号(PID:2088621987755475)对应的产品协议状态异常或已经失效。

先确认请求发送到了支付宝沙箱网关,再检查 appid、商家 PID 和应用密钥是否属于同一套沙箱环境。如果配置一致后仍然报错,问题很可能出在支付宝沙箱侧,无法通过修改代码续签协议。可以在开放平台重新配置沙箱应用、重置沙箱环境,或者向支付宝开放平台技术支持提交该 appid 和 PID,请其处理。

原因分析

手机网站支付使用 alipay.trade.wap.pay 接口。支付宝收到请求后,不仅会校验签名,还会检查以下内容:

  • 应用是否有效;
  • 应用绑定的商家账号是否有效;
  • 商家是否具备手机网站支付权限;
  • 对应产品协议是否有效;
  • appid、seller_id 和收款账号是否匹配。

当前涉及的账号信息如下:

appid: 2021000121635859
商家 PID: 2088621987755475

如果返回信息明确显示”商户合作协议已到期”,一般说明支付宝已经完成了基础解析和身份识别,但商家侧的产品协议没有通过状态检查。这和”验签失败""应用不存在”是不同类型的问题,不应优先尝试修改签名代码。

排查步骤

1. 确认使用沙箱网关

沙箱请求地址应为:

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

不要把沙箱 appid 和沙箱私钥发送到正式环境网关:

https://openapi.alipay.com/gateway.do

还要检查 SDK 初始化代码,确认配置文件、环境变量或部署参数没有覆盖网关地址,导致程序实际使用了正式网关。

2. 核对整套沙箱配置

以下配置必须来自同一个沙箱应用:

  • appid;
  • 应用私钥;
  • 支付宝公钥;
  • 沙箱商家账号;
  • 商家 PID;
  • 沙箱买家账号。

不要混用正式环境的应用密钥、PID 或买家账号。

如果请求中传递了 seller_id,它必须和当前应用绑定的商家 PID 一致,即:

2088621987755475

如果业务不需要指定收款方,可以暂时删除 seller_id,让支付宝根据 appid 识别默认商家。这样可以排除 PID 填写错误或配置被覆盖的问题。

3. 检查手机网站支付产品状态

进入支付宝开放平台的沙箱环境,查看对应应用是否仍有手机网站支付能力,并确认沙箱商家账号的产品协议是否有效。

应用存在,不代表对应的支付产品协议一定有效。即使 appid 和签名都正确,商家协议异常仍会导致交易创建失败。

如果页面提供重新签约、重新授权或重置沙箱环境的入口,可以按照页面提示操作。开放平台界面可能随时间调整,应以当前控制台显示的内容为准。

4. 检查接口返回的完整错误信息

不要只记录页面上的中文提示,还应保存支付宝返回的完整字段,例如:

code
msg
sub_code
sub_msg

排查时应重点查看 sub_code。相同的中文提示可能对应不同的 sub_code,处理方式也可能不同。

建议记录以下信息:

appid
method
seller_id
out_trade_no
code
sub_code
sub_msg
支付宝返回的 request_id(如果有)

不要在日志或工单中公开应用私钥、完整签名串、买家密码等敏感信息。

5. 重新生成沙箱配置后再测试

如果控制台允许重置或重新生成沙箱配置,可以按以下顺序操作:

  1. 保存现有配置,避免误影响其他测试人员;
  2. 重置沙箱环境或重新生成应用密钥;
  3. 更新项目中的应用私钥和支付宝公钥;
  4. 再次核对沙箱 appid 和商家 PID;
  5. 使用新的 out_trade_no 发起测试。

不要反复使用已经失败或已存在的商户订单号,否则可能产生”订单号重复”等额外错误,影响判断。

6. 提交支付宝技术支持

如果以下条件都已满足,但错误依然存在:

  • 请求发送到沙箱网关;
  • appid 为 2021000121635859;
  • PID 为 2088621987755475;
  • 密钥属于该沙箱应用;
  • 接口为 alipay.trade.wap.pay;
  • 控制台没有可用的重新签约入口;

则需要由支付宝检查或恢复该沙箱商家账号的协议状态。提交问题时,建议附上:

  • 沙箱 appid;
  • 沙箱商家 PID;
  • 完整的 code、sub_code、sub_msg;
  • 请求发生时间;
  • 接口名称;
  • 脱敏后的请求参数;
  • 问题页面截图。

Java 调用示例

下面的示例用于确认基本调用方式。密钥、回调地址和订单信息需要替换为实际的测试配置。

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeWapPayRequest;

public class AlipayWapPayExample {

    public static void main(String[] args) throws Exception {
        String gatewayUrl =
                "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
        String appId = "2021000121635859";
        String merchantPrivateKey = "YOUR_APP_PRIVATE_KEY";
        String alipayPublicKey = "YOUR_ALIPAY_PUBLIC_KEY";

        AlipayClient alipayClient = new DefaultAlipayClient(
                gatewayUrl,
                appId,
                merchantPrivateKey,
                "json",
                "UTF-8",
                alipayPublicKey,
                "RSA2"
        );

        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        request.setReturnUrl("https://example.com/alipay/return");
        request.setNotifyUrl("https://example.com/alipay/notify");

        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo("SANDBOX_" + System.currentTimeMillis());
        model.setTotalAmount("0.01");
        model.setSubject("沙箱手机网站支付测试");
        model.setProductCode("QUICK_WAP_WAY");

        // 一般可不设置 seller_id,由 appid 关联的商家账号收款。
        // 如必须设置,其值应与应用绑定的沙箱商家 PID 一致。
        // model.setSellerId("2088621987755475");

        request.setBizModel(model);

        String paymentForm = alipayClient.pageExecute(request).getBody();
        System.out.println(paymentForm);
    }
}

pageExecute() 成功生成 HTML 表单,不等于交易已经创建成功。浏览器跳转到支付宝后,支付宝仍会检查商家协议、产品权限和账号状态。

注意事项

  • 不要尝试通过修改订单金额、回调地址或签名算法绕过协议到期错误,这些参数与协议状态没有直接关系。
  • 沙箱账号和正式商家账号相互独立。正式环境已经签约,不代表沙箱环境的状态一定正常。
  • 重新生成密钥只能解决密钥配置问题,不能保证商家协议状态恢复正常。
  • 重置沙箱环境可能改变原有测试账号、密钥或测试数据。操作前应确认是否有其他项目共用该环境。
  • 最终应以接口返回的 sub_code 和支付宝开放平台对该沙箱账号的实际查询结果为准。仅凭中文提示,无法判断究竟是协议自然失效、产品权限被回收,还是沙箱数据异常。

备注:内容仅供参考。