mobilpay-node
Version:
MobilPay Gateway library
305 lines (257 loc) • 9.31 kB
JavaScript
;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
/**
* @typedef {Object} MobilPayConfig
* @property {Number} serviceType
* @property {String} paymentType
* @property {String} publicKeyFile
* @property {String} privateKeyFile
* @property {Boolean} sandbox - Toggle sandbox mode
* @property {String} currency - Transaction currency
* @property {String} signature - Unique key assigned to your seller account for the payment process
* @property {String} confirmUrl - Callback URL where the payment
* gateway will post transaction status updates
* @property {String} returnUrl - A URL in your web application where the client
* will be redirected to once the payment is complete
* @property {String} lang - If you wish to display the interface in a different language other than RO
*/
var CardRequest = require('./request/CardRequest');
var RequestError = require('./errors/RequestError');
var constants = require('./constants');
var encrypt = require('./utils').encrypt;
var decrypt = require('./utils').decrypt;
var Promise = require('es6-promise').Promise;
var xml2js = require('xml2js');
var _ = require('lodash');
var Notify = require('./Notify');
var request = require('request');
var MobilPay =
/*#__PURE__*/
function () {
/**
* @param {MobilPayConfig} config
*/
function MobilPay(config) {
_classCallCheck(this, MobilPay);
if (!config) {
throw new Error('Config is required');
}
this.config = Object.assign({
currency: 'RON',
serviceType: constants.SERVICE_STANDARD_PAYMENT,
paymentType: constants.PAYMENT_TYPE_CARD,
sandbox: false,
privateKeyFile: '',
publicKeyFile: ''
}, config);
if (this.config.serviceType !== constants.SERVICE_STANDARD_PAYMENT && this.config.serviceType !== constants.SERVICE_PREFILLED_CARD_DATA_PAYMENT) {
throw new Error('Unsupported service type');
}
if (this.config.paymentType !== constants.PAYMENT_TYPE_CARD) {
throw new Error('Unsupported payment type');
}
if (!this.config.signature) {
throw new Error('Missing merchant signature');
}
}
_createClass(MobilPay, [{
key: "createRequest",
value: function createRequest(data) {
var params = data || {};
params.paymentType = this.config.paymentType;
params.signature = this.config.signature;
params.returnUrl = this.config.returnUrl;
params.currency = this.config.currency;
if (params.paymentType === constants.PAYMENT_TYPE_CARD) {
return new CardRequest(params);
}
throw new RequestError("Payment type '".concat(params.paymentType, "' not supported"));
}
}, {
key: "prepareRedirectData",
value: function prepareRedirectData(request) {
var _this = this;
return new Promise(function (resolve, reject) {
var xml = request.toXml();
encrypt(xml, {
publicKeyFile: _this.config.publicKeyFile
}).then(function (result) {
resolve({
'url': constants.REQUEST_ENDPOINTS[_this.config.serviceType][_this.config.sandbox ? constants.SANDBOX_MODE : constants.LIVE_MODE],
'envKey': result.key,
'data': result.message
});
})["catch"](function (err) {
reject(err);
});
});
}
}, {
key: "createSoapRequest",
value: function createSoapRequest(_ref) {
var _this2 = this;
var body = _ref.body;
return new Promise(function (resolve, reject) {
var url = constants.REQUEST_ENDPOINTS.SOAP_API[_this2.config.sandbox ? constants.SANDBOX_MODE : constants.LIVE_MODE];
var builder = new xml2js.Builder();
var xml = builder.buildObject({
"soapenv:Envelope": {
"$": {
"xmlns:soapenv": "http://schemas.xmlsoap.org/soap/envelope/",
"xmlns:pay": url
},
"soapenv:Body": body
}
});
var options = {
url: url,
body: xml,
headers: {
'Content-Type': 'text/xml'
}
};
return request.post(options, function (err, response, body) {
if (err) {
return reject(err);
}
var parser = new xml2js.Parser({
explicitArray: false
});
parser.parseString(body, function (err, parsedXML) {
if (err) {
return reject(err);
}
var soapBody = parsedXML['SOAP-ENV:Envelope']['SOAP-ENV:Body']; // SOAP should response with statuses 2xx or 500 - https://www.w3.org/TR/2000/NOTE-SOAP-20000508/
if (response.statusCode === 500) {
var error = soapBody['SOAP-ENV:Fault'];
return reject(error);
}
return resolve(soapBody);
});
});
});
}
}, {
key: "getSessionId",
value: function getSessionId(_ref2) {
var _this3 = this;
var username = _ref2.username,
password = _ref2.password;
if (!username) {
throw new Error('username is required');
}
if (!password) {
throw new Error('password is required');
}
return new Promise(function (resolve, reject) {
var body = {
"pay:logIn": {
request: {
username: username,
password: password
}
}
};
return _this3.createSoapRequest({
body: body
}).then(function (soapBody) {
var sessionId = soapBody['ns1:logInResponse'].logInResult.id;
return resolve({
sessionId: sessionId
});
})["catch"](function (err) {
reject(err);
});
});
}
}, {
key: "creditInvoice",
value: function creditInvoice(_ref3) {
var _this4 = this;
var sessionId = _ref3.sessionId,
orderId = _ref3.orderId,
amount = _ref3.amount;
if (!sessionId) {
throw new Error('sessionId is required');
}
if (!this.config.signature) {
throw new Error('signature is required');
}
if (!orderId) {
throw new Error('orderId is required');
}
if (!amount) {
throw new Error('amount is required');
}
if (amount < 0.1 || amount > 99999) {
throw new Error('Invalid amount value. A minimum of ' + '0.10 and a maximum of 99999 units are permitted ');
}
return new Promise(function (resolve, reject) {
var body = {
"pay:credit": {
request: {
sessionId: sessionId,
sacId: _this4.config.signature,
orderId: orderId,
amount: amount
}
}
};
return _this4.createSoapRequest({
body: body
}).then(function (soapBody) {
var creditResult = soapBody['ns1:creditResponse'].creditResult;
return resolve(creditResult);
})["catch"](function (err) {
reject(err);
});
});
}
}, {
key: "handleGatewayResponse",
value: function handleGatewayResponse() {
var _this5 = this;
var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
envKey = _ref4.envKey,
data = _ref4.data;
return new Promise(function (resolve, reject) {
decrypt(data, {
privateKeyFile: _this5.config.privateKeyFile,
key: envKey
}).then(function (data) {
var parser = new xml2js.Parser({
explicitArray: false
});
parser.parseString(data, function (err, result) {
if (err) {
return reject(err);
}
if (!result.order) {
return reject(new Error('Invalid XML data'));
}
var notify = null;
var order = null;
if (result.order.mobilpay && _.isFunction(Notify.xmlDataToAttributes)) {
notify = Notify.fromXmlData(result.order.mobilpay);
}
if (result.order['$'].type && result.order['$'].type == constants.PAYMENT_TYPE_CARD) {
if (_.isFunction(CardRequest.fromXmlData)) {
order = CardRequest.fromXmlData(result);
}
}
resolve({
order: order,
response: notify
});
});
})["catch"](function (err) {
reject(err);
});
});
}
}]);
return MobilPay;
}();
module.exports = MobilPay;