garanti-3dpay
Version:
Garanti 3D Payment module for Node.js
325 lines (303 loc) • 11.9 kB
JavaScript
var options = {};
var hexcase = 1;
var b64pad = "=";
var chrsz = 8;
function hex_sha1(s) { return binb2hex(core_sha1(str2binb(s), s.length * chrsz)); }
function b64_sha1(s) { return binb2b64(core_sha1(str2binb(s), s.length * chrsz)); }
function str_sha1(s) { return binb2str(core_sha1(str2binb(s), s.length * chrsz)); }
function hex_hmac_sha1(key, data) { return binb2hex(core_hmac_sha1(key, data)); }
function b64_hmac_sha1(key, data) { return binb2b64(core_hmac_sha1(key, data)); }
function str_hmac_sha1(key, data) { return binb2str(core_hmac_sha1(key, data)); }
function sha1_vm_test() {
return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}
function core_sha1(x, len) {
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for (var j = 0; j < 80; j++) {
if (j < 16)
w[j] = x[i + j];
else
w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
function sha1_ft(t, b, c, d) {
if (t < 20) return (b & c) | ((~b) & d);
if (t < 40) return b ^ c ^ d;
if (t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
function sha1_kt(t) {
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
}
function core_hmac_sha1(key, data) {
var bkey = str2binb(key);
if (bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
return core_sha1(opad.concat(hash), 512 + 160);
}
function safe_add(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
function str2binb(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz)
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i % 32);
return bin;
}
function binb2str(bin) {
var str = "";
var mask = (1 << chrsz) - 1;
for (var i = 0; i < bin.length * 32; i += chrsz)
str += String.fromCharCode((bin[i >> 5] >>> (32 - chrsz - i % 32)) & mask);
return str;
}
function binb2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
}
return str;
}
function binb2b64(binarray) {
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx yz0123456789+/";
var str = "";
for (var i = 0; i < binarray.length * 4; i += 3) {
var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16)
| (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8)
| ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 > binarray.length * 32)
str += b64pad;
else
str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
}
}
return str;
}
var init = function(params,res){
function getSecurityCode(txtTerminalID,txtPassword){
var strTerminalID = "0" + txtTerminalID; //Basına 0 eklenerek 9 digite tamamlanmalıdır.
return hex_sha1(txtPassword + strTerminalID);
}
function getHashData(txtTerminalID,txtPassword,txtOrderID,txtCCNumber,txtAmount){
txtTerminalID = "0"+txtTerminalID;
txtAmount = txtAmount.toString().replace(/,/g,"");
var securityData = getSecurityCode(txtTerminalID,txtPassword);
var hashData = hex_sha1(txtOrderID + txtTerminalID + txtCCNumber + txtAmount + securityData);
return hashData;
}
function get3dHash(txtTerminalID,txtPassword,txtOrderID,txtCCNumber,txtAmount,successURL,errorURL,strType,strInstallmentCnt){
txtTerminalID = "0"+txtTerminalID;
txtAmount = txtAmount.toString().replace(/,/g,"");
var securityData = getSecurityCode(txtTerminalID,txtPassword);
var hashData = hex_sha1( txtTerminalID + txtOrderID + txtAmount + successURL + errorURL + strType + strInstallmentCnt + strStoreKey + securityData);
return hashData;
}
function makePayment(params,res){
var defaultParams = {
strMode : "PROD",
strApiVersion : "v0.01",
strTerminalProvUserID : "PROVAUT",
strTerminalUserID : "PROVAUT",
strTerminalMerchantID:"",
strType : "sales",
strAmount : "100",
strCurrencyCode : "949",
strInstallmentCount : "",
strOrderID : "Deneme",
strTerminalID:"",
strSuccessURL : "",
strErrorURL : "",
strCustomeripaddress : "192.168.1.1",
strStoreKey:"",
customeremailaddress:"",
strProvisionPassword : "",
cardnumber:"",
cardexpiredatemonth:"",
cardexpiredateyear:"",
cardcvv2:""
};
/*
strHostAddress : "https://sanalposprov.garanti.com.tr/VPServlet",
strUserID : "XXXXXX",
strMerchantID : "XXXXXX", // Üye syeri Numarası
strCustomerName : "Yahya EK NC ",
strEmailAddress : "info@tradesis.com",
strNumber : "",
strExpireDate : "",
strCVV2 : "",
strCardholderPresentCode : "0",
strMotoInd : "N",
hashData: ""*/
for(var key in params)
if (key in defaultParams)
defaultParams[key] = params[key];
options = defaultParams;
var securityData = getSecurityCode(defaultParams.strTerminalID, defaultParams.strProvisionPassword );
var myStr = defaultParams.strTerminalID + defaultParams.strOrderID + defaultParams.strAmount + defaultParams.strSuccessURL + defaultParams.strErrorURL + defaultParams.strType + defaultParams.strInstallmentCount + defaultParams.strStoreKey + securityData;
var hashData = hex_sha1(myStr);
var postParams = {
mode:defaultParams.strMode,
apiversion:defaultParams.strApiVersion,
terminalprovuserid:defaultParams.strTerminalProvUserID,
terminaluserid:defaultParams.strTerminalUserID,
terminalmerchantid:defaultParams.strTerminalMerchantID,
txntype:defaultParams.strType,
txnamount:defaultParams.strAmount,
txncurrencycode:defaultParams.strCurrencyCode,
txninstallmentcount:defaultParams.strInstallmentCount,
orderid:defaultParams.strOrderID,
terminalid:defaultParams.strTerminalID,
successurl:defaultParams.strSuccessURL,
errorurl:defaultParams.strErrorURL,
customeripaddress:defaultParams.strCustomeripaddress,
secure3dhash:hashData,
customeremailaddress:defaultParams.customeremailaddress,
secure3dsecuritylevel:"3D_PAY",
cardnumber:defaultParams.cardnumber,
cardexpiredatemonth:defaultParams.cardexpiredatemonth,
cardexpiredateyear:defaultParams.cardexpiredateyear,
cardcvv2:defaultParams.cardcvv2,
}
var inputs = [];
for(var key in postParams){
inputs.push("<textarea style='display:none;' name='"+key+"'>"+postParams[key]+"</textarea>");
}
var html = '<html>\
<body onload="document.getElementById(\'myForm\').submit()">\
<form action="https://sanalposprov.garanti.com.tr/servlet/gt3dengine" method="post" name="myForm" id="myForm">\
'+inputs.join('')+'\
</form>\
</body>\
</html>';
res.writeHead(200, {"Content-Type":"text/html"});
res.end(html);
}
makePayment(params,res);
}
var getStatus = function(req,callback){
if (!options.strSuccessURL)
return undefined;
var success = function(){
var formidable = require('formidable');
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
var strMode = fields["mode"]
var strVersion = fields["apiversion"]
var strTerminalID = fields["clientid"]
var strTerminalID_ = "0" + fields["clientid"]
var strProvisionPassword = options.strProvisionPassword; // 'Terminal UserID sifresi
var strProvUserID = fields["terminalprovuserid"]
var strUserID = fields["terminaluserid"]
var strMerchantID = fields["terminalmerchantid"] //Uye syeri Numarası
var strIPAddress = fields["customeripaddress"]
var strEmailAddress = fields["customeremailaddress"]
var strOrderID = fields["orderid"]
var strNumber = "" //Kart bilgilerinin bos gitmesi gerekiyor
var strExpireDate = "" //Kart bilgilerinin bos gitmesi gerekiyor
var strCVV2 = "" //Kart bilgilerinin bos gitmesi gerekiyor
var strAmount = fields["txnamount"] // islem Tutarı
var strCurrencyCode = fields["txncurrencycode"]
var strCardholderPresentCode = "13"; //3D Model islemde bu de er 13 olmalı
var strType = fields["txntype"];
var strMotoInd = "N";
var strAuthenticationCode = encodeURIComponent(fields["cavv"])
var strSecurityLevel = encodeURIComponent(fields["eci"])
var strTxnID = encodeURIComponent(fields["xid"])
var strMD = encodeURIComponent(fields["md"])
var SecurityData = hex_sha1(strProvisionPassword + strTerminalID_)
var HashData = hex_sha1(strOrderID + strTerminalID + strAmount + SecurityData)
var strHostAddress = "https://sanalposprov.garanti.com.tr/VPServlet";
var strXML = "<?xml version=\"1.0\" encoding=\"ISO-8859-9\"?>" +
"<GVPSRequest>" +
"<Mode>" + strMode + "</Mode>" +
"<Version>" + strVersion + "</Version>" +
"<ChannelCode></ChannelCode>" +
"<Terminal><ProvUserID>" + strProvUserID + "</ProvUserID><HashData>" + HashData +
"</HashData><UserID>" + strUserID + "</UserID><ID>" + strTerminalID + "</ID><MerchantID>" + strMerchantID +
"</MerchantID></Terminal>" +
"<Customer><IPAddress>" + strIPAddress + "</IPAddress><EmailAddress>" + strEmailAddress +
"</EmailAddress></Customer>" +
"<Card><Number></Number><ExpireDate></ExpireDate></Card>" +
"<Order><OrderID>" + strOrderID +
"</OrderID><GroupID></GroupID><Description></Description></Order>" +
"<Transaction>" +
"<Type>" + strType + "</Type><InstallmentCnt></InstallmentCnt><Amount>" + strAmount +
"</Amount><CurrencyCode>" + strCurrencyCode + "</CurrencyCode><CardholderPresentCode>" + strCardholderPresentCode +
"</CardholderPresentCode><MotoInd>" + strMotoInd + "</MotoInd>" +
"<Secure3D><AuthenticationCode>" + strAuthenticationCode +
"</AuthenticationCode><SecurityLevel>" + strSecurityLevel + "</SecurityLevel><TxnID>" + strTxnID + "</TxnID><Md>" +
strMD + "</Md></Secure3D>" +
"</Transaction>" +
"</GVPSRequest>"
require('request').post({url:strHostAddress,form: {data:strXML}}, function(err,httpResponse,body){
if (err){
callback(true);
return;
}
callback(false,body);
});
});
}
if (req.url.split('/').pop() == options.strSuccessURL.split('/').pop()){
var formidable = require('formidable');
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
callback(false,fields);
});
return true;
}
else if (req.url.split('/').pop() == options.strErrorURL.split('/').pop()){
var formidable = require('formidable');
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
callback(true,fields);
});
return false;
}
callback(true);
return undefined;
}
exports.init = init;
exports.getStatus = getStatus;