h5各端支付接入纪录

一、微信公众号支付(微信jsapi支付)

  1、开发准备

    1.1、公众号需要开通微信支付功能

    1.2、到微信商户平台 https://pay.weixin.qq.com 注册一个商户账号,并关联你的公众号,如果需要实现小程序支付的,需要关联小程序

    1.3、配置支付授权目录,登录商户平台 -> 产品中心 -> 开发配置 -> JSAPI支付 -> 支付授权目录(当前支付页面域名)

    1.4、设置API密钥,登录商户平台 -> 账户中心 -> API安全 -> API密钥

    1.5、配置JS接口安全域名与网页授权域名,登录公众平台https://mp.weixin.qq.com -> 公众号设置 -> 功能设置 -> 配置JS接口安全域名和网页授权域名  

      配置网页授权域名:主要用于获取用户的openId,需要识别这是哪个人。

      配置JS接口安全域名:要让我们的页面中弹出输入密码的窗口,需要使用微信提供的JS-SDK工具,如果不配置JS接口安全域名,你的页面无法使用JS-SDK

      注意:如果提示访问当前域名出错,则可能是验证文件(例如:MP_verify_9NHz19oBkiqQc3L7.txt)没有下载并上传到域名可访问到的服务器上

  2、前端开发
    2.1、首次进入页面,请求微信指定地址换取code,参考文档https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0
const getWeChatCode = () => {
 const APPID = ''
 const { origin, pathname, search } = window.location  const href
= origin + pathname + search window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APPID}&redirect_uri=${encodeURIComponent(href)}&response_type=code&scope=snsapi_base&state=state#wechat_redirect` }

     2.2、拿第二部换取到的code,请求后端接口换取token,换取到token写入本地缓存(不强制写入本地缓存,可以每次都重新获取token)

const getAuthToken = async () => {
 const { data }
= await Apis.GET_JSAPI_AUTH({ code })

 if (data?.token) localStorage.setItem('authToken', data.token) }

    2.3、点击支付按钮,请求后端预支付接口(相关订单参数和第二步获取的token),返回订单相关参数,通过微信JS-SDK的getBrandWCPayRequest方法调起微信支付窗口,自行处理支付后的回调,参考文档https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_3.shtml

 /**
 * 微信公众号支付
 * payParams: 预支付接口参数
 */
const weixinGzhPay = async (payParams) => {
 const authToken = localStorage.getItem('authToken') || ''   
if (authToken) {   const { data } = await Apis.GET_JSAPI_PREORDER({ ...payParams, token: authToken })
  if (data?.['token_expired'] === TOKEN_EXPIRED) {     localStorage.removeItem('authToken')     getWeChatCode()     return false
  }
  const { app_id: appId, timestamp: timeStamp, nonce_str: nonceStr, package: pack, sign_type: signType, pay_sign: paySign } = data
  const result: any
= await weChatPay({ appId, timeStamp: `${timeStamp}`, nonceStr, package: pack, signType, paySign })
  console.log(
'pay_result', result)
  if (result?.['err_msg'] === 'get_brand_wcpay_request:ok') {
    Toast.info(
'支付成功', 2)   } else {     Toast.info('支付失败', 2)   }
 }
else {
  getWeChatCode()
 }
}
const weChatPay = (WechatPayParams) => {
  console.log('wechatPayParams', wechatPayParams)
  return new Promise((resolve, reject) => {
    function onBridgeReady() {
      // 记录支付参数,用户取消支付时,则直接使用
      window.WeixinJSBridge.invoke('getBrandWCPayRequest', wechatPayParams, function(res) {
        if (res.err_msg === 'get_brand_wcpay_request:ok') {
          // 使用以上方式判断前端返回,微信团队郑重提示:
          // res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
          resolve(res)
        } else {
          console.log('res.err_msg:', res.err_msg)
          reject(res)
        }
      })
    }
    if (typeof window.WeixinJSBridge === 'undefined') {
      if (document.addEventListener) {
        document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false)
      } else if (document['attachEvent']) {
        document.attachEvent('WeixinJSBridgeReady', onBridgeReady)
        document.attachEvent('onWeixinJSBridgeReady', onBridgeReady)
      }
    } else {
      onBridgeReady()
    }
  })
}

    2.4、非首次访问页面

    缓存了token:查看本地缓存的token是否过期,过期则执行2.1、2.2,支付走2.3

    未缓存token:直接执行2.1、2.2,支付走2.3

 

