Skip to main content
Cashfree’s web checkout offers merchants a secure, pre-built, and user-friendly interface that supports a wide variety of payment methods, enhancing the transaction experience for both merchants and customers.

Key benefits

Web checkout provides the following advantages for your payment integration:
  • Simplified checkout: Provides a pre-built, easy-to-use checkout page that delivers an optimised payment experience. It accepts payments from over 120 payment methods easily and securely.
  • Secure and PCI compliant: Securely collects payment details and submits them directly to Cashfree servers, removing the need for Payment Card Industry Data Security Standard (PCI DSS) compliance requirements at the merchant’s end.
  • Personalised: Customise your payment methods, branding, and various other elements to align seamlessly with your company’s specific theme.

Prerequisites

Ensure you complete the following tasks before starting the integration: The web checkout integration consists of three essential steps:

Step 1

Create an order

Step 2

Open the checkout page

Step 3

Confirm the payment
The step-by-step guide for each step of the integration process is as follows:

Step 1: Create an order Server-side

To integrate the Cashfree Payment Gateway, you must first create an order. Complete this step before you process any payments. Configure an endpoint on your server to handle order creation. You cannot call this API from the client-side.
Create orders through your backend as this API requires your secret key. Do not call it directly from the client-side.
API request for creating an order
Here’s a sample request for creating an order using your desired backend language. Cashfree offers backend SDKs to simplify the integration process.
import { Cashfree, CFEnvironment } from "cashfree-pg";

const cashfree = new Cashfree(
	CFEnvironment.PRODUCTION,
	"{Client ID}",
	"{Client Secret Key}"
);

function createOrder() {
	var request = {
		order_amount: "1",
		order_currency: "INR",
		customer_details: {
			customer_id: "node_sdk_test",
			customer_name: "",
			customer_email: "example@gmail.com",
			customer_phone: "9999999999",
		},
		order_meta: {
			return_url:
				"https://test.cashfree.com/pgappsdemos/return.php?order_id=order_123",
		},
		order_note: "",
	};

	cashfree
		.PGCreateOrder(request)
		.then((response) => {
			var a = response.data;
			console.log(a);
		})
		.catch((error) => {
			console.error("Error setting up order request:", error.response.data);
		});
}
from cashfree_pg.models.create_order_request import CreateOrderRequest
from cashfree_pg.api_client import Cashfree
from cashfree_pg.models.customer_details import CustomerDetails


Cashfree.XClientId = {Client ID}
Cashfree.XClientSecret = {Client Secret Key}
Cashfree.XEnvironment = Cashfree.XSandbox
x_api_version = "2023-08-01"

def create_order():
        customerDetails = CustomerDetails(customer_id="123", customer_phone="9999999999")
        createOrderRequest = CreateOrderRequest(order_amount=1, order_currency="INR", customer_details=customerDetails)
        try:
            api_response = Cashfree().PGCreateOrder(x_api_version, createOrderRequest, None, None)
            print(api_response.data)
        except Exception as e:
            print(e)
import com.cashfree.*;

Cashfree.XClientId = {Client Key};
Cashfree.XClientSecret = {Client Secret Key};
Cashfree.XEnvironment = Cashfree.SANDBOX;

static void createOrder() {
  CustomerDetails customerDetails = new CustomerDetails();
  customerDetails.setCustomerId("123");
  customerDetails.setCustomerPhone("9999999999");

  CreateOrderRequest request = new CreateOrderRequest();
  request.setOrderAmount(1.0);
  request.setOrderCurrency("INR");
  request.setCustomerDetails(customerDetails);
  try {
    Cashfree cashfree = new Cashfree();
    ApiResponse<OrderEntity> response = cashfree.PGCreateOrder("2023-08-01", request, null, null, null);
    System.out.println(response.getData().getOrderId());

  } catch (ApiException e) {
    throw new RuntimeException(e);
  }
}
import (
  cashfree "github.com/cashfree/cashfree-pg/v3"
)

