> 技术文档 > 【HarmonyOS】鸿蒙应用实现微信支付-最新版_鸿蒙微信支付弹窗

【HarmonyOS】鸿蒙应用实现微信支付-最新版_鸿蒙微信支付弹窗


【HarmonyOS】鸿蒙应用实现微信支付-最新版

一、前言

最近做了鸿蒙应用集成微信支付的功能,踩了不少坑,整理了一下完整流程和注意事项,希望能帮到有需要的同学。

1、微信开放平台配置应用信息:
在接入过程之前,我们需要在微信开放平台,注册自己的应用,开启支付权限。理论上这些都应该是运营提前做好,不过在这里也事先讲一下。

需在微信开放平台完成移动应用的创建/配置,获取AppID并填写鸿蒙应用信息:
创建/修改应用:进入「管理中心 - 移动应用」,新建应用或在已有应用的「开发配置」中编辑鸿蒙信息。
填写关键信息
Bundle ID:鸿蒙应用的包名(见下方链接)。
Identifier:鸿蒙应用的appIdentifier(见下方链接)。
【HarmonyOS】鸿蒙应用实现微信支付-最新版_鸿蒙微信支付弹窗

注意
若应用已上架Android/iOS市场,需选择「已上架至少一个应用市场」并填写备案号;仅鸿蒙未上架时,可按需选择上架状态

「未上架任何应用市场」选项仅适用于Android、iOS、鸿蒙均未上架的情况,此类应用使用微信能力会受限,需谨慎选择。

Bundle ID:
https://developer.huawei.com/consumer/cn/doc/app/agc-help-createharmonyapp-0000001945392297

appIdentifier:
https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-bundlemanager-bundleinfo-V5

2、鸿蒙应用接入微信OpenSDK:
(1)sdk在OH三方库的地址:

// 把地址放到浏览器打开,查看最新的版本号,如我下方截图所示,是最近的最新版本信息。https://ohpm.openharmony.cn/#/cn/detail/@tencent%2Fwechat_open_sdk

【HarmonyOS】鸿蒙应用实现微信支付-最新版_鸿蒙微信支付弹窗
(2)接入方式:
在你项目的oh-package.json5的dependencies中配置sdk依赖:

