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

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

一、前言

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

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

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

注意

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

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

Bundle ID: developer.huawei.com/consumer/cn...

appIdentifier: developer.huawei.com/consumer/cn...

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

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

(2)接入方式: 在你项目的oh-package.json5的dependencies中配置sdk依赖:

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

二、支付流程整体步骤:

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

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

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

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

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

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

三、详细步骤拆解

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

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

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

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

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

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

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

步骤1:创建WXApi实例

typescript 复制代码
import * as wxopensdk from '@tencent/wechat_open_sdk';

// 传入移动应用的AppID(注意:需使用移动应用AppID,不可用小程序AppID)
export const WXApi = wxopensdk.WXAPIFactory.createWXAPI(APP_ID);

步骤2:实现回调处理

typescript 复制代码
// 实现微信数据回调接口
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:发送登录请求

typescript 复制代码
// 构建登录请求参数
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中处理回调

typescript 复制代码
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)后,调用关单接口就行,关单后订单就成失败终态了。

请求支付:

typescript 复制代码
IWXAPI api;
let req = new wxopensdk.PayReq
req.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)

支付返回

typescript 复制代码
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函数处理数据(参考代码示例)。

typescript 复制代码
// 官方文档链接参见:
https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Pay/Android.html
相关推荐
Georgewu15 小时前
【HarmonyOS】鸿蒙应用实现微信登录-最新版
harmonyos
二流小码农17 小时前
鸿蒙开发:一键更新的内测打包工具“火了”
android·ios·harmonyos
HarmonyOS_SDK21 小时前
Car Kit重构车机开发体验,让车载应用开发驶入快车道
harmonyos
zhanshuo1 天前
HarmonyOS 网络请求优化实战指南:从0到1写出流畅不卡顿的应用!
harmonyos
搜狐技术产品小编20231 天前
鸿蒙搜狐新闻如何在Native调用ArkTS方法
华为·harmonyos
迷曳2 天前
21、鸿蒙Harmony Next开发:组件导航(Navigation)
前端·harmonyos·鸿蒙·navigation
腾讯云qcloud07552 天前
腾讯位置商业授权鸿蒙地图SDK工程配置
华为·harmonyos
迷曳2 天前
29、鸿蒙Harmony Next开发:深浅色适配和应用主题换肤
ui·华为·harmonyos·鸿蒙
迷曳2 天前
30、鸿蒙Harmony Next开发:应用文件上传下载,压缩与解压
华为·harmonyos·文件处理