2.2 Cashfree Drop Checkout

Learn in detail about the drop checkout web integration type.

Overview

This type of integration is our pre-built UI solution for accepting payments. You can build your own payment experience and add elements as per your requirements to your payments page design using this integration.

Use cases for customisation

  • If you want to add or remove any payment method from the checkout page.
  • If you want to change the theme of the payments page.
  • If you want to increase/decrease the font size.
  • If you want to enable or disable the option of sharing the order details with your customers.

Features

The Drop SDK offers the following features:

  • Highly customisable
  • Pure javascript
  • Automatic theme detection
  • No PCI certification required

How it works

The drop method works by displaying payment components, which we call drops, at any place you want on your page. It can either display all the payment components in one place or in different places depending on your need. Currently, this method supports the following payment methods:

  • Card
  • UPI (collect, intent, qrcode)
  • Wallet
  • Netbanking
  • Paylater
  • Credit Card EMI
  • Cardless EMI

INTEGRATION TOOLKIT

Try our Integration

From an implementation perspective, the drop integration contains the following components:

Server Side

  • API call to create the payment_session_id
  • API call to check the payment status
  • Receive webhook events

Client Side

  • JS code uses payment_session_id to render and initiate a payment.

Cashfree Drop Checkout Payment Flow

  • Your customer goes to the checkout page.
  • Your server now makes an API call to create an order with Cashfree Payments to get the payment_session_id.
  • The server shares the payment_session_id to your website post which your website initialises the Drop SDK.
  • Drop shows the available payment methods, makes the payment request, and handles additional actions.
  • Once the payment is completed, Drop sends callback and uses the callback data to verify the payment status from your backend.
  • Additionally, you can use webhook to verify the payment status. The customers are redirected to the corresponding return URL.

Demo

Here is a codepen demo. You can play around with different options. The demo uses a payment_session_id, which can be generated using the Create Order API.


Prerequisties

  • Cashfree Payments test account
  • Client-id and client-secret (obtained from the dashboard)
  • A backend server

Step 1: Create an order

To redirect your customer to Cashfree Payments checkout page, you must first create an order. Click here to read more on how to create an order.


Step 2: Include SDK in your client code

To use a pre-built checkout page, you need to use our javascript SDK. This will redirect your customer to the standard checkout page. Use the payment_session_id you have received when creating an order in Cashfree Payments JS SDK 2.0.0.

Production

<script src="https://sdk.cashfree.com/js/ui/2.0.0/cashfree.prod.js></script>

Sandbox

<script src="https://sdk.cashfree.com/js/ui/2.0.0/cashfree.sandbox.js"></script>

Step 3: Initialize the SDK

Use the snippet below to initialize and invoke JS SDK.

const paymentSessionId = "your payment session id"; 
const cashfree = new Cashfree(paymentSessionId);

Step 4: Initiate drop

The configuration object will help you build a custom flow. For instance, if you need to display a card element, you can specify that in the components array. The details about each of these parameters are listed below.

const dropinConfig = {
                components: [
                    "order-details",
                    "card",
                    "netbanking",
                    "app",
                    "upi",
                ],
                onSuccess: function(data){
                   //on success
                },
                onFailure: function(data){
                   //on success
                },
                style: {
                      //to be replaced by the desired values
                      backgroundColor: "#ffffff",
                      color: "#11385b", 
                      fontFamily: "Lato",
                      fontSize: "14px",
                      errorColor: "#ff0000",
                      theme: "light", (or dark)
                }
    }

Use the drop function to render the Drop. There are two parameters involved:

  1. The first parameter is the HTML element where the drop will be rendered.
  2. The second parameter is your drop config.
cashfree.drop(document.getElementById("paymentForm"),dropinConfig);

The following objects can be part of the drop configuration. This configuration will get passed to the SDK.

Parameter NameRequiredDescription
componentsAn array that takes in the components to be rendered. Available: order-details card netbanking app upi-collect upi-intent upi-qrcode
onSuccessCallback function triggered when the payment flow is completed
onFailure Callback function triggered whenever an error occurs
style Custom styling for components. Available: backgroundColor color fontFamily fontSize errorColor theme

Drop Components

Components represent specific blocks used to display specific parts of the payment UI. You can think of components as pre-built react components which can be imported into your payment page. These components handle different workflows and their lifecycle is managed by the Drop library.

NameDescription
order-detailsUse this component to display order and customer details
cardUse this component to display card as a payment method
netbankingUse this component to display Net Banking as a payment method
appUse this component to display wallets as a payment method
upiUse this component to display upi as a payment method
paylaterUse this component to display paylater as a payment method
creditcardemiUse this component to display Credit Card EMI as a payment method for orders above Rs. 2500
cardlessemiUse this component to display Cardless EMI as a payment method for orders above 500

Style

You can style the components by providing some specific parameters as a part of the style object.