func createOrder() {

clientId := {Client ID}
clientSecret := {Client Secret Key}
cashfree.XClientId = &clientId
cashfree.XClientSecret = &clientSecret
cashfree.XEnvironment = cashfree.SANDBOX

request := cashfree.CreateOrderRequest{
		OrderAmount: 1,
		CustomerDetails: cashfree.CustomerDetails{
			CustomerId:    "1",
			CustomerPhone: "9999999999",
		},
		OrderCurrency: "INR",
		OrderSplits:   []cashfree.VendorSplit{},
	}
	version := "2023-08-01"
	response, httpResponse, err := cashfree.PGCreateOrder(&version, &request, nil, nil, nil)
	if err != nil {
		fmt.Println(err.Error())
	} else {
		fmt.Println(httpResponse.StatusCode)
		fmt.Println(response)
    }
}
using cashfree_pg.Client;
using cashfree_pg.Model;

Cashfree.XClientId = {Client ID};
Cashfree.XClientSecret = {Client Secret Key};
Cashfree.XEnvironment = Cashfree.PRODUCTION;
var cashfree = new Cashfree();
var xApiVersion = "2023-08-01";

void CreateOrder() {
    var customerDetails = new CustomerDetails("123", null, "9999999999");
    var createOrdersRequest = new CreateOrderRequest(null, 1.0, "INR", customerDetails);
    try {
        // Create Order
        var result = cashfree.PGCreateOrder(xApiVersion, createOrdersRequest, null, null, null);
        Console.WriteLine(result);
        Console.WriteLine(result.StatusCode);
        Console.WriteLine((result.Content as OrderEntity));
    } catch (ApiException e) {
        Console.WriteLine("Exception when calling PGCreateOrder: " + e.Message);
        Console.WriteLine("Status Code: " + e.ErrorCode);
        Console.WriteLine(e.StackTrace);
    }
}
\Cashfree\Cashfree::$XClientId = "<x-client-id>";
\Cashfree\Cashfree::$XClientSecret = "<x-client-secret>";
\Cashfree\Cashfree::$XEnvironment = Cashfree\Cashfree::$SANDBOX;

$cashfree = new \Cashfree\Cashfree();

$x_api_version = "2023-08-01";
$create_orders_request = new \Cashfree\Model\CreateOrdersRequest();
$create_orders_request->setOrderAmount(1.0);
$create_orders_request->setOrderCurrency("INR");
$customer_details = new \Cashfree\Model\CustomerDetails();
$customer_details->setCustomerId("123");
$customer_details->setCustomerPhone("9999999999");
$create_orders_request->setCustomerDetails($customer_details);

try {
    $result = $cashfree->PGCreateOrder($x_api_version, $create_orders_request);
    print_r($result);
} catch (Exception $e) {
    echo 'Exception when calling PGCreateOrder: ', $e->getMessage(), PHP_EOL;
}
curl --location 'https://sandbox.cashfree.com/pg/orders' \
--header 'X-Client-Secret: {{clientKey}}' \
--header 'X-Client-Id: {{clientId}}' \
--header 'x-api-version: 2025-01-01' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
  "order_amount": 10.10,
  "order_currency": "INR",
  "customer_details": {
    "customer_id": "USER123",
    "customer_name": "joe",
    "customer_email": "joe.s@cashfree.com",
    "customer_phone": "+919876543210"
  },
  "order_meta": {
    "return_url": "https://b8af79f41056.eu.ngrok.io?order_id=order_123"
  }
}'
  }

}'
After successfully creating an order, you will receive a unique order_id and payment_session_id that you need for subsequent steps. You can view all the complete API request and response for /orders here.

Step 2: Open the checkout page Client-side

You must whitelist your domain with Cashfree before you start this step.

1. Include JS SDK in your client code

Include our JavaScript SDK in your client-side code to integrate the Cashfree checkout.
<script src="https://sdk.cashfree.com/js/v3/cashfree.js"></script>
npm install @cashfreepayments/cashfree-js

2. Initialise the SDK

Initialise the SDK using the Cashfree() function. You can use one of two modes:
  • sandbox: Use this for a test environment.
  • production: Use this for your live environment.
const cashfree = Cashfree({
    mode:"sandbox" //or production
});
const cashfree = await load({
	mode: "sandbox" //or production
});
//This load function returns a Promise that resolves with a newly created Cashfree object once Cashfree.js has loaded. If you call load in a server environment it will resolve to null.

3. Open Cashfree checkout

Use the cashfree.checkout() method to open the checkout page. Use the following parameters with this method:
  • paymentSessionId: The ID you receive from the create order response.
  • redirectTarget (optional): This parameter determines how the checkout page opens. Use one of the following values:
Property valueDescription
_self (default)Opens the payment link in the same frame as it was clicked.
_blankOpens the payment link in a new window or tab.
_topOpens the linked document in the full body of the window.
_modalOpens the payment link in a pop-up window on the current page.
DOM elementOpens the payment link directly within a specified DOM element.

Checkout variants

Cashfree supports the following checkout variants:
  • Redirect checkout: Use for redirectTarget values _self, _blank, or _top.
  • Popup checkout: Use for redirectTarget value _modal.
  • Inline checkout: Use for redirectTarget as a DOM element.
The integration approach varies for pop-up and inline checkout. You must manage the promise that cashfree.checkout() returns to execute additional code after the payment attempt.
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Cashfree Checkout Integration</title>
        <script src="https://sdk.cashfree.com/js/v3/cashfree.js"></script>
    </head>
    <body>
        <div class="row">
            <p>Click below to open the checkout page in the current tab</p>
            <button id="renderBtn">Pay Now</button>
        </div>
        <script>
            const cashfree = Cashfree({
                mode: "production",
            });
            document.getElementById("renderBtn").addEventListener("click", () => {
                let checkoutOptions = {
                    paymentSessionId: "your-payment-session-id",
                    redirectTarget: "_self",
                };
                cashfree.checkout(checkoutOptions);
            });
        </script>
    </body>
</html>
import { load } from "@cashfreepayments/cashfree-js";

function Checkout() {
  let cashfree;
  var initializeSDK = async function () {
    cashfree = await load({
      mode: "production",
    });
  };
  initializeSDK();

  const doPayment = async () => {
    let checkoutOptions = {
      paymentSessionId: "your-payment-session-id",
      redirectTarget: "_self",
    };
    cashfree.checkout(checkoutOptions);
  };

  return (
    <div class="row">
      <p>Click below to open the checkout page in the current tab</p>
      <button type="submit" class="btn btn-primary" id="renderBtn" onClick={doPayment}>
        Pay Now
      </button>
    </div>
  );
}
export default Checkout;
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Cashfree Checkout Integration</title>
        <script src="https://sdk.cashfree.com/js/v3/cashfree.js"></script>
    </head>
    <body>
        <div class="row">
            <p>Click below to open the checkout page in a pop-up </p>
            <button id="renderBtn">Pay Now</button>
        </div>
        <script>
            const cashfree = Cashfree({
                mode: "production",
            });
            document.getElementById("renderBtn").addEventListener("click", () => {
                let checkoutOptions = {
                    paymentSessionId: "your-payment-session-id",
                    redirectTarget: "_modal",
                };
                cashfree.checkout(checkoutOptions).then((result) => {
                    if(result.error){
                        // This will be true whenever the user clicks on the close icon inside the modal or any error happens during the payment
                        console.log("User has closed the popup or there is some payment error, Check for Payment Status");
                        console.log(result.error);
                    }
                    if(result.redirect){
                        // This will be true when the payment redirection page can't be opened in the same window
                        // This is an exceptional case only when the page is opened inside an inAppBrowser
                        // In this case the customer will be redirected to the return URL once payment is completed
                        console.log("Payment will be redirected");
                    }
                    if(result.paymentDetails){
                        // This will be called whenever the payment is completed irrespective of transaction status
                        console.log("Payment has been completed, Check for Payment Status");
                        console.log(result.paymentDetails.paymentMessage);
                    }
                });
            });
        </script>
    </body>
</html>
import { load } from "@cashfreepayments/cashfree-js";

