Nodejs Integrated silver Networking Close Payment (DEMO) _node.js

Source: Internet
Author: User
Tags abstract base64 require sha1 asymmetric encryption

UnionPay pays the test development to do very well, can download each language test package, carries on the development test, but does not have the Nodejs, the difficulty is the certificate signature and has the verification sign these two steps.

In fact, UnionPay encryption and pay Bao micro-letter is different in the use of asymmetric encryption, meaning that in order to transport security in the network, the two sides agreed to produce a public key and private key, the private key to save their own, public key to the other (you want to send information to the people know). When you need to transmit a secret message, encrypted with its own private key, sent to each other, the other party received information, in order to determine whether this forgery (is indeed sent to him from you), then take out your public key to verify that the discovery is the same, then you can determine this is really you sent. This will ensure the security of the information.

Here is code:

UnionPay configuration file: Config.js

Configure UnionPay to pay the required data-this is the UnionPay test merchant information, you can go to https://merchant.unionpay.com/portal/login.jsp to apply for testing merchant
Merid: ' 777290058136713 ' ,//Merchant ID
font_trans_url: ' https://101.231.204.80:5000/gateway/api/frontTransReq.do ',//gateway jump to UnionPay Platform Payment page address
Sigle_query_url: ' https://101.231.204.80:5000/gateway/api/queryTrans.do ',//single query request address
Sign_cert_dir: __dirname + '/certificates ',//Signature certificate path
certid: ' 40220995861346480087409489142384722381 ',
sign_cert_pwd: ' 0000000 ',// Signing certificate Password
sign_cert_path: __dirname + '/certificates/700000000000001_acp.pfx ',//signature with private key certificate
Validate_cert_path: _ _dirname + '/certificates/verify_sign_acp.cer ',//check with UnionPay public key certificate

The end of the PFX is the secret key that is encrypted with the password.

The end of a CER is a public key.

