• 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支付

        同微信h5支付流程,配置H5支付域名略有不同

  • 相关阅读:
    H5系列之drag拖放
    H5系列之contenteditable
    H5系列之新input
    利用css3和js实现旋转木马图片小demo
    利用css3实现照片列表展开小demo
    reduce()、filter()、map()、some()、every()、...展开属性
    ES6,ES7,ES8,ES9,ES10新特性
    Web Components 是什么?它为什么对我们这么重要?
    vscode常用快捷键以及插件
    使用for..in时会遍历对象原型中的自定义属性
  • 原文地址:https://www.cnblogs.com/huangfeihong/p/16330015.html
Copyright © 2020-2023  润新知