基于node 的微信退款

申请微信退款:微信退款

1.在前端页面访问 /refund

var request = require('request');
var WxPayRefund = require('./WxPayRefund');
var config = require('./../config');
var axios = require('axios')
/* 退款 */
const refund = async(ctx, next) => {
const { request: req, response: res } = ctx
// 退款 参数
var RefundInfo = {
mch_id: config.mch_id, //商户号
out_refund_no: req.query.out_refund_no, //商户退款单号 //商户系统内部的退款单号(自己生成)
out_trade_no: req.query.out_trade_no, //商户系统内部订单号
refund_fee: req.query.refund_fee, //退款金额
total_fee: req.query.total_fee, //订单金额
};
console.log('RefundInfo', RefundInfo);
// 参数成功回调
var result = await WxPayRefund.WxPayRefund(RefundInfo).then(function(data) {
// 成功返回 退款参数
return JSON.stringify(data);
});
ctx.type = 'json';
ctx.body = result;
}
module.exports = { refund };

1.1  WxPayRefund.js

var express = require('express');
var request = require('request');
var Q = require("q");
var crypto = require('crypto');
var ejs = require('ejs');
var fs = require('fs');
// 需要的参数设置 自行定义
var config = require("./../config");
var router = express.Router(); /* 微信 申请 退款 */
var key = config.key; //此处为申请微信支付的API密码
var APPID = config.AppID;
var WxPayRefund = {
// 生成微信的xml
getXMLNodeValue: function(node_name, xml) {
var tmp = xml.split("<" + node_name + ">");
var _tmp = tmp[1].split("</" + node_name + ">");
return _tmp[0];
}, raw: function(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;
}, paysignjs: function(appid, nonceStr, package, signType, timeStamp) {
var ret = {
appId: appid,
nonceStr: nonceStr,
package: package,
signType: signType,
timeStamp: timeStamp
};
var string = this.raw(ret);
string = string + '&key=' + key;
var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex');
return sign.toUpperCase();
},
//签名
paysignjsapi: function(appid, mch_id, nonce_str, out_refund_no, out_trade_no, refund_fee, total_fee) {
var ret = {
appid: appid,
mch_id: mch_id,
nonce_str: nonce_str,
// notify_url: notify_url,
out_refund_no: out_refund_no,
out_trade_no: out_trade_no,
refund_fee: refund_fee,
total_fee: total_fee,
};
var string = this.raw(ret);
string = string + '&key=' + key; //key为在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
var crypto = require('crypto');
var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex');
return sign.toUpperCase();
}, // 随机字符串产生函数
createNonceStr: function() {
return Math.random().toString(36).substr(2, 15);
}, // 时间戳产生函数
createTimeStamp: function() {
return parseInt(new Date().getTime() / 1000) + '';
},
// 此处的attach不能为空值 否则微信提示签名错误
WxPayRefund: function(_order) {
var deferred = Q.defer();
var appid = APPID;
var nonce_str = this.createNonceStr();
var timeStamp = this.createTimeStamp();
var url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; //
var formData = "<xml>";
formData += "<appid>" + appid + "</appid>"; // 公众账号ID appid
formData += "<mch_id>" + _order.mch_id + "</mch_id>"; // 商户号 mch_id
formData += "<nonce_str>" + nonce_str + "</nonce_str>"; // 随机字符串
// formData += "<notify_url>" + _order.notify_url + "</notify_url>"; // 退款结果通知url
formData += "<out_refund_no>" + _order.out_refund_no + "</out_refund_no>"; // 商户退款单号
formData += "<out_trade_no>" + _order.out_trade_no + "</out_trade_no>"; //商户系统内部订单号
formData += "<refund_fee>" + _order.refund_fee + "</refund_fee>"; // 退款金额
formData += "<total_fee>" + _order.total_fee + "</total_fee>"; // 订单金额
formData += "<sign>" + this.paysignjsapi(appid, _order.mch_id, nonce_str, _order.out_refund_no, _order.out_trade_no, _order.refund_fee, _order.total_fee) + "</sign>"; // 签名 sign
formData += "</xml>";
var self = this;
request({
url: url,
method: 'POST',
body: formData,
agentOptions: {
pfx: fs.readFileSync(__dirname + './../cert/apiclient_cert.p12'),
passphrase: _order.mch_id
}
}, function(err, response, body) {
if (!err && response.statusCode == 200) {
console.log('11', body);
var data = parser(body);
deferred.resolve(data);
} else {
console.log('12', body);
}
});
return deferred.promise;
},
}; function parser(_da) {
var xml = _da;
xml = xml.slice('<xml>'.length, xml.indexOf('</xml>'));
var tag = xml.match(/<\w+>/g);
var len = tag.length;
var obj = new Object(); //将微信 支付成功 返回的 xml 数据处理为json格式
for (var i = 0; i < len; i++) {
var node_name = tag[i].replace(/\<|\>/g, '');
var tmp = xml.split("<" + node_name + ">");
var _tmp = tmp[1].split("</" + node_name + ">");
var result = _tmp[0];
if (result.match(/^(?!.*CDATA)/)) {
obj[node_name] = result;
} else {
obj[node_name] = result.split('[')[2].split(']')[0];
}
}
return obj;
}
module.exports = WxPayRefund;

