Seamless Pro (Deprecated)

The Seamless Pro integration allows you to present your own payment form to your customers and collect payment details on your webpage. This allows a seamless checkout experience to your customer. You will post the payment details to Cashfree for us to complete the two-factor authentication.

Endpoints

Test Environment: https://test.cashfree.com/billpay/checkout/post/submit
Production Environment: https://www.cashfree.com/checkout/post/submit

Steps to Integrate

  1. Collect Payment Details
  2. Generate Signature
  3. Submit Payment

Collect Payment Details

Customers make payments for their orders. To identify this particular order in your system you use an identifier orderId. You must send us the orderId and the corresponding orderAmount to process payments. We send you the payment status against each order.

You need to send us a few more details to process the payment. Details required are available in the request parameters here.

Collect all these relevant payment details (request parameters) from your customer.
Ensure to fill in the correct credentials for appId and secret key. You can find your AppId and Secret key from the merchant dashboard here.

Cashfree will post the response parameters to the returnUrl which you have specified while making the order request.

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

<form id="redirectForm" method="post" action="<ACTION_URL>">
<input type="hidden" name="appId" value="<YOUR_APP_ID>"/>
<input type="hidden" name="orderId" value="<ORDERID>"/>
<input type="hidden" name="orderAmount" value="<ORDERAMOUNT>"/>
<input type="hidden" name="orderCurrency" value="<ORDER_CURRENCY>"/>
<input type="hidden" name="orderNote" value="<ORDERNOTE>"/>
<input type="hidden" name="customerName" value="<CUSTOMER_NAME>"/>
<input type="hidden" name="customerEmail" value="<CUSTOMER_EMAIL>"/>
<input type="hidden" name="customerPhone" value="<CUSTOMER_PHONE>"/>
<input type="hidden" name="merchantData" value="<GENERATED_BASE64_MERCHANTDATA>"/>
<input type="hidden" name="returnUrl" value="<RETURN_URL>"/>
<input type="hidden" name="notifyUrl" value="<NOTIFY_URL>"/>
<input type="hidden" name="signature" value="<GENERATED_SIGNATURE>"/>

Request Parameters

You must send us the below JSON data parameters for us to process your request. Ensure to send us all the required fields mentioned below to process the request.

ParameterRequiredDescription
appIdYesYour app ID.
orderIdYesOrder/Invoice ID.
orderAmountYesBill amount of the order.
orderCurrencyNoCurrency for the order. See Currencies Supported for a list of available currencies.

Contact [email protected] to enable new currencies.
orderNoteNoA help text to make customers know more about the order.
customerNameYesName of the customer.
customerPhoneYesPhone number of customer.
customerEmailYesEmail id of the customer. Should be a valid email iD, and cannot be from blocked email IDs.
merchantDataNoA base 64 encoded json array (as a key value pair). Maximum 10 pairs allowed, at max 64 chars for each key and 256 chars for each value.
notifyUrlNoNotification URL for server-server communication. Useful when user’s connection drops during redirection. NotifyUrl should be an https URL.
returnUrlYesReturn URL for redirecting once payment is completed.
pcNoPartner Code. It is the MID of the partner account who is a merchant aggregator. If you are transacting under the specific partner account pass this parameter. If you are an individual merchant do not pass this parameter.
accountNumberNoRequired for third party validation flow.
ifscNoRequired for third party validation flow.
signatureYesRequest signature, click here for more information.

Each payment method also requires some additional information to be collected. You can refer below to know more about the information required for each method.

Payment Parameters

Cards

To accept payment through cards, add the following input parameters to your HTML form.

<form>
   ....
   <input name="paymentOption" value="card"/>
  <input name="card_number" value="4444333322221111"/>
  <input name="card_holder" value="John Doe"/>
  <input name="card_expiryMonth" value="09"/>
  <input name="card_expiryYear" value="2020"/>
  <input name="card_cvv" value="123"/>
</form>

To accept card payments on your website ensure you have the PCI DSS Level 3 Certificate.

These parameters are available only for card payments.

ParameterRequiredDescription
card_numberYesCard Number. Sixteen digits only. No spaces or Hyphens.
card_expiryMonthYesExpiration Month for the Card. In MM format.
card_expiryYearYesExpiration Year for the Card. In YYYY format.
card_cvvYesCVV number of the Card.
card_holderYesName of the Card Holder.
payment_OptionYes'card' for Debit/Credit Cards.

Net Banking

To accept payment through net banking include the following parameters in your HTML form. Click here to see the complete list of banks available for net banking and their corresponding payment code values.

<form>
   ....
 <input name="paymentOption" value="nb"/>
 <input name="paymentCode" value="3333"/>
</form> 

These parameters are available only for net banking.

ParameterRequiredDecription
paymentCodeYesRefer the list for the codes.
paymentOptionYes'nb' for net banking.

Wallet

To accept payments through wallets you need to set the paymentOption as “wallet”. Click here to see the complete list of available wallets and their payment codes.

<form>
   ....
 <input name="paymentOption" value="wallet"/>
 <input name="paymentCode" value="4001"/>
