ykassa
Version:
Yandex Kassa wrapper for NodeJS
362 lines (315 loc) • 11.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _lodash = require("lodash");
var _lodash2 = _interopRequireDefault(_lodash);
var _xml2js = require("xml2js");
var _xml2js2 = _interopRequireDefault(_xml2js);
var _nodeForge = require("node-forge");
var _nodeForge2 = _interopRequireDefault(_nodeForge);
var _request = require("request");
var _request2 = _interopRequireDefault(_request);
var _md = require("md5");
var _md2 = _interopRequireDefault(_md);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function findContent(content) {
if (_lodash2.default.isString(content)) {
return content;
}
if (_lodash2.default.isPlainObject(content)) {
return findContent(content.value);
}
if (_lodash2.default.isArray(content)) {
return findContent(content[0]);
}
return null;
// msg2.rawCapture.content.value[0].value[0].value
}
// module.exports = class Ykassa
var Ykassa = function () {
function Ykassa(params) {
_classCallCheck(this, Ykassa);
this.defaultParams = {
mime: "application/pkcs7-mime",
tmp: "/tmp",
cardServer: "paymentcard.yamoney.ru"
};
this.params = _lodash2.default.assignInWith({}, this.defaultParams, params);
}
_createClass(Ykassa, [{
key: "getXml",
value: function getXml(params) {
var builder = new _xml2js2.default.Builder();
return builder.buildObject(params);
}
}, {
key: "getJson",
value: function getJson(xml) {
var builder = new _xml2js2.default.Builder();
return builder.buildObject(params);
}
}, {
key: "getRequestParams",
value: function getRequestParams() {
var rawParams = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var date = new Date();
var params = _lodash2.default.clone(rawParams);
if (!params.agentId && this.params.agentId) {
params.agentId = this.params.agentId;
}
if (!params.clientOrderId) {
params.clientOrderId = date.getTime();
}
if (!params.requestDT) {
params.requestDT = date.toISOString();
}
if (!params.currency && this.params.currency) {
params.currency = this.params.currency;
}
return params;
}
}, {
key: "generateHash",
value: function generateHash(request) {
var shopPassword = arguments.length <= 1 || arguments[1] === undefined ? this.params.shopPassword : arguments[1];
var action = request.action;
var orderSumAmount = request.orderSumAmount;
var orderSumCurrencyPaycash = request.orderSumCurrencyPaycash;
var orderSumBankPaycash = request.orderSumBankPaycash;
var shopId = request.shopId;
var invoiceId = request.invoiceId;
var customerNumber = request.customerNumber;
return (0, _md2.default)([action, orderSumAmount, orderSumCurrencyPaycash, orderSumBankPaycash, shopId, invoiceId, customerNumber, shopPassword].join(';')).toUpperCase();
}
}, {
key: "checkMD5",
value: function checkMD5(request, shopPassword) {
var originalHash = request.md5;
var resultHash = this.generateHash(request, shopPassword);
return resultHash === originalHash;
}
//
// Build XML response
//
}, {
key: "buildResponse",
value: function buildResponse(action, params) {
var performedDatetime = new Date().toISOString();
var code = params.code;
var shopId = params.shopId;
var invoiceId = params.invoiceId;
var message = params.message;
return this.getXml(_defineProperty({}, action + "Response", {
'$': {
performedDatetime: performedDatetime,
code: code,
invoiceId: invoiceId,
shopId: shopId,
message: message
}
}));
}
/**
* API для массовых выплат
*/
}, {
key: "decryptPack2",
value: function decryptPack2(pem) {
var msg = _nodeForge2.default.pem.decode(pem)[0];
console.log("decryptPack", msg);
var obj = _nodeForge2.default.asn1.fromDer(msg.body);
console.log("obj", obj);
var msg2 = _nodeForge2.default.pkcs7.messageFromAsn1(obj);
console.log("msg2", msg2);
return findContent(msg2.rawCapture.content);
}
}, {
key: "decryptPack",
value: function decryptPack(pem) {
var date = new Date();
var id = date.getTime().toString();
var fs = require("fs");
var path = require("path");
var file = path.join(this.params.tmp, id);
var execSync = require('child_process').execSync;
fs.writeFileSync(file + ".pem", pem);
// ../kassa/strategystroy/strategy_demo/depositresponsegenerator.cer
var command = "openssl smime -verify -in " + file + ".pem -inform PEM -nointern -certfile " + this.params.ssl.serverCertPath + " -CAfile " + this.params.ssl.serverCertPath + " -out " + file + ".xml";
// var command = `openssl smime -sign -in ${file}.xml -out ${file}.pem -nochain -nocerts -nodetach -outform PEM -signer ${this.params.ssl.certPath} -inkey ${this.params.ssl.keyDecPath}`;
execSync(command);
var data = fs.readFileSync(file + ".xml").toString();
// fs.unlinkSync(`${file}.pem`)
// fs.unlinkSync(`${file}.xml`)
return data;
}
}, {
key: "encryptPack",
value: function encryptPack(str) {
var date = new Date();
var id = date.getTime().toString();
var fs = require("fs");
var path = require("path");
var file = path.join(this.params.tmp, id);
var execSync = require('child_process').execSync;
fs.writeFileSync(file + ".xml", str);
var command = "openssl smime -sign -in " + file + ".xml -out " + file + ".pem -nochain -nocerts -nodetach -outform PEM -signer " + this.params.ssl.certPath + " -inkey " + this.params.ssl.keyDecPath;
execSync(command);
var data = fs.readFileSync(file + ".pem").toString();
// fs.unlinkSync(`${file}.pem`)
// fs.unlinkSync(`${file}.xml`)
return data;
}
}, {
key: "doRequest",
value: function doRequest(method, xml, next) {
// if (!next) {
// next = params
// }
var url = "https://" + this.params.server + "/webservice/deposition/api/" + method;
var pack = this.encryptPack(xml);
console.log(xml);
console.log(pack);
_request2.default.post({
url: url,
headers: {
'Accept': this.params.mime,
'Content-Type': this.params.mime
},
agentOptions: this.params.ssl,
body: pack,
timeout: 5000
}, function (err, response, body) {
if (err) return next(err);
// console.log('body!!!!', body)
if (body.substr(0, '<!DOCTYPE'.length) === '<!DOCTYPE') {
var errMessage = body.match(/<h1>(.*?)<\/h1>/i);
if (errMessage && errMessage[1]) {
return next(new Error(errMessage[1]));
} else {
return next(new Error('doRequest error'));
}
}
var xml2 = this.decryptPack(body);
next(null, xml2);
}.bind(this));
}
}, {
key: "storeCard",
value: function storeCard(card, next) {
var url = "https://" + this.params.cardServer + "/gates/card/storeCard";
var json = {
skr_destinationCardNumber: card,
skr_responseFormat: "json"
};
_request2.default.post({
url: url,
form: json
}, function (err, response, body) {
if (err) return next(err);
next(null, JSON.parse(body));
}.bind(this));
}
}, {
key: "getCardSynonim",
value: function getCardSynonim(card, next) {
this.storeCard(card, function (err, data) {
if (err) return next(err);
next(null, data.storeCard.skr_destinationCardSynonim);
});
}
}, {
key: "testDepositionXml",
value: function testDepositionXml(rawParams, next) {
var params = this.getRequestParams(rawParams);
var root = {
$: params
};
if (params.paymentParams) {
root.paymentParams = params.paymentParams;
delete params.paymentParams;
}
var xml = this.getXml({
testDepositionRequest: root
});
this.doRequest("testDeposition", xml, next);
}
}, {
key: "testDeposition",
value: function testDeposition(rawParams, next) {
var _this = this;
this.testDepositionXml(rawParams, function (err, xml) {
if (err) return next(err);
_this.parseJsonFromXml(xml, next);
});
}
}, {
key: "makeDepositionXml",
value: function makeDepositionXml(rawParams, next) {
var params = this.getRequestParams(rawParams);
var root = {
$: params
};
if (params.paymentParams) {
root.paymentParams = params.paymentParams;
delete params.paymentParams;
}
var xml = this.getXml({
makeDepositionRequest: root
});
this.doRequest("makeDeposition", xml, next);
}
}, {
key: "makeDeposition",
value: function makeDeposition(rawParams, next) {
var _this2 = this;
this.makeDepositionXml(rawParams, function (err, xml) {
if (err) return next(err);
_this2.parseJsonFromXml(xml, next);
});
}
}, {
key: "balanceXml",
value: function balanceXml(rawParams, next) {
if (typeof rawParams == "function") {
next = rawParams;
rawParams = {};
}
var params = this.getRequestParams(rawParams);
var xml = this.getXml({
balanceRequest: {
$: params
}
});
this.doRequest("balance", xml, next);
}
}, {
key: "balance",
value: function balance(rawParams, next) {
var _this3 = this;
this.balanceXml(rawParams, function (err, xml) {
if (err) return next(err);
_this3.parseJsonFromXml(xml, next);
});
}
}, {
key: "parseJsonFromXml",
value: function parseJsonFromXml(xml, next) {
_xml2js2.default.parseString(xml, function (err, json) {
if (err) return next(err);
var keys = Object.keys(json);
try {
next(null, json[keys[0]]['$']);
} catch (err) {
next(err);
}
});
}
}]);
return Ykassa;
}();
exports.default = Ykassa;
module.exports = exports['default'];