鸿蒙系统接入支付宝支付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();
}
}
审核通过后的联调步骤
取得有效的应用权限和支付产品权限后,再测试真实支付链路:
- 在支付宝开放平台确认应用审核状态及支付产品签约状态。
- 按当前官方文档配置
app_id、应用公钥或支付宝公钥、签名算法和回调地址。 - 由业务服务端创建订单并完成签名。
- 将服务端生成的订单字符串返回给鸿蒙客户端。
- 使用文档指定的鸿蒙支付 SDK 发起支付。
- 分别验证支付成功、用户取消、支付失败和结果处理中等场景。
- 检查服务端对异步通知的验签、金额校验和幂等处理。
- 使用订单查询接口核对最终交易状态。
- 确认退款、重复支付、超时关闭等异常流程不会造成重复发货。
如果开放平台以后为鸿蒙 SDK 提供独立沙箱客户端,或公布明确的沙箱接入方式,应配套使用对应的沙箱网关、沙箱应用参数、沙箱账号和指定客户端,不能与生产环境配置混用。
注意事项
- 不要把应用私钥、商户私钥或完整的签名逻辑放入鸿蒙客户端。
- 不要根据 Android SDK 的类名和调用方式推测鸿蒙 SDK 接口。
- 不要把 Mock 支付成功视为真实交易成功。
- 不要只根据客户端同步返回的结果发货。
- 支付回调必须验签,还要校验应用、订单号、金额等关键数据。
- 订单更新和权益发放必须具备幂等性。
- 沙箱订单、沙箱账号和沙箱密钥不能用于生产环境。
- 正式测试前需要分别检查应用审核状态和支付产品签约状态。应用审核通过不代表支付产品已经签约生效。
- 如果当前官方文档没有明确说明鸿蒙支持沙箱,应按“不支持完整沙箱链路”处理,并向支付宝技术支持确认所用 SDK 版本是否增加了相关能力。
备注:内容仅供参考。
