欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

NodeJS整合銀聯(lián)網(wǎng)關(guān)支付(DEMO)

 更新時間:2016年11月09日 16:01:26   作者:我叫干脆面  
這篇文章主要介紹了NodeJS整合銀聯(lián)網(wǎng)關(guān)支付DEMO的相關(guān)資料非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下

銀聯(lián)支付的測試開發(fā)做的很完善,可以下載各個語言的測試包,進(jìn)行開發(fā)測試,但是并沒有 nodejs 的,難點(diǎn)就是證書簽名還有驗簽這兩個步驟。

其實銀聯(lián)加密方式和支付寶微信不同的地方在于,使用了非對稱加密,意思是為了在網(wǎng)絡(luò)中傳輸安全,雙方約定各自產(chǎn)生一個公鑰還有私鑰,私鑰自己保存,公鑰公開給對方(你要發(fā)送信息的人都知道)。當(dāng)需要傳輸秘密的信息時候,用自己的私鑰加密,發(fā)給對方,對方收到信息后,為了判定這個是否偽造(是不是確實從你這兒發(fā)送給他的),那么拿出你的公鑰進(jìn)行驗證,發(fā)現(xiàn)是一樣的,那么就可以確定這個確實是你發(fā)送的。這樣做就可以保證信息的安全。

下面是 code :

銀聯(lián)配置文件:config.js

//配置銀聯(lián)支付需要的數(shù)據(jù) - 這都是銀聯(lián)測試商戶信息,可以上 https://merchant.unionpay.com/portal/login.jsp 去申請測試商戶
merId: '777290058136713', //商戶id
font_trans_url: 'https://101.231.204.80:5000/gateway/api/frontTransReq.do', //網(wǎng)關(guān)跳轉(zhuǎn)至銀聯(lián)平臺支付頁面地址
sigle_query_url: 'https://101.231.204.80:5000/gateway/api/queryTrans.do', //單筆查詢請求地址
sign_cert_dir: __dirname + '/certificates', //簽名證書路徑
certId: '40220995861346480087409489142384722381',
sign_cert_pwd: '0000000', //簽名證書密碼
sign_cert_path: __dirname + '/certificates/700000000000001_acp.pfx', //簽名用私鑰證書
validate_cert_path: __dirname + '/certificates/verify_sign_acp.cer', //驗簽用銀聯(lián)公鑰證書

.pfx 結(jié)尾的都是用密碼加密過后的私鑰

.cer 結(jié)尾的都是公鑰

銀聯(lián)支付模塊 unionPay.js