</form>

These parameters are available only for wallets.

ParameterRequiredDescription
paymentCodeYesRefer the list for codes.
paymentOptionYes'wallet' for Wallet.

UPI

We also support payment through UPI, you need to set the paymentOption as upi. We support the below modes of payment within UPI.

  • Collect
  • Google Pay
  • QR Code

Collect

Collect request is sent to customers VPA which is specified in upi_vpa.

<form>
   ....
 <input name="paymentOption" value="upi"/>
 <input name="upi_vpa" value="testsuccess@gocash"/>
</form>

To test the integration, you can use testsuccess@gocash as your default UPI VPA.

Google Pay

Notification to Google Pay is directly sent to the customer contact number specified in customerPhoneparameter present in the request parameters. upiMode attribute needs to be set to gpay.

 <form>
  ....
   <input name="paymentOption" value="upi"/>
   <input name="upiMode" value="gpay"/>
 </form> 

upi_vpa is not required.

QR Code

On selecting QR code as the payment method, customers will be redirected to the QR code page which can be scanned to complete the payment. upiMode attribute needs to be set to qrcode.

<form>
  ....
 <input name="paymentOption" value="upi"/>
 <input name="upiMode" value="qrcode"/>
 </form> 
 ....

upi_vpa is not required.

UPI One time mandate

Cashfree allows you to process one time mandate for UPI. To send a one time mandate request on a particular UPI id, you need to send the following details.

<form>
  ....
 <input name="paymentOption" value="upi"/>
 <input name="responseType" value="json"/>
 <input name="upi_collect_time" value="2021-08-20 16:20:39"/>
 <input name="upi_end_time" value="2021-09-20 16:20:39"/>
 <input name="upi_start_time" value="2021-08-20 16:21:39"/>
 <input type="text" name="upi_vpa" value="rohit@okicici"/>
 </form> 
ParameterDescriptionExample
upi_collect_timeThis is the time until when the collect request will remain valid. You should send it as around 1-2 hours from now.2021-08-21 16:20:39
upi_start_timeThis is when the one time mandate will start. Send current date.2021-08-20 16:20:39
upi_end_timeThis is when the mandate ends. On the next day the customer will receive funds back in their account if not authorised.2021-08-20 16:20:39

EMI

You can also accept EMI payments from your customers. Set the paymentOption as emi. Click here to see the complete list of available EMI providers and their payment codes along with the available plan.

<form>
  ....
  <input name="paymentOption" value="emi"/>
  <input name="emiPlan" value="2"/>
  <input name="paymentCode" value="6005"/>
</form>

emiPlan is required only in case of Card EMI.

These parameters are available only for EMI.

ParameterRequiredDecription
paymentCodeYesSee here for the codes
paymentOptionYes'emi' for EMI
emiPlanNoOnly required for Card EMI.

Pay Later

We also support Pay Later option for payments. For this, you need to set the paymentOption as paylater. Click here to see the complete list of available Pay Later providers and their payment codes.

<form>
  ....
  <input name="paymentOption" value="paylater"/>  
  <input name="paymentCode" value="4503"/>  
</form>

These parameters are available only for pay later option.

ParameterRequiredDescription
paymentCodeYesSee the payment codes here.
paymentOptionYes'paylater' for Pay Later.

Paypal

To accept payments through PayPal you just need to set the paymentOption to Paypal.

<form>
   ...
   <input name="paymentOption" value="paypal"/>
</form> 

Generate Signature

Every request to Cashfree must contain authentication information to establish the identity of the user making the request. We use a digital signature to validate each transaction. A digital signature helps us to verify the originator of the message and also ensure the integrity of the signed data against tampering.

The signature is generated as the HMAC value of the data being passed which uses SHA256 hash function in combination with your API secret key.

We will generate a signature at our end and want you to do the same with the posted data and match it with the passed argument.

You can find your App Id and Secret key in the merchant dashboard here.

$merchantData = array(
     "key1" => "value1",
     "key2" => "value2",
     "key3" => "value3"
);
$merchantData = base64_encode(json_encode($merchantData));

$postData = array( 
  "appId" => $appId, 
  "orderId" = > $orderId, 
  "orderAmount" => $orderAmount, 
  "orderCurrency" => $orderCurrency, 
  "orderNote" => $orderNote, 
  "customerName" => $customerName, 
  "customerPhone" => $customerPhone, 
  "customerEmail" => $customerEmail,
  "returnUrl" => $returnUrl, 
  "notifyUrl" => $notifyUrl,
  "paymentOption" => "nb",
  "paymentCode" => "3333"
);
 // 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,
  "paymentOption" : "nb",
  "paymentCode" : "3333"
}

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);
postData.put("paymentOption", "nb");
postData.put("paymentCode", "3333");

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", "[email protected]");
      formParams.Add("returnUrl", "http://example.com");
      formParams.Add("notifyUrl", "http://example.com");
      formParams.Add("paymentOption", "nb");
      formParams.Add("paymentCode", "3333");

      foreach (var kvp in formParams) {
        data = data + kvp.Key + kvp.Value;
      }

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

