2023-01-30 16:33:15 +00:00
|
|
|
const UserError = require('vn-loopback/util/user-error');
|
|
|
|
const base64url = require('base64url');
|
2023-01-30 11:39:47 +00:00
|
|
|
|
|
|
|
module.exports = Self => {
|
2023-06-15 11:10:44 +00:00
|
|
|
Self.remoteMethod('confirm', {
|
2023-01-30 11:39:47 +00:00
|
|
|
description: 'Confirms electronic payment transaction',
|
|
|
|
accessType: 'WRITE',
|
|
|
|
accepts: [
|
|
|
|
{
|
|
|
|
arg: 'Ds_SignatureVersion',
|
|
|
|
type: 'string',
|
2023-01-30 16:33:15 +00:00
|
|
|
required: false,
|
2023-01-30 11:39:47 +00:00
|
|
|
}, {
|
|
|
|
arg: 'Ds_MerchantParameters',
|
|
|
|
type: 'string',
|
|
|
|
required: true,
|
|
|
|
}, {
|
|
|
|
arg: 'Ds_Signature',
|
|
|
|
type: 'string',
|
|
|
|
required: true,
|
|
|
|
}
|
|
|
|
],
|
2023-01-31 13:00:10 +00:00
|
|
|
returns: {
|
|
|
|
type: 'Boolean',
|
|
|
|
root: true
|
|
|
|
},
|
2023-01-30 11:39:47 +00:00
|
|
|
http: {
|
|
|
|
path: `/confirm`,
|
|
|
|
verb: 'POST'
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-06-15 11:10:44 +00:00
|
|
|
Self.confirm = async(signatureVersion, merchantParameters, signature) => {
|
2023-01-30 16:33:15 +00:00
|
|
|
const $ = Self.app.models;
|
2023-03-03 17:55:58 +00:00
|
|
|
let transaction;
|
2023-01-30 16:33:15 +00:00
|
|
|
|
2023-03-03 17:55:58 +00:00
|
|
|
try {
|
|
|
|
const decodedParams = JSON.parse(
|
|
|
|
base64url.decode(merchantParameters, 'utf8'));
|
|
|
|
const params = {};
|
2023-01-30 16:33:15 +00:00
|
|
|
|
2023-03-03 17:55:58 +00:00
|
|
|
for (const param in decodedParams)
|
|
|
|
params[param] = decodeURIComponent(decodedParams[param]);
|
2023-01-30 16:33:15 +00:00
|
|
|
|
2023-03-03 17:55:58 +00:00
|
|
|
const orderId = params['Ds_Order'];
|
|
|
|
if (!orderId)
|
|
|
|
throw new UserError('Order id not provided');
|
2023-03-03 09:57:57 +00:00
|
|
|
|
2023-03-03 17:55:58 +00:00
|
|
|
transaction = await Self.findById(orderId, {fields: ['id']});
|
|
|
|
if (!transaction)
|
|
|
|
throw new UserError('Order not found');
|
2023-01-30 16:33:15 +00:00
|
|
|
|
2023-03-03 09:57:57 +00:00
|
|
|
await transaction.updateAttributes({
|
|
|
|
merchantParameters,
|
|
|
|
signature,
|
|
|
|
signatureVersion,
|
|
|
|
});
|
2023-01-30 16:33:15 +00:00
|
|
|
|
2023-03-03 09:57:57 +00:00
|
|
|
const merchantId = parseInt(params['Ds_MerchantCode']);
|
|
|
|
if (!merchantId)
|
|
|
|
throw new UserError('Merchant id not provided');
|
2023-01-30 16:33:15 +00:00
|
|
|
|
2023-03-03 09:57:57 +00:00
|
|
|
const merchant = await $.TpvMerchant.findById(merchantId, {
|
|
|
|
fields: ['id', 'secretKey']
|
|
|
|
});
|
|
|
|
if (!merchant)
|
|
|
|
throw new UserError('Merchant not found');
|
2023-01-30 16:33:15 +00:00
|
|
|
|
2023-03-03 09:57:57 +00:00
|
|
|
const base64hmac = Self.createSignature(
|
2023-01-30 16:33:15 +00:00
|
|
|
orderId,
|
2023-03-03 09:57:57 +00:00
|
|
|
merchant.secretKey,
|
|
|
|
merchantParameters
|
|
|
|
);
|
|
|
|
|
|
|
|
if (base64hmac !== base64url.toBase64(signature))
|
|
|
|
throw new UserError('Invalid signature');
|
2023-01-31 13:00:10 +00:00
|
|
|
|
2023-03-03 09:57:57 +00:00
|
|
|
await Self.rawSql(
|
|
|
|
'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [
|
|
|
|
params['Ds_Amount'],
|
|
|
|
orderId,
|
|
|
|
merchantId,
|
|
|
|
params['Ds_Currency'],
|
|
|
|
params['Ds_Response'],
|
|
|
|
params['Ds_ErrorCode']
|
2023-06-15 11:10:44 +00:00
|
|
|
]);
|
2023-03-03 09:57:57 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
} catch (err) {
|
2023-03-03 17:55:58 +00:00
|
|
|
if (transaction)
|
2023-03-03 09:57:57 +00:00
|
|
|
await transaction.updateAttribute('responseError', err.message);
|
2023-03-03 17:55:58 +00:00
|
|
|
else
|
|
|
|
console.error(err);
|
2023-03-03 09:57:57 +00:00
|
|
|
throw err;
|
|
|
|
}
|
2023-01-30 11:39:47 +00:00
|
|
|
};
|
|
|
|
};
|