• vue--支付宝+微信--支付


    微信支付

    1 PC网页集成 微信支付 native 生成 付款二维码 扫码直接支付 (二维码带价格)

    后端 生成 微信返回的 response 中的 code_url

    前端 A

    将 URL 转换成 二维码 展示即可 或者 后端生成二维码 前端获取该二维码图片 展示
    qrcodejs 二维码生成插件

    支付结果通知 微信调用 后台接口 后台按照规范应答 或者 后台主动查询订单
    对应 后端 Map 参数中 “notify_url”:“供 微信调用的后台接口”

    前端 B

    支付完成 pay/callback 回调页展示 – XXXX/#/pay/callback

    方式一

    后端使用 goEasy 推送 给前端 前端跳转 pay/callback socket 发送 接收的 channel 名字 使用 唯一的 订单号

    方式二

    前端 轮询 后端 得到 跳转 指令 后 前端跳转 pay/callback http

                let timer = null
                if(timer) return
                timer = setInterval(async()=>{
                // 发请求获取用户支付状态
                let result = await API.reqPayStatus(orderId)
                // 如果code===200
                if(result.code===200){
                  // 第一步:清除定时器
                  clearInterval(timer)
                  timer = null
                  // 保存支付成功返回的code
                  code.value = result.code
                  // 关闭弹出框
                  msgBox.close()
                  // 跳转到下一路由 查询订单操作
                  router.push('pay/callback')
                }
              },2000)
        // 组件销毁  也要 清除定时器
        onBeforeUnmount(()=>{
          clearInterval(timer)
          timer = null
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2 手机端 微信扫一扫 前端页面 – JSAPI 支付 点击 调用 微信支付框 支付 微信内支付

    微信内 支付 没有 openID–code 需要授权获取

    这个也分两种

    1、跳转授权页
    2、静默授权,只获取code,后端凭借code换取openId,也称静默授权 parking为静默

    流程

    1 看 URL是否有 code 没有需要 授权获取 重定向为当前页 重新获取 code 就可以拿到 可以理解为 先静默后跳转
    2 获取code
    3 调用 后台接口 传递 code 并且获取 调起支付的 参数

    // created阶段   微信内
    let openId = null
    const ua = window.navigator.userAgent.toLowerCase();
    if(ua.match(/MicroMessenger/i) == 'micromessenger'){
      getCode()
    }
    
    const getCode = () =>{
       // 服务号id
     const appid = 'XXX'
     const local = window.location.href
     // 截取路径中的 code,如果没有就去微信授权,如果已经获取到了就直接传code给后台获取openId
     // 静默获取 code
     openId = GetUrlParam('code')
     // 获取不到  跳转授权
       if (openId == null || openId === '') {
        window.location.href =
          'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + appid + '&redirect_uri=' + encodeURIComponent(local) + '&response_type=code&scope=snsapi_base&state=#wechat_redirect'
      }
    }
    // 注意 变量提升  应该放在调用之前
      const GetUrlParam = code => {
      var reg = new RegExp('(^|&)' + code + '=([^&]*)(&|$)')
      let url = window.location.href.split("#")[0]
      let search = url.split('?')[1]
      if (search) {
        var r = search.substr(0).match(reg)
        if (r !== null) return unescape(r[2])
        return null
      } else {
        return null
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    // 调用后台接口 传递 code + 其他参数   并且获取 调起支付的 参数
    // 定义 调用 微信支付 的参数
    let payInfo = null
    // data 内包含 code--openId
    findParkingInfo(data).then(({ data }) => {
    				if (!data) {
    					alert('数据错误,请联系管理员')
    					return
    				}
    				// 车牌 第二个 字符 插入 圆圈··· •
    				showInfo.carId = data.carid.replace(/^(.{2})/, '$1 · ')
    				showInfo.money = data.money
    				showInfo.parkName = data.parkname
    				// 赋值  微信支付 数据
    				payInfo = data.paystream
    			})
    			
    // onClick-->doPay(payInfo)
    // 发起微信支付
    const doPay = () => {
      // btnDisabled.value = true
      isIn ? inWeiXin(payInfo) : outWeiXin()
    	}
    
    // 微信内支付
    const inWeiXin = params => {
    	if (typeof WeixinJSBridge === 'undefined') {
    		if (document.addEventListener) {
    			document.addEventListener(
    				'WeixinJSBridgeReady',
    				onBridgeReady(params),
    				false
    			)
    		} else if (document.attachEvent) {
    			document.attachEvent('WeixinJSBridgeReady', onBridgeReady(params))
    			document.attachEvent('onWeixinJSBridgeReady', onBridgeReady(params))
    		}
    	} else {
    		onBridgeReady(params)
    	}
    }
    
    // 搭桥onBridgeReady()
    const onBridgeReady = weChatParameter => {
    	// const timestamp = Math.round(weChatParameter.timeStamp).toString()
    	window.WeixinJSBridge.invoke(
    		'getBrandWCPayRequest',
    		{
    			debug: false,
    			/*
    			appId: weChatParameter.appId, // 公众号名称,由商户传入
    			timeStamp: timestamp, // 时间戳,自1970年以来的秒数
    			nonceStr: weChatParameter.nonceStr, // 随机串
    			package: weChatParameter.package,
    			signType: weChatParameter.signType, // 微信签名方式:
    			paySign: weChatParameter.paySign, // 微信签名
    			*/
    			...weChatParameter,
    			jsApiList: ['chooseWXPay'],
    		},
    		function (res) {
    			// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
    			if (res.err_msg === 'get_brand_wcpay_request:ok') {
    				// 支付成功后的操作
    				// alert('支付成功')
    				router.replace({
    					path: '/success',
    					query: { message: '支付成功,一路顺风' },
    				})
    			} else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
    				// 取消支付的操作
    				// 取消支付
    				router.replace({
    					path: '/success',
    					query: { message: '支付取消,请重新支付' },
    				})
    			} else {
    				// 支付失败
    				router.replace({
    					path: '/success',
    					query: { message: '支付失败,请重新支付' },
    				})
    			}
    		}
    	)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    3 手机端 H5页面 手机端浏览器集成 微信支付 --H5 支付 调用 微信支付框 支付 微信外支付

    location.replace(‘后端地址? XXXXX’ 最后拼接 redirect_url = encodeURIComponent(“XXXX/callback”) 需要回调地址 encodeURIComponent

    location.href 尽量用 replace

    // 微信外支付
    const outWeiXin = async () => {
    	// 项目支付相关的参数
    	// requestPay 后台接口 返回 跳转 URL
    	// const { params } = await requestPay()
    	// 返回成功  跳转
    	if (params) {
    		window.location.replace(params)
    	} else {
    		// '提交订单失败'
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    callback 页面 1 支付完成 2 支付取消 3 5秒不操作 都会跳转 所以此页面应该查询 订单状态 而不是直接显示成功

    查询订单操作 后台接口 orderId trade_state :SUCCESS

    注意

    vue 哈希路由模式,微信回跳会把 # 后全部干掉,等于直回跳个域名,无法跳转 #/callback
    解决方案: 可以自己拼接,把#省去,浏览器在访问时,会自动加上

    支付宝支付

    1 PC端 网页直接调起 支付宝支付

      // 同 QQ 登陆  AAAA-->127.0.0.1:8080
    		const redirect = encodeURIComponent(
    			'AAAA/pay/callback'
    		)
        const payUrl = `${baseURL}pay/aliPay?orderId=${route.query.orderId}&redirect=${redirect}`
      // 新开窗口   支付完后  跳转  AAAA/pay/callback
        const aliPay = () => {
    			window.open(payUrl)
    		}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    查询订单操作 后台接口 orderId trade_state :SUCCESS

    2 PC端 二维码支付 同 微信 native 支付

    查询订单操作 后台接口 orderId trade_state :SUCCESS

    3 手机端 类似 微信 内外 支付宝不区分

    getApplyAliPay({
        // 传递的其它参数
        orderNumber: orderNumber,
        // 支付成功之后重定向的地址
        paySuccessUrl: 'xxx'
      }).then(res => {
        const div = document.createElement('div')
        div.id = 'aliPay'
        div.innerHTML = res
        document.body.appendChild(div)
        // 执行后会唤起支付宝
        document.querySelector('#aliPay').children[0].submit()
      })
    
    // paySuccessUrl  -- 查询订单操作
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    查询订单操作 后台接口 orderId trade_state :SUCCESS

    分享 vue-shares

  • 相关阅读:
    Mac 点击桌面 出现黑边框 解决
    SpFFmpeg音视频开发1:Linux开发环境下常用Shell脚本语法
    达人评测r9 5900hx和i5 12500h选哪个好
    echarts配合google地图,并自定义google地图的样式
    Java面试题总结(一)
    在Android中实现动态应用图标
    盘盘在项目中你常用的那些数组API
    Python实现办公自动化读书笔记——自动化处理Word文档
    java毕业设计权益会员管理源码+lw文档+mybatis+系统+mysql数据库+调试
    红包派送逻辑代码
  • 原文地址:https://blog.csdn.net/u014105655/article/details/128150481