nodejs后台实现app端微信支付

本文详细介绍如何使用Node.js实现微信支付功能,包括统一下单请求、签名生成及验证等关键步骤,并提供客户端调起支付的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现微信支付有很多方式,至于开始菜鸟的我使用app支付,后期考虑安全性问题,只好把统一下单,得到prepay_id之后再次签名sign全在服务端写了,废话不多说,进入操作。

做任何东西,我喜欢了解整个流程,然后一步一步做起来,开始看清微信支付业务流程图

业务流程步骤写的很清楚。下面一步一步操作:

服务端提供接口,服务端需要拿到订单号、商品介绍、商品价格(单位是分)

服务端对微信服务端发出统一下单请求

https://api.mch.weixin.qq.com/pay/unifiedorder

xml参数(注意参数名)

 

<xml>

<appid>wx2421b1c4370ec43b</appid>

<attach>支付测试</attach>

<body>APP支付测试</body>

<mch_id>10000100</mch_id>

<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str> <notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url>

<out_trade_no>1415659990</out_trade_no>

<spbill_create_ip>14.23.150.211</spbill_create_ip>

<total_fee>1</total_fee>

<trade_type>APP</trade_type>

<sign>0CB01533B8C1EF103065174F50BCA001</sign>

</xml>

 

请求返回结果是success说明签名成功

快捷测试方法:

使用微信支付签名测试工具https://pay.weixin.qq.com/wiki/tools/signverify/

得到xml参数签名之后请求看返回结果

推荐一个在线http接口测试工具  http://coolaf.com/

在里面放入http地址https://api.mch.weixin.qq.com/pay/unifiedorder

post参数放签名xml参数

返回结果就可以检测签名是否成功,成功之后差不多成功了一半

服务端代码:weixinpay.js

 

var request = require('request');

var xml2js = require('xml2js');

function paysign(appid, attach, body, mch_id, nonce_str, notify_url, out_trade_no, spbill_create_ip, total_fee, trade_type) {

var ret = {

appid: appid,

attach: attach,

body: body,

mch_id: mch_id,

nonce_str: nonce_str,

notify_url: notify_url,

out_trade_no: out_trade_no,

spbill_create_ip: spbill_create_ip,

total_fee: total_fee,

trade_type: trade_type

};

var string = raw(ret);

var key = '密钥'; //微信商户密钥

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();

};

 

//解析xml数据

function getXMLNodeValue(node_name,xml){

var tmp = xml.split("<"+node_name+">");

var _tmp = tmp[1].split("</"+node_name+">");

var tmp1 = _tmp[0].split('[');

var _tmp1 = tmp1[2].split(']');

return _tmp1[0];

}

 

function raw(args) {

var keys = Object.keys(args);

keys = keys.sort()

var newArgs = {};

keys.forEach(function (key) {

newArgs[key.toLowerCase()] = args[key];

});

 

var string = '';

for (var k in newArgs) {

string += '&' + k + '=' + newArgs[k];

}

string = string.substr(1);

console.log(string);

return string;

};

 

// 随机字符串产生函数

function createNonceStr() {

return Math.random().toString(36).substr(2, 15);

};

 

exports.pay = function (req, res) //微信支付函数

