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

106 lines
3.2 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]);
2023-01-30 18:59:46 +00:00
console.debug('Payment confirmation received:', {
signatureVersion,
merchantParameters,
signature,
params
});
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);
2023-01-30 16:45:36 +00:00
const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64')
2023-01-30 19:23:52 +00:00
+ cipher.final();
const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64'))
.update(merchantParameters)
.digest('base64');
const base64Res = base64url.encode(res, 'base64');
2023-01-30 19:22:52 +00:00
// if (res !== signature)
2023-01-30 18:59:46 +00:00
// throw new UserError('Invalid signature');
console.debug('Payment signature:', {
res,
base64Res
});
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]);
}
};