Getting Started

Checkout Form is the simplest way to integrate Cashfree Payment Gateway in your website. When using this mode of integration customers will be directed from your checkout page to the Cashfree page which collects payment details and completes the payment.

If you want more control over the payment flow, and not a Cashfree hosted payment form, try out the below integrations methods.
  1. No-Redirect (Pop-up/Inline)
  2. Seamless Basic - Javascript Integration
  3. API Integration

Checkout Form

In this method, you will prepare the checkout form with order and customer details and redirect the user to cashfree payment page. Your customer will enter the card/bank details on our page and we take care of PCI compliance on your behalf. Integrating Checkout Form on your website requires as little as you sending us the Checkout details with the correct data.

Step 1: Creating checkout form

Ideally your customers will be making a transaction for a particular order. To identify this particular order in your system you’ll use an identifier aka orderId. As your payments are processed by Cashfree you’ll need to send us the orderId and the corresponding orderAmount. In return after the payment is completed we will inform you about the status of the payment corresponding to this orderId.
There are other details also which you need to send to us for processing a payment. You can take a look at all the request parameters here.

This integration requires you to create a sample html form like below. You’ll need to fill in the correct credentials for appId (You can find your appId from the merchant dashboard). The returnUrl is your webpage where the customer will be redirected to post payment on Cashfree, we will post the response parameters to this page.

Cashfree also posts form variables to a URL notifyUrl you specify that runs a program to process these variables. See below the response parameters which Cashfree will post to these URLs.

Every request to Cashfree must contain authentication information to establish the identity of the user making the request, we use the `signature` field for this authentication. See below code on how to generate a valid signature for Checkout integration.


For production/live usage set the action attribute of the form to: https://www.cashfree.com/checkout/post/submit
For testing set the action attribute to: https://test.cashfree.com/billpay/checkout/post/submit

  <form id="redirectForm" method="post" action="https://test.cashfree.com/billpay/checkout/post/submit">
    <input type="hidden" name="appId" value="<YOUR_APPID_HERE>"/>
    <input type="hidden" name="orderId" value="order00001"/>
    <input type="hidden" name="orderAmount" value="100"/>
    <input type="hidden" name="orderCurrency" value="INR"/>
    <input type="hidden" name="orderNote" value="test"/>
    <input type="hidden" name="customerName" value="John Doe"/>
    <input type="hidden" name="customerEmail" value="Johndoe@test.com"/>
    <input type="hidden" name="customerPhone" value="9999999999"/>
    <input type="hidden" name="returnUrl" value="<RETURN_URL>"/>
    <input type="hidden" name="notifyUrl" value="<NOTIFY_URL>"/>
    <input type="hidden" name="signature" value="<GENERATED_SIGNATURE>"/>
  </form>

Step 2: Checksum Generation

Every request to Cashfree must contain authentication information to establish the identity of the user making the request. We use a digital signature (aka a digital thumbprint) to validate each transaction. A digital signature helps us in verifying the originator of the message and also ensures integrity of the signed data against tampering.

In the sample form above you need to generate a signature for every checkout. Technically, the signature is generated as the HMAC value of the data being passed. Generated using SHA256 hash function in combination with merchant’s API secret key (Your API secret key can be retrieved from https://merchant.cashfree.com/merchant/pg#api-key ). We will generate a signature at our end and expect you to do the same with the posted data and match it with the passed argument.

Checksum generation varies across integration methods, please verify if you are using the right signature generation method.
Sample code for you to generate a valid `signature`.

  $secretKey = "secret_key";
  $postData = array( 
  "appId" => $appId, 
  "orderId" => $orderId, 
  "orderAmount" => $orderAmount, 
  "orderCurrency" => $orderCurrency, 
  "orderNote" => $orderNote, 
  "customerName" => $customerName, 
  "customerPhone" => $customerPhone, 
  "customerEmail" => $customerEmail,
  "returnUrl" => $returnUrl, 
  "notifyUrl" => $notifyUrl,
);
 // get secret key from your config
 ksort($postData);
 $signatureData = "";
 foreach ($postData as $key => $value){
      $signatureData .= $key.$value;
 }
 $signature = hash_hmac('sha256', $signatureData, $secretKey,true);
 $signature = base64_encode($signature);

import hashlib
import hmac
import base64

postData = {
  "appId" : appId, 
  "orderId" : orderId, 
  "orderAmount" : orderAmount, 
  "orderCurrency" : orderCurrency, 
  "orderNote" : orderNote, 
  "customerName" : customerName, 
  "customerPhone" : customerPhone, 
  "customerEmail" : customerEmail, 
  "returnUrl" : returnUrl, 
  "notifyUrl" : notifyUrl
}

sortedKeys = sorted(postData)
signatureData = ""
for key in sortedKeys:
  signatureData += key+postData[key];

message = bytes(signatureData).encode('utf-8')
#get secret key from your config
secret = bytes(secretKey).encode('utf-8')
signature = base64.b64encode(hmac.new(secret, message,digestmod=hashlib.sha256).digest())

  Map<String, String> postData = new HashMap<String, String>();
  postData.put("appId", appId);
  postData.put("orderId", ORDERID);
  postData.put("orderAmount", ORDERAMOUNT);
  postData.put("orderCurrency", ORDER_CURRENCY);
  postData.put("orderNote", ORDERNOTE);
  postData.put("customerName", CUSTOMER_NAME);
  postData.put("customerEmail", CUSTOMER_EMAIL);
  postData.put("customerPhone", CUSTOMER_PHONE);
  postData.put("returnUrl",RETURN_URL);
  postData.put("notifyUrl", NOTIFY_URL);
  String data = "";
  SortedSet<String> keys = new TreeSet<String>(postData.keySet());
  for (String key : keys) {
      data = data + key + postData.get(key);
  }
  Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
  SecretKeySpec secret_key_spec = new
  SecretKeySpec(secretKey.getBytes(),"HmacSHA256");
  sha256_HMAC.init(secret_key_spec);
  String signature = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(data.getBytes()));