{

var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

var appid = 'wx2421b1c4370ec43b';//应用微信中的id

var mch_id = '1511515151';//商户号

var notify_url = 'http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php';//回调通知地址

var out_trade_no = req.body.orderId;//订单号

var total_fee = req.body.orderRate;//商品价格

var attach = 'feeLT运动App';

var body = req.body.content; //客户端商品描述

var nonce_str = createNonceStr();//随机32位之内字符串

var formData = "<xml>";

formData += "<appid>"+appid+"</appid>"; //appid

formData += "<attach>"+attach+"</attach>"; //附加数据

formData += "<body>"+body+"</body>"; //商品或支付单简要描述

formData += "<mch_id>"+mch_id+"</mch_id>"; //商户号

formData += "<nonce_str>"+nonce_str+"</nonce_str>"; //随机字符串,不长于32位

formData += "<notify_url>"+notify_url+"</notify_url>"; //支付成功后微信服务器通过POST请求通知这个地址

formData += "<out_trade_no>"+out_trade_no+"</out_trade_no>"; //订单号

formData += "<spbill_create_ip>120.79.65.254</spbill_create_ip>"; //服务端ip

formData += "<total_fee>"+total_fee+"</total_fee>"; //金额

formData += "<trade_type>APP</trade_type>"; //类型APP

formData += "<sign>" + paysign(appid,attach,body,mch_id,nonce_str,notify_url,out_trade_no,'120.79.65.254',total_fee,'APP') + "</sign>";

formData += "</xml>";

request(

{

url : url,

method : 'POST',

body : formData

}, function (err, response, body){

if (!err && response.statusCode == 200){

console.log(body);

var parser = new xml2js.Parser({ trim:true, explicitArray:false, explicitRoot:false });//解析签名结果xml转json

parser.parseString(body, function(err, result){

var timeStamp = Date.parse(new Date()) / 1000;

var sign = paySignTwo(appid,nonce_str,'Sign=WXPay',mch_id,result['prepay_id'],timeStamp);//得到prepay再次签名

res.send({result: {'appid':appid, 'mch_id': mch_id, 'prepay_id': result['prepay_id'], 'nonce_str': nonce_str, 'time_stamp':timeStamp, 'package_value':'Sign=WXPay', 'sign': sign}});//返回客户端数据

});

}

});

}

 

function buildXML(json){

var builder = new xml2js.Builder();

return builder.buildObject(json);

};

 

function paySignTwo(appid,notifystr,packagevalue,mchid,prepayid,timestamp) { //参数名不可改,必须严格一模一样(在此我掉坑一次)

var ret = {

appid: appid,

noncestr: notifystr,

package: packagevalue,

partnerid: mchid,

prepayid: prepayid,

timestamp:timestamp

};

var string = raw(ret);

var key = '密钥';

string = string + '&key='+key; //key为在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

var crypto = require('crypto');

console.log("签名");

console.log(crypto.createHash('md5').update(string,'utf8').digest('hex').toUpperCase());

return crypto.createHash('md5').update(string,'utf8').digest('hex').toUpperCase();

};

 

 

再次签名参数名:

 

 

剩下就是客户端的事了,短短几行代码调起微信支付接口请求。

 

 
  1. req = new PayReq();

  2. req.appId = weixinOrder.getString("appid");

  3. req.partnerId = weixinOrder.getString("mch_id");

  4. req.prepayId = weixinOrder.getString("prepay_id");

  5. req.nonceStr = weixinOrder.getString("nonce_str");

  6. req.timeStamp = weixinOrder.getString("time_stamp");

  7. req.packageValue = weixinOrder.getString("package_value");

  8. req.sign = weixinOrder.getString("sign");

  9. Log.i("sign-----jieguo", weixinOrder.getString("sign"));

  10. Toast.makeText(WorkPay.this, "正常调起支付", Toast.LENGTH_SHORT).show();

  11. // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信

  12. api.registerApp(Constants.APP_ID);

  13. api.sendReq(req);


manifest需要配置:

 

 
  1. <activity android:name="app包名.WorkPay" <!--支付类需加上以下intent-filter内容-->

  2. android:exported="true"

  3. android:launchMode="singleTop">

  4. <intent-filter>

  5. <action android:name="android.intent.action.VIEW"/>

  6. <category android:name="android.intent.category.DEFAULT"/>

  7. <data android:scheme="wxb6ff1aa7f0350ccf"/>

  8. </intent-filter>

  9. </activity>

  10. <activity

  11. android:name="aizhinong.yys.sbm.wxapi.WXPayEntryActivity"

  12. android:exported="true"

  13. android:launchMode="singleTop">

  14.  
  15. </activity>


提醒:所有参数必须跟微信给的参数名一致(参数个数不能少),(使用微信签名工具是一定需要分辨测试包签名还是正式发布签名)

如果一切顺利,恭喜你接入支付成功。

发这个目的是为了node.js服务端的同胞们多点资源共享

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值