二、支付宝内部支付(支付宝jsapi支付)

  支付宝jsapi引入地址://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js

  1、开发准备

    账号申请、开发配置

  2、前端开发

    2.1、首次进入页面,请求支付宝指定地址换取code,参考文档:https://opendocs.alipay.com/open/284/web

const getAliPayCode = () => {
  const ALIPAY_APPID = ''
  const href = origin + pathname + search
  window.location.href = `https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=${ALIPAY_APPID}&scope=auth_base&redirect_uri=${encodeURIComponent(href)}&state=state#apipay_redirect`
}

    2.2、拿第二部换取到的code,请求后端接口换取需要的参数

let userId = ''
const getAliOauth = async () => { const { data } = await Apis.GET_ALI_OAUTH({ grant_type: 'authorization_code', code: AUTH_CODE }) if (data?.user_id) userId = data.user_id
}

    2.3、点击支付按钮,请求后端预支付接口(相关订单参数和第二步获取的参数),返回订单相关参数trado_no,通过支付宝的alipayjsapi的tradePay方法调起支付宝支付窗口,自行处理支付后的回调参考文档:https://myjsapi.alipay.com/alipayjsapi/util/pay/tradePay.html

  const ALI_PAY_SUCCESS: string = '9000'
const aliJsApiPay = async payParams => {
  if (userId) {
    const { data } = await Apis.POST_PHONE_PAY({ alipay_uid: userId, { ...payParams } })if (data?.trade_no) {
      try {
        const res = await aliPay(data.trade_no)
          if (res?.resultCode === ALI_PAY_SUCCESS) {
          Toast.info('支付成功', 2, () => {
            const { origin } = window.location
            window.location.replace(`${origin}${REDIRECT_URL_MAP[paySource]}?chl_click_id=${chlClickId}&biz_order=${data.order_id}&phoneNum=${phone}&userId=${userId}`)
          })
        } else {
          Toast.info('支付失败')
        }
      } catch {
        Toast.info('支付失败')
      }
    }
  }
}
const aliPay = tradeNo => {
  return new Promise((resolve, reject) => {
    window['ap'].tradePay({
      tradeNO: tradeNo
    }, function (res) {
      resolve(res)
    }, function (err) {
      reject(err)
    })
  })
}

 

三、h5支付

  1、微信h5支付,参考文档:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_6_2.shtml

    1.1、开发前准备,配置H5支付域名,登录商户平台 -> 产品中心 -> 开发配置 -> H5支付 -> H5支付域名(当前支付页面域名)

    1.2、前端开发,请求后端预支付接口,获取相关支付链接,前端跳转到此链接进行支付

/**
 * h5支付(微信h5、支付宝h5)
 * payParams: 支付接口参数
 */
const h5Pay = async payParams => {
  const { data } = await Apis.POST_PRE_ORDER({ ...payParams })
  if (data?.['mweb_url'] !== '') window.location.href = data.mweb_url
}

    1.3、后端配置支付回跳地址页面,在回跳页面查询当前订单是否支付成功

  2、支付宝h5支付

    2.1、微信内部

      2.1.1、判断是否在微信内部,在微信内部就弹出遮罩层,提示去浏览器支付,接下来继续执行微信外部浏览器支付逻辑(可能需要对token进行一些处理)

    2.2、微信外部浏览器

      2.2.1、通过后端接口获取form表单对应的html字符串,渲染到页面上,点击支付按钮吊起支付宝支付(可以在原支付页面也可以新增一个支付宝支付承接页面)

 

posted @ 2022-05-31 12:13  狮子爱吃草  阅读(487)  评论(0编辑  收藏  举报