NameDescription
backgroundColorCan be used to modify the background color of the drop. The default background color is #fafafa
colorCan be used to set the theme color of the drop. The default color is #6933D3
fontFamilyCan be used to set the font family to match your website. The default font is Lato
fontSizeCan be used to set the base font size. The default font size is 14px
errorColorCan be used to modify the color of error text. The default color is #ff0000
themeCan be used to set the dark or light theme. The default theme is light

Step 5: Handle the response and verify the order status

Verify order status

You need to verify your order status with Cashfree Payments from your backend server. You must first verify this order in your system and ensure that it is the correct order_id. You must then make an API call to Cashfree Payments server to fetch the order status. Based on Cashfree Payments response, you can update your system and share the same information with your client code.

Use the following API to get the order status - https://docs.cashfree.com/reference/getorder

Complete Demo code

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Cashfree Drops</title>
  </head>
  <body>
    <div id="payment-form"></div>
    <button id="pay-btn">Pay</button>
  	  
	<script src="https://sdk.cashfree.com/js/ui/2.0.0/cashfree.sandbox.js"></script>
    <script src="main.js"></script>
  </body>
</html>
let paymentSessionId = "your-payment-session-id";
const paymentDom = document.getElementById("payment-form");
const success = function(data) {
    if (data.order && data.order.status == "PAID") {
        $.ajax({
            url: "checkstatus.php?order_id=" + data.order.orderId,
            success: function(result) {
                if (result.order_status == "PAID") {
                    alert("Order PAID");
                }
            },
        });
    } else {
        //order is still active
        alert("Order is ACTIVE")
    }
}
let failure = function(data) {
    alert(data.order.errorText)
}
document.getElementById("pay-btn").addEventListener("click", () => {
    const dropConfig = {
        "components": [
            "order-details",
            "card",
            "netbanking",
            "app",
            "upi"
        ],
        "onSuccess": success,
        "onFailure": failure,
        "style": {
            "backgroundColor": "#ffffff",
            "color": "#11385b",
            "fontFamily": "Lato",
            "fontSize": "14px",
            "errorColor": "#ff0000",
            "theme": "light", //(or dark)
        }
    }
    if (paymentSessionId == "") {
        $.ajax({
            url: "fetchtoken.php",
            success: function(result) {
                paymentSessionId = result["payment_session_id"];
                const cashfree = new Cashfree(paymentSessionId);
                cashfree.drop(paymentDom, dropConfig);
            },
        });
    } else {
        const cashfree = new Cashfree(paymentSessionId);
        cashfree.drop(paymentDom, dropConfig);
    }

})
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://sandbox.cashfree.com/pg/orders",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"customer_details\":{\"customer_id\":\"12345\",\"customer_email\":\"[email protected]\",\"customer_phone\":\"1299087801\"},\"order_amount\":1,\"order_currency\":\"INR\",\"order_note\":\"test order\"}",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json",
    "Content-Type: application/json",
    "x-api-version: 2022-09-01",
    "x-client-id: Test_Client_ID",
     "x-client-secret: TEST_CLIENT_SECRET"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  header('Content-Type: application/json; charset=utf-8');
  echo json_encode(array("error" => 1));
  echo "cURL Error #:" . $err;
  die();

} else {
  $result = json_decode($response, true);
  header('Content-Type: application/json; charset=utf-8');
  $output = array("payment_session_id" => $result["payment_session_id"]);
  echo json_encode($output);
  die();
}
?>
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://sandbox.cashfree.com/pg/orders/" . $_GET["order_id"],
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json",
    "Content-Type: application/json",
    "x-api-version: 2022-09-01",
    "x-client-id: Test_Client_ID",
     "x-client-secret: TEST_CLIENT_SECRET"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  header('Content-Type: application/json; charset=utf-8');
  echo json_encode(array("error" => 1));
  echo "cURL Error #:" . $err;
  die();

} else {
  $result = json_decode($response, true);
  header('Content-Type: application/json; charset=utf-8');
  $output = array("order_status" => $result["order_status"]);
  echo json_encode($output);
  die();
}
?>

NPM

npm i cashfree-pg-sdk-javascript

For further steps please visit the official npm package

Handle Response

Once you have presented the payment form to the customer, they will be able to attempt the payment. When your customers complete the payment, you need to redirect them to a webpage that shows the payment status. This provides your customers with a complete payment experience. To handle this return URL, Drop emits events which need to be handled by you.

You can provide two different event handlers to handle these two scenarios: onSuccess and onFailure.

Handle onSuccess and onFailure

 onSuccess: (data) => {
      if (data.order && data.order.status == "PAID") {
            //order is paid
            //verify order status by making an API call to your server
            // using data.order.orderId
      } else {
          //order is still active and payment has failed
      }
    
},
onFailure: (data) => {                                                
      console.log(data.order.errorText)
}