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. In this integration method, if there are multiple vendors associated in a transaction you can easily disburse payments to the vendors in one go.
Test Environment: https://test.cashfree.com/billpay/checkout/post/submit Production Environment: https://www.cashfree.com/checkout/post/submit
Steps to integrate with Cashfree Payment Gateway,
Customers make payments for their orders. To identify this particular order in your system you must 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.
If a transaction involves multiple vendors you must split the payments when you create the order itself. You do not have to split the amount manually later and process the payment. To do this, ensure you have the Easy Split feature enabled for your account and the required vendor details are added.
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="returnUrl" value="<RETURN_URL>"/> <input type="hidden" name="notifyUrl" value="<NOTIFY_URL>"/> <input type="hidden" name="signature" value="<GENERATED_SIGNATURE>"/> <input type="hidden" name="paymentSplits" value="<payment_split_value>"/> </form> <script type="text/javascript"> document.getElementById("redirectForm").submit(); </script>
With Easy Split feature, you can easily disburse payments to vendors in one go. Splitting of payments made through Cards, UPI, Netbanking, and all major Wallets (except PayTM and PayPal) are supported. Currently, we support payment split in absolute amounts of INR.
Add the vendor details before you process the payment split to vendors. You assign each vendor a Vendor ID which will be used to pass the split amount as shown below. While submitting the order details, an extra parameter, paymentSplits must be passed. The parameter paymentSplits is a base64 encoded JSON array of Vendor Ids and their corresponding splits. To generate paymentSplits first generate the JSON array of Vendors as follows:
[ { "vendorId" : "AXIS_FUND", "amount" : 10000 }, { "vendorId" : "HDFC_FUND", "amount" : 15000 }]
If any of the below conditions fail, the order will not be created:
Easy Split feature is enabled for your Cashfree Account and you have added the required vendor's details.
The sum of all split amounts must be equal to or less than the order amount. Note: If the total split amount is less than the order amount the remaining amount will be processed as merchant settlement.
The number of vendor splits is less than 20.
Once the JSON array is generated, encode it using the base64 encoding. The resulting value is the paymentSplits to be attached during the order creation.
For example, the base64 encoded value of the above JSON array will look like this:
paymentSplits => "WwoJewoJCSJiZW5lSWQiIDogIkFYSVNfRlVORCIsCgkJInNwbGl0QW1vdW50IiA6IDEwMDAwCgl9LAoJewoJCSJiZW5lSWQiIDogIkhERkNfRlVORCIsCgkJInNwbGl0QW1vdW50IiA6IDE1MDAwCgl9Cl0K"
Integrating paymentSplits The paymentSplits value generated above must be sent during the PG order creation. For Checkout and Seamless Pro, include an additional field in the form you generate:
<input type="hidden" name="paymentSplits" value="<payment_split_value>"/>
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. The default currency is INR. See the Currency Codes for a list of available currencies. 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 | The URL to which user will be redirected after the payment |
notifyUrl | No | Notification URL for server-server communication. Useful when the user's connection drops. notifyUrl should be an https URL |
pc | No | Partner 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. |
accountNumber | No | Required for third party validation flow. |
ifsc | No | Required for third party validation flow. |
paymentSplits | No | Use this parameter when the order amount has to be split between multiple vendors. |
signature | Yes | Request 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.
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.
Parameter | Required | Description |
card_number | Yes | Sixteen digit card number. No spaces or hyphens accepted. |
card_expiryMonth | Yes | Expiration month for the card, in MM format. |
card_expiryYear | Yes | Expiration year for the card, in YYYY format. |
card_cvv | Yes | CVV number of the card |
card_holder | Yes | Name of the card holder |
paymentOption | Yes | 'card' for Debit/Credit Cards |
To accept payment through netbanking include the following parameters in your HTML form. Click here to see the complete list of banks available for netbanking and their corresponding payment code values.
<form> .... <input name="paymentOption" value="nb"/> <input name="paymentCode" value="3333"/> </form>
These parameters are available only for netbanking payments.
Parameter | Required | Description |
paymentCode | Yes | Refer the list for the codes |
paymentOption | Yes | '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.
Parameter | Required | Description |
paymentCode | Yes | Refer the list for codes |
paymentOption | Yes | 'wallet' for Wallet |
UPI
We also support payment through UPI, you need to set the paymentOption as upi. We support 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.
Notification to Google Pay is directly sent to the customer contact number specified incustomerPhone
parameter 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.
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.
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.
Parameter | Required | Description |
paymentCode | Yes | See the payment codes here |
paymentOption | Yes | 'emi' for EMI |
emiPlan | No | Only required for Card EMI |
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.
Parameter | Required | Description |
paymentCode | Yes | See the payment codes here |
paymentOption | Yes | 'paylater' for Pay Later |
Every request to Cashfree must contain authentication information to establish the identity of the user making the request. We use a digital signature (a digital thumbprint) 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 is using 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 appId and secret key in the merchant dashboard here.
Note: Signature generation varies across integration methods, ensure you are using the right signature generation method.
$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 configksort($postData);$signatureData = "";foreach ($postData as $key => $value){$signatureData .= $key.$value;}$signature = hash_hmac('sha256', $signatureData, $secretKey,true);$signature = base64_encode($signature);
import hashlibimport hmacimport base64postData = {"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 configsecret = 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 = newSecretKeySpec(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");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.
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:
Case | event.name | event.status |
Successful Payment | PAYMENT_RESPONSE | SUCCESS |
Payment Failed | PAYMENT_RESPONSE | FAILED |
Pending Payment | PAYMENT_RESPONSE | PENDING |
Payment cancelled by user | PAYMENT_RESPONSE | CANCELLED |
Payment successful but kept on hold by risk system | PAYMENT_RESPONSE | FLAGGED |
Invalid inputs | VALIDATION_ERROR | - |
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.
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. Example, GZ-212 |
orderAmount | Amount of the order. Example, 256.00 |
referenceId | Cashfree generated unique transaction Id. Example, 140388038803 |
txStatus | Payment status for that order. Values can be : SUCCESS, FLAGGED, PENDING, FAILED, CANCELLED. |
paymentMode | Payment mode used by customers to make the payment. Example, DEBIT_CARD, MobiKwik, etc. |
txMsg | Message related to the transaction. Payment failure reason is included here. |
txTime | Time of the transaction |
signature | Response signature. Click here for more information. |
Similar to every request signature, 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.PYTHONJAVACSHARP
?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 } ?>
After the integration is complete, you can test the flow of the transaction before you start accepting payments online. Ensure you use the TEST appId and secret key while working on the TEST mode. Click here to know how to view/generate API keys.
You can make a test transaction using the test card and netbanking 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 Number | Expiry | CVV | Name |
4444 3333 2222 1111 | 07/23 | 123 | Test |
4111 1111 1111 1111 | 07/23 | 123 | Test |
Bank | Payment Code |
Test Bank | 3333 |
A transaction can be created and tracked across its lifecycle to test if the entire flow is working.
Initiate a test transaction with a split.
Track the status of the transaction and the associated splits in the Transactions screen.
Track your settlements and the vendor settlements in the Settlements screen. (Only in Production).