IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> nodejs+Koa2实现小程序的微信支付请求(一) -> 正文阅读

[移动开发]nodejs+Koa2实现小程序的微信支付请求(一)

nodejs+koa2 实现微信支付请求

在开发之前我们先看一下小程序向微信请求支付的业务流程

?第一步,小程序先发起支付请求

小程序首先先向“商家系统后台”发起请求支付,也就是我们自己的后端服务,生成平台订单和签x

第二步,我们的nodejs服务接收到请求之后,处理支付请求,签名后强微信请求支付

let xmlData = await WXPlay.requestWXPay(wxPayInfo);? ->这里是向微信支付服务器请求支付的地方

router.post('/xxxxPay',async (ctx) => {
    const v = await new PayFeeValidator().validate(ctx);
    let body = ctx.request.body;
    let payAmount = Math.floor(parseFloat(body.payAmount))*100);
    let orderType = body.orderType;
    let content = body.content)?body.content):'支付费用';
    let wxPayInfo = {
        userId: ctx.auth.uid,
        entriesId: body.entriesId,
        openId: header.openid,
        payAmount: payAmount,
        money: body.payAmount,
        ip: host,
        productIntro: content,
        orderType: orderType
    }
    let xmlData = await WXPlay.requestWXPay(wxPayInfo);
    let response = xmlData.xml

    if (response.return_code === 'SUCCESS') {
        if (response.result_code === 'SUCCESS') {
            let timeStamp = createTimeStamp();
            let nonceStr = response.nonce_str;
            let prepay_id = response.prepay_id;
            let appid = global.config.violinWx.appid;
            let package = 'prepay_id=' + prepay_id;
            let apiKey = global.config.violinWx.payApiKey;
            let paySign = getPaySignJs(appid, timeStamp, nonceStr, package, apiKey);
            const order = await Order.getOrderDetailByPer(prepay_id);
            ctx.body = {
                code: 0,
                msg: 'SUCCESS',
                data: {
                    timeStamp: timeStamp,
                    nonceStr: nonceStr,
                    package: package,
                    paySign: paySign,
                    orderNo: order.orderNo
                }
            }
        } else {
            ctx.body = {
                code: response.err_code,
                msg: response.err_code_des
            } 
        } 
    } else {
        ctx.body = {
            code: 1,
            msg: response.return_msg
        }
    }
})

我们的服务端拿到微信的支付响应之后,返回给小程序以下参数

timeStamp: 时间戳

nonceStr: 随机字符串

package: 订单详情扩展字符串

paySign: 签名

orderNo: 我们系统的订单号

?signType:?签名方式

小程序拿到这些信心后才开始真正调起支付,代码如下

                wx.requestPayment({
                    timeStamp: res.data.timeStamp.toString(),
                    nonceStr: res.data.nonceStr,
                    package: res.data.package,
                    signType: 'MD5',
                    paySign: res.data.paySign,
                    success (result) {
                        wx.showToast({
                            title: `支付成功`,
                            icon: 'none',
                            duration: 2000
                        })
                        // 下面做支付成功的事情
                    },
                    fail (result) {
                        wx.showToast({
                            title: `您的支付请求失败,请重新支付`,
                            icon: 'none',
                            duration: 2000
                        })
                        
                    }
                })

微信支付成功后下面需要处理的就是微信收到付款后的回调,这里的支付回调接口一定要在微信支付平台配置正确

router.post('/XXXPayNotice', async (ctx) => {
    let result = 1;
    const wxResponse = ctx.body.xml;
    if (wxResponse && wxResponse.return_code[0] === 'SUCCESS') {
        if (wxResponse.result_code[0] === 'SUCCESS') {
            let timeEnd = wxResponse.time_end[0];
            let pattern = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;
            let formateDate = timeEnd.replace(pattern, '$1/$2/$3 $4:$5:$6');
            let order = {
                orderStatus: 1,
                confirmTime: new Date(),
                arrivalTime: formateDate,
                confirmFlag: 1,
                transactionNo: wxResponse.transaction_id[0],
                orderNo: wxResponse.out_trade_no[0]
            }
            const orderR = await Order.getOrderByOrderNo(order.orderNo);
            if (orderR) {
                let payAmount = Math.floor(parseFloat(orderR.payAmount)*100); 
                if (payAmount === parseInt(wxResponse.total_fee[0])) {
                    await Order.updateOrderByWxResponse(order);
                    result = 1;
                } else {
                    result = 2;
                }
                if (orderR.orderType === 0) {
                    let entries = {
                        entriesStage: 2,
                        payStatus: 1,
                        orderNo: order.orderNo,
                        entriesId: orderR.entriesId
                    }
                    if( result === 1) {
                        await V_Entries.updateEntriesPayInfo(entries);
                        // 修改用户标记为已支付用户
                        await V_User.updateIsEnteriesUser(1,orderR.userId);
                    }
                }
                if (orderR.orderType === 1) {
                    // 处理大师班报名
                    let payInfo = {
                        payStatus: 1,
                        orderNo: order.orderNo
                    }
                    await T_Student_Class.updatePayInfoByOrderNo(payInfo);
                }
            } else {
                result = 3;
            }
        } else {
            let timeEnd = wxResponse.time_end[0];
            let pattern = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;
            let formateDate = timeEnd.replace(pattern, '$1/$2/$3 $4:$5:$6');
            let order = {
                orderStatus: 2,
                confirmTime: new Date(),
                arrivalTime: formateDate,
                confirmFlag: 1,
                transactionNo: wxResponse.transaction_id[0],
                orderNo: wxResponse.out_trade_no[0]
            }
            await Order.updateOrderByWxResponse(order)
        }
    }
    if (result === 2) {
        ctx.type = 'application/xml';
        ctx.headers[{
            'Content-Type': 'text/xml'
        }];
        ctx.body = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[未找到订单]]></return_msg></xml>';
    } else if (result === 3) {
        ctx.type = 'application/xml';
        ctx.headers[{
            'Content-Type': 'text/xml'
        }];
        ctx.body = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[金额校验失败]]></return_msg></xml>';
    } else {
        ctx.type = 'application/xml';
        ctx.headers[{
            'Content-Type': 'text/xml'
        }];
        ctx.body = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
    }    
})

微信支付成功的通知参数消息体

let wxResponse = {

? ? "appid": ["XXXXX"],

? ? "attach": ["XXXX"],

? ? "bank_type": ["OTHERS"],

? ? "cash_fee": ["1"],

? ? "fee_type": ["CNY"],

? ? "is_subscribe": ["N"],

? ? "mch_id": ["XXXX"],商户号

? ? "nonce_str": ["uNE3NFA0nGPAU7iiOGsuDRkC6qNcNQc8"],

? ? "openid": [""], 支付用户的openID

? ? "out_trade_no": [""],

? ? "result_code": ["SUCCESS"],

? ? "return_code": ["SUCCESS"],

? ? "sign": ["C82D1DE210366E280DBBE6F7D9A3A63A"],

? ? "time_end": ["20200628212320"],

? ? "total_fee": ["1"],

? ? "trade_type": ["JSAPI"],

? ? "transaction_id": [""]

}

?*/

里面用的签名和具体的支付请求,查看这里签名预支付请求

参数说明,参考微信支付-开发者文档

?

未完待续?

欢迎交流,分享不易,谢谢点赞!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-17 12:52:17  更:2021-11-17 12:53:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:41:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码