zoukankan      html  css  js  c++  java
  • Vue — 微信公众号内置h5支付相关

    首先,在公众号后台配置h5页面地址

    开发流程

    1.通过配置h5地址,获取code。再通过code,获取openid

    getOpenid(){
      let
    url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx697881XXXXXXXX&redirect_uri=https://XXXXX.com&response_type=code&scope=snsapi_userinfo&state=access#wechat_redirect'
      let self = this;   
      let access_code
    =this.GetQueryString('code');   
      let local
    = window.location.href;   
      if
    (access_code == null) {     
        window.location.href
    = url;   
      }
    else {     
        self.curCode
    = access_code;     
        self.$axios.get(self.baseUrl
    +'/api/weixin/openid/'+ self.curCode).then(res =>{       
          if
    (res.data.data.openid == ''){         
            window.location.href
    = url;
          }       
          self.openid
    = res.data.data.openid;
          self.token
    = res.data.data.token;
          localStorage.setItem(
    'openid',self.openid);
          self.getCerList();     
        })   
      }
    },
    GetQueryString(name){
    var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
    var r = window.location.search.substr(1).match(reg)
    if(r!=null)return unescape(r[2]); return null;
    }
     

    将获取到的openid和token保存起来(有时获取的openid为空,可以重新再获取一遍)

    2.提交支付,获取 prepay_id 和 appid

       saveForm: function () {
            var self = this;
            if(!self.checkForm()){
              self.$toast.center('输入有误,请检查');
              return false;
            }
            var data = {
              cert_id:self.curCertId,
              cert_name:self.curCertName,
              cert_type:0,
              wechat_id: localStorage.openid
            }
            self.$axios({
              method:"post",
              url:self.baseUrl+'/api/v1/weixin/applicants/users',
              headers:{
                'Content-Type': 'application/json'
              },
              data:data,
            }).then((res)=>{
              if(res.data.success){
                self.getOrderMsg();
              }else{
                self.$toast.center(res.data.msg);
              }
            })
          },
          getOrderMsg(){
            let self = this;
            let openid = localStorage.getItem('openid');
            self.$axios({
              method:"get",
              url:self.baseUrl+'/api/v1/weixin/wxorder/'+ openid +'/'+ self.curCertId,
            }).then((res)=>{
              if(res.data.success){
                let data = res.data.data;
                let price = data.price;
                if(price == 0){//免费
                  this.$router.push({path:'/Wait'});
                }else{
                  let appid = data.appid;
                  let prepayid = data.prepay_id;
                  let name = data.name;
                  let apikey = data.apikey;
                  let orderid = data.orderid;
    
                  this.$router.push({path:'/Order',query:{appid:appid,prepayid:prepayid,price:price,name:name,orderid:orderid,apikey:apikey}});
                }
    
    
              }else{
                self.$toast.center(res.data.msg);
              }
            })
    
    
          },

    3.参见 微信开发文档,逐一获得相关参数

    https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6

    data() {
          return {
            prepayid:'',
            price:'',
            name:'',
            orderid:'',
            apikey:'',
    
            timestamp:'',
            time:0,
            orderData:{
              appId:'',
              nonceStr:'',
              package:'',
              signType:'MD5',
              timeStamp:'',
            },
            paySign:'',
          }
        }
      getParams: function(){
            var self = this;
            self.orderData.appId = self.$route.query.appid;
            self.orderData.package = 'prepay_id=' + self.$route.query.prepayid;
            self.price = Number(self.$route.query.price)/100;
            self.name = self.$route.query.name;
            self.orderid = self.$route.query.orderid;
            self.apikey = self.$route.query.apikey;
    
            self.getOrderData();
          },
          getOrderData(){
            this.getTimeStamp();//获取时间戳
            this.orderData.nonceStr = this.getNonceStr(32);//获取32位随机数
            this.getPaySign(this.orderData);//生成签名
          },

    获取时间戳参数

    getTimeStamp(){
        const DATE = new Date();
        this.orderData.timeStamp = Date.parse(DATE)/1000 + '';//秒数 例如:1414561699
        this.time = this.formatDate();
    }
        formatDate() {//时间格式
            let date = new Date();
            let y = date.getFullYear();
            let MM = date.getMonth() + 1;
            MM = MM < 10 ? ('0' + MM) : MM;
            let d = date.getDate();
            d = d < 10 ? ('0' + d) : d;
            let h = date.getHours();
            h = h < 10 ? ('0' + h) : h;
            let m = date.getMinutes();
            m = m < 10 ? ('0' + m) : m;
            let s = date.getSeconds();
            s = s < 10 ? ('0' + s) : s;
            return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s;
          }

    获取随机数参数

      getNonceStr(n){//生成 n 位随机数
            let chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
            let res = "";
            for(let i = 0; i < n; i++) {
              let id = Math.ceil(Math.random() * 35);
              res += chars[id];
            }
            return res;
    
          }

    生成签名

        getPaySign(obj){
            let self = this;
            const params = [];
            Object.keys(obj).forEach((key) => {
              let value = obj[key]
              // 如果值为undefined我们将其置空
              if (typeof value === 'undefined') {
                value = ''
              }
              // 对于需要编码的文本(比如说中文)我们要进行编码
              // params.push([key, encodeURIComponent(value)].join('='))
              params.push([key, value].join('='))
            })
            let stringA = params.join('&');
            let stringSingTemp = stringA + '&key='+self.apikey;
            let sign = md5(stringSingTemp).toUpperCase();
            self.paySign = sign;
    var testparams = { "appId":self.orderData.appId, //公众号名称,由商户传入 "timeStamp":self.orderData.timeStamp, //时间戳,自1970年以来的秒数 "nonceStr":self.orderData.nonceStr, //随机串 "package": self.orderData.package, "signType":self.orderData.signType, //微信签名方式: "paySign":self.paySign, //微信签名 'key':self.apikey } }

    可以通过 签名校验工具 进行验证

    4.调起微信支付接口

        pay(){
            let self = this;
            if (typeof WeixinJSBridge == "undefined"){
              if( document.addEventListener ){
                document.addEventListener('WeixinJSBridgeReady',self.onBridgeReady,false);
              }else if (document.attachEvent){
                document.attachEvent('WeixinJSBridgeReady', self.onBridgeReady);
                document.attachEvent('onWeixinJSBridgeReady', self.onBridgeReady);
              }
            }else{
              self.onBridgeReady();
            }
    
          },
       onBridgeReady(){
            let self = this;
            var params = {
              "appId":self.orderData.appId,//公众号名称,由商户传入
              "timeStamp":self.orderData.timeStamp,//时间戳,自1970年以来的秒数
              "nonceStr":self.orderData.nonceStr,//随机串
              "package": self.orderData.package,
              "signType":self.orderData.signType,//微信签名方式:MD5
              "paySign":self.paySign,//微信签名
            };
            WeixinJSBridge.invoke('getBrandWCPayRequest',params ,function(res){
              if(res.err_msg == "get_brand_wcpay_request:ok"){
                self.$router.push('/Wait');
              }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
                self.$toast.center('取消支付!');
              }else{
                alert(JSON.stringify(res));
              }
            });
          },

    这是调起支付密码页面

     支付成功后跳转到wait等待页面

  • 相关阅读:
    python 数据类型 变量 注释
    tornado 模版
    tornado 响应头 中断 状态码 工作流程
    tornado write render redirect IP
    tornado样板
    Celery实现异步任务
    Python pika简单实现RabbitMQ通信
    进程、线程与协程的比较
    使用 flask 实现 RESTful API
    阿里云服务器部署Tornado应用
  • 原文地址:https://www.cnblogs.com/lingnweb/p/9964677.html
Copyright © 2011-2022 走看看