• 纯前端JS实现微信H5支付(微信外浏览器)


    H5支付文档 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1

    1.发送请求所需要的参数

    /* 
    微信后台 设置的key
    怎么拿到key https://jingyan.baidu.com/article/c1465413f093870bfcfc4c82.html
    */
    let key = "ORM1NEK98XXXXXX3JJAITO6EB14W274ZH";
    /* 支付必要参数  */
    let h5Obj = {
      appid: "wxddxx8xx48c19xxxsdsbdcb", //appid
      body: "xx-商品", //商品描述
      mch_id: "1579347061", //商户号
      nonce_str: randomString(), //随机字符串,不长于32位。
      notify_url: "https://www.baidu.com/", //接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
      out_trade_no: randomString(), // 订单号
      spbill_create_ip: ip, //用户的ip地址 本地不影响 127.0.0.1
      total_fee: total, //价格
      trade_type: "MWEB", // h5为MWEB 固定
      scene_info: '{"h5_info":{"type":"Wap","wap_url":"支付的域名www.baidu.com","wap_name":"订单"}}', // 信息
    };

    2.用户IP地址获取

    // 这里使用的是souhu的 发送GET请求到 保存IP即可
    let url = 'https://pv.sohu.com/cityjson?ie=utf-8'

    3.如何进行sign签名?

    // 1排序(ASCII)
    let reStr = sortStr(h5Obj, false, key);
    // 2 签名方法 获取签名
    let sign = nodeMd5(reStr).toUpperCase();
    // 3设置要发送的xml参数;sign放在后面
    let formData = `<xml>
         <appid>${h5Obj.appid}</appid>
         <body>${h5Obj.body}</body>
         <mch_id>${h5Obj.mch_id}</mch_id>
         <nonce_str>${h5Obj.nonce_str}</nonce_str>
         <notify_url>${h5Obj.notify_url}</notify_url>
         <out_trade_no>${h5Obj.out_trade_no}</out_trade_no>
         <spbill_create_ip>${h5Obj.spbill_create_ip}</spbill_create_ip>
         <total_fee>${h5Obj.total_fee}</total_fee>
         <trade_type>${h5Obj.trade_type}</trade_type>
         <scene_info>${h5Obj.scene_info}</scene_info>
         <sign>${sign}</sign>
         </xml>`;
        return {
          h5Obj,
          formData,
        };

      (1).排序方法(根据ASCII进行)

    /* 这里放一个通用方法 字节小程序也可以使用 */
    /* params为排序对象 , ttKey是字节小程序key ,h5Key微信h5key */
    const sortStr = (params, ttKey, h5Key) => {
      const paramKeys = Object.keys(params).sort();
      let signStr = "";
      paramKeys.forEach((key) => {
        let value = params[key];
        // 空值,risk_info, sign 不参与签名
        if (!value || ["risk_info", "sign"].indexOf(key) >= 0) {
          return;
        }
        if (signStr.length > 0) {
          signStr += "&";
        }
        if (typeof value === "object") {
          value = JSON.stringify(value);
        }
        signStr += key + "=" + value;
      });
      if (ttKey) {
        signStr += `${ttKey}`;
        return signStr;
      }
      if (h5Key) {
        signStr += "&key=" + h5Key;
        return signStr;
      }
    };
    export default sortStr;

    (2)签名方法node版(如果不能使用 后面有js版)

    const crypto = require("crypto");
    const createSign = (signStr) => {
      const md5 = crypto.createHash("md5");
      const sign = md5.update(signStr).digest("hex");
      return sign;
    };
    export default createSign;

    (3)随机字符方法

    /* 随机字符串32 */
    function randomString() {
      /* 去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1 */
      let chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
      let maxPos = chars.length;
      let pwd = "";
      for (let i = 0; i < 32; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos));
      }
      return pwd;
    }
    export default randomString;

    4.封装支付方法 (vue可用)

    //  ASCII 码排序
    import sortStr from "../MD5/sortStr/sortStr";
    // md5 加密
    // import wxMD5 from "../MD5/md5";
    import nodeMd5 from "../MD5/nodeMd5";
    // 32位随机串
    import randomString from "../randomString/randomString";
    
    let h5PayFn = {
      /* 下单 */
       h5Pay(total = 100, ip = "127.0.0.1") {
         // ...h5obj
       }
    }
    export default h5PayFn;
    // 微信h5支付
    import h5PayFn from "./H5pay";
    Vue.prototype.$utils = {
      ...h5PayFn,
    };

    5.使用

    /* 这里使用的是 flyio 不要忘记ip地址  */ 
    let { h5Obj, formData } = this.$utils.h5Pay(100, this.ip);
    // 生成的订单号
    let out = h5Obj.out_trade_no;
    // 下单
    this.$utils.flypost("https://api.mch.weixin.qq.com/pay/unifiedorder", formData)
       .then((res) => {
              console.log(res);
    // 得到最后结果
    mweb_url 进行跳转即可
       }).catch()

    6.常见报错

    https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4

    1.商家存在未配置的参数,请联系商家解决

    一般是因为微信后台未配置支付的域名 , 这个一定要注意 ,有的可能一个微信绑定多个商户号! ,要确保配置正确

     jsMD5排序

    https://www.cnblogs.com/ZeroShiro/p/13305803.html

    仅供参考

  • 相关阅读:
    redis cluster 详解
    redis 数据占用内存大小分析
    java 中@RequestParam和@PathVariable
    git merge后,想恢复之前版本步骤
    Typescript中?? ?: ?. 都代表什么作用
    买卖股票的最佳时机系列问题
    最长递增子序列
    结构体统一说明
    Barcode Detection API All In One
    Learn Progressive Web Apps All In One
  • 原文地址:https://www.cnblogs.com/ZeroShiro/p/13305716.html
Copyright © 2020-2023  润新知