{ \"name\": \"demo\", \"version\": \"1.0.0\", \"description\": \"Please describe the basic information.\", \"main\": \"\", \"author\": \"\", \"license\": \"\", \"dependencies\": { \"@tencent/wechat_open_sdk\": \"1.0.14\" }}

二、支付流程整体步骤:

【HarmonyOS】鸿蒙应用实现微信支付-最新版_鸿蒙微信支付弹窗

简单说,整个支付流程大概是这样:

1、商户后端先调用微信的APP支付下单接口,拿到一个prepay_id

2、然后在商户的鸿蒙APP里,通过微信OpenSDK的sendReq方法调起微信,用户在微信里完成支付(或取消)

3、之后会跳转回商户APP,这时候前端会收到回调,一定要记得让后端调用查询订单接口确认状态(别光信回调里的信息)

4、支付成功的话,微信还会发个支付成功的回调通知给后端

5、最后就是对账和可能的退款操作了。

三、详细步骤拆解

【HarmonyOS】鸿蒙应用实现微信支付-最新版_鸿蒙微信支付弹窗

1、 拿到prepay_id是第一步,用于商户下单:

首先得调用微信的APP支付下单接口,核心是获取prepay_id(预支付交易会话标识),这是后面调起支付的关键。

这里有两个时间点要特别注意:

time_expire:可以设置订单的支付结束时间。超过这个时间用户再支付,会提示“订单已超过最晚支付时间”,这时候商户得做关单处理。如果不设置,默认订单7天内有效,7天后微信会自动关单。

prepay_id有效期:这个ID只有2小时!过期了就得用原来的下单参数重新调用接口拿新的,别想着复用。

2、OpenSDK接入,来调起支付:

拿到prepay_id后,就该调起微信支付了。首先得接入微信的OpenSDK(建议用最新版,兼容性更好),然后通过OpenSDK的sendReq方法调起微信支付页面。

步骤1:创建WXApi实例
import * as wxopensdk from \'@tencent/wechat_open_sdk\';// 传入移动应用的AppID(注意:需使用移动应用AppID,不可用小程序AppID)export const WXApi = wxopensdk.WXAPIFactory.createWXAPI(APP_ID);
步骤2:实现回调处理
// 实现微信数据回调接口class WXApiEventHandlerImpl implements wxopensdk.WXApiEventHandler { private onReqCallbacks: Map<OnWXReq, OnWXReq> = new Map(); private onRespCallbacks: Map<OnWXResp, OnWXResp> = new Map(); // 注册/取消注册回调 registerOnWXReqCallback(on: OnWXReq) { this.onReqCallbacks.set(on, on); } unregisterOnWXReqCallback(on: OnWXReq) { this.onReqCallbacks.delete(on); } registerOnWXRespCallback(on: OnWXResp) { this.onRespCallbacks.set(on, on); } unregisterOnWXRespCallback(on: OnWXResp) { this.onRespCallbacks.delete(on); } // 处理来自微信的请求 onReq(req: wxopensdk.BaseReq): void { this.onReqCallbacks.forEach(on => on(req)); } // 处理微信返回的响应 onResp(resp: wxopensdk.BaseResp): void { this.onRespCallbacks.forEach(on => on(resp)); }}export const WXEventHandler = new WXApiEventHandlerImpl();
步骤3:发送登录请求
// 构建登录请求参数let req = new wxopensdk.SendAuthReq();req.scope = \'snsapi_userinfo\'; // 授权范围req.state = \'none\'; // 自定义状态值req.transaction = \'test123\'; // 事务标识// 发送请求(context为UIAbilityContext,从组件中获取)let finished = await WXApi.sendReq(context, req);// finished为true表示跳转微信成功,false可能因微信未安装导致
步骤4:在EntryAbility中处理回调
export default class EntryAbility extends UIAbility { onCreate(want: Want, _launchParam: AbilityConstant.LaunchParam): void { this.handleWeChatCallIfNeed(want); } onNewWant(want: Want, _launchParam: AbilityConstant.LaunchParam): void { this.handleWeChatCallIfNeed(want); } // 处理微信返回的Want数据 private handleWeChatCallIfNeed(want: Want) { WXApi.handleWant(want, WXEventHandler); }}

3、 用户支付:回调处理和订单确认是关键

用户在微信里完成支付或取消支付后,会跳转回商户APP,这时候前端会收到OpenSDK的onResp回调。划重点:千万别只靠这个回调就判断支付状态! 必须让后端调用查询订单API,确认真实的订单状态后再处理业务(比如展示支付结果、更新系统订单状态)。

如果需要限制用户支付时间,有两种方式:

  1. 下单时用time_expire参数设置结束时间,超时后做关单;
  2. 自己系统里做倒计时,超时后主动关单。

另外,如果想在有效期内主动关闭未支付的订单,先查一下订单状态,确认是未支付(NOTPAY)后,调用关单接口就行,关单后订单就成失败终态了。

请求支付:

IWXAPI api;let req = new wxopensdk.PayReqreq.appId = \'wxd930ea5d5a258f4f\'req.partnerId = \'1900000109\'req.prepayId = \'1101000000140415649af9fc314aa427\'req.packageValue = \'Sign=WXPay\'req.nonceStr = \'1101000000140429eb40476f8896f4c9\'req.timeStamp = \'1398746574\'req.sign = \'oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT+Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV+JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu+LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2+AehHvz+n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\\/xDg==\'api.sendReq(context: common.UIAbilityContext, req)

支付返回

onResp(resp: wxopensdk.BaseResp): void {Log.i(kTag, \"onResp:%s\", JSON.stringify(resp))this.onRespCallbacks.forEach((on) => {on(resp)})}

4、 对账和退款

对账可以参考微信的“账单产品介绍”,按官方指引来就行。

如果需要退款,调用退款接口即可,不过要注意:只有支付成功1年内的订单才能申请退款。

三、订单状态总览:

最后梳理下订单状态的流转逻辑,这个理清楚了,业务处理就不容易出错:

1、下单成功后,订单状态是未支付(NOTPAY),这时候用户可以支付

2、用户支付成功,状态变成支付成功(SUCCESS);如果支付失败,还是NOTPAY

3、未支付的订单,要么超过7天(或设置的time_expire)被自动关单,要么被商户主动关单,状态会变成已关闭(CLOSED)

4、 支付成功(SUCCESS)的订单,申请退款后,状态会变成转入退款(REFUND),退款状态可以查退款单确认

5、有三个终态要记牢:CLOSED(已关闭)、SUCCESS(支付成功)、REFUND(转入退款),到了这三个状态就不会再变了。

常见问题

1、如何判断微信是否安装?
通过WXApi.isWXAppInstalled()判断,需在module.json5中添加相关声明(参考「使用canOpenLink判断应用是否可访问」)。

2、登录失败:Bundle ID校验不通过?
原因:鸿蒙应用信息提交后未审核通过(审核中/驳回),或审核通过但appid + identifier + bundleId不匹配。
解决:重新提交审核,确保信息与微信开放平台配置一致。

3、第三方应用信息校验失败?
可能原因:
createWXAPI传入的AppID错误(需为移动应用AppID,不可用小程序/AppID);
微信开放平台配置的Identifier与应用实际appIdentifier不一致。
建议:检查AppID正确性,确认Identifier匹配,避免使用IDE自动生成的测试签名(可申请测试用移动应用账号)。

4、App如何接收微信返回的数据?
需配置action为wxentity.action.open,并通过实现WXApiEventHandleronReq函数处理数据(参考代码示例)。

// 官方文档链接参见:https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Pay/Android.html