function Checkout() {
  let cashfree;
  var initializeSDK = async function () {
    cashfree = await load({
      mode: "production",
    });
  };
  initializeSDK();

  const doPayment = async () => {
    let checkoutOptions = {
      paymentSessionId: "your-payment-session-id",
      redirectTarget: "_modal",
    };
    cashfree.checkout(checkoutOptions).then((result) => {
      if (result.error) {
        // This will be true whenever the user clicks on the close icon inside the modal or any error happens during the payment
        console.log("User has closed the popup or there is some payment error, Check for Payment Status");
        console.log(result.error);
      }
      if (result.redirect) {
        // This will be true when the payment redirection page can't be opened in the same window
        // This is an exceptional case only when the page is opened inside an inAppBrowser
        // In this case the customer will be redirected to the return URL once payment is completed
        console.log("Payment will be redirected");
      }
      if (result.paymentDetails) {
        // This will be called whenever the payment is completed irrespective of transaction status
        console.log("Payment has been completed, Check for Payment Status");
        console.log(result.paymentDetails.paymentMessage);
      }
    });
  };

  return (
    <div class="row">
      <p>Click below to open the checkout page in a pop-up </p>
      <button type="submit" class="btn btn-primary" id="renderBtn" onClick={doPayment}>
        Pay Now
      </button>
    </div>
  );
}
export default Checkout;
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Cashfree Checkout Integration</title>
        <script src="https://sdk.cashfree.com/js/v3/cashfree.js"></script>
    </head>
    <body>
        <div class="row">
            <p>Click below to open the checkout page here</p>
            <button id="renderBtn">Pay Now</button>
            <div id="cf_checkout"></div>
        </div>
        <script>
            const cashfree = Cashfree({
                mode: "production",
            });
            document.getElementById("renderBtn").addEventListener("click", () => {
                let checkoutOptions = {
                    paymentSessionId: "your-payment-session-id",
                    redirectTarget: document.getElementById("cf_checkout"),
                    appearance: {
                        width: "425px",
                        height: "700px",
                    },
                };
                cashfree.checkout(checkoutOptions).then((result) => {
                    if(result.error){
                        // This will be true when there is any error during the payment
                        console.log("There is some payment error, Check for Payment Status");
                        console.log(result.error);
                    }
                    if(result.redirect){
                        // This will be true when the payment redirection page can't be opened in the same window
                        // This is an exceptional case only when the page is opened inside an inAppBrowser
                        // In this case the customer will be redirected to the return URL once payment is completed
                        console.log("Payment will be redirected");
                    }
                    if(result.paymentDetails){
                        // This will be called whenever the payment is completed irrespective of transaction status
                        console.log("Payment has been completed, Check for Payment Status");
                        console.log(result.paymentDetails.paymentMessage);
                    }
                });
            });
        </script>
    </body>
</html>
import { load } from "@cashfreepayments/cashfree-js";

function Checkout() {
    let cashfree;
    var initializeSDK = async function () {          
        cashfree = await load({
            mode: "production"
        });
    }
    initializeSDK();

    const doPayment = async () => {
        let checkoutOptions = {
            paymentSessionId: "your-payment-session-id",
            redirectTarget: document.getElementById("cf_checkout"),
            appearance: {
                width: "425px",
                height: "700px",
            },
        };
        cashfree.checkout(checkoutOptions).then((result) => {
            if(result.error){
                // This will be true when there is any error during the payment
                console.log("There is some payment error, Check for Payment Status");
                console.log(result.error);
            }
            if(result.redirect){
                // This will be true when the payment redirection page can't be opened in the same window
                // This is an exceptional case only when the page is opened inside an inAppBrowser
                // In this case the customer will be redirected to the return URL once payment is completed
                console.log("Payment will be redirected");
            }
            if(result.paymentDetails){
                // This will be called whenever the payment is completed irrespective of transaction status
                console.log("Payment has been completed, Check for Payment Status");
                console.log(result.paymentDetails.paymentMessage);
            }
        });
    };

    return (
        <div class="row">
            <p>Click below to open the checkout page here</p>
            <button type="submit" class="btn btn-primary" id="renderBtn" onClick={doPayment}>
                Pay Now
            </button>
            <div id="cf_checkout"></div>
        </div>
    );
}
export default Checkout;

Step 3: Confirm the payment Server-side

After the customer completes the payment, you must confirm the payment status.

Redirect checkout

When the payment process finishes, the user redirects to the return URL you provided when you created the order (Step 1). If you do not provide a return URL, customers redirect to a default Cashfree page.
We recommend that you provide a return URL while creating an order. This will improve the overall user experience by ensuring your customers don’t land on broken or duplicated pages. Also, remember to add context of the order in your return URL so that you can identify the order once the customer has returned to this URL.
When the payment process finishes, the cashfree.checkout() function returns a promise. You must handle this promise to process the payment response.

Order status verification

