Integrate Cashfree Payouts With Your Serverless Application
user-pic Srinu Madhav Vysyaraju
10 min read Sep 27, 2023

Integrate Cashfree Payouts With Your Serverless Application

Introduction

Cashfree is a popular payment gateway that offers a payout solution for businesses. With Cashfree payouts, you can automate payments to your vendors, suppliers, employees, and customers. In this blog, we will explore how to integrate Cashfree payouts with a serverless application.

Why Consider Cashfree as your payment gateway provider ?

Cashfree, Stripe, and Razorpay are all popular payment gateway providers, and the choice between them depends on various factors specific to your business needs. Here are a few reasons why you might consider Cashfree payments over Stripe and Razorpay:

  1. Extensive Payment Method Support: Cashfree supports a wide range of Indian payment methods such as UPI, Netbanking, debit cards, and popular digital wallets like Paytm and PhonePe. This comprehensive coverage allows your customers to make payments through their preferred methods, resulting in better conversion rates.
  2. Disbursal Solutions: Cashfree offers efficient payout and disbursal solutions that allow businesses to make bulk payments to vendors, suppliers, employees, and partners. This feature can be beneficial if your business involves frequent payouts or relies on a marketplace model.
  3. Support and Customization: Cashfree provides dedicated customer support and offers customization options to tailor the payment experience according to your business requirements. This can be valuable if you have specific needs or require personalised assistance during the integration process.
  4. Direct Bank Transactions : Cashfree Payments allows us to make transactions directly from our bank account without the need to create another bank account with the provider unlike other payment gateways. See the list of banks supported by Cashfree Payments here.

However, it’s important to note that Stripe and Razorpay also have their own strengths. Stripe, for example, is known for its extensive global reach, developer-friendly APIs, and robust ecosystem of integrations. Razorpay, on the other hand, offers a balance of Indian and international payment options, comprehensive developer tools, and a user-friendly interface.

When choosing a payment gateway, consider factors such as your target audience, supported payment methods, integration ease, pricing structure, security, and additional features that align with your business objectives. Evaluate the strengths and weaknesses of each provider to determine which one best suits your specific requirements. For this Post , we are moving forward with Cashfree Payments especially Payouts and see how we can integrate with our NodeJS application.

Below is the Flow diagram on steps needed to make payouts to users . Flow Diagram

Once we integrate the Cashfree APIs or SDK with our application , we need to create a Beneficiary (Person whom we need to send money) , then we can make a payout request to the Beneficiary after successful authorization Cashfree payments will make the fund transfer . Once the payout event is completed , we can track the status of the payout using webhooks . In case of any failed or incomplete transactions, Cashfree provides detailed error codes and messages to help you identify the reasons for the failure which should be handled by the application .

It’s important to note that the exact implementation and customization of the payouts architecture may vary depending on your specific requirements, business processes, and integration preferences.

Step 1: Integration

The first step is to create a Cashfree account. You can do this by visiting the Cashfree website and signing up for an account. Once you have created an account, you will need to verify your email address and complete your profile.

Generate API keys from the dashboard i.e., Client ID and Client Secret and add it to your env file. These credentials will be used to authenticate and authorize your API requests.

Once you generate API keys we can get started to integrate CashFree with our application.

Step 2: Authentication

To interact with Cashfree Payments we need to have an auth token passed in every api call . To generate an auth token and we also need to do a 2FA with Cashfree , There are two methods to do 2FA :

  1. IP WhiteListing :

The IP of the system from which you make your request has to be whitelisted to connect with the Cashfree Payments production server. If the IP is not whitelisted, Cashfree Payments will reject all incoming requests.

To whitelist your IP you can follow the instructions here.

  1. Public Key:

As we are going to use Serverless and we wont be having any static IP address, we can use PublicKey

To generate a public key,

  1. Go Payouts Dashboard > Developers section on the left-side navigation > Payouts > Two-Factor Authentication > Public Key.
sc.png

We need to generate secret using this public key and send it in header to generate auth token which needs to be sent for every request .

const axios = require("axios");
const NodeRSA = require("node-rsa");