using System;
using System.Security.Cryptography;
using System.Collections.Generic;
namespace Rextester {
public class Program {
  private string CreateToken(string message, string secret){
    secret = secret ?? "";
    var encoding = new System.Text.ASCIIEncoding();
    byte[] keyByte = encoding.GetBytes(secret);
    byte[] messageBytes = encoding.GetBytes(message);
    
    using (var hmacsha256 = new HMACSHA256(keyByte))
    {
      byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
      return Convert.ToBase64String(hashmessage);
    }
  }
  public static void Main(string[] args) {
      
    string secret = "<your_secret_key>";
    string data = "";  
      
    SortedDictionary<string, string> formParams = new SortedDictionary<string, string>();
    formParams.Add("appId", "<your_app_id>");
    formParams.Add("orderId", "FEX101");
    formParams.Add("orderAmount", "10.00");
    formParams.Add("orderCurrency", "INR");
    formParams.Add("orderNote", "Test payment");
    formParams.Add("customerName", "Customer Name");
    formParams.Add("customerPhone", "9900000085");
    formParams.Add("customerEmail", "test@cashfree.com");
    formParams.Add("returnUrl", "http://example.com");
    formParams.Add("notifyUrl", "http://example.com");
    foreach (var kvp in formParams) {
      data = data + kvp.Key + kvp.Value;
    }
    Program n = new Program();
    string signature = n.CreateToken(data, secret);
    Console.WriteLine(signature);
    }
  }
}

Step 3: Submitting form

Once you have the above form prepared you can either submit the form manually, paste the below html just before the closing </form> tag. By default all the fields in the above html form are hidden, you can make them visible by removing the type="hidden" text from every input field.

<input type="submit" value="Pay">

Don't add name parameter to the html submit button.

or you can also prepare the above form and submit it automatically on page load without waiting for user’s click - paste the below javascript code just before the closing </body> tag.

<script>document.getElementById("redirectForm").submit();</script>

Test Card

You can use these cards in your test suite.


Request Parameters

Checkout Form accepts the below mentioned request parameters. Make sure you send us all the required fields. Note that requests with an invalid signature will be rejected.

Parameter Required Description
appId Yes Your app id
orderId Yes Order/Invoice Id
orderAmount Yes Bill amount of the order
orderCurrency No Currency for the order. INR if left empty. See the Currency Codes for a list of available currencies. Please contact care@cashfree.com to enable new currencies
orderNote No A help text to make customers know more about the order
customerName Yes Name of the customer
customerPhone Yes Phone number of customer
customerEmail Yes Email id of the customer
returnUrl Yes Return URL to which user will be redirected after the payment
notifyUrl No Notification URL for server-server communication. Receive a notification here whenever this order is successful. Useful when user’s connection drops while notifyUrl should be an https URL
paymentModes No Allowed payment modes for this order. Available values: cc, dc, nb, paypal, wallet. Example values: “cc”, “cc,dc”, “paypal,nb” etc.
pc No Partner Code
signature Yes request signature. More here

Response parameters

CashFree will post details about every transaction to both the returnUrl and the notifyUrl. These parameters will be posted to the services you host on these urls. You should use these details accordingly.