UnionPay Payment Module 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 '); Load UnionPay configuration//Silver networking off pay var UnionPay = {//create reservation/* * Parameters Parms: {out_trade_no:out_trade_no, Fee:fee} * out_trade_no Merchant order number fee Order Amount, Unit points * * * * sdk_front_notice_url: ' http://' + config.domain + '/unionpay/result ',//Silver networking close pay Front notice address sdk_back_notic_url: ' http://' + config.domain + '/unionpay/productpay ',//Silver networking off Payment background notification address 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_no
Tic_url; } var formData = {' Version ': ' 5.0.0 ', '//' encoding ': ' Utf-8 ',//Encoding ' txntype ': ' 01 ',//transaction type ' Txnsubtype ': ' 01 ',/ /transaction sub-class ' BiztYpe ': ' 000201 ',//Business type ' Fronturl ': this.sdk_front_notice_url,//Front notice address ' signmethod ': ' 01 ',//Signature method ' Channeltype ': ' 08 ', Channel type, 07-pc,08-mobile phone ' accesstype ': ' 0 ',///access type ' currencycode ': ' 156 ',///trading currency, domestic merchant fixed 156//todo The following information needs to be filled in ' Merid ': config.m Erid,//merchant code, please change your own test merchant number, here by default take demo Demo page pass parameter ' orderId ': parms.out_trade_no,//Merchant order number, 8-32 digit letter, can not contain "-" or "_", Here by default to take demo Demo page pass parameters, you can customize the rules ' Txntime ': timeStamp,///order sent time TimeStamp, format for YYYYMMDDHHMMSS, take Beijing time, here by default take demo Demo page pass parameters '
Txnamt ': Parms.fee,//Transaction amount, Unit divided ' backurl ': back_notic_url,//Backstage notice address ' certid ': '//may not be filled in, return in SIGNKEYFROMPFX};
var Privatekey;
var CertId;
var cert; SIGNKEYFROMPFX (function (err, result) {if (error) {errmsg = ' certificate signature failed ';} else {certid = Result.certid; Privatekey = result
. Key;
Formdata.certid = CertId; if (formdata.signature) {Delete Formdata.signature}//----signature begins----//parameter is converted to the signature string var unionpay_parms = transforsign (formdat
a);
abstract var unionpay_parms_sha1 = SHA1 (unionpay_parms);
Signature var signer = crypto.createsign (' rsa-sha1 '); Signer.Update (UNIONPAY_PARMS_SHA1);
var signature_base64 = signer.sign (Privatekey, ' base64 ');
into the domain formdata.signature = signature_base64;
Join the form request UnionPay's address Formdata.action_url = Config.font_trans_url;
Console.log (FormData);
if (errmsg) {callback (errmsg);} else {callback (null,formdata);}}
});
},//Signature Sign:function (Parms, callback) {var errmsg; var formData = parms; SIGNKEYFROMPFX (function (err, result) {if (error) {errmsg = ' certificate signature failed ';} else {certid = Result.certid; Privatekey = result
. Key; if (formdata.signature) {Delete Formdata.signature}//----signature begins----//parameter is converted to the signature string var unionpay_parms = transforsign (formdat
a);
abstract var unionpay_parms_sha1 = SHA1 (unionpay_parms);
Signature var signer = crypto.createsign (' rsa-sha1 ');
Signer.update (UNIONPAY_PARMS_SHA1);
var signature_base64 = signer.sign (Privatekey, ' base64 ');
into the domain formdata.signature = signature_base64;
Console.log (FormData);
if (errmsg) {callback (errmsg);} else {callback (null,formdata);}}
}); },//Check 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 (' verification failure ');
Callback (' verification failure '); else {var PublicKey = Result.key if (formdata.signature) {Delete Formdata.signature}//----check start----var Unionpay_pa
RMS = Transforsign (formData);
var unionpay_parms_sha1 = SHA1 (unionpay_parms);
Console.log (' Pending verification: ' + validate_signature ');
var verifier = crypto.createverify (' rsa-sha1 ');
Console.log (' Verify signature public key:\n ' + publickey);
Console.log (' Verify signature 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 (' Verify not equal '); callback (' Check not Equal ');}
});
}
}; Signature string algorithm--sort the parameter to a key value pair format string 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 (' & ');
}; The Rsa-privatekey value of the certificate and the certificate ID function signkeyfrompfx (callback) {if (Config.certsdata) {callback (NULL) are obtained through the certificate password.
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 and p12.rsa var certs = Wopenssl.x509.parseCert (p12.certificate);
Because I don't know how to turn a hexadecimal certificate id:certs.serial into a decimal certificate ID because it's a big plastic biglong var certsdata = {};
Certsdata.certid = Config.certid;
Certsdata.key = P12.rsa;
certsdata.ca = certs;
Deposit config config.certsdata = certsdata; Callback (Null,certsdata);
{key:string, certid:string, Ca:array}}};
Obtain the Rsa-publickey value 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 = ' verification failed '; callback (msg);}}
};  Transformation time Format function functions format () {//Time formatted 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.get
Seconds (),//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]: (' + o[k]). substr ((' + o[k
]. length));
return format;
}; Module.exports = UnionPay;

In fact, the most important thing is the signature and the verification section, the processing of the certificate. PFX and. CER, where the Createorder method simply facilitates the use of the requested form content returned.

After the test is complete, the configuration of the production environment is still not the same. After the successful application of UnionPay merchants, the Bank of China issued an email with the merchant number and your private key certificate. PFX needs you to download according to his email prompts, the "certificate download, installation" file in the attachment has a detailed instruction tutorial. There is the configuration of the request address https://101.231.204.80:5000 need to change for https://gateway.95516.com, production environment, unless it is submitted from the merchant domain name initiated by the request, otherwise will be the error of the user, You may be at risk for this transaction.

The above is a small set to introduce the NODEJS integrated silver Network closed to pay demo, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.