const ClientSecret = process.env.CLIENT_SECRET; // looks something like this : 1cf095a46f4ac61f65c024ca4bbwbdaac141a9af
const ClientId = process.env.CLIENT_ID; // BF292C03DFPPAKH2GP8D3QVLVPMG
const publicKeypem = process.env.PUBLIC_KEY // Adding DummyKey below
const TestUrl = "https://payout-gamma.cashfree.com/payout/v1"; // TEST URL 
/*
`-----BEGIN PUBLIC KEY-----
HIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5J8keFd1LaeKHdpud7MD
EHtaBiz1Ozf1PpFmpgyFHGxvHRIuKU/4oCnco93SwkCa1hsHBy4WRP7Nfb9ZAz9H
MtEicRPMAzjD9KcTExcYgy8ijhI7xUvicsnL0PtL2JEOQVH4fy76eDn0KG5Yihor
zXBa2LdLJGc+DrEywuWXyBfaFtH0RNAM0QGHq8Kkdk4x@4Fecv8XXl+6L6mNgl08
dn1KIxBI3Ytxw2GYYL09fxWbhG9JBIEAEw0Ba8EDVOu3NBQ5bzg6LoQQZgGRI9RK
EmCDXO7WEzdWELCaI8cWZFCCGgDXmp9y1iGncFQzo7R8yo2r02yCs49YKlsjvoe9
0wIDAQAB
-----END PUBLIC KEY-----`;
*/

// Generating Secret using public key 
const generateSecret = () => {
    try{
      let pubicKey = new NodeRSA(publicKeyPem);
      const secret = ClientId + "." + Math.floor(Date.now() / 1000);
      let encryptedString = pubicKey.encrypt(secret, "base64");
      return encryptedString;
    }catch(err){
        console.log(err);
  }
}; 

// Generating AuthToken which is used for authenticating a request.
const getAuthTokenFromCashFree = async () => {
  try {
    const options = {
      method: "POST",
      url: TestUrl + "/authorize",
      headers: {
        accept: "application/json",
        "X-Client-Secret": ClientSecret,
        "X-Client-Id": ClientId,
        "X-Cf-Signature": generateSecret(),
      },
    };
    console.log("options",options);
    const { data } = await axios.request(options);
    console.log("token", data.data.token);
    return data.data.token;
  } catch (err) {
    console.log(err);
  }
};

Step 3: Create and Manage Beneficiaries

Now we can start interacting with Cashfree , with all the authentication functions added . To create Beneficiary add the following lines to your file:

const addBeneficiary = async () => {
  try {
    const authToken = await getAuthTokenFromCashFree(); // This needs to be sent with every request made with cashfree
    const options = {
      method: "POST",
      url: TestUrl + "/addBeneficiary",
      data: {
        beneId: "TESTID",
        name: "TEST USER",
        email: "testuser@gmail.com",
        phone: "9876543210",
        bankAccount: "00111122223",
        ifsc: "HDFC0000006",
        address1: "ABC Street",
        city: "Bangalore",
        state: "Karnataka",
        pincode: "560001",
      },
      headers: {
        accept: "application/json",
        Authorization: `Bearer ${authToken}`,
      },
    };
    const { data } = await axios.request(options);
    console.log("data", data);
    return data;
  } catch (err) {
    console.log(err);
  }
};

Once we added the beneficiary we can get the details of the beneficiary using :

const getBeneficiaryDetails = async () => {
  try {
    const authToken = await getAuthTokenFromCashFree();
        const beneId = 1 // unique id added while creating Beneficiary
    const { data } = await axios.get(`${TestUrl}/getBeneficiary/${beneId}`, {
      headers: {
        accept: "application/json",
        Authorization: `Bearer ${authToken}`,
      },
    });
    console.log("data", data);
    return data;
  } catch (err) {
    console.log(err);
  }
};

To modify the bank details of beneficiary , we cannot directly edit the details, we should delete the old beneficiary and add a new beneficiary.

const deleteBeneficiary = async (id) => {
  try {
    const authToken = await getAuthTokenFromCashFree();
    const options = {
      method: "POST",
      url: TestUrl + "/removeBeneficiary",
      data: {
        beneId: id
      },
      headers: {
        accept: "application/json",
        Authorization: `Bearer ${authToken}`
      }
    };
    const { data } = await axios.request(options);
    console.log("data", data);
    return data;
  } catch (err) {
    console.log(err);
  }
};

Step 4: Creating Payouts

Now, we can make transfer to the Beneficiaries using either single payouts or bulk payouts.There are two methods of transfers it can be synchronous or asynchronous ,In synchronous mode we need to wait until the transfer is success or failed, but in asynchronous mode we can initiate the transaction , and it will send an agreement message, which will be much faster when we want to make multiple transactions. Following is the example of asynchronous single and bulk payouts :

