diff --git a/src/config/redis.js b/src/config/redis.js index 2f468ad..61b2fa7 100644 --- a/src/config/redis.js +++ b/src/config/redis.js @@ -14,7 +14,7 @@ const client = createClient({ }); client.on('connect', () => logger.info('Connected to redis')); -client.on('error', () => logger.error(err, 'Redis error')); +client.on('error', (err) => logger.error(err, 'Redis error')); client.on('ready', () => logger.info('Redis client ready')); client.on('end', () => logger.info('Redis connection closed')); diff --git a/src/controllers/beneficiary.controller.js b/src/controllers/beneficiary.controller.js index 07fb52d..ccac3bf 100644 --- a/src/controllers/beneficiary.controller.js +++ b/src/controllers/beneficiary.controller.js @@ -1,8 +1,7 @@ const { logger } = require('../util/logger'); -const { setJson, getJson } = require('../config/redis'); const beneficiaryService = require('../services/beneficiary.service'); const db = require('../config/db'); -const axios = require('axios'); +const randomName = require('../util/name.generator'); async function validateWithinBank(req, res) { const { accountNumber } = req.query; @@ -25,58 +24,75 @@ async function validateWithinBank(req, res) { } } +async function validateOutsideBank(req, res) { + const { accountNo, ifscCode, remitterName } = req.query; + if (!accountNo || !ifscCode || !remitterName) { + res.status(401).json({ error: 'BAD_REQUEST' }); + return; + } + + try { + const refNo = await beneficiaryService.validateOutsideBank( + accountNo, + ifscCode, + remitterName + ); + if (!refNo) + return res.status(401).json({ error: 'invalid account number' }); + //**IN PRODUCTION** poll the redis server continuously giving the refNo since the response from NPCI will be stored there + await delay(3000); + const name = randomName(); + return res.json({ name }); + } catch (err) { + logger.error(err, 'beneficiary validation within bank failed'); + res.status(500).json({ error: 'invalid account number' }); + } +} + async function addBeneficiary(req, res) { try { const { accountNo, ifscCode, accountType, name } = req.body; const customerNo = req.user; - console.log(`Customer Number: ${customerNo}`); - const uuid = await beneficiaryService.validateOutsideBank( - accountNo, - ifscCode, - name - ); - await setJson( - uuid, - { customerNo, accountNo, ifscCode, accountType, name }, - 300 - ); - - //------------------------------------------------------------------------- - //*REMOVE IN PRODUCTION* firing this from here since no NPCI in test region - const r = await axios.post( - 'http://localhost:8081/api/npci/beneficiary-response', - { - resp: { status: 'Success', txnid: uuid, benename: name }, - } - ); - console.log(r.data); - //------------------------------------------------------------------------- - - res.json({ message: 'SENT_FOR_VALIDATION' }); + const query = + 'INSERT INTO beneficiaries (customer_no, account_no, account_type, ifsc_code, name) VALUES ($1, $2, $3, $4, $5)'; + await db.query(query, [customerNo, accountNo, accountType, ifscCode, name]); + res.json({ message: 'SUCCESS' }); } catch (error) { logger.error(error, 'Error adding beneficiary'); + if ( + error.message == + 'duplicate key value violates unique constraint "beneficiaries_pkey"' + ) { + res.status(409).json({ error: 'BENEFICIARY_ALREADY_EXITS' }); + } res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' }); } } -async function checkBeneficiary(req, res) { - await delay(5000); +async function getBeneficiary(req, res) { const { accountNo } = req.query; - const customerNo = req.user; - if (!accountNo) { - res.status(403).json({ error: 'BAS_REQUEST' }); - return; + let beneficiaryDetails; + try { + if (accountNo) { + beneficiaryDetails = await beneficiaryService.getSingleBeneficiary( + req.user, + accountNo + ); + } else { + beneficiaryDetails = await beneficiaryService.getAllBeneficiaries( + req.user + ); + } + if (!beneficiaryDetails) { + res.status(404).json({ error: 'NO_BENEFICIARY_FOUND' }); + return; + } + + res.json(beneficiaryDetails); + } catch (error) { + logger.error(error, 'error fetching beneficiaries'); + res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' }); } - console.log(customerNo, accountNo); - const query = - 'SELECT EXISTS(SELECT 1 FROM beneficiaries WHERE customer_no = $1 AND account_no = $2)'; - const result = await db.query(query, [customerNo, accountNo]); - const exists = result.rows[0].exists; - if (!exists) { - res.status(404).json({ error: 'NOT_FOUND' }); - return; - } - res.json({ message: 'FOUND' }); } async function getIfscDetails(req, res) { @@ -87,7 +103,7 @@ async function getIfscDetails(req, res) { } console.log(ifscCode); try { - const query = 'SELECT * FROM ifsc_code_bank WHERE ifsc_code = $1'; + const query = 'SELECT * FROM ifsc_details WHERE ifsc_code = $1'; const result = await db.query(query, [ifscCode]); console.log(result.rows); if (!result.rows) { @@ -107,7 +123,8 @@ function delay(ms) { module.exports = { validateWithinBank, + validateOutsideBank, addBeneficiary, - checkBeneficiary, getIfscDetails, + getBeneficiary, }; diff --git a/src/controllers/neft.controller.js b/src/controllers/neft.controller.js new file mode 100644 index 0000000..091b7a3 --- /dev/null +++ b/src/controllers/neft.controller.js @@ -0,0 +1,35 @@ +const axios = require('axios'); + +async function send( + fromAccount, + toAccount, + amount, + ifscCode, + beneficiaryName, + remitterName +) { + try { + const response = await axios.post( + 'http://localhost:8690/kccb/Neftfundtransfer', + { + stFromAcc: fromAccount, + stToAcc: toAccount, + stTranAmt: amount, + stCommission: 0, + stIfscCode: ifscCode, + stFullName: remitterName, + stBeneName: beneficiaryName, + stAddress1: '', + stAddress2: '', + stAddress3: '', + } + ); + return response.data; + } catch (error) { + throw new Error( + 'API call failed: ' + (error.response?.data?.message || error.message) + ); + } +} + +module.exports = { send }; diff --git a/src/controllers/npci.controller.js b/src/controllers/npci.controller.js index c677c03..7de4341 100644 --- a/src/controllers/npci.controller.js +++ b/src/controllers/npci.controller.js @@ -1,5 +1,5 @@ const db = require('../config/db'); -const { getJson } = require('../config/redis'); +const { getJson, setJson } = require('../config/redis'); const { logger } = require('../util/logger'); async function npciResponse(req, res) { @@ -15,26 +15,9 @@ async function npciResponse(req, res) { async function handleNPCISuccess(response) { const { txnid, benename } = response; try { - const beneficiaryDetails = await getJson(txnid); - if (!beneficiaryDetails) { - logger.warn('no txnid in redis'); - return false; - } - const { customerNo, accountNo, ifscCode, accountType } = beneficiaryDetails; - const query = - 'INSERT INTO beneficiaries (customer_no, account_no, name, account_type, ifsc_code) VALUES ($1, $2, $3, $4, $5)'; - const result = await db.query(query, [ - customerNo, - accountNo, - benename, - accountType, - ifscCode, - ]); - logger.info(result); - return true; + await setJson(txnid, benename); } catch (error) { logger.error(error, 'error processing npci response'); - return false; } } diff --git a/src/controllers/rtgs.controller.js b/src/controllers/rtgs.controller.js new file mode 100644 index 0000000..e5c9625 --- /dev/null +++ b/src/controllers/rtgs.controller.js @@ -0,0 +1,36 @@ +const axios = require('axios'); + +async function send( + fromAccount, + toAccount, + amount, + ifscCode, + beneficiaryName, + remitterName +) { + try { + const response = await axios.post( + 'http://localhost:8690/kccb/Rtgsfundtransfer', + { + stFromAcc: fromAccount, + stToAcc: toAccount, + stTranAmt: amount, + stCommission: 0, + stIfscCode: ifscCode, + stFullName: remitterName, + stBeneName: beneficiaryName, + stAddress1: '', + stAddress2: '', + stAddress3: '', + } + ); + return response.data; + } catch (error) { + throw new Error( + 'API call to CBS failed' + + (error.response?.data?.message || error.message) + ); + } +} + +module.exports = { send }; diff --git a/src/controllers/transactions.controller.js b/src/controllers/transactions.controller.js index 47a4f81..297ae8c 100644 --- a/src/controllers/transactions.controller.js +++ b/src/controllers/transactions.controller.js @@ -21,5 +21,27 @@ async function getLastTen(accountNumber) { ); } } - -module.exports = { getLastTen }; +async function getFiltered(accountNumber, fromDate, toDate) { + try { + const response = await axios.get( + `http://localhost:8688/kccb/cbs/montlyacctstmt/details`, + { + params: { stacctno: accountNumber, fromdate: fromDate, todate: toDate }, + } + ); + const transactions = response.data; + const processedTransactions = transactions.map((tx) => ({ + id: tx.stTransactionNumber, + name: tx.stTransactionDesc, + date: tx.stTransactionDate, + amount: tx.stTransactionAmount.slice(0, -3), + type: tx.stTransactionAmount.slice(-2), + })); + return processedTransactions; + } catch (error) { + throw new Error( + 'API call failde: ' + (error.response?.data?.message || error.message) + ); + } +} +module.exports = { getLastTen, getFiltered }; diff --git a/src/routes/beneficiary.route.js b/src/routes/beneficiary.route.js index dde2125..d1483d8 100644 --- a/src/routes/beneficiary.route.js +++ b/src/routes/beneficiary.route.js @@ -5,12 +5,9 @@ const newBeneficiaryValidator = require('../validators/beneficiary.validator'); const router = express.Router(); router.get('/validate/within-bank', beneficiaryController.validateWithinBank); -router.get('/check', beneficiaryController.checkBeneficiary); +router.get('/validate/outside-bank', beneficiaryController.validateOutsideBank); router.get('/ifsc-details', beneficiaryController.getIfscDetails); -router.post( - '/add', - newBeneficiaryValidator, - beneficiaryController.addBeneficiary -); +router.get('/', beneficiaryController.getBeneficiary); +router.post('/', newBeneficiaryValidator, beneficiaryController.addBeneficiary); module.exports = router; diff --git a/src/routes/index.js b/src/routes/index.js index 316885f..38dc800 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -6,6 +6,8 @@ const transactionRoute = require('./transactions.route'); const authenticate = require('../middlewares/auth.middleware'); const transferRoute = require('./transfer.route'); const beneficiaryRoute = require('./beneficiary.route'); +const neftRoute = require('./neft.route'); +const rtgsRoute = require('./rtgs.route'); const { npciResponse } = require('../controllers/npci.controller'); const router = express.Router(); @@ -15,6 +17,8 @@ router.use('/auth/admin',adminAuthRoute); router.use('/customer', authenticate, detailsRoute); router.use('/transactions/account/:accountNo', authenticate, transactionRoute); router.use('/payment/transfer', authenticate, transferRoute); +router.use('/payment/neft', authenticate, neftRoute); +router.use('/payment/rtgs', authenticate, rtgsRoute); router.use('/beneficiary', authenticate, beneficiaryRoute); router.use('/npci/beneficiary-response', npciResponse); diff --git a/src/routes/neft.route.js b/src/routes/neft.route.js new file mode 100644 index 0000000..89342b3 --- /dev/null +++ b/src/routes/neft.route.js @@ -0,0 +1,49 @@ +const express = require('express'); +const neftController = require('../controllers/neft.controller'); +const { logger } = require('../util/logger'); +const neftValidator = require('../validators/neft.validator.js'); +const paymentSecretValidator = require('../validators/payment.secret.validator'); + +const router = express.Router(); +router.use(neftValidator, paymentSecretValidator); + +const neftRoute = async (req, res) => { + const { + fromAccount, + toAccount, + ifscCode, + amount, + beneficiaryName, + remitterName, + } = req.body; + + try { + const result = await neftController.send( + fromAccount, + toAccount, + amount, + ifscCode, + beneficiaryName, + remitterName + ); + logger.info(result); + + if (result.status.startsWith('O.K.')) { + const utr = result.status.slice(9, 25); + return res.json({ message: 'SUCCESS', utr }); + } else if (result.status.includes('INSUFFICIENT FUNDS')) { + return res.status(422).json({ error: 'INSUFFICIENT_FUNDS' }); + } else if (result.status.includes('INVALID CHECK DIGIT')) { + return res.status(400).json({ error: 'INVALID_ACCOUNT_NUMBER' }); + } else { + return res.status(400).json({ error: 'PROBLEM_TRANSFERRING_FUNDS' }); + } + } catch (error) { + logger.error(error, 'error occured while doing NEFT transaction'); + return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' }); + } +}; + +router.post('/', neftRoute); + +module.exports = router; diff --git a/src/routes/rtgs.route.js b/src/routes/rtgs.route.js new file mode 100644 index 0000000..389bb93 --- /dev/null +++ b/src/routes/rtgs.route.js @@ -0,0 +1,48 @@ +const express = require('express'); +const rtgsController = require('../controllers/rtgs.controller'); +const { logger } = require('../util/logger'); +const rtgsValidator = require('../validators/rtgs.validator.js'); +const paymentSecretValidator = require('../validators/payment.secret.validator'); + +const router = express.Router(); +router.use(rtgsValidator, paymentSecretValidator); + +const rtgsRoute = async (req, res) => { + const { + fromAccount, + toAccount, + ifscCode, + amount, + beneficiaryName, + remitterName, + } = req.body; + + try { + const result = await rtgsController.send( + fromAccount, + toAccount, + amount, + ifscCode, + beneficiaryName, + remitterName + ); + + if (result.status.startsWith('O.K.')) { + const utr = result.status.slice(9, 25); + return res.json({ message: 'SUCCESS', utr }); + } else if (result.status.includes('INSUFFICIENT FUNDS')) { + return res.status(422).json({ error: 'INSUFFICIENT_FUNDS' }); + } else if (result.status.include('INVALID CHECK DIGIT')) { + return res.status(400).json({ error: 'INVALID_ACCOUNT_NUMBER' }); + } else { + return res.status(400).json({ error: 'PROBLEM_TRANSFERRING_FUNDS' }); + } + } catch (error) { + logger.error(error, 'error occured while doing NEFT transaction'); + return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' }); + } +}; + +router.post('/', rtgsRoute); + +module.exports = router; diff --git a/src/routes/transactions.route.js b/src/routes/transactions.route.js index 9e4ff8c..822c24a 100644 --- a/src/routes/transactions.route.js +++ b/src/routes/transactions.route.js @@ -3,15 +3,44 @@ const { logger } = require('../util/logger'); const transactionsRoute = async (req, res) => { const accountNo = req.params.accountNo; + const { fromDate, toDate } = req.query; + let data; try { - const data = await transactionsController.getLastTen(accountNo); + if (fromDate && toDate) { + if (!isValidDDMMYYYY(fromDate) || !isValidDDMMYYYY(toDate)) { + return res.status(400).json({ error: 'INVALID_DATE_FORMAT' }); + } + data = await transactionsController.getFiltered( + accountNo, + fromDate, + toDate + ); + } else { + data = await transactionsController.getLastTen(accountNo); + } return res.json(data); } catch (error) { - logger.error('error retriving last 10 txns', error); + logger.error('error retriving transaction history', error); return res .status(500) .json({ message: 'error occured while fetching transactions' }); } }; +function isValidDDMMYYYY(dateStr) { + if (!/^\d{8}$/.test(dateStr)) return false; + + const day = parseInt(dateStr.slice(0, 2), 10); + const month = parseInt(dateStr.slice(2, 4), 10); + const year = parseInt(dateStr.slice(4), 10); + + const date = new Date(year, month - 1, day); + + return ( + date.getFullYear() === year && + date.getMonth() === month - 1 && + date.getDate() === day + ); +} + module.exports = transactionsRoute; diff --git a/src/routes/transfer.route.js b/src/routes/transfer.route.js index 7d94aea..3fd9afa 100644 --- a/src/routes/transfer.route.js +++ b/src/routes/transfer.route.js @@ -1,24 +1,10 @@ const transferController = require('../controllers/transfer.controller'); const { logger } = require('../util/logger'); const express = require('express'); -const tpinValidator = require('../validators/tpin.validator'); -const tpasswordValidator = require('../validators/tpassword.validator'); const transferValidator = require('../validators/transfer.validator'); +const passwordValidator = require('../validators/payment.secret.validator.js'); const router = express.Router(); -// Added for tpassword -const passwordValidator=async(req,res,next)=>{ - const{tpin,tpassword} =req.body; - if(tpin){ - return tpinValidator(req,res,next); - } - else if(tpassword){ - return tpasswordValidator(req,res,next); - } - else{ - return res.status(400).json({error:"tpin or tpassword is required"}) - } -} router.use(passwordValidator, transferValidator); const transferRoute = async (req, res) => { diff --git a/src/services/auth.service.js b/src/services/auth.service.js index db520ec..b5cfe71 100644 --- a/src/services/auth.service.js +++ b/src/services/auth.service.js @@ -48,10 +48,10 @@ async function setTpin(customerNo, tpin) { async function setLoginPassword(customerNo, login_psw) { const hashedLoginPassword = await hashPassword(login_psw); try { - await db.query('UPDATE users SET password_hash = $1 ,is_first_login = false WHERE customer_no = $2', [ - hashedLoginPassword, - customerNo, - ]); + await db.query( + 'UPDATE users SET password_hash = $1 ,is_first_login = false WHERE customer_no = $2', + [hashedLoginPassword, customerNo] + ); } catch (error) { throw new Error( `error occured while while setting new Login Password ${error.message}` @@ -62,7 +62,7 @@ async function setLoginPassword(customerNo, login_psw) { async function validateTransactionPassword(customerNo, tpassword) { const user = await findUserByCustomerNo(customerNo); if (!user?.transaction_password) return null; - const isMatch = await comparePassword(tpassword, user.transaction_password ); + const isMatch = await comparePassword(tpassword, user.transaction_password); return isMatch; } @@ -70,10 +70,10 @@ async function validateTransactionPassword(customerNo, tpassword) { async function setTransactionPassword(customerNo, trans_psw) { const hashedTransPassword = await hashPassword(trans_psw); try { - await db.query('UPDATE users SET transaction_password = $1 WHERE customer_no = $2', [ - hashedTransPassword, - customerNo, - ]); + await db.query( + 'UPDATE users SET transaction_password = $1 WHERE customer_no = $2', + [hashedTransPassword, customerNo] + ); } catch (error) { throw new Error( `error occured while while setting new Transaction Password ${error.message}` @@ -81,5 +81,13 @@ async function setTransactionPassword(customerNo, trans_psw) { } } -module.exports = { validateUser, findUserByCustomerNo, setTpin, validateTpin, - CheckFirstTimeLogin, setLoginPassword, validateTransactionPassword,setTransactionPassword }; +module.exports = { + validateUser, + findUserByCustomerNo, + setTpin, + validateTpin, + CheckFirstTimeLogin, + setLoginPassword, + validateTransactionPassword, + setTransactionPassword, +}; diff --git a/src/services/beneficiary.service.js b/src/services/beneficiary.service.js index bba42cd..136f3d1 100644 --- a/src/services/beneficiary.service.js +++ b/src/services/beneficiary.service.js @@ -1,6 +1,7 @@ const axios = require('axios'); const { logger } = require('../util/logger'); const { v4: uuidv4 } = require('uuid'); +const db = require('../config/db'); async function validateWithinBank(accountNo) { const url = 'http://localhost:8687/kccb/cbs/acctInfo/details'; @@ -36,4 +37,33 @@ async function validateOutsideBank(accountNo, ifscCode, name) { } } -module.exports = { validateWithinBank, validateOutsideBank }; +async function getSingleBeneficiary(customerNo, accountNo) { + const queryStr = + 'SELECT b.account_no, b.name, b.account_type, b.ifsc_code, i.bank_name, i.branch_name FROM beneficiaries b JOIN ifsc_details i ON b.ifsc_code = i.ifsc_code WHERE customer_no = $1 AND account_no = $2'; + const result = await db.query(queryStr, [customerNo, accountNo]); + return result.rows[0]; +} + +async function getAllBeneficiaries(customerNo) { + const queryStr = + 'SELECT b.account_no, b.name, b.account_type, b.ifsc_code, i.bank_name, i.branch_name FROM beneficiaries b JOIN ifsc_details i ON b.ifsc_code = i.ifsc_code WHERE customer_no = $1'; + const result = await db.query(queryStr, [customerNo]); + const list = result.rows.map((row) => { + return { + accountNo: row['account_no'], + name: row['name'], + accountType: row['account_type'], + ifscCode: row['ifsc_code'], + bankName: row['bank_name'], + branchName: row['branch_name'], + }; + }); + + return list; +} +module.exports = { + validateWithinBank, + validateOutsideBank, + getAllBeneficiaries, + getSingleBeneficiary, +}; diff --git a/src/util/name.generator.js b/src/util/name.generator.js new file mode 100644 index 0000000..2a90373 --- /dev/null +++ b/src/util/name.generator.js @@ -0,0 +1,36 @@ +const indianFirstNames = [ + 'Aarav', + 'Vivaan', + 'Aditya', + 'Vihaan', + 'Krishna', + 'Ishaan', + 'Rohan', + 'Ananya', + 'Diya', + 'Aisha', + 'Priya', + 'Sneha', +]; +const indianLastNames = [ + 'Sharma', + 'Verma', + 'Iyer', + 'Reddy', + 'Patel', + 'Mehta', + 'Choudhary', + 'Kumar', + 'Das', + 'Rao', +]; + +function getRandomIndianName() { + const firstName = + indianFirstNames[Math.floor(Math.random() * indianFirstNames.length)]; + const lastName = + indianLastNames[Math.floor(Math.random() * indianLastNames.length)]; + return `${firstName} ${lastName}`; +} + +module.exports = getRandomIndianName; diff --git a/src/validators/beneficiary.validator.js b/src/validators/beneficiary.validator.js index 1a0963c..53a4f91 100644 --- a/src/validators/beneficiary.validator.js +++ b/src/validators/beneficiary.validator.js @@ -18,7 +18,7 @@ const newBeneficiaryValidator = async (req, res, next) => { return; } const query_str = - 'SELECT EXISTS(SELECT 1 FROM ifsc_code_bank WHERE ifsc_code = $1)'; + 'SELECT EXISTS(SELECT 1 FROM ifsc_details WHERE ifsc_code = $1)'; const result = await db.query(query_str, [ifscCode]); const exists = result.rows[0].exists; if (!exists) { diff --git a/src/validators/neft.validator.js b/src/validators/neft.validator.js new file mode 100644 index 0000000..a4bd271 --- /dev/null +++ b/src/validators/neft.validator.js @@ -0,0 +1,36 @@ +const neftValidator = (req, res, next) => { + const { + fromAccount, + toAccount, + amount, + remitterName, + beneficiaryName, + ifscCode, + } = req.body; + + if (!isAccountNumbersValid(fromAccount, toAccount)) { + return res.status(400).json({ error: 'INVALID_ACCOUNT_NUMBER_FORMAT' }); + } + + if (amount < 1) { + return res.status(400).json({ error: 'INVALID_AMOUNT' }); + } + + if (!remitterName || !beneficiaryName) { + return res + .status(400) + .json({ error: 'REMITTER_NAME AND BENEFICIARY_NAME REQUIRED' }); + } + + if (!ifscCode || !/^[A-Z]{4}0[0-9]{6}$/.test(ifscCode)) { + return res.status(400).json({ error: 'INVALID_IFSC_CODE' }); + } + + next(); +}; + +const isAccountNumbersValid = (fromAcct, toAcct) => { + return !(!fromAcct || !toAcct || fromAcct.length != 11 || toAcct.length < 7); +}; + +module.exports = neftValidator; diff --git a/src/validators/payment.secret.validator.js b/src/validators/payment.secret.validator.js new file mode 100644 index 0000000..1f12e34 --- /dev/null +++ b/src/validators/payment.secret.validator.js @@ -0,0 +1,15 @@ +const tpasswordValidator = require('./tpassword.validator.js'); +const tpinValidator = require('./tpin.validator.js'); + +const paymentSecretValidator = async (req, res, next) => { + const { tpin, tpassword } = req.body; + if (tpin) { + return tpinValidator(req, res, next); + } else if (tpassword) { + return tpasswordValidator(req, res, next); + } else { + return res.status(400).json({ error: 'tpin or tpassword is required' }); + } +}; + +module.exports = paymentSecretValidator; diff --git a/src/validators/rtgs.validator.js b/src/validators/rtgs.validator.js new file mode 100644 index 0000000..6eb28d0 --- /dev/null +++ b/src/validators/rtgs.validator.js @@ -0,0 +1,36 @@ +const rtgsValidator = (req, res, next) => { + const { + fromAccount, + toAccount, + amount, + remitterName, + beneficiaryName, + ifscCode, + } = req.body; + + if (!isAccountNumbersValid(fromAccount, toAccount)) { + return res.status(400).json({ error: 'INVALID_ACCOUNT_NUMBER_FORMAT' }); + } + + if (amount < 200000) { + return res.status(400).json({ error: 'AMOUNT_SHOULD_BE_MORE_THAN_200000' }); + } + + if (!remitterName || !beneficiaryName) { + return res + .status(400) + .json({ error: 'REMITTER_NAME AND BENEFICIARY_NAME REQUIRED' }); + } + + if (!ifscCode || !/^[A-Z]{4}0[0-9]{6}$/.test(ifscCode)) { + return res.status(400).json({ error: 'INVALID_IFSC_CODE' }); + } + + next(); +}; + +const isAccountNumbersValid = (fromAcct, toAcct) => { + return !(!fromAcct || !toAcct || fromAcct.length != 11 || toAcct.length < 7); +}; + +module.exports = rtgsValidator; diff --git a/src/validators/transfer.validator.js b/src/validators/transfer.validator.js index 11155cf..2d10c48 100644 --- a/src/validators/transfer.validator.js +++ b/src/validators/transfer.validator.js @@ -1,7 +1,7 @@ -const transferValidator = async (req, res, next) => { +const transferValidator = (req, res, next) => { const { fromAccount, toAccount, toAccountType, amount } = req.body; - const accountTypes = ['SB', 'LN','Savings','Current']; + const accountTypes = ['SB', 'LN', 'Savings', 'Current']; if (!fromAccount || fromAccount.length != 11) { return res.status(400).json({ error: 'INVALID_ACCOUNT_NUMBER_FORMAT' }); }