UNPKG

mobilpay-card

Version:

Mobilpay card gateway library

293 lines (277 loc) 9.21 kB
const rc4 = require('./encrypt'); const fs = require('fs'); const xml2js = require('xml2js'); let builder = new xml2js.Builder({ cdata: true }); let parser = new xml2js.Parser({ explicitArray:false }); /** * MobilPay class. * * @constructor * @param {String} signature - The signature of the account. */ class MobilPay { constructor(signature) { this.signature = signature; this.publicKey = null; this.privateKey = null; this.clientData = { billing: null, shipping: null, }; this.paymentData = null; } /** * Set the publicKey from path * * @param {String} publicPemPath - The path to the public pem file. */ setPublicKeyFromPath (publicPemPath) { try { this.publicKey = fs.readFileSync(publicPemPath).toString(); } catch (e) { throw new Error('PUBLIC_CERTIFICATE_MISSING') } } /** * Set the privateKey from path * * @param {String} privateKeyPath - The path to the private key file. */ setPrivateKeyFromPath (privateKeyPath) { try { this.privateKey = fs.readFileSync(privateKeyPath).toString(); } catch (e) { throw new Error('PRIVATE_CERTIFICATE_MISSING') } } /** * Set public key from string * * @param {String} publicKey The publicKey contents */ setPublicKey (publicKey) { this.publicKey = publicKey; } /** * Set private key from string * * @param {String} privateKey The privateKey contents */ setPrivateKey (privateKey) { this.privateKey = privateKey; } /** * Set the client billing information. * * @param {String} firstName The client's first name. * @param {String} lastName The client's last name. * @param {String} county The client's county. * @param {String} city The client's city. * @param {String} address The client's address. * @param {String} email The client's email. * @param {String} phone The client's phone number. */ setClientBillingData({firstName, lastName, county, city, address, email, phone}) { this.clientData.billing = { first_name: firstName, last_name: lastName, address: `${county}, ${city}, ${address}`, email: email, mobile_phone: phone } } /** * Set the client shipping information. * * @param {String} firstName The client's first name. * @param {String} lastName The client's last name. * @param {String} county The client's county. * @param {String} city The client's city. * @param {String} address The client's address. * @param {String} email The client's email. * @param {String} phone The client's phone number. */ setClientShippingData({firstName, lastName, county, city, address, email, phone}) { this.clientData.shipping = { first_name: firstName, last_name: lastName, address: `${county}, ${city}, ${address}`, email: email, mobile_phone: phone } } /** * Set the split payment information. * * @param {String} destinationId The sac id (signature) of the first recipient. * @param {Number} destinationAmount The amount for the first recipient. */ setSplitPayment(destinationId, destinationAmount) { this.splitPayment = { split: { destination: [ {$: { id: destinationId, amount: destinationAmount.toString() }} ] }, } } /** * Set the client billing information. * * @param {String} orderId The id of the order. * @param {String} amount The amount to be charged. * @param {String} currency The currency in which to be charged. * @param {String} details The details about the transaction. * @param {String} confirmUrl The url which the MobilPay API should call for confirmation. * @param {String} returnUrl The url which the MobilPay API should return after confirmation. */ setPaymentData({orderId, amount, currency, details, confirmUrl, returnUrl}) { if (!this.clientData.billing) { throw new Error('BILLING_DATA_MISSING') } if (!this.clientData.shipping) { this.setClientShippingData(this.clientData.billing); } if (typeof this.splitPayment === 'undefined') { this.splitPayment = null } this.paymentData = { order: { $: { id: orderId, timestamp: new Date().getTime(), type: 'card' }, ...this.splitPayment, signature: this.signature, url: { return: returnUrl, confirm: confirmUrl }, invoice: { $: { currency: currency.toString().toUpperCase(), amount: amount, }, details: details, contact_info: { billing: { $: { type: 'person' }, ...this.clientData.billing }, shipping: { $: { type: 'person' }, ...this.clientData.shipping } } }, } } } /** * Build the request for the API call * * @param {Boolean} sandbox Use for sandbox */ buildRequest (sandbox) { if (!this.paymentData) { throw new Error('PAYMENT_DATA_MISSING'); } let xml = null; let request = null; try { xml = builder.buildObject(this.paymentData) } catch (e) { console.log(e); throw new Error('XML_BUILDER_ERROR'); } try{ request = rc4.encrypt(this.publicKey, xml) } catch (e) { console.log(e); throw new Error('RC4_BUILDER_ERROR'); } return { url: sandbox ? 'http://sandboxsecure.mobilpay.ro' : 'https://secure.mobilpay.ro/en', env_key: request.envKey, data: request.envData } } /** * Get the payment confirmation * * @param {String} envKey The env_key. * @param data The data. */ confirmPayment (envKey, data) { const privateKey = this.privateKey; return new Promise(function(resolve,reject){ parser.parseString(rc4.decrypt(privateKey, envKey, data),function(err,result){ if(err){ console.log(err); reject(err); } resolve(result); }); }); } /** * Validate a payment * * @param {String} envKey The env_key from the Mobilpay request body * @param data The data from the Mobilpay request body */ async validatePayment (envKey, data) { const confirmedPayment = await this.confirmPayment(envKey, data); return new Promise(function(resolve, reject) { if (confirmedPayment.errorType) { reject(confirmedPayment.errorMessage) } const mobilpayAction = confirmedPayment.order.mobilpay.action; const errorObj = confirmedPayment.order.mobilpay.error; let errorMessage = errorObj._; let errorCode = errorObj.$.code; if (parseInt(errorCode) !== 0) { resolve({ action: mobilpayAction, errorMessage: errorMessage, error: errorObj, $: confirmedPayment.order.$, orderInvoice: confirmedPayment.order.invoice, res: { set: { key: 'Content-Type', value: 'application/xml' }, send: `<?xml version="1.0" encoding="utf-8" ?><crc error_code="${errorCode}">${errorMessage}</crc>`, } }); } resolve({ action: mobilpayAction, errorMessage: null, error: null, $: confirmedPayment.order.$, orderInvoice: confirmedPayment.order.invoice, res: { set: { key: 'Content-Type', value: 'application/xml' }, send: `<?xml version="1.0" encoding="utf-8" ?><crc>${errorMessage}</crc>` } }); }) } } module.exports = MobilPay;