PAYATHON 2026

App 未上架时如何在测试环境调试支付宝 App 支付 API?

支付小周

结论

App 还没上架,也可以联调支付宝 App 支付接口。只要已经在支付宝开放平台创建应用,并取得沙箱环境的 app_id、密钥和沙箱买家账号,就能在测试安装包中接入 App 支付 SDK,通过沙箱网关测试下单、唤起支付宝和接收支付结果通知等流程。

沙箱能力、测试钱包支持的平台以及应用签约要求可能会随开放平台调整,请以当前控制台显示的信息为准。沙箱配置和生产环境配置不能混用。

调试流程

1. 创建开放平台应用并进入沙箱环境

先在支付宝开放平台控制台创建应用,再进入开发工具或沙箱相关页面,获取以下信息:

  • 沙箱应用 app_id
  • 应用私钥
  • 支付宝公钥,或支付宝公钥证书
  • 沙箱买家账号及登录密码
  • 沙箱网关地址

常见的沙箱网关是:

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

生产网关通常是:

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

具体地址请以控制台当前配置为准。

2. 在服务端生成支付订单

不要在 App 中保存应用私钥,也不要让 App 自行拼接和签名支付请求。支付流程应当是:

  1. App 请求业务服务端创建订单。
  2. 服务端调用 alipay.trade.app.pay,生成签名后的订单字符串。
  3. 服务端将订单字符串返回给 App。
  4. App 通过支付宝客户端 SDK 发起支付。
  5. 服务端根据异步通知确认最终支付结果。

Java 服务端示例:

AlipayClient alipayClient = new DefaultAlipayClient(
    "https://openapi.alipaydev.com/gateway.do",
    APP_ID,
    APP_PRIVATE_KEY,
    "json",
    "UTF-8",
    ALIPAY_PUBLIC_KEY,
    "RSA2"
);

AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setNotifyUrl("https://example.com/api/alipay/notify");

AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setSubject("测试商品");
model.setOutTradeNo("TEST_" + System.currentTimeMillis());
model.setTotalAmount("0.01");
model.setProductCode("QUICK_MSECURITY_PAY");

request.setBizModel(model);

AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
if (!response.isSuccess()) {
    throw new IllegalStateException(
        response.getCode() + ": " + response.getSubMsg()
    );
}

String orderString = response.getBody();

orderString 是已经完成签名的完整支付参数,需要原样返回给 App,不能再次编码或重新拼接。

如果使用证书模式,需要通过对应的证书客户端初始化方式,配置应用公钥证书、支付宝公钥证书和支付宝根证书,不能按普通公钥模式处理。

3. App 调用支付 SDK

以 Android 为例,App 拿到服务端返回的 orderString 后,可以调用支付宝 SDK:

Runnable payRunnable = () -> {
    PayTask payTask = new PayTask(activity);
    Map<String, String> result = payTask.payV2(orderString, true);

    activity.runOnUiThread(() -> {
        String resultStatus = result.get("resultStatus");
        String memo = result.get("memo");

        // 客户端结果仅用于页面展示,
        // 订单最终状态应由服务端查询或异步通知确认。
    });
};

Thread payThread = new Thread(payRunnable);
payThread.start();

支付 SDK 的依赖配置、Android 清单要求和 iOS 回跳配置,请按照当前版本的支付宝 App 支付接入文档处理。不同版本的 SDK 可能采用不同的初始化方式,不要直接照搬过旧的示例。

4. 使用沙箱账号完成支付

测试时,需要使用沙箱提供的买家账号,以及与沙箱环境匹配的支付宝测试客户端。普通支付宝账号通常不能直接用于沙箱交易。

如果控制台只提供某个平台的沙箱钱包,例如只提供 Android 测试客户端,就需要在该平台完成整个沙箱支付流程。其他平台可以先验证下单、签名、回跳和服务端业务逻辑,再根据开放平台当前的支持情况安排真机联调。

5. 验证异步通知

支付完成后,支付宝会向 notify_url 发送异步通知。该地址必须能够被支付宝服务器访问,localhost、局域网 IP 等地址通常无法直接接收通知。

服务端收到通知后,至少需要完成以下处理:

  1. 验证支付宝签名。
  2. 校验 app_id。
  3. 确认 out_trade_no 属于当前系统。
  4. 确认 total_amount 与订单金额一致。
  5. 判断 trade_status。
  6. 以幂等方式更新订单。
  7. 处理成功后返回纯文本 success。

示意代码:

boolean valid = AlipaySignature.rsaCheckV1(
    requestParams,
    ALIPAY_PUBLIC_KEY,
    "UTF-8",
    "RSA2"
);

if (!valid) {
    return "failure";
}

String appId = requestParams.get("app_id");
String outTradeNo = requestParams.get("out_trade_no");
String totalAmount = requestParams.get("total_amount");
String tradeStatus = requestParams.get("trade_status");

if (!APP_ID.equals(appId)) {
    return "failure";
}

// 继续校验订单号、金额和订单状态。
// 更新操作必须保证幂等。

if ("TRADE_SUCCESS".equals(tradeStatus)
        || "TRADE_FINISHED".equals(tradeStatus)) {
    return "success";
}

return "failure";

常见问题

唤不起支付宝客户端

可以重点检查以下配置:

  • 是否使用 App 支付 SDK,而不是手机网站支付接口。
  • Android 包配置或 iOS URL Scheme 是否正确。
  • 测试设备是否安装了沙箱支持的支付宝客户端。
  • orderString 是否完整传递,是否经过重复 URL 编码。
  • 服务端是否使用沙箱 app_id 和沙箱网关。

出现签名错误

常见原因包括:

  • 应用私钥与平台配置的应用公钥不匹配。
  • 把支付宝公钥误当成应用公钥。
  • 混用普通公钥模式和证书模式。
  • RSA2、字符集或签名算法的配置不一致。
  • 修改了已经签名的订单字符串。
  • 混用沙箱环境和生产环境的密钥。

App 返回支付成功,但服务端订单仍未支付

客户端返回的结果可能受到网络中断、回跳失败或结果伪造的影响,不能据此发货。服务端应优先通过支付宝异步通知确认订单状态,必要时再调用交易查询接口核实。

注意事项

  • App 是否上架和能否进行技术联调没有直接关系,内部测试包、真机安装包也可以接入支付 SDK。
  • 沙箱数据与生产数据完全隔离。切换到生产环境时,需要同时更换网关、app_id、密钥或证书、账号及相关配置。
  • 应用私钥只能保存在服务端,不能写入 App、前端代码或公开仓库。
  • 测试订单号必须唯一。重复使用 out_trade_no,可能导致重复下单错误或返回旧交易状态。
  • 异步通知可能会重复发送,因此订单更新必须具备幂等性。
  • 上线前,仍需按照开放平台当时的要求完成应用审核、能力签约和生产配置,并在真实环境中重新进行小额支付验证。

备注:内容仅供参考。