鸿蒙h5支付

1,110 阅读1分钟

需求:

在鸿蒙的 web 中通过拦截url,实现h5拉起支付宝或者微信的支付

实现

实现的过程很简单,主要思路就是根据协议拦截url做处理即可。 目前h5拉起支付宝是没有问题的,但是微信支付暂时还不支持。这里就不得不夸奖下阿里,适配很积极,点赞👍

踩坑过程

拦截微信支付携带“Referer”的问题,目前发现onLoadIntercept返回的header数据是空数组,导致无法从header中拿取Referer,当再次执行loadUrl,因无法判断是否已经携带了Referer信息,导致无限循环进入拦截微信支付的逻辑,这里应该是鸿蒙web的问题,暂且解决的办法是在url中添加自定义Parameter。

代码实现

///web请求之前拦截
.onLoadIntercept((event)=>{
  if (!event) {return};
  const url = event.data.getRequestUrl()
  const headers = event.data.getRequestHeader()
  const shouldUrlIntercept = this.handleUrlIntercept(url,headers)
  return shouldUrlIntercept
})
///处理拦截逻辑
handleUrlIntercept(url:string,headers:Array<Header>): boolean {
  ///h5拉起支付宝/微信支付
  if (url.startsWith("alipays://") || url.startsWith("weixin://")){
    const ctx = getContext(this) as common.UIAbilityContext
    this.openUrlBySystemBrowse(ctx,url)
    return true
  }
  
  ///拦截h5微信支付添加Referer信息
  if (url.startsWith("https://wx.tenpay.com/"){
    const payKey = 'xxxxx'
    if(!this.getParameter(url, payKey)){
      ///获取referer
      const referer = this.controller.getUrl()
      /// url添加自定义 参数
      const crossUrl =  this.addParameter(url, payKey, '1')
      ///load一次
      this.controller.loadUrl(crossUrl,[{headerKey:"Referer",headerValue:referer}])
      return true
    }
  }
  return false
 }
 
///获取url参数
getParameter(url: string, name: string): string {
    const r = new RegExp('(\?|#|&)' + name + '=([^&#]*)(&|#|$)'); const m = url.match(r)
    return decodeURIComponent(!m ? '' : m[2])
  }

///往url中添加参数
addParameter(url: string, key: string, value: string): string {
    value = encodeURIComponent(value)
    if (url.indexOf(`${key}=`) > -1) {
      const reg = new RegExp(`${key}=(\w+)(&|#)?`)
      url = url.replace(reg, (match, $1: string, $2: string) => {
        return `${key}=${value}${$2 || ''}`
      })
    } else {
      if (url.indexOf('?') > -1) {
        url = url.replace('?', `?${key}=${value}&`)
      } else {
        url = `${url}?${key}=${value}`
      }
    }
    return url
}


///使用手机系统浏览器打开url
openUrlBySystemBrowse(context: common.UIAbilityContext,url:string): Promise<void> {
  let want: Want = {
    action: 'ohos.want.action.viewData',
    entities: ['entity.system.browsable'],
    uri: url,
  };
  return context.startAbility(want)
}