var validator = require('validator'),
util = require('util'),
_ = require('underscore'),
crypto = require('crypto'),
x509 = require('x509'),
sha1 = require('sha1'),
wopenssl = require('wopenssl'),
config = require('./config'); //加載銀聯(lián)配置
//銀聯(lián)網(wǎng)關(guān)支付
var unionPay = {
//創(chuàng)建預(yù)訂單
/*
* 參數(shù) parms: {out_trade_no: OUT_TRADE_NO, fee: FEE}
* out_trade_no 商戶訂單號 fee 訂單金額,單位分
*/
sdk_front_notice_url: 'http://'+ config.domain +'/unionPay/result', //銀聯(lián)網(wǎng)關(guān)支付前臺通知地址
sdk_back_notic_url: 'http://'+ config.domain +'/unionPay/productPay', //銀聯(lián)網(wǎng)關(guān)支付后臺通知地址
createOrder:
function(parms, callback) {
var errmsg;
var timeStamp = parms.timeStamp;
if(parms.payType==0) {
var back_notic_url = 'http://'+ config.domain +'/unionPay/productPay';
} else if(parms.payType==1) {
var back_notic_url = 'http://'+ config.domain +'/unionPay/rechargePay';
} else {
var back_notic_url = this.sdk_back_notic_url;
}
var formData = {
'version' : '5.0.0', //版本號
'encoding' : 'utf-8', //編碼方式
'txnType' : '01', //交易類型
'txnSubType' : '01', //交易子類
'bizType' : '000201', //業(yè)務(wù)類型
'frontUrl' : this.sdk_front_notice_url, //前臺通知地址
'signMethod' : '01', //簽名方法
'channelType' : '08', //渠道類型,07-PC,08-手機(jī)
'accessType' : '0', //接入類型
'currencyCode' : '156', //交易幣種,境內(nèi)商戶固定156
//TODO 以下信息需要填寫
'merId' : config.merId, //商戶代碼,請改自己的測試商戶號,此處默認(rèn)取demo演示頁面?zhèn)鬟f的參數(shù)
'orderId' : parms.out_trade_no, //商戶訂單號,8-32位數(shù)字字母,不能含“-”或“_”,此處默認(rèn)取demo演示頁面?zhèn)鬟f的參數(shù),可以自行定制規(guī)則
'txnTime' : timeStamp, //訂單發(fā)送時間timestamp,格式為YYYYMMDDhhmmss,取北京時間,此處默認(rèn)取demo演示頁面?zhèn)鬟f的參數(shù)
'txnAmt' : parms.fee, //交易金額,單位分
'backUrl' : back_notic_url, //后臺通知地址
'certId' : '' //可不必填寫,在SignKeyFromPfx中返回
};
var privateKey;
var certId;
var cert;
SignKeyFromPfx(function(err , result){
if (err) {
errmsg = '證書簽名失敗';
} else { 
certId = result.certId;
privateKey = result.key;
formData.certId = certId;
if (formData.signature) {
delete formData.signature
}
//----簽名開始----
//參數(shù)轉(zhuǎn)變?yōu)楹灻?
var unionPay_parms = transForSign(formData);
//摘要
var unionPay_parms_sha1 = sha1(unionPay_parms);
//簽名
var signer = crypto.createSign('RSA-SHA1');
signer.update(unionPay_parms_sha1);
var signature_base64 = signer.sign(privateKey, 'base64');
//放入域中
formData.signature = signature_base64;
//加入表單請求銀聯(lián)的地址
formData.action_url = config.font_trans_url;
//console.log(formData);
if (errmsg) {
callback(errmsg);
} else {
callback(null,formData);
}
}
});
},
//簽名
sign:
function(parms, callback) {
var errmsg;
var formData = parms;
SignKeyFromPfx(function(err , result){
if (err) {
errmsg = '證書簽名失敗';
} else { 
certId = result.certId;
privateKey = result.key;
if (formData.signature) {
delete formData.signature
}
//----簽名開始----
//參數(shù)轉(zhuǎn)變?yōu)楹灻?
var unionPay_parms = transForSign(formData);
//摘要
var unionPay_parms_sha1 = sha1(unionPay_parms);
//簽名
var signer = crypto.createSign('RSA-SHA1');
signer.update(unionPay_parms_sha1);
var signature_base64 = signer.sign(privateKey, 'base64');
//放入域中
formData.signature = signature_base64;
//console.log(formData);
if (errmsg) {
callback(errmsg);
} else {
callback(null,formData);
}
}
});
},
//驗簽
validate:
function(parms,callback) {
var validate_signature = parms.signature;
delete parms.signature;
var formData = parms;
ValidateKeyFromCer(formData,validate_signature,function(err , result){
if (err || !validate_signature || !formData) {
console.log('驗簽失敗');
callback('驗簽失敗');
} else { 
var publicKey = result.key;
if (formData.signature) {
delete formData.signature
}
//----驗簽開始----
var unionPay_parms = transForSign(formData);
var unionPay_parms_sha1 = sha1(unionPay_parms);
//console.log('待驗證簽:' + validate_signature);
var verifier = crypto.createVerify('RSA-SHA1');
//console.log('驗證簽名public key:\n' + publicKey);
//console.log('驗證簽名src_sign:' + unionPay_parms_sha1);
verifier.update(new Buffer(unionPay_parms_sha1, 'utf-8'));
var is_success = verifier.verify(publicKey, validate_signature, 'base64');
if (is_success) {
callback(null,formData);
} else {
console.log('驗簽不相等');
callback('驗簽不相等');
}
}
});
}
};
// 簽名串算法--將參數(shù)排序,轉(zhuǎn)成鍵值對格式字符串
function transForSign(params){
var array = []
for (var i in params) {
array.push('' + i + '=' + params[i])
}
var stringSignTemp = _.sortBy(array, function (str) {
return str;
});
return stringSignTemp.join('&');
};
//通過證書密碼獲得證書的rsa-privatekey值和證書Id
function SignKeyFromPfx(callback){
if (config.certsData) {
callback(null, config.certsData);
} else {
var certPath = config.sign_cert_path;
var certPwd = config.sign_cert_pwd;
var certDir = config.sign_cert_dir;
var p12 = wopenssl.pkcs12.extract(certPath, certPwd);
//console.log(p12.certificate); //p12.certificate和p12.rsa
var certs = wopenssl.x509.parseCert(p12.certificate);
//因為不知道怎么將十六進(jìn)制證書id:certs.serial變成十進(jìn)制證書id,因為這是個很大的整形biglong
var certsData = {};
certsData.certId = config.certId;
certsData.key = p12.rsa;
certsData.ca = certs;
//存入config
config.certsData = certsData;
callback(null,certsData); //{key: String, certId: String, ca: Array}
}
};
//獲得驗簽證書的rsa-publickey值
function ValidateKeyFromCer(formData, signature, callback){
if (config.validCertsData) {
callback(null, config.validCertsData);
} else {
var validateCertPath = config.validate_cert_path;
var certs = wopenssl.x509.parseCert(validateCertPath);
//console.log(certs);
var fs = require('fs');
var CERTIFICATE = fs.readFileSync(validateCertPath);
console.log(CERTIFICATE);
var publicKey = CERTIFICATE.toString('ascii');
var validCertsData = {};
validCertsData.key = publicKey;
validCertsData.cert = CERTIFICATE;
config.validCertsData = validCertsData;
if (publicKey) {
callback(null,validCertsData);
} else {
msg = '驗簽失敗';
callback(msg);
}
}
};
//轉(zhuǎn)化時間格式函數(shù)
function format(){
//時間格式化
var format = 'yyyyMMddhhmmss';
date = new Date();
var o = {
'M+' : date.getMonth() + 1, //month
'd+' : date.getDate(), //day
'h+' : date.getHours(), //hour
'm+' : date.getMinutes(), //minute
's+' : date.getSeconds(), //second
'q+' : Math.floor((date.getMonth() + 3) / 3), //quarter
'S' : date.getMilliseconds() //millisecond
};
if (/(y+)/.test(format))
format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp('(' + k + ')').test(format))
format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
return format;
};
module.exports = unionPay;