Once you have collected this information you need to send this to Cashfree.

Submit Payment

Once you submit these details we will process the payment on your behalf. The payment processing status can be one of the following described below:

Caseevent.nameevent.status
Successful PaymentPAYMENT_RESPONSESUCCESS
Payment FailedPAYMENT_RESPONSEFAILED
Pending PaymentPAYMENT_RESPONSEPENDING
Payment cancelled by userPAYMENT_RESPONSECANCELLED
Payment successful but kept on hold by risk systemPAYMENT_RESPONSEFLAGGED
Invalid inputsVALIDATION_ERROR-

Webhook Notification

Webhooks are events that notify you about the payment. A notification is sent to your backend from Cashfree when payments are successful. These notifications are useful in cases when the internet connection is unstable or slow while the payment is being processed. This will allow you to reconcile all the successful orders at your end. Notifications will be sent to notifyUrl which is a part of the request parameter specified while creating an order request.

📘

  • Notifications are sent only for successful payments.
    • Sometimes you may receive the same notification more than once. It is recommended to ensure that your implementation of the webhook is idempotent.

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.

ParameterDescription
orderIdOrder id for which transaction has been processed. Example, GZ-212.
orderAmountAmount of the order. Example, 256.00
referenceIdCashfree generated unique transaction Id. Example, 140388038803
txStatusPayment status for that order. Values can be: SUCCESS, FLAGGED, PENDING, FAILED, CANCELLED, USER_DROPPED.
paymentModePayment mode used by customers to make the payment. Example, DEBIT_CARD, MobiKwik, PREPAID_CARD, etc.
txMsgMessage related to the transaction. Payment failure reason is included here.
txTimeTime of the transaction.
signatureResponse signature, refer here. It is recommended to verify the signature at your end.

Response Verification

Similar to every request checksum, we also send a digital signature in our response message. We strongly recommend you to verify this response signature at your end. This will ensure the response has not tampered.

?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 = postData["orderId"] + postData["orderAmount"] + postData["referenceId"] + postData["txStatus"] + postData["paymentMode"] + postData["txMsg"] + postData["txTime"]

 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);
    }
  }
}

Third-Party Validation

Third-party Validation (TPV) as per the SEBI guidelines is a mandatory requirement for web merchants such as stockbrokers and mutual funds operating in the BFSI (Banking, Financial Services and Insurance) sector. As per SEBI guidelines, transactions on an MF/stockbroker platform must be made by their customers exclusively from the pre-registered bank accounts.

Using Cashfree’s TPV feature, you can comply with the regulatory guidelines in a manner such that the customers make payments only from their registered bank accounts.

Cashfree supports TPV via Net Banking and UPI.

Note: We are dependent on Banks to enable this feature. Hence, there will be a lead time involved in getting this feature enabled. Write to [email protected] or contact your account managers to enable this feature.

Integration flow

There is no change in the integration method, the only exception is that you have to send us the pre-registered account number and IFSC code for each of your customers as part of the request parameter.

For UPI, we support all banks while for Netbanking the list is given below.

Note: For SBI bank customers with account numbers starting with 0's (zeros), ensure to include all the 0's in the beginning.

Banks Supported for Net Banking

Name of the BankBank Code
Gujarat State Co-operative Bank Limited3091
The Surat People’s Co-operative Bank Limited3090
Utkarsh Small Finance Bank3089
IDBI Bank3023
IndusInd Bank3028
Karur Vysya Bank3031
Union Bank of India3055
IDFC FIRST Bank3024
Bank of India3006
State Bank of India3044
ICICI Bank3022
HDFC Bank3021
Yes Bank Ltd3058
Axis Bank3003
Laxmi Vilas Bank3033
City Union Bank3012
South Indian Bank3042
Indian Overseas Bank3027
Kotak Mahindra Bank3032
Deutsche Bank3016
Punjab National Bank - Retail Banking3038
AU Small Finance Bank3087
Shivalik Mercantile Cooperative Bank Ltd3086
HSBC Retail NetBanking3092
Karnataka Bank3030
Indian Bank3026
Federal Bank3020
Tamilnad Mercantile Bank3052

Test the Integration

After the integration is complete, you can test the flow of the transaction before you start accepting payments online. Click here to know how to view/generate API keys.

You can make a test transaction using the test card and net banking details available below. You can verify the payment status using the PG Dashboard, APIs, or webhooks. After completing the test, you can start accepting payments from your customers in real-time.

Card Details

Card NumberExpiryCVVName
4444 3333 2222 111107/23123Test
4111 1111 1111 111107/23123Test

Net Banking Details

BankPayment Code
Test Bank3333

Test TPV Net Banking

ParameterValues
accountNumber1111222233
ifscTEST0001234

Test TPV UPI

ParameterValues
userVPAtesttpv@gocash
accountNumber1111222233
ifscTEST0001234

Important

We have decided to close down our old integration methods. We suggest you head over to the new APIs to complete your integration.

Read more here.