Integrate Cashfree’s prebuilt, PCI compliant hosted web checkout to accept 120+ payment methods on your site while keeping branding and UX in your control.
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.
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.
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); });}
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 /ordershere.
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.
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;
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.
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.
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:
Open the Network tab in your browser developer tools.
Click the pay button and check the console logs.
Ensure you pass the correct environment and payment_session_id.
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.