公众号调用微信扫一扫(记录)

1,506 阅读4分钟

前几天写了一个B扫C,管理员登录公众号扫用户微信付款码,类似于超市收银员扫我们的手机一样,第一次做这种,就把流程写下来!

B扫C

1.首先第一步要先设置安全域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

备注:登录后可在“开发者中心”查看对应的接口权限。


2.引入js文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js

如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)。

安装:npm install  weixin-js-sdk

引入:let wx = require('weixin-js-sdk');

备注:支持使用 AMD/CMD 标准模块加载方法加载

3.通过config接口注入权限验证配置

let timestamp = DateFmt.Formate(DateFmt.DateCalc(new Date(), 'd', 0), 'yyyyMMddHHmmss'); 
let curUrl = window.location.href.split('#')[0];                
let nonceStr = uuids(16, 16);                
let jsapiTicket = data.retData.ticket;                
let appid = data.retData.appid;                
let before = 'jsapi_ticket=' + jsapiTicket + '&noncestr=' + nonceStr + '&timestamp=' + timestamp + '&url=' + curUrl;
let signature = sha1(before);                
wx.config({                    
    debug: false, // 开启调试模式
    appId: appid, // 必填,公众号的唯一标识                    
    timestamp: timestamp, // 必填,生成签名的时间戳                    
    nonceStr: nonceStr, // 必填,生成签名的随机串                    
    signature: signature, // 必填,签名                    
    jsApiList: ['scanQRCode']                

appid是公众号的唯一标识,可以让后端返回。

timestamp是生成当前时间的时间戳

nonceStr是生成一个随机串

jsapi_ticket是公众号用于调用微信JS接口的临时票据,让后端返回

signature是签名,生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

即signature=sha1(string1)。

jsApiList是需要使用的js接口列表

4.验证成功就可以写逻辑

let that = this;
wx.scanQRCode({                        
    needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
    scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
    success: function(res) {                            
        let result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果                            
        let barCode = that.getBarCode(result);                            
     
        这里掉后端接口,把barCode用户的付款码传给后端             },                            fail: function(res) {                            
        console.log(res);                       
     }
});

引入js-sdk文件

let wx = require('weixin-js-sdk');

调起微信扫一扫接口

1.这里注意this指向

2.needResult要改成1,我们只要结果

wx.scanQRCode({
  needResult: 0, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
  scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
  success: function (res) {
    var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
    }
})

获取返回结果

var result = res.resultStr;

3.result为用户的付款码,苹果扫苹果手机当时正常,当苹果扫安卓手机的时候返回的结果带一个CODE_128。例:CODE_128,134564512168951760;这个时候就要把CODE_128截取掉;CODE_128是一种条码类型值

let result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果                            
let barCode = that.getBarCode(result);  

调用getBarCode方法截取code_128

getBarCode(resultStr) {            
    let serial = resultStr.split(',');           
    let barCode = serial[serial.length - 1];            
    return barCode;        
};

最后把用户的付款码传给后端,具体扣款逻辑在后端!

PS:此次项目,前端都是axios的get请求,在苹果手机上是没有问题的,在安卓所有机型上就不行,status为0,报错为Network Error(网络错误)。这个时候就考虑到是Promise,es6语法等兼容性问题,后来确定是get请求URL拼接的参数过长导致的,然后就改用post请求,就遇到了新问题,前端post请求所有参数传过去,后端日志收到的都是null,

传过去是这样的,status为200,部分参数后端还是接收不到。

问题分析:也就是说,我们的 Content-Type 变成了 application/json;charset=utf-8然后,因为我们的参数是 JSON 对象,axios 帮我们做了一个 stringify 的处理。 而且查阅 axios 文档可以知道:axios 使用 post 发送数据时,默认是直接把 json 放到请求体中提交到后端的。

解决方案一:引入 qs ,这个库是 axios 里面包含的,不需要再下载了。

import Qs from 'qs';

return new Promise((resolve, reject) => {       
 axios({            
    url: url,            
    method,            
    params: isGet ? params : '',            
    data: isGet ? '' : Qs.stringify(params),
     ...config        
 }).then(rep => 

Qs.stringify()将对象 序列化成URL的形式,以&进行拼接

这样才完美解决!试了华为,vivo,oppo,等各种主流机型都没有问题。只有一个小米低版本目前还是存在一些问题!

结尾:第一次写文章,写的比较乱,以后会争取每周写一篇文章,有写的不好的地方或者有更好的代码可以贴出来一起讨论,互相学习,望大家指点交流!