node微信小程式支付驗證
阿新 • • 發佈:2018-12-29
Node 微信支付驗證
說明
之前寫了一個,單純的微信小程式支付的介面,這篇介紹一下支付完之後如何驗證.
業務流程
支付驗證
我們之前支付的時候有一個引數 nonce_str 這個是驗證支付的必要引數所以當支付的時候可以將該訂單資訊儲存到資料庫中用於支付驗證的時候使用
exports.miniVerify = async (req,res)=> {
/*因為我寫的驗證介面是一個get請求,所以客戶端會將引數寫在url中,可以通過querystring 和url 這兩個模組獲取到引數
這裡我需要的兩個引數為openid和orderNumber 使用者的唯一標識和訂單唯一標識,因為將之前的訂單資訊存入到了資料庫,
可以通過這兩個引數找到訂單資訊.
*/
let arg = url.parse(req.url).query;
let orderNumber = qs.parse(arg)['orderNumber'];
let openid = qs.parse(arg)['openid'];
let orderMsg = await db.findData_2(dbUrl,{orderNumber:orderNumber},'test','test');//資料庫查詢該訂單,我這裡用的是mongodb
if(orderMsg.length!=1){ //判斷訂單號是否存在
let data = {
result:"0",
msg :"該訂單不存在,請確認後再次訪問"
};
res.json(data);
return
}else if(orderMsg[0].openid!=openid){
let data = {
result:"0",
msg :"該訂單號和openid不匹配請確認後再次訪問"
} ;
res.json(data);
return
}
//如果滿足以上的條件獲取訂單的資訊 orderNumber 因為之前支付的時候我是把out_trade_no是以orderNumber欄位存到資料庫的
//其實這些東西只要和你之前支付的時候引數用的是一個就行
let appid = orderMsg[0].appid;
let mch_id = orderMsg[0].mch_id;
let nonce_str = orderMsg[0].nonce_str;//在統一下單時生成的唯一的隨機字串
let out_trade_no=orderMsg[0].orderNumber;//訂單號
//之後會將該方法貼出
let sign=wechatUtil.querySign(appid,mch_id,nonce_str,out_trade_no);//查詢簽名,傳參需要注意
let formData = "<xml>";
formData += "<appid>"+appid+"</appid>";
formData += "<mch_id>"+mch_id+"</mch_id>";
formData += "<nonce_str>"+nonce_str+"</nonce_str>";
formData += "<out_trade_no>"+out_trade_no+"</out_trade_no>";
formData += "<sign>"+sign+"</sign>";
formData += "</xml>";
let regUrl= "https://api.mch.weixin.qq.com/pay/orderquery";
/*拿著這些引數和查詢到的簽名去驗證*/
request({
url: regUrl,
method: 'POST',
body: formData
}, async (err, response, body)=> {
console.log(body.toString());
//getXMLNodeValue 解析xml的方法
var trade_state_desc = wechatUtil.getXMLNodeValue('trade_state_desc', body.toString('utf-8'));
//如果返回的trade_state_desc引數是支付成功則表示支付成功
if(trade_state_desc=="支付成功"){
//這裡修改訂單狀態
let payMsg = await db.updateOneData(dbUrl,{orderNumber:orderNumber},{$set: {state:1}},'test','test');
if(payMsg=="修改成功"){//這是我操作資料庫的返回資料
orderMsg = await db.findData_2(dbUrl,{orderNumber:orderNumber},'ykPay','order');
let data = {
result:"1",
orderMsg:orderMsg[0]
};
log.info(data);
res.json(data);
}
}
})
}catch (err){
log.error(err)
}
};
輔助方法
//查詢簽名
exports.querySign=(appid,mch_id,nonce_str,out_trade_no)=>{
let ret = {
appid: appid,
mch_id: mch_id,
nonce_str:nonce_str,
out_trade_no:out_trade_no//注意左邊引數名
};
log.info("查詢簽名驗證的引數",ret);
let string = raw(ret);
let key = "*******************";
string = string + '&key='+key;
return crypto.createHash('md5').update(string,'utf8').digest('hex').toUpperCase();
};
//解析xml資料
exports.getXMLNodeValue = (node_name,xml)=>{
log.info(xml)
let tmp = xml.split("<"+node_name+">");
if(tmp[1]!=undefined){
let _tmp = tmp[1].split("</"+node_name+">");
let tmp1 = _tmp[0].split('[');
let _tmp1 = tmp1[2].split(']');
return _tmp1[0];
}
};
結束
之後會寫一個企業支付到零錢的功能