做元服务商业化,支付绕不开。ASCF 提供两套方案:华为支付 has.requestPayment 和应用内购买 IAP has.createIap。两者不是一回事:华为支付是直接付钱给商户,适合实物商品和服务;IAP 走华为应用商店支付通道,适合虚拟商品、会员、道具、解锁内容和订阅。选型先看卖什么。
开发前准备:不管用华为支付还是 IAP,都需要在 AGC 配置 Client ID、签名证书指纹,开通商户服务,开启并激活应用内购买服务(IAP)。不配置这些,支付相关 API 都会 fail。
华为支付的核心是前端不生成订单。服务端生成 orderStr,里面包含 app_id、merc_no、prepay_id、timestamp、noncestr、sign、auth_id 等信息;前端只把 orderStr 传给 requestPayment,负责拉起支付和处理结果。
- has.requestPayment({
- orderStr: orderStr,
- success: (res) => {
- console.info('支付成功');
- },
- fail: (err) => {
- console.error('支付失败:', err);
- }
- });
复制代码
华为支付有三种模式,通过 payload 区分:默认支付不传 payload;混合支付在收银台选择,payload 传空字符串;三方支付(微信/支付宝)payload 固定传 'AP',同时 orderStr 里需要 nextAction、linkUrl、clientToken。
ASCF 1.0.9 新增 has.cashierPicker,可拉起通用收银台,不需要传复杂 orderStr,适合快速接入。它接收 tradeSummary、amount、currency,amount 单位是分。9900 分等于 99 元。成功回调里 res.selectedPaymentType 可能是 wechat_pay、ali_pay 等。
- has.cashierPicker({
- tradeSummary: '购买VIP会员',
- amount: 9900,
- currency: 'CNY',
- success: (res) => {
- console.info('用户选择了:', res.selectedPaymentType);
- }
- });
复制代码
IAP 流程复杂一些,但更适合虚拟商品。四步走:检查环境、查询商品、发起购买、确认发货。
第一步检查环境用 has.queryIapEnvStatus。如果用户没登录华为账号或地区不支持,直接调 createIap 会报错。地区不支持对应错误码 1001860054。
第二步查询商品用 has.queryIapProducts,传入 productType 和 productIds。商品类型包括:0 消耗型、1 非消耗型、2 自动续期订阅、3 非续期订阅。
第三步发起购买用 has.createIap。成功回调里的 res.purchaseData 是 JSON 字符串,解析后有 purchaseToken、purchaseOrderId 等。用户取消对应错误码 1001860000;您已拥有此商品对应 1001860051。
第四步确认发货用 has.finishIap。这个必须调,不然华为会认为你没发货,多次不确认可能触发自动退款。正确流程是:createIap 成功 → 服务端验证 → 发货 → finishIap。createIap 和 finishIap 的 productType 必须一致,商品在 AGC 配置成什么类型,代码里就传什么类型,类型不对会报错。
查询已购和补发货要用 has.queryIap。queryType 有三个值:0 所有购买记录,1 已购买未发货,2 当前有效的购买/订阅。启动时补发货用 1,检查订阅状态用 2。典型处理是:App onLaunch 时对 [0,1,2,3] 四个 productType 分别查询 queryType:1,如果 purchaseDataList 有数据,就解析并走服务端验证、发货、finishIap。
- has.queryIap({
- productType: 0,
- queryType: 1,
- success: (res) => {
- if (res.purchaseDataList && res.purchaseDataList.length > 0) {
- res.purchaseDataList.forEach((item) => {
- const data = JSON.parse(item);
- this.deliverGoods(data);
- });
- }
- }
- });
复制代码
这个补发货逻辑很重要。用户支付成功但 App 崩溃,没来得及发货,下次启动时用 queryIap 查未发货订单并补发。
沙盒测试用 has.isIapSandboxActivated。它只在 debug 包有效,release 包调用会报 1001860057。订阅管理用 has.showIapManagedSubscriptions,可跳转到订阅管理页,用户能在那里取消订阅、查看订阅状态。
实际场景里,VIP 会员购买可以用 IAP:先用 queryIapProducts 查询 vip_month、vip_year 等 productType 2 商品,用户点击后 createIap,成功拿到 purchaseData,发给服务端验证并发货,服务端确认成功后再 finishIap。华为支付下单则是先调服务端 createOrder 拿到 orderStr,再调 requestPayment;用户取消同样可处理 1001860000。
最后整理几个容易踩的坑。IAP 调用前先做 queryIapEnvStatus;finishIap 必须调;createIap 和 finishIap 的 productType 要对且一致;queryIap 的 queryType 要按场景选;华为支付的 orderStr 必须由服务端生成,前端不要自己拼签名;沙盒测试需要 debug 包;cashierPicker 的 amount 单位是分,别按元传导致多收 100 倍。
API 层面可记成两组。华为支付:has.requestPayment、has.cashierPicker。应用内购买 IAP:has.queryIapEnvStatus、has.queryIapProducts、has.createIap、has.finishIap、has.queryIap、has.isIapSandboxActivated、has.showIapManagedSubscriptions。开发前别忘了 AGC 的 Client ID、签名证书指纹、商户服务和 IAP 服务配置。
选型结论:实物商品、服务用华为支付;虚拟商品、订阅用 IAP。IAP 流程长一些,但查环境、查商品、购买、确认发货四步走通后就很顺畅,关键是 finishIap 一定不能漏。 |