A Guide to Integrate CCAvenue Payment Gateway With Nodejs
Online payments have become an essential part of businesses today. With the rise of e-commerce and online transactions, having a secure and reliable payment gateway is crucial. CCAvenue is a popular payment gateway in India that offers businesses an easy way to process payments online. In this blog, we will guide you through the steps of integrating the CCAvenue payment gateway into your system and help you to start accepting payments online.
Unfortunately, there’s no such help in Nodejs so I am making it to save others’ hours.
I am assuming you’ll have node (express.js) code and support Rest APIs.
How CCAvenue Payment Gateway Work?
Integrate CCAvenue Payment Gateway:
Step 1:
Create an account on CCAvenue and you will get a few credentials just like:
access_key , working_key, merchant_id
Step 2: Coding Part
As per the diagram send the payload to the server your payload will have relevant information server will encrypt the request and send HTML to the payment gateway.
// payload
{
merchant_id = 000, // your merchant id provided by bank
order_id = Date.now(), // uniuqe order_no
currency = "USD", // or any supported currency
amount,
redirect_url = "https://your_domain.com/ccavResponseHandler", // any route name that where ccaveneue response hit back to sever
cancel_url = "https://your_domain.com/ccavResponseHandler",//any route name that where ccaveneue response hit back to sever
merchant_param1 = "any_value", // extra information can be send in these params you are not allowed to use any other custom field
merchant_param2,
merchant_param3,
merchant_param4,
merchant_param5,
promo_code,
customer_identifier, //can be you user_id to save card info on payment gateway side
}
We will need to encrypt this request before sending it to the payment gateway There are a few packages in the node but not work with CCAvenue so I wrote it my encryption and decryption algorithm that works well.
// utils.js
/* payment gaetway encryption */
exports.node_encrypt_ccavenue_request = (payload) => {
// parameter payload should be in string/stringify
let key = "XXXXXXX"; // your working_key provided by bank
const method = "aes-256-gcm";
const initVector = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(method, key, initVector);
let encrypted = cipher.update(payload, 'utf8', 'hex');
encrypted += cipher.final('hex');
const tag = cipher.getAuthTag().toString('hex');
return initVector.toString('hex') + encrypted + tag;
}
/* payment gateway decryption */
exports.node_dencrypt_ccavenue_response = (encResp) => {
// parameter encResp should be in string
let key = "XXXXXXX"; // your working_key provided by bank
const method = "aes-256-gcm";
const encryptedTextBuffer = Buffer.from(encResp, 'hex');
const iv_len = 16;
const tag_length = 16;
const iv = encryptedTextBuffer.slice(0, iv_len);
const tag = encryptedTextBuffer.slice(-tag_length);
const ciphertext = encryptedTextBuffer.slice(iv_len, -tag_length);
const decipher = crypto.createDecipheriv(method, key, iv);
decipher.setAuthTag(tag);
let decrypted = decipher.update(ciphertext, 'binary', 'utf8');
decrypted += decipher.final('utf8');
let data = qs.parse(decrypted);
return data;
}
This is how our Html that needs to send to the payment gateway
<!-- payment_requset.html or payment_requset.ejs-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Payment</title>
</head>
<body>
Loading...
<!-- For production payment url will be changed. Please Ask Payment gateway for testign and production url-->
<form id="nonseamless" method="post" name="redirect" action="https://ccavenue_url.com/transaction.do?command=initiateTransaction"/>
<input type="hidden" id="encRequest" name="encRequest" value="<%= encryptedData %>">
<input type="hidden" name="access_code" id="access_code" value="<%= access_code %>">
<script language="javascript">
setTimeout(() => {
document.redirect.submit();
}, 500);
</script>
</form>
</body>
</html>
This is what our whole controller method will look like:
// PaymentController.js
const qs = require('qs');
const utils = require('./utils');
//encrypt request
exports.ccav_request_handler = async function (req, res) {
const {
merchant_id = 000, // your merchant id provided by bank
order_id = Date.now(), // uniuqe order_no
currency = "USD", // or any supported currency
amount,
redirect_url = 'https://your_domain.com/ccavResponseHandler', // any route name that where ccaveneue response hit back to sever
cancel_url = 'https://your_domain.com/ccavResponseHandler',//any route name that where ccaveneue response hit back to sever
merchant_param1, // extra information can be send in these params you are not allowed to use any other custom field
merchant_param2,
merchant_param3,
merchant_param4,
merchant_param5,
promo_code,
customer_identifier, // to save card info on payment gateway side
} = req.body;
const stringify_payload = qs.stringify({
...req.body
})
const encryptionResponseData = utils.node_encrypt_ccavenue_request(stringify_payload);
res.render("payment_request", {
encryptedData: encryptionResponseData,
access_code: 'XXXXXX', // your access_code provided by bank
});
}
// handle request from bank
exports.ccav_response_handler = async function (req, res) {
const { encResp } = req.body;
/* decrypt */
let decryptedJsonResponseData;
decryptedJsonResponseData = utils.node_dencrypt_ccavenue_response(encResp);
let data = decryptedJsonResponseData;
const {
merchant_param1,
merchant_param2,
merchant_param6,
merchant_param3,
merchant_param4,
order_status,
failure_message,
status_code,
status_message,
amount,
tracking_id,
payment_mode,
card_name,
customer_card_id,
} = data || {}
if (
order_status == 'Invalid'
|| order_status == 'Aborted'
|| order_status == 'Cancelled'
|| order_status == 'Unsuccessful'
|| order_status == 'Failure'
) {
// return response
return res.render("ccav_payment_response", {
data_string: JSON.stringify(data),
order_status,
});
}
// write your logic here...
// and return response
return res.render("ccav_payment_response", {
data_string: JSON.stringify(data),
order_status,
});
}
<!-- ccav_payment_response.html or ccav_payment_response.ejs -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Payment</title>
</head>
<body>
Please Wait...
<input type="hidden" id="paymet_response" name="paymet_response" value="<%= data_string %>">
<input type="hidden" name="order_status" id="order_status" value="<%= order_status %>">
<input type="hidden" name="status_code" id="status_code" value="<%= status_code %>">
</form>
</body>
</html>
Remember i am sending the HTML PAGE back as response you may send json as well but i am not sure at this moment.
IMPORTANT! To Test the integration your transaction initiate request will only work under the registered domain on CCAvenue dashboard You might not be able to test locally.
That’s it You have all code now to send a request to the payment gateway and receive the response.
Check the Order Status using CCAvenue API
Call the below function to get any order status
// utils.js
exports.check_order_status = async (payload) => {
let payload = {
order_no: payload.orderNo, // your order_no that you sent to payment gateway
}
let final_payload = JSON.stringify(payload)
encryptionResponseData = exports.node_encrypt_ccavenue_request(final_payload);
let ccave_payload = {
command: 'orderStatusTracker',
enc_request: encryptionResponseData,
access_code: 'XXXX', // your access code
request_type: 'JSON',
response_type: 'JSON',
version: 1.1
}
const stringify_data = qs.stringify({
...ccave_payload
});
let ccave_response = {};
try {
// for production the base url could be different
let ccav_base_url = "https://apitest.ccavenue.com";
ccave_response = await axios.post(`${ccav_base_url}/apis/servlet/DoWebTrans?${stringify_data}` , {}, {
});
} catch (err) {
console.log('>>>>>>> axios order status api error >>>>>>>> ')
console.log(err)
}
return ccave_response.data;
}
I hope this guide has been helpful in getting you started with CCAvenue payment gateway integration.
Don’t forget to hit the share button and follow me on, Twitter, and LinkedIn. Thank you for your support.