const transferMoneyToSingleUser = async () => { // This function makes a transaction to single person
  try {
    const authToken = await getAuthTokenFromCashFree();
    const options = {
      method: "POST",
      url: TestUrl + ".2/requestAsyncTransfer",
      data: {
        beneId: "TEST",
        amount: 2000,
        transferId: "07MAR2022_CLIENT05_03",
        // transferMode: "banktransfer",
        // paymentInstrumentId: CashFreeWalletID,
      },
      headers: {
        accept: "application/json",
        Authorization: `Bearer ${authToken}`,
      },
    };
    const { data } = await axios.request(options);
    console.log("data", data);
    return data;
  } catch (err) {
            console.log(err);
    }
};

const bulkTransfer = async()=>{
  try {
    const authToken = await getAuthTokenFromCashFree();
    const options = {
      method: "POST",
      url: TestUrl + ".2/requestBatchTransfer",
      data: {
        "batchTransferId":"batch_req_21",
        "batchFormat":"BENEFICIARY_ID",
        "batch": [
          {
            "transferId":"transfer1",
            "amount":10,
            "beneId":"4937",
            "transferMode":"banktransfer",
          },
          {
            "transferId":"transfer2",
            "amount":20,
            "beneId":"TEST2",
            "transferMode":"banktransfer",
          }
        ],
        "paymentInstrumentId":"CASHFREE_300557"
      },
      headers: {
        accept: "application/json",
        Authorization: `Bearer ${authToken}`,
      },
    };
    const { data } = await axios.request(options);
    console.log("data", data);
    return data;
  } catch (err) {
            console.log(err);
    }
}

Step 5: Status Tracking

Once we initiate the transactions whether single or bulk payouts , we need the application to know the status of the transaction whether it failed or the payment was succeeded. For this purpose Cashfree payments provide webhooks which send an event whenever a transaction is succeeded or failed.

Let us consider we have an endpoint where an event from webhook is processed , but what happens if someone pretends to be Cashfree payments and tries to misuse the api, so it is important for us to verify the signature of the event that was received by Cashfree . To verify the signature you can follow this code snippet:

const verifyCashFreeSignature = (reqbody, secret) => {
  // Function to Verify CashFree Signature
  const urlParams = new URLSearchParams(reqbody); // converting "&" separated string to URLParams Object
  const signature = urlParams.get("signature");
  const entries = urlParams.entries();
  const params = paramsToObject(entries);
  delete params["signature"];
  const ordered = Object.keys(params)
    .sort()
    .reduce(
      // order the object by Keys
      (obj, key) => {
        obj[key] = params[key];
        return obj;
      },
      {}
    );
  let postData = "";
  for (let key of Object.keys(ordered)) {
    // appending the sorted object values to string
    postData += ordered[key];
  }
  const sha256Hasher = crypto.createHmac("sha256", secret);
  const encryptedString = sha256Hasher
    .update(postData)
    .digest("base64")
    .toString(); // encrypting using sha256 with base 64 encoding
  console.log("encryptedString", encryptedString, "signature", signature);
  return encryptedString === signature;
};

Once the signature is verified from the webhook , we can proceed with the application logic.

Conclusion

In this Blog, we have seen how to interact with cashfree payments ,how to use PublicKey to generate AuthToken which is needed for every api call ,why signature verification is important and how to verify the signature using NodeJs.

Integrating Cashfree Payments Payouts with Node.js and serverless architecture provides a powerful solution for seamless payment processing. By following the steps outlined in this blog, you can leverage the capabilities of Cashfree Payments and build a secure and scalable payment system for your online business.

Remember to handle errors gracefully, implement proper security measures, and continuously monitor your integration for optimal performance. With Cashfree Payments and Node.js, you can provide a seamless payment experience to your customers while focusing on growing your business.

References

Application Modernization Icon

Innovate faster, and go farther with serverless-native application development. Explore limitless possibilities with AntStack's serverless solutions. Empowering your business to achieve your most audacious goals.

Talk to us

Author(s)

Tags

Your Digital Journey deserves a great story.

Build one with us.

Recommended Blogs

Cookies Icon

These cookies are used to collect information about how you interact with this website and allow us to remember you. We use this information in order to improve and customize your browsing experience and for analytics and metrics about our visitors on this website.

If you decline, your information won’t be tracked when you visit this website. A single cookie will be used in your browser to remember your preference not to be tracked.

Talk to us