其實最重要的是簽名還有驗簽部分,對證書 .pfx 和 .cer 的處理,其中的 createOrder 方法只是方便使用返回的請求表單內(nèi)容。

在測試完成后,生產(chǎn)環(huán)境的配置還是不太一樣。當(dāng)銀聯(lián)商戶申請成功后,銀聯(lián)會發(fā)一份郵件,上面有商戶號,你的私鑰證書 .pfx 需要你自己根據(jù)他的郵件提示去下載的,附件內(nèi)的 “證書下載,安裝” 文件有詳細(xì)的說明教程。還有就是配置中的請求地址 https://101.231.204.80:5000需要換為 https://gateway.95516.com ,生產(chǎn)環(huán)境中除非是從商戶提交審核的域名發(fā)起的請求,否則一律會報錯 親愛的用戶,您本次交易可能存在風(fēng)險.

以上所述是小編給大家介紹的NodeJS整合銀聯(lián)網(wǎng)關(guān)支付DEMO,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • nodejs實現(xiàn)聊天機(jī)器人功能

    nodejs實現(xiàn)聊天機(jī)器人功能

    這篇文章主要介紹了nodejs實現(xiàn)聊天機(jī)器人功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • Nest.js 授權(quán)驗證的方法示例

    Nest.js 授權(quán)驗證的方法示例

    這篇文章主要介紹了Nest.js 授權(quán)驗證的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • node.js增刪改查保姆級教程方法

    node.js增刪改查保姆級教程方法

    這篇文章主要給大家介紹了關(guān)于node.js增刪改查保姆級教程的相關(guān)資料,node.js接口可以實現(xiàn)增加、刪除、修改和查詢操作,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • koa+mongoose實現(xiàn)簡單增刪改查接口的示例代碼

    koa+mongoose實現(xiàn)簡單增刪改查接口的示例代碼

    這篇文章主要介紹了koa+mongoose實現(xiàn)簡單增刪改查接口的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • Nodejs實現(xiàn)定時爬蟲的完整實例

    Nodejs實現(xiàn)定時爬蟲的完整實例

    這篇文章主要給大家介紹了關(guān)于Nodejs實現(xiàn)定時爬蟲的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Node.js開發(fā)教程之基于OnceIO框架實現(xiàn)文件上傳和驗證功能

    Node.js開發(fā)教程之基于OnceIO框架實現(xiàn)文件上傳和驗證功能

    這篇文章主要介紹了Node.js開發(fā)教程之基于OnceIO框架實現(xiàn)文件上傳和驗證的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-11-11
  • 前端如何更好的展示后端返回的十萬條數(shù)據(jù)

    前端如何更好的展示后端返回的十萬條數(shù)據(jù)

    這篇文章主要為大家介紹了前端如何更好的展示后端返回的十萬條數(shù)據(jù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-11-11
  • 了解javascript中變量及函數(shù)的提升

    了解javascript中變量及函數(shù)的提升

    這篇文章主要介紹了關(guān)于javascript中變量及函數(shù)的提升,下面和小編來一起學(xué)習(xí)吧
    2019-05-05
  • node.js中fs文件系統(tǒng)模塊的使用方法實例詳解

    node.js中fs文件系統(tǒng)模塊的使用方法實例詳解

    這篇文章主要介紹了node.js中fs文件系統(tǒng)模塊的使用方法,結(jié)合實例形式詳細(xì)分析了node.js fs文件系統(tǒng)模塊各種常見方法的基本使用技巧與相關(guān)操作注意事項,需要的朋友可以參考下
    2020-02-02
  • NodeJS學(xué)習(xí)筆記之Module的簡介

    NodeJS學(xué)習(xí)筆記之Module的簡介

    模塊是Node.js 應(yīng)用程序的基本組成部分,文件和模塊是一一對應(yīng)的。換言之,一個 Node.js 文件就是一個模塊,這個文件可能是JavaScript 代碼、JSON 或者編譯過的C/C++ 擴(kuò)展。
    2017-03-03

最新評論