在这里再次感谢在人生路上帮助我的人!谢谢你们。

如果以上代码对您有用,欢迎打赏!如有错误的地方也请您留言指出。

node 微信退款的更多相关文章

  1. C#.NET ,微信退款证书

    微信退款时遇到:基础连接已经关闭 连接被意外关闭. 服务器环境:WIN SERVER 2008 R2.  WINDOWS服务承载的WCF服务,基于.NET FRAMEWORK 3.5. 第一笔交易的退 ...

  2. 微信退款 - tp5

    原文:http://www.upwqy.com/details/19.html 1 微信退款官方文档  https://pay.weixin.qq.com/wiki/doc/api/app/app.p ...

  3. 微信退款证书使用c#

    微信退款需要证书 data为已封装好的xml数据 具体怎么封装>打开 public string get(string data) { string cert = @"D:\certi ...

  4. 微信退款和支付宝退款接口调用(java版)

    项目中需要使用到微信和支付宝的退款功能,在这两天研究了一下这两个平台的退款,有很多坑,在开发中需要留意 1.微信退款接口 相对来说我感觉微信的退款接口还是比较好调用的,直接发送httppost请求即可 ...

  5. 微信小程序支付以及微信退款开发

    最近公司项目急着测试,需要开发微信小程序+微信支付+微信退款,本着这几天的一些研究,决定记录一下开发的过程. 本着知识分享的原则,希望对大家有所帮助. 本篇针对的是微信小程序的支付开发,如果有对微信公 ...

  6. PHP实现微信退款功能

    最近在调微信退款接口,发现有许多坑,更大家分享一下 ① 要是在测试的时候,网页提示 curl 58 说明 证书的路径出现问题(这里要填物理路径,也就是绝对路径) ②网页提示curl 52 说明你的证书 ...

  7. PHP实现微信退款的分析与源码实现

    原文:https://blog.csdn.net/jason19905/article/details/78628349 网上的很多PHP微信支付接入教程都颇为复杂,且需要配置和引入较多的文件,本人通 ...

  8. 微信退款流程,以及在过程中遇见的错误和解决方式(php 语言)

    官方下载demo 1:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 开发步骤  :    https://pay.weix ...

  9. 微信退款SpringBoot读取resource下的证书

    微信支付退款接口,需要证书双向验证,测试的时候证书暂时放在resource下,上图 起初MyConfig中我是这样,在本机IDE中运行没有问题 但到Linux服务器的docker中运行就IO异常了,查 ...

随机推荐

  1. Java判断字符串是否为空

    我们常常在实际开发调用一些类库,或者本身框架里面有类库去实现判断字符串空的操作,但是某些场景下上不是很方便去引入外部库的,所以需要我们自己去做这个工作,事实上判断空的操作不是很复杂,所以做个记录. 空 ...

  2. 使用jxl操作之一: 实现对Excel简单读写操作

    项目目录树 对象类UserObject UserObject.java package com.dlab.jxl; public class UserObject { private String u ...

  3. 监控Linux系统节点和服务CPU内存性能

    1.获取信息 #!/bin/bash #描述: # 把top信息输入到一个文件内部 #作者:孤舟点点 #版本:1.0 #创建时间:-- :: PATH=/bin:/sbin:/usr/bin:/usr ...

  4. Ubuntu在没用root权限下如何创建sudo用户

    起因 安装openCryptoki之后,如果想执行相关命令的话,那么该用户必须在pkcs11用户组中,于是执行 sudo uersmod -G pkcs11 $(whoami) 之后重启系统,执行 s ...

  5. 不装逼地说,在 Google 到底能学到啥?

    不装逼地说,在 Google 到底能学到啥? 2017-03-17 PHP开发者 (点击上方蓝字,快速关注我们) 本文转自公众号「半轻人」(ID:ban-qing-ren),伯乐在线/PHP开发者已获 ...

  6. OPPO招聘-互联网测试

    邮       箱:ljy@oppo.com 工作地点:深圳

  7. Java 并发编程 -- Fork/Join 框架

    概述 Fork/Join 框架是 Java7 提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架.下图是网上流传的 Fork Join 的 ...

  8. ES6学习笔记之变量的解构赋值

    变量的解构赋值 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构. 数组的解构赋值 以前,为变量赋值,只能直接指定值: 1 2 3 var a = 1; var b = 2; ...

  9. 使用BIND搭建内部DNS服务

    ​​‌‌​​​‌‌​‌​​‌‌‍​‌​‌‌‌​​‌‌‌‌​‌​‍​‌​​‌​​​‌​​​‌‌​‍​‌ ...

  10. Liferay7 Intellij IDEA 开发环境搭建

    一.安装Liferay插件 安装过程不在赘述,推荐两种安装方式: 通过Intellij插件市场安装 通过下载插件zip包安装 安装完成后,在项目板块中点鼠标右键,会出现Liferay菜单. 二.安装L ...