• vue+vant打包,vue+vant-ui小程序,微信支付


    微信JS支付代码_前端调用微信支付接口

    其实参照官方文档一步一步操作不是很难,但很多人在签名这个地方就总是出现问题,因为文档中签名时使用的字段大小写时错误的。。。。好坑啊!!然而PHP版本的代码官方有封装SDK包,不用操心那么多细节。

    NODEJS版本的只能自己写了。

    1.签名方法(简单不会错)

    //签名;
    //mchkey是你在支付平台设置的一个API密钥
    function MSign(param, mchkey){
    var string = raw(param);
    string = string + '&key=' + mchkey; //key拼接在字符串最后面
    var crypto = require('crypto');
    return crypto.createHash('md5').update(string, 'utf8').digest('hex').toUpperCase();
    }
    //args是一个JSON,方法将json中的字段按照ASCII码从小到大排序,生成一个字符串key1=value1&key2=value2。
    function raw(args) {
    var keys = Object.keys(args);
    keys = keys.sort();
    var newArgs = {};
    keys.forEach(function (key) {
    newArgs[key] = args[key];
    });
    var string = '';
    for (var k in newArgs) {
    string += '&' + k + '=' + newArgs[k];
    }
    string = string.substr(1);
    return string;
    }

    2.创建订单

    //创建随机数;
    getRandomNumberSection(begin, end) {
    return Math.floor(Math.random() * (begin - end) + end);
    }
    //创建随机字符串;
    getRandomStr(length) {
    let value = ['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', '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', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    let result = "";
    for (let i = 0; i < length; i++) {
    let v = value[getRandomNumberSection(0, value.length - 1)];
    while (i === 0 && v === '0') {
    v = value[getRandomNumberSection(0, value.length - 1)];
    }
    result += v;
    }
    return result;
    }
    //创建JSAPI订单;
    //openid:微信用户的OPENID
    //body: 订单信息;
    //out_trade_no: 你自己生产的商户订单号;
    //spbill_create_ip: 客户端IP地址
    //total_fee: 支付金额(单位分)
    async CreateJSAPIpay(openid, body, out_trade_no, spbill_create_ip, total_fee, callback) {
    let that = this;
    let notify_url = '你需要设置支付完成后的回调URL';
    let WxAppid = '微信APPID';
    let mch_id = '商户ID';
    let trade_type = 'JSAPI';
    let sign_type = 'MD5';
    let noncestr = (new Date()).getTime() + '_';
    noncestr += getRandomStr(31 - noncestr.length); //产生32位随机字符串;
    //1.签名参数;
    let sign = MSign({
    appid: WxAppid,
    mch_id: mch_id,
    nonce_str: noncestr,
    notify_url: notify_url,
    trade_type: trade_type,
    sign_type: sign_type,
    openid: openid, //微信用户的OPENID
    body: body, //订单信息;
    out_trade_no: out_trade_no,//你自己生产的商户订单号;
    spbill_create_ip: spbill_create_ip,//客户端IP地址
    total_fee: total_fee //金额(单位分)
    }, this.mchkey);

    //2.生成XML格式;
    let formData = "<xml>";
    formData += "<appid>" + WxAppid + "</appid>";
    formData += "<body><![CDATA[" + body + "]]></body>";
    formData += "<mch_id>" + mch_id + "</mch_id>";
    formData += "<nonce_str>" + noncestr + "</nonce_str>";
    formData += "<notify_url>" + notify_url + "</notify_url>";
    formData += "<out_trade_no>" + out_trade_no + "</out_trade_no>";
    formData += "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>";
    formData += "<total_fee>" + total_fee + "</total_fee>";
    formData += "<trade_type>" + trade_type + "</trade_type>";
    formData += "<openid>" + openid + "</openid>";
    formData += "<sign_type>" + sign_type + "</sign_type>";
    formData += "<sign>" + sign + "</sign>"; //sign是上一步签名产生的;
    formData += "</xml>";

    //3.请求微信
    let url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
    request({ url: url, method: 'POST', body: formData },
    function (err, response, body) {
    if (!err && response.statusCode == 200) {
    xmlreader.read(body.toString("utf-8"), function (errors, response) {
    if (null !== errors) {
    callback(false, errors, null);
    }
    else {
    if (response.xml.return_msg.text().toLocaleUpperCase() == 'OK') {
    //此时返回的数据并不能直接用在客户端,需要再次签名;
    let prepay_id = response.xml.prepay_id.text();
    let timestamp = parseInt(new Date().getTime() / 1000) + '';
    //4.签名
    let finalsign = MSign({
    appId: WxAppid,
    timeStamp: timestamp,
    nonceStr: noncestr,
    package: 'prepay_id=' + prepay_id,
    signType: sign_type
    }, mchkey);
    //这才是客户端最后使用的数据;
    let clientParam = {
    'appId': WxAppid,
    'nonceStr': noncestr,
    'timeStamp': timestamp,
    'package': 'prepay_id=' + prepay_id,
    'signType': that.sign_type,
    'sign': finalsign
    };
    callback(true, clientParam);
    }
    else {
    callback(false, null);
    }
    }
    });
    }
    else {
    callback(false, null);
    }
    });
    }

    3.公众号网页唤起支付页面

    如果要在WEB端使用微信的功能,则需要在页面打开时使用JSAPI签名进行初始化,服务端JSAPI签名的方法如下,其中,jsapi参数是使用全局access_token获取的,url是网页的地址。


    //获取JSAPI签名;
    static GetJSAPISign(appid, jsapi, url) {
    var ret = {
    jsapi_ticket: jsapi,
    noncestr: Math.random().toString(36).substr(2, 15),
    timestamp: parseInt(new Date().getTime() / 1000) + '',
    url: url
    };

    var string = raw(ret);

    let jsSHA = require('jssha');
    let shaObj = new jsSHA(string, 'TEXT');
    let signature = shaObj.getHash('SHA-1', 'HEX');
    return {
    appid:appid,
    nonceStr:ret.noncestr,
    timestamp:ret.timestamp,
    signature:signature,
    url: url
    };
    }

    网页端初始化微信JSAPI代码
    需要引入

    <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>

    <script>
    //我使用的EJS,参数在请求页面时就生成好了;
    var jsapiSign = JSON.parse('<%- JSON.stringify(jsapiSign)%>');
    var paymentSign = JSON.parse('<%- JSON.stringify(paymentSign)%>');
    //初始化JSAPI;
    function init(){
    wx.config({
    debug: true,
    appId: jsapiSign.appid,
    timestamp: jsapiSign.timestamp,
    nonceStr: jsapiSign.nonceStr,
    signature: jsapiSign.signature,
    jsApiList : [
    'chooseWXPay' //请求微信支付权限
    ]
    });

    wx.ready(function () {
    wx.hideOptionMenu(); //隐藏菜单;
    onBridgeReady(); //初始化完成后立即调用微信支付;
    });

    wx.error(function(res){
    console.log('初始化失败了,请稍后重试');
    });
    }
    //唤起支付;
    function onBridgeReady(){
    var param = {
    appid:paymentSign.appId,
    timestamp: paymentSign.timeStamp,
    nonceStr: paymentSign.nonceStr,
    package: paymentSign.package,
    signType: paymentSign.signType,
    paySign: paymentSign.sign,
    success: function (res) {
    console.log("支付完成,请稍候");
    },
    cancel: function(res){
    console.log("用户取消支付");
    },
    fail: function(msg){
    console.log("支付调用失败");
    }
    };
    //API唤起支付;
    wx.chooseWXPay(param);
    }
    init();
    </script>

    目前学到了一种方法!

    一:cd到文件夹对应的项目中  在cmd中输入 你npm run build

    二:此时项目中会生成一个文件夹dist,在dist文件夹下的index文件里每个路径前加  ./ 如下图

    三:在HBuilder X中 点击文件---新建--项目---选择5+App---定义名称--模板选空项目

    四:删除刚刚新建项目里面的  除了manifest.json 这个文件的其他文件

    五:打开原来项目并复制dist中的文件,不包括dist,粘贴到,在HBuilder X中创建的项目里

    六:点击HBuilder X中的  发行---原生APP云打包  ----Android(apk包)----使用公共测试证书

    七:点击打包

    八:打包成功后会显示下载地址

  • 相关阅读:
    【LOJ6041】「雅礼集训 2017 Day7」事情的相似度(用LCT维护SAM的parent树)
    【BZOJ1171】大sz的游戏(线段树+单调队列)
    2019年4月训练记录(4.07~4.22)
    【BZOJ4766】文艺计算姬(prufer序列)
    【BZOJ4573】[ZJOI2016] 大森林(LCT)
    2019.03.19 ZJOI2019模拟赛 解题报告
    【牛客挑战赛30D】小A的昆特牌(组合问题抽象到二维平面)
    【洛谷2624】[HNOI2008] 明明的烦恼(Python+利用prufer序列结论求解)
    【洛谷2290】[HNOI2004] 树的计数(Python+利用prufer序列结论求解)
    初识prufer序列
  • 原文地址:https://www.cnblogs.com/maliyaya/p/13368633.html
Copyright © 2020-2023  润新知