To verify an order you can call our /pg/orders endpoint from your backend. You can also use our SDK to achieve the same.
version := "2023-08-01"
response, httpResponse, err := cashfree.PGFetchOrder(&version, "<order_id>", nil, nil, nil)
if err != nil {
	fmt.Println(err.Error())
} else {
	fmt.Println(httpResponse.StatusCode)
	fmt.Println(response)
}
cashfree
	.PGFetchOrder("<order_id>")
	.then((response) => {
		console.log("Order fetched successfully:", response.data);
	})
	.catch((error) => {
		console.error("Error:", error.response.data.message);
	});
$x_api_version = "2023-08-01";
try {
    $response = $cashfree->PGFetchOrder($x_api_version, "<order_id>");
    print_r($response);
} catch (Exception $e) {
    echo 'Exception when calling PGFetchOrder: ', $e->getMessage(), PHP_EOL;
}
import com.cashfree.*;
//other code

try {
    Cashfree.XClientId = "<x-client-id>";
    Cashfree.XClientSecret = "<x-client-secret>";
    Cashfree.XEnvironment = Cashfree.SANDBOX;

    Cashfree cashfree = new Cashfree();
    String xApiVersion = "2023-08-01";

    ApiResponse<OrderEntity> responseFetchOrder = cashfree.PGFetchOrder(xApiVersion, "<order_id>", null, null, null);
    System.out.println(response.getData().getOrderId());
} catch (ApiException e) {
    throw new RuntimeException(e);
}
from cashfree_pg.models.create_order_request import CreateOrderRequest
from cashfree_pg.api_client import Cashfree
from cashfree_pg.models.customer_details import CustomerDetails
from cashfree_pg.models.order_meta import OrderMeta

Cashfree.XClientId = "<x-client-id>"
Cashfree.XClientSecret = "<x-client-secret>"
Cashfree.XEnvironment = Cashfree.SANDBOX
x_api_version = "2023-08-01"

try:
    api_response = Cashfree().PGFetchOrder(x_api_version, "order_3242X4jQ5f0S9KYxZO9mtDL1Kx2Y7u", None)
    print(api_response.data)
except Exception as e:
    print(e)

using cashfree_pg.Client;
using cashfree_pg.Model;

Cashfree.XClientId = "<x-client-id>";
Cashfree.XClientSecret = "<x-client-secret>";
Cashfree.XEnvironment = Cashfree.SANDBOX;
var cashfree = new Cashfree();
var xApiVersion = "2023-08-01";

try {
    var result = cashfree.PGFetchOrder(xApiVersion, "<order_id>>", null, null);
    Console.WriteLine(result);
    Console.WriteLine(result.StatusCode);
    Console.WriteLine((result.Content as OrderEntity));
} catch (ApiException e) {
    Console.WriteLine("Exception when calling PGFetchOrder: " + e.Message);
    Console.WriteLine("Status Code: " + e.ErrorCode);
    Console.WriteLine(e.StackTrace);
}
curl --request GET \
     --url https://sandbox.cashfree.com/pg/orders/{order_id} \
     --header 'accept: application/json' \
     --header 'x-api-version: 2025-01-01'
     --header 'x-client-id: "YOUR APP ID GOES HERE"'
     --header 'x-client-secret: "YOUR SECRET KEY GOES HERE'
Always verify the order status before you deliver services to the customer. You can use the Get Order API for this. An order is successful when the order_status is PAID.

Testing

After you integrate the checkout button, verify that it opens the Cashfree-hosted payment page. If the integration does not work, follow these steps to troubleshoot:
  1. Open the Network tab in your browser developer tools.
  2. Click the pay button and check the console logs.
  3. Ensure you pass the correct environment and payment_session_id.
  4. Use console.log() in your button click listener to confirm that you pass data correctly.

Affiliate partner program

As a developer building payment experiences for your clients, you can earn additional income while providing them with industry-leading payment solutions.

Join the Cashfree affiliate partner program and get rewarded every time your clients use Cashfree.

What you get:

  • Earn up to 0.25% commission on every transaction.
  • Become a trusted fintech partner for your clients.
  • Access to a dedicated partner manager for expert support.

What your clients get:

  • Instant activation and go live in minutes.
  • Industry-best success rate across all payment modes.
  • Effortless acceptance of international payments in 140+ currencies.

Get started today. Become a partner now.