salix/modules/client/back/methods/tpv-transaction/confirm.js

95 lines
2.9 KiB
JavaScript
Raw Normal View History

const crypto = require('crypto');
const UserError = require('vn-loopback/util/user-error');
const base64url = require('base64url');
module.exports = Self => {
Self.remoteMethod('confirm', {
description: 'Confirms electronic payment transaction',
accessType: 'WRITE',
accepts: [
{
arg: 'Ds_SignatureVersion',
type: 'string',
required: false,
}, {
arg: 'Ds_MerchantParameters',
type: 'string',
required: true,
}, {
arg: 'Ds_Signature',
type: 'string',
required: true,
}
],
returns: {
type: 'Boolean',
root: true
},
http: {
path: `/confirm`,
verb: 'POST'
}
});
/*
* Source: https://github.com/santiperez/node-redsys-api
*/
Self.confirm = async(signatureVersion, merchantParameters, signature) => {
const $ = Self.app.models;
const decodedParams = JSON.parse(
base64url.decode(merchantParameters, 'utf8'));
const params = {};
for (const param in decodedParams)
params[param] = decodeURIComponent(decodedParams[param]);
const orderId = params['Ds_Order'];
const merchantId = parseInt(params['Ds_MerchantCode']);
if (!orderId)
throw new UserError('Order id not found');
if (!merchantId)
throw new UserError('Mechant id not found');
const merchant = await $.TpvMerchant.findById(merchantId, {
fields: ['id', 'secretKey']
});
const secretKey = Buffer.from(merchant.secretKey, 'base64');
const iv = Buffer.alloc(8, 0);
2023-01-30 19:22:52 +00:00
const cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv);
cipher.setAutoPadding(false);
const orderKey = Buffer.concat([
cipher.update(zeroPad(orderId, 8)),
cipher.final()
]);
const base64hmac = crypto.createHmac('sha256', orderKey)
.update(merchantParameters)
.digest('base64');
if (base64hmac !== base64url.toBase64(signature))
throw new UserError('Invalid signature');
await Self.rawSql(
'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [
params['Ds_Amount'],
orderId,
merchantId,
params['Ds_Currency'],
params['Ds_Response'],
params['Ds_ErrorCode']
]
);
return true;
};
function zeroPad(buf, blocksize) {
const buffer = typeof buf === 'string' ? Buffer.from(buf, 'utf8') : buf;
const pad = Buffer.alloc((blocksize - (buffer.length % blocksize)) % blocksize, 0);
return Buffer.concat([buffer, pad]);
}
};