• Taro/JS/H5/小程序:纯前端解决小程序微信支付统一下单和调起支付


    这个文章不会说具体0到1的代码流程,我会着重讲几个问题的解决

    准备以下依赖

      "md5": "^2.2.1",
      "xml-js": "^1.6.11",
      "xmldom": "^0.1.27"

    支付主要遇到的问题如下:

    1.获取openid

    2.统一下单,拿到预单号(我起的,全名叫预支付交易会话标识)

    3.再次签名调起支付

    4.支付后的处理

    1.获取openid很简单,调用Taro.login()拿到code,传给后端获取openid,这个必须后端拿

    2.统一下单的几个问题:

    大概需要这么些必填参数:

    {
                appid: '', // appid
                mch_id: '',  // 商户id
                nonce_str:'', // 随机字符串
                body: '', // 商品简单描述
                out_trade_no:  '', // 商户系统内部订单号,唯一
                total_fee: '', // 订单总金额,单位为分
                spbill_create_ip:  '', // 你的ip,要后端传给你
                notify_url: '', // 通知地址,微信调的,告诉你支付的情况
                trade_type: 'JSAPI', 
                openid: '' 
    }

    ①随机字符串

    ②签名

    ③XML的组装与解析

    export function randomString(len = 32) {
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
        const maxPos = chars.length;
        let pwd = '';
        for (let i = 0; i < len; i++) {
            pwd += chars.charAt(Math.floor(Math.random() * maxPos));
        }
        return pwd;
    }

    准备一个参数如下

    const params = {
        appid: '', 
        mch_id: '', 
        nonce_str:randomString(32),
        body: '',
        out_trade_no:  '',
        total_fee: '',
        spbill_create_ip:  '',
        notify_url: '',
        trade_type: 'JSAPI',
        openid: ''
    }

    签名:

    const sign = signFunc(params)
            params.sign = sign

    签名函数

    export function signFunc(data) {
        // 1.对key字典排序
        const sortArr = Object.keys(data).sort()
    
        // 2.转URL键值对
        // const qsString = stringify(sortObj)
        let qsString = ''
        sortArr.map((t, index) => {
            if (index === 0) {
                qsString = `${t}=${data[t]}`
            } else {
                qsString = `${qsString}&${t}=${data[t]}`
            }
        })
    
        // 3.拼接string+key
        const stringSignTemp = qsString + `&key=${key}`
    
        // 4.MD5签名
        const sign = md5(stringSignTemp).toUpperCase()
    
        return sign
    }

    注意,我注释的那句,是一个叫做qs的npm库提供 ,不要用它对参数生成 URL键值对,因为它会把 再次签名时,会把=转成%3d

        console.log(stringify({
            package: 'prepay_id=wx2017033010242291fcfe0db70013231072'
        }))

    输出:

    package=prepay_id%3Dwx2017033010242291fcfe0db70013231072

    这样的值不符合要求,md5处理后是和官方对不上 ,一定要package=prepay_id=wx2017033010242291fcfe0db70013231072

    统一下单的参数必须是xml

    发送请求,header要设置如下

    'Content-Type': 'text/plain',
    const xml =
                `<xml>
            <appid>${params.appid}</appid>
            <openid>${ConfirmStore.openId}</openid>
            <body>${params.body}</body>
            <mch_id>${params.mch_id}</mch_id>
            <nonce_str>${params.nonce_str}</nonce_str>
            <notify_url>${params.notify_url}</notify_url>
            <out_trade_no>${params.out_trade_no}</out_trade_no>
            <spbill_create_ip>${params.spbill_create_ip}</spbill_create_ip>
            <total_fee>${params.total_fee}</total_fee>
            <trade_type>${params.trade_type}</trade_type>
            <sign>${params.sign}</sign>
         </xml>`
    Taro.request({
                url: `${unifyOrderUrl}`,
                header: {
                    'Content-Type': 'text/plain',
                },
                method: 'POST',
                data: {
                    xml,
                },
            })

    返回结果,xml的解析

    由于小程序无dom,所以不可用 DOMParser() ,解决办法是使用xmldom这个库

    示例写法:xml字符串转json

    // 若结果data为以下
    const data = `
    <xml>
     <appid></appid>
     <timeStamp></timeStamp>
     <nonce_str></nonce_str>
     <package></package>
     <signType></signType>   
    </xml>`

    const doc = new DOMParser().parseFromString(data); const result = convert.xml2json(doc, { compact: true, spaces: 4 }); const { xml } = JSON.parse(result)

    xml直接用即可

    3可以参考2,主要问题也是签名

    4.记得做好支付成功或者失败的处理

    注意事项:

    1.调用支付使用的noncestr这个参数必须和商家服务器调用统一下单接口返回的那个noncestr一致

    https://developers.weixin.qq.com/community/develop/doc/000c209934c8d0bad528fc8bc56800

    2.请在小程序后台,把微信支付统一下单URLhttps://api.mch.weixin.qq.com/pay/unifiedorder加到安全域名中

  • 相关阅读:
    jQuery.extend
    Topshelf便捷创建Windows服务
    cron表达式
    定时调度框架:Quartz.net
    sqlserver自定义函数
    HTML dom document 对象
    正则表达式之 数据验证 与 文本替换
    JavaScript 之 DOM 与 BOM
    CSS 之pseudo-classes 与pseudo-element的异同
    CSS中的 position与Grid Layout
  • 原文地址:https://www.cnblogs.com/ww01/p/11778398.html
Copyright © 2020-2023  润新知