PAYATHON 2026

鸿蒙系统接入支付宝支付SDK是否支持沙箱环境测试?

支付阿杰

结论

目前无法直接套用 Android 平台的“沙箱版支付宝”,完成鸿蒙支付 SDK 的完整链路测试。Android 沙箱钱包不等于鸿蒙测试客户端,也不能作为鸿蒙支付 SDK 的运行依赖。

应用资质尚未审核通过时,可以先完成客户端调用封装、服务端下单与签名、回调验签、支付状态处理,并使用 Mock 数据联调。支付宝客户端唤起、真实付款和异步通知等端到端验证,通常要等应用审核通过、支付产品签约生效,并取得可用的生产参数后再进行。

支付宝开放平台的能力和支持范围可能随 SDK 版本变化。正式接入前,请以当前鸿蒙支付 SDK 文档、开放平台控制台显示的产品能力和支付宝技术支持的答复为准。

为什么 Android 沙箱方案不能直接使用

支付 SDK 的客户端测试既依赖服务端接口,也依赖对应平台的支付宝客户端。Android 沙箱环境通常要求安装专用的沙箱版支付宝,并使用沙箱账号付款。

鸿蒙应用接入与 Android 沙箱至少有以下区别:

  • Android 沙箱版支付宝是 Android 应用,不能据此认定鸿蒙支付 SDK 也支持沙箱。
  • 鸿蒙客户端 SDK、应用跳转方式和系统能力可能与 Android 版本不同。
  • 沙箱网关只能解决服务端接口测试,无法自动提供鸿蒙端的沙箱支付宝客户端。
  • 服务端即使能用沙箱参数创建订单,也不代表鸿蒙正式版支付宝可以正常受理该订单。

因此,沙箱网关、生产版支付宝客户端和生产环境应用参数不能混用。环境不匹配时,可能出现无法唤起支付宝、订单参数错误、应用未签约或支付结果无法识别等问题。

资质审核期间可以先做什么

可以把支付流程分成鸿蒙客户端、业务服务端和支付宝接口三部分。审核期间先完成客户端和业务服务端的工作。

1. 先定义统一的支付接口

鸿蒙客户端只向业务服务端请求支付参数。支付宝应用私钥不能保存在客户端,完整订单也不能由客户端自行拼接和签名。

interface CreatePaymentRequest {
  orderId: string;
  amount: string;
  subject: string;
}

interface CreatePaymentResponse {
  orderString: string;
}

interface PaymentResult {
  resultStatus: string;
  result?: string;
  memo?: string;
}

amount 建议使用字符串或以“分”为单位的整数,以免产生浮点数精度问题。订单金额和商品信息必须由服务端根据业务订单生成,不能直接信任客户端提交的值。

2. 封装 SDK 调用层

把支付宝 SDK 调用集中封装起来,业务代码只处理统一格式的结果。以下代码仅用于展示结构,实际类名、方法名和返回字段必须以当前鸿蒙 SDK 文档为准:

class AlipayPaymentService {
  async pay(orderString: string): Promise<PaymentResult> {
    if (!orderString) {
      throw new Error('orderString is empty');
    }

    // 在此调用鸿蒙支付宝支付 SDK。
    // 不要根据 Android SDK 的接口名称自行推断鸿蒙 API。
    const sdkResult = await invokeAlipaySdk(orderString);

    return {
      resultStatus: sdkResult.resultStatus,
      result: sdkResult.result,
      memo: sdkResult.memo
    };
  }
}

不同版本 SDK 的包名和接口可能发生变化。invokeAlipaySdk 只表示 SDK 的调用位置,不是支付宝官方 API。

3. 使用 Mock 结果验证业务流程

暂时不能进行真实支付时,可以用可替换的支付实现,模拟成功、取消、处理中和失败等状态:

class MockPaymentService {
  async pay(
    orderString: string,
    scene: 'success' | 'cancel' | 'processing' | 'failure'
  ): Promise<PaymentResult> {
    const results: Record<string, PaymentResult> = {
      success: {
        resultStatus: 'MOCK_SUCCESS',
        memo: '模拟支付成功'
      },
      cancel: {
        resultStatus: 'MOCK_CANCEL',
        memo: '模拟用户取消'
      },
      processing: {
        resultStatus: 'MOCK_PROCESSING',
        memo: '模拟结果确认中'
      },
      failure: {
        resultStatus: 'MOCK_FAILURE',
        memo: '模拟支付失败'
      }
    };

    return results[scene];
  }
}

这些状态值只是业务侧的 Mock 标识,并非支付宝官方状态码,不能作为生产环境的判断依据。

通过 Mock 可以提前验证:

  • 支付按钮能否防止重复点击;
  • 用户取消支付后,页面能否正常恢复;
  • 支付失败时的提示和重试流程;
  • 应用切到后台再返回后的状态恢复;
  • 支付处理中对订单状态的轮询;
  • 支付成功后的页面跳转;
  • 同一订单重复支付时的幂等处理。

4. 提前完成服务端验签和订单状态设计

客户端返回的结果只能用于界面展示,不能作为发货或开通权益的唯一依据。最终支付结果应由服务端通过支付宝异步通知或主动查询来确认。

服务端可以先按以下流程实现处理逻辑:

接收异步通知
    ↓
验证支付宝签名
    ↓
校验 app_id、商户订单号、金额等关键字段
    ↓
查询本地订单并执行幂等检查
    ↓
更新支付状态
    ↓
返回支付宝协议要求的应答

正式联调前还要准备订单查询接口。鸿蒙客户端从支付宝返回后,应向业务服务端查询订单状态:

async function confirmPayment(orderId: string): Promise<void> {
  const response = await queryOrderFromBusinessServer(orderId);

  switch (response.status) {
    case 'PAID':
      showPaymentSuccess();
      break;
    case 'PENDING':
      showPaymentProcessing();
      break;
    case 'CLOSED':
    case 'FAILED':
      showPaymentFailure();
      break;
    default:
      showPaymentProcessing();
  }
}

审核通过后的联调步骤

取得有效的应用权限和支付产品权限后,再测试真实支付链路:

  1. 在支付宝开放平台确认应用审核状态及支付产品签约状态。
  2. 按当前官方文档配置 app_id、应用公钥或支付宝公钥、签名算法和回调地址。
  3. 由业务服务端创建订单并完成签名。
  4. 将服务端生成的订单字符串返回给鸿蒙客户端。
  5. 使用文档指定的鸿蒙支付 SDK 发起支付。
  6. 分别验证支付成功、用户取消、支付失败和结果处理中等场景。
  7. 检查服务端对异步通知的验签、金额校验和幂等处理。
  8. 使用订单查询接口核对最终交易状态。
  9. 确认退款、重复支付、超时关闭等异常流程不会造成重复发货。

如果开放平台以后为鸿蒙 SDK 提供独立沙箱客户端,或公布明确的沙箱接入方式,应配套使用对应的沙箱网关、沙箱应用参数、沙箱账号和指定客户端,不能与生产环境配置混用。

注意事项

  • 不要把应用私钥、商户私钥或完整的签名逻辑放入鸿蒙客户端。
  • 不要根据 Android SDK 的类名和调用方式推测鸿蒙 SDK 接口。
  • 不要把 Mock 支付成功视为真实交易成功。
  • 不要只根据客户端同步返回的结果发货。
  • 支付回调必须验签,还要校验应用、订单号、金额等关键数据。
  • 订单更新和权益发放必须具备幂等性。
  • 沙箱订单、沙箱账号和沙箱密钥不能用于生产环境。
  • 正式测试前需要分别检查应用审核状态和支付产品签约状态。应用审核通过不代表支付产品已经签约生效。
  • 如果当前官方文档没有明确说明鸿蒙支持沙箱,应按“不支持完整沙箱链路”处理,并向支付宝技术支持确认所用 SDK 版本是否增加了相关能力。

备注:内容仅供参考。