Parameter Description
orderId Order id for which transaction has been processed. Ex: GZ-212
orderAmount Amount of the order. Ex: 256.00
referenceId Cashfree generated unique transaction Id. Ex: 140388038803
txStatus Payment status for that order. Values can be : SUCCESS, FLAGGED, PENDING, FAILED, CANCELLED. More here
paymentMode Payment mode used by customer to make the payment. Ex: DEBIT_CARD, MobiKwik, etc See
txMsg Message related to the transaction. Will have the reason, if payment failed
txTime Time of the transaction
signature Response signature, more here. It is mandatory to verify the signature.

Response Verification

IMPORTANT: Verify the response signature to check the authenticity of transaction response. Don't forget to follow the steps mentioned below.

Similar to every request (request checksum) we also send a digital signature in our response message. We strongly recommend you to verify this received signature at your end as well. This will verify if the response has not been tampered with.


<?php  
 $orderId = $_POST["orderId"];
 $orderAmount = $_POST["orderAmount"];
 $referenceId = $_POST["referenceId"];
 $txStatus = $_POST["txStatus"];
 $paymentMode = $_POST["paymentMode"];
 $txMsg = $_POST["txMsg"];
 $txTime = $_POST["txTime"];
 $signature = $_POST["signature"];
 $data = $orderId.$orderAmount.$referenceId.$txStatus.$paymentMode.$txMsg.$txTime;
 $hash_hmac = hash_hmac('sha256', $data, $secretkey, true) ;
 $computedSignature = base64_encode($hash_hmac);
 if ($signature == $computedSignature) {
    // Proceed
  } else {
   // Reject this call
 }
 ?>

import hashlib
import hmac
import base64

@app.route('/notify_url/', methods=["POST"])
def notify_url_process():

 postData = {
  "orderId" : request.form['orderId'], 
  "orderAmount" : request.form['orderAmount'], 
  "referenceId" : request.form['referenceId'], 
  "txStatus" : request.form['txStatus'], 
  "paymentMode" : request.form['paymentMode'], 
  "txMsg" : request.form['txMsg'], 
  "txTime" : request.form['txTime'], 
 }

 signatureData = ""
 for key in postData.keys():
   signatureData += postData[key];

 message = bytes(signatureData).encode('utf-8')
 #get secret key from your config
 secret = bytes(secretKey).encode('utf-8')
 signature = base64.b64encode(hmac.new(secret, 
   message,digestmod=hashlib.sha256).digest())

LinkedHashMap<String, String> postData = new LinkedHashMap<String, String>();

postData.put("orderId", ORDERID);
postData.put("orderAmount", ORDERAMOUNT);
postData.put("referenceId", REFERENCE_ID);
postData.put("txStatus", TXN_STATUS);
postData.put("paymentMode", PAYMENT_MODE);
postData.put("txMsg", TX_MSG);
postData.put("txTime", TX_TIME);

String data = "";
Set<String> keys = postData.keySet();

for (String key : keys) {
    data = data + postData.get(key);
}
String secretKey = "" // Get secret key from config;
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key_spec = new
SecretKeySpec(secretKey.getBytes(),"HmacSHA256");
sha256_HMAC.init(secret_key_spec);

String signature = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(data.getBytes()));

using System;
using System.Security.Cryptography;
using System.Collections.Generic;
namespace Rextester {
  public class Program {
    private string CreateToken(string message, string secret){
      secret = secret ?? "";
      var encoding = new System.Text.ASCIIEncoding();
      byte[] keyByte = encoding.GetBytes(secret);
      byte[] messageBytes = encoding.GetBytes(message);
      
      using (var hmacsha256 = new HMACSHA256(keyByte))
      {
        byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
        return Convert.ToBase64String(hashmessage);
      }
    }

    public static void Main(string[] args) {
        
      string secret = "<your_secret_key>";
      string data = "";  
        
      data = data + "FEX101";
      data = data + "10.00";
      data = data + "19992";
      data = data + "SUCCESS";
      data = data + "pg";
      data = data + "payment done";
      data = data + "2018-02-02 17:29:12";

      Program n = new Program();
      string signature = n.CreateToken(data, secret);
      Console.WriteLine(signature);
    }
  }
}

Integration Kits

Please find the integration for all major platforms here:

Platform Link
PHP https://github.com/cashfree/php-pg-integration
Java https://github.com/cashfree/java-pg-integration
Node.js https://github.com/cashfree/node-pg-integration
.net https://github.com/cashfree/net-pg-integration
Python https://github.com/cashfree/python-pg-integration
Ruby https://github.com/cashfree/ruby-pg-integration

Test Checksum

Use the below form to confirm if you are generating the correct checksum. To understand the logic behind generating the checksum, see here.

If you are sending us any additional field from the html form it should also be included in the checksum generation. We have not included these fields in this tool.


App Id: Secret Key: Order Id: Order Amount: Order Currency: Order Note: Customer Name: Customer Phone: Customer Email: Return URL: Notify URL:

Checksum: checksum