Cashfree uses API keys to allow access to the API. Once you have signed up at our merchant site, you will be able to see your AppId and SecretKey.
Cashfree expects the API key to be included in all API requests to the server. Use the endpoint /api/v1/credentials/verify
to verify your credentials. X-Client-Id is your appID, and X-Client-Secret is your secretKey. You can view these details here.
All API responses are in JSON format. POST requests should include ContentType: application/json
Environment | URL |
Test |
|
Production |
|
Get started quickly with Cashfree Subscription APIs by downloading the following collection and importing it in Postman.
URL | HTTP Verb | Functionality |
| POST | ​To create plans​ |
| POST | ​To create subscriptions​ |
| POST | |
| GET | |
| GET | |
| GET | |
| POST | ​To cancel subscriptions​ |
| POST |
To create a new plan on Cashfree, send a POST request to the class URL containing the contents of the plan.
/api/v2/subscription-plans
Parameter | Required | Description |
planId | Yes | Unique identifier for the plan (Alphanumeric) |
planName | Yes | Specify plan name for easy reference (Alphanumeric) |
type | Yes | The type can be PERIODIC or ON_DEMAND. For more details refer to Appendix 1 for description (Alphanumeric) |
maxCycles | Optional | Maximum number of debits set for the plan. The subscription will automatically change to COMPLETED status once this limit is reached (Numeric) |
amount | Optional | The amount to be charged for PERIODIC plan (Numeric) |
maxAmount | Optional | The maximum amount to be charged for ON_DEMAND plan (Numeric) |
intervalType | Optional | The type of interval for a PERIODIC plan like daily, week, month, year (Alphanumeric) |
intervals | Optional | Number of intervals of intervalType between every subscription payment. For example for charging a customer bi-weekly use intervalType as “week” and intervals as 2. Required for PERIODIC plan (Numeric) |
description | Optional | A brief note for the plan (Alphanumeric) |
For POST requests, Content-Type header should be set to application/json
.
Authentication is done via parameters. The appId parameter identifies which merchant account you are accessing, and the secretKey parameter authenticates the endpoint.
curl -XPOST -H 'cache-control: no-cache' -H 'content-type: application/json' -H'X-Client-Id: asdf1234' -H 'X-Client-Secret: qwer9876' -d '{"planId":"BASIC", "planName":"Basic subscription plan", "amount":12,"intervalType":"week", "intervals":2,"description":"This is the standard planfor our services"}' 'https://test.cashfree.com/api/v2/subscription-plans'
The response format for all requests is a JSON object.
{"status":"OK","message":"Subscription Plan created successfully"}
You can now easily create a subscription as per the plan created in the previous step.
The Auth Link will be redirected to a link hosted on cashfree.com. Once the authorization is complete, your customer will be redirected to returnUrl. Store the subReferenceId as this is the unique id generated by Cashfree for the subscription and will be required for subsequent operations.
/api/v2/subscriptions
Below are the Post Parameters.
Parameter | Required | Description |
subscriptionId | Yes | A unique id generated for subscription (Alphanumeric) |
planId | Yes | Id of a valid plan created earlier (Alphanumeric) |
customerName | Optional | Name of the customer (Alphanumeric) |
customerEmail | Yes | Email of the customer (Alphanumeric) |
customerPhone | Yes | Contact number of the customer (Numeric) |
firstChargeDelay | Optional | Number of Days after which the first debit for subscription will occur.Applicable for periodic subscriptions only (Numeric) |
authAmount | Optional | The amount that will be charged to authenticate the payment. The default amount is Re. 1 (Numeric) |
expiresOn | Required | The last date till which the subscription stands valid. The status of subscription will be COMPLETED. Default value is 2 years from date of subscription creation. Format is “yyyy-mm-dd hr:min:sec” (Alphanumeric) |
returnUrl | Yes | A valid url to which customer will be redirected to after the subscription is done. Refer “Payment Response” section (Alphanumeric) |
subscriptionNote | Optional | A brief note about the subscription (Alphanumeric) |
curl -XPOST -H 'cache-control: no-cache' -H 'content-type: application/json' -H'X-Client-Id: asdf1234' -H 'X-Client-Secret: qwer9876' -d'{"subscriptionId":"sub1", "planId":"BASIC", "customerEmail":"test@gmail.com","customerPhone":"99000XXXXX"}' 'https://test.cashfree.com/api/v2/subscriptions'
{"status":"OK","message":"Subscription created successfully","subReferenceId": 123,"authLink":"https://bit.ly/1234qwer"}
You can also create a subscription in a seamless manner. This allows you to provide your own payment experience to your customers. With this, you can collect all payment details on your webpage and safely send them to Cashfree for processing. The authLink here will redirect the customer to the 2FA page of the issuer/destination bank.
/api/v2/subscriptions
Store the subReferenceId as this is the unique id generated by Cashfree for the subscription. It will be required for subsequent operations.
It is recommended that the checkout page showcases all the subscription and payment details so that the customer can make an informed decision. For e-mandates, the NPCI guidelines state that the checkout information should include but are not limited to the following
First ordered list item
Account type - Savings or Current
Bank Name
Customer Name
Recurring payment details: This should include the following information
a. Frequency of the subscription
b. Recurring amount/Maximum amount
c. Last Payment date
d. Purpose of the Subscription
Bank ID | Bank Name |
ANDB | ANDHRA BANK |
BARB | BANK OF BARODA |
CBIN | CENTRAL BANK OF INDIA |
CIUB | CITY UNION BANK LTD |
CNRB | CANARA BANK |
COSB | Cosmos Bank |
DEUT | DEUTSCHE BANK AG |
DLXB | DHANALAXMI BANK |
ESFB | EQUITAS SMALL FINANCE BANK LTD |
FDRL | FEDERAL BANK |
HDFC | HDFC BANK LTD |
IBKL | IDBI BANK LTD |
ICIC | ICICI BANK LTD |
IDFB | IDFC Bank |
INDB | INDUSIND BANK |
IOBA | INDIAN OVERSEAS BANK |
KARB | KARNATAKA BANK LTD |
KKBK | KOTAK MAHINDRA BANK LTD |
MAHB | BANK OF MAHARASHTRA |
ORBC | ORIENTAL BANK OF COMMERCE |
PUNB | PUNJAB NATIONAL BANK |
PYTM | PAYTM PAYMENTS BANK LTD |
RATN | RBL BANK LIMITED |
SBIN | STATE BANK OF INDIA |
SCBL | STANDARD CHARTERED BANK |
TMBL | TAMILNAD MERCANTILE BANK LTD |
UBIN | UNION BANK OF INDIA |
USFB | UJJIVAN SMALL FINANCE BANK LTD |
UTIB | AXIS BANK |
YESB | YES BANK |
SIBL | SOUTH INDIAN BANK |
DBSS | DBS BANK INDIA LTD |
JSFB | JANA SMALL FINANCE BANK LTD |
HSBC | THE HONGKONG AND SHANGHAI BANKING CORPORATION LTD |
SYNB | SYNDICATE BANK |
PSIB | PUNJAB AND SIND BANK |
KVBL | KARUR VYSA BANK |
Below are the Post Parameters.
Parameter | Required | Description |
subscriptionId | Yes | A unique id generated for subscription (Alphanumeric) |
planId | Yes | Id of a valid plan created earlier (Alphanumeric) |
customerName | Optional | Name of the customer (Alphanumeric) |
customerEmail | Yes | Email of the customer (Alphanumeric) |
customerPhone | Yes | Contact number of the customer (Numeric) |
firstChargeDelay | Optional | Number of Days after which the first debit for subscription will occur.Applicable for periodic subscriptions only (Numeric) |
authAmount | Optional | The amount that will be charged to authenticate the payment. The default amount is Re. 1 (Numeric) |
expiresOn | Optional | The last date till which the subscription stands valid. The status of subscription will be COMPLETED. Default value is 2 years from date of subscription creation. Format is “yyyy-mm-dd hr:min:sec” (Alphanumeric) |
returnUrl | Yes | A valid url to which customer will be redirected to after the subscription is done. Refer “Payment Response” section (Alphanumeric) |
subscriptionNote | Optional | A brief note about the subscription (Alphanumeric) |
paymentOption | Optional | Use “emandate/card”. This is the only valid option currently (Alphanumeric) |
card_number | Optional | 16 digit long valid card number (Numeric) |
card_expiryMonth | Optional | Month of expiration of card in MM format (Numeric) |
card_expiryYear | Optional | Year of expiration of card in YYYY format (Numeric) |
card_cvv | Optional | The CVV of the card (Numeric) |
card_holder | Optional | The name on the card (Alphanumeric) |
emandate_accountHolder | Optional | Account Holder’s name |
emandate_accountNumber | Optional | Account Number |
emandate_bankId | Optional | The bank with the account is held. Check reference for the possible values |
emandate_authMode | (optional) | Possible values - debitCard/netbanking. Default is netbanking. |
emandate_accountType | (optional) | Possible values - SAVINGS/CURRENT. Default is SAVINGS. |
If emandate_authMode is NetBanking: | If emandate_authMode is debitCard: |
ANDB, BARB, CBIN, CIUB, CNRB, COSB, DEUT, DLXB, ESFB, FDRL, HDFC, IBKL, ICIC, IDFB, INDB, IOBA, KARB, KKBK, MAHB, ORBC, PUNB, PYTM, RATN, SBIN, SCBL, TMBL, UBIN, USFB, UTIB, YESB, SIBL, DBSS, JSFB, HSBC, SYNB, PSIB, KVBL | ANDB, AUBL, CITI, DCBL, DEUT, DLXB, ESFB, FDRL, HDFC, ICIC, IDFB, INDB, KARB, KKBK, MAHB, PUNB, PYTM, RATN, SBIN, SIBL, USFB, YESB, DBSS, TMBL, UTIB, BARB, JSFB |
curl -XPOST -H 'cache-control: no-cache' -H 'content-type: application/json' -H'X-Client-Id: asdf1234' -H 'X-Client-Secret: qwer9876' -d'{"subscriptionId":"sub1", "planId":"ON_DEMAND","customerEmail":"test@gmail.com", "customerPhone":"99000XXXXX","paymentOption":"card", "card_number": "4434260000000008", "card_expiryMonth" :"05", "card_expiryYear" : "2021", "card_cvv":"123", "card_holder": "Nafey"}''https://test.cashfree.com/api/v2/subscriptions'
{"status":"OK","message":"Subscription created successfully","subReferenceId": 123,"authLink":"https://bit.ly/1234qwer"}
You can extract the details of the subscription when required.
/api/v2/subscriptions/:subReferenceId
Below is the URL Parameter.
Parameter | Required | Description |
subReferenceId | Yes | A unique Id which was generated when the subscription was created (Numeric) |
curl -i -H 'cache-control: no-cache' -H 'content-type: application/json' -H 'X-Client-Id: asdf1234' -H 'X-Client-Secret: qwer9876''https://test.cashfree.com/api/v2/subscriptions/123'
{"status":"OK","message":"Subscription Details","subscription": {"subscriptionId": "sub1","subReferenceId": "123","planId": "BASIC","customerName": "","customerEmail": "test@gmail.com","customerPhone": "99000XXXXX","mode": "CREDIT_CARD","cardNumber":"411111XXXXXX1111","status": "INITIALIZED","addedOn": "2018-01-01 12:23:34","scheduledOn": "2018-02-01 09:00:00","currentCycle": 14}}
Card Number is available only when payment is done by credit card.
Status values and their description are listed in Appendix 1a.
Current cycle shows how many payments have been initiated for the subscription.
scheduledOn will be null for ON_DEMAND type subscriptions.
You can fetch all the payment details for a subscription with just one request.
/api/v2/subscriptions/:subReferenceId/payments?lastId=:lastId&count=:count
Below are the URL Parameters.
Parameter | Required | Description |
subReferenceId | Yes | A unique Id which was generated when the subscription was created (Numeric) |
lastId | Optional | The pagination counter to return results from (Numeric) |
count | Optional | The total number of payments to be shown in a paginated query (Numeric) |
curl -i -H 'cache-control: no-cache' -H 'content-type: application/json' -H 'X- Client-Id: asdf1234' -H 'X-Client-Secret: qwer9876' 'https://test.cashfree.com/api/v2/subscriptions/123/payments?last=114&count=2'
{"status":"OK","message":"Subscription Payments","payments":[{"paymentId": 113,"cycle": 15,"amount": 12,"status": "SUCCESS","addedOn": "2018-01-20 12:23:34"},{"paymentId": 112,"cycle": 14,"amount": 12,"status": "SUCCESS","addedOn": "2018-01-19 12:23:34"}],"lastId": 112}
lastId and count help in paginating queries for ease of use. Every query returns "count" number of payments. To fetch next page set lastId of the previous page. To get first page do not include lastId in the request
Cycle indicates after how many intervals was this payment processed.
Payment status field values are described in Appendix 1b.
You can fetch the details of a particular payment of the subscription.
/api/v2/subscriptions/:subReferenceId/payments/:paymentId
Below are the URL Parameters.
Parameter | Required | Description |
subReferenceId | Yes | A unique Id which was generated when the subscription was created (Numeric) |
paymentId | Yes | A unique Id for the payment (Numeric) |
curl -i -H 'cache-control: no-cache' -H 'content-type: application/json' -H 'X- Client-Id: asdf1234' -H 'X-Client-Secret: qwer9876' 'https://test.cashfree.com/api/v2/subscriptions/123/payments/113'
{"status":"OK","message":"Subscription Payments","payment":{"paymentId": 113,"cycle": 15,"amount": 12,"status": "SUCCESS","addedOn": "2018-01-20 12:23:34"}}
Payment Id is generated at every payment.
Cycle indicates after how many intervals was this payment processed.
Payment status field values are described in Appendix 1b.
You can cancel the subscription at any point so that the subscription will no longer be charged to your customer. Subscription once cancelled cannot be reactivated. The status of the subscription will be CANCELLED.
/api/v2/subscriptions/:subReferenceId/cancel
Below is the URL Parameter.
Parameter | Required | Description |
subReferenceId | Yes | A unique Id which was generated when the subscription was created (Numeric) |
curl -XPOST -H 'cache-control: no-cache' -H 'content-type: application/json' -H'X-Client-Id: asdf1234' -H 'X-Client-Secret: qwer9876''https://test.cashfree.com/api/v2/subscriptions/123/cancel'
{"status":"OK","message":"Subscription Cancelled"}
For an ON-DEMAND plan, you will have to explicitly debit customers account. The customer will receive a notification from their respective bank regarding the payment.
/api/v2/subscriptions/:subReferenceId/charge
Below is the URL Parameter.
Parameter | Required | Description |
subReferenceId | Yes | A unique Id which was generated when the subscription was created (Numeric) |
Below are the Post Parameters.
Parameter | Required | Description |
amount | Yes | The amount which will be debited from the customer (Numeric) |
remarks | Optional | Details of this payment (Alphanumeric) |
curl -XPOST -H 'cache-control: no-cache' -H 'content-type: application/json' -H'X-Client-Id: asdf1234' -H 'X-Client-Secret: qwer9876' -d '{"amount":"12"}''https://test.cashfree.com/api/v2/subscriptions/123/charge'
{"status":"OK","message":"Subscription charged","payment": {"paymentId": 113,"amount": 12,"status": "SUCCESS","addedOn": "2018-01-20 12:23:34"}}
Retry the last failed payment for a subscription in ONHOLD state. On a successful retry, the subscription gets activated.
Only one retry attempt is allowed per day. If the nextScheduledOn is not set, the charge date for the next cycle is auto-calculated based on the plant interval.
/api/v2/subscriptions/:subReferenceId/charge-retry
URL Parameter
Parameter | Required | Description |
subReferenceId | Yes | A unique ID generated when the subscription was created (Numeric). |
Post Parameter
Parameter | Required | Description |
nextScheduledOn | Optional | Applicable for periodic subscriptions. The date when the charge for the next cycle should be scheduled. |
Request
curl -X POST 'https://api.cashfree.com/api/v2/subscriptions/989898/charge-retry' -H 'cache-control: no-cache' -H 'content-type: application/json' -H 'X-Client-Id: asdf1234 -H 'X-Client-Secret: qwer9876
{"status": "OK","subStatus": "ACTIVE","payment":{"paymentId": 123456,"amount": 2,"status": "SUCCESS","addedOn": "2021-02-26 13:35:12","retryAttempts": 1}}​
Activate API activates the subscription that is in ONHOLD state. For periodic subscriptions, the next charge date is calculated for the next cycle.
/api/v2/subscriptions/:subReferenceId/activate
URL Parameter
Parameter | Required | Description |
subReferenceId | Yes | A unique ID which was generated when the subscription was created (Numeric) |
Post Parameter
Parameter | Required | Description |
nextScheduledOn | Optional | Applicable for periodic subscriptions. The date when the charge for the next cycle should be scheduled. |
Request
curl -X POST 'https://api.cashfree.com/api/v2/subscriptions/989898/activate' -H 'cache-control: no-cache' -H 'content-type: application/json' -H 'X-Client-Id: asdf1234' -H 'X-Client-Secret: qwer9876'
Response
{"status": "OK","subStatus": "ACTIVE","subscriptionResponse":{"subReferenceId": 123456,"subscriptionId": "testabcd","planId": "test_demo","customerPhone": "9876543210","customerName": "John Doe","customerEmail": "abc@gmail.com","addedOn": "2021-02-24 11:15:10"}}
When a subscription is created a returnUrl is provided as a part of the request. When the customer authorizes the payment, he will be redirected to the returnURL. This redirection is done a POST request with the following parameters.
Method | URL |
cf_subReferenceId | Unique Id which was generated when the subscription was created (Numeric) |
cf_subscriptionId | Checksum used to authenticate the transaction (Alphanumeric) |
cf_authAmount | The money that was charged to authorize the subscription (Numeric) |
cf_orderId | The PG Order created for authorization (Alphanumeric) |
cf_referenceId | The referenceId/transactionId of authorization in PG (Numeric) |
cf_status | Status of the subscription. In the returnUrl, the response should be ACTIVE if the authorization was successful or INITIALIZED if the authorization failed (Alphanumeric) |
cf_message | A brief note about the payment (Alphanumeric) |
signature | The hash of all parameters in the request generated using secretKey. Refer Appendix 2 for details (Alphanumeric) |
cf_umrn | The unique identifier associated with a mandate. Applicable if the payment mode is eMandate. |
Contact care@cashfree.com to configure your Webhook endpoint.
Make sure that you don’t process duplicate events. For instance, if you have already received a success response to the Subscription API call, discard any identical Subscription success events for the corresponding API.
Please note that there might be new events added in the future.
Webhook will be sent to your configured endpoint as a POST request with the body containing the various parameters specifying the details of each event. Each request contains an event parameter that identifies its type. Here are the various events that can be sent to your webhook endpoint:
Parameter | Description |
cf_event | The event for which the subscription was authorized. The value for this event is SUBSCRIPTION_STATUS_CHANGE( Alphanumeric) |
cf_subReferenceId | A unique Id which was generated when the subscription was created (Numeric) |
cf_status | The new status of the subscription. Refer Appendix 1 for more subscription status values (Alphanumeric) |
cf_lastStatus | The old status of the subscription. Refer Appendix 1 for the description of different subscription status values (Alphanumeric) |
cf_eventTime | The time when the event was dispatched (Alphanumeric) |
signature | The hash of all parameters in request generated using secretKey. Refer Appendix 2 for details (Alphanumeric) |
Parameter | Description |
cf_event | The event for which the subscription was authorized. The value for this event is SUBSCRIPTION_NEW_PAYMENT (Alphanumeric) |
cf_subReferenceId | A unique Id which was generated when the subscription was created (Numeric) |
cf_paymentId | The unique paymentId for the payment (Alphanumeric) |
cf_amount | The amount of money charged for payment (Numeric) |
cf_eventTime | The time when the event was dispatched (Alphanumeric) |
signature | The hash of all parameters in request generated using secretKey. Refer Appendix 2 for details (Alphanumeric) |
retryAttempts | The number of payment retries. This is applicable for failed payments. |
Parameter | Description |
cf_event | The event for which the subscription was authorized. The value for this event is SUBSCRIPTION_PAYMENT_DECLINED (Alphanumeric) |
cf_subReferenceId | A unique Id which was generated when the subscription was created (Numeric) |
cf_paymentId | The unique paymentId for the payment (Alphanumeric) |
cf_amount | The amount of money charged for payment (Numeric) |
cf_reasons | A possible reason for failure (Alphanumeric) |
cf_eventTime | The time when the event was dispatched (Alphanumeric) |
signature | The hash of all parameters in request generated using secretKey. Refer Appendix 2 for details (Alphanumeric) |
retryAttempts | The number of payment retries. This is applicable for failed payments. |
For subscriptions through e-mandates (bank accounts), it takes 1 to 2 working days to activate the subscription. For subscriptions through cards, it is activated instantly.
A description of all possible status for a subscription.
Status | Description |
INITIALIZED | The subscription has just been created and is ready to be authorized by the customer. |
BANK_APPROVAL_PENDING | E-Mandate has been authorised and registration is pending at the Bank. This status is specific for e-mandates. |
ACTIVE | The customer has authorized the subscription and will be debited accordingly. |
ON_HOLD | The subscription failed due to insufficient funds, expiration of payment method, and so on. |
CANCELLED | The subscription was cancelled by the merchant and can no longer be activated. |
COMPLETED | The subscription has completed its total active period. |
It takes 1 to 2 working days for the transactions to be complete through e-mandates, and through cards it is instant.
A description of all possible status for a subscription payment.
Status | Description |
SUCCESS | Payment for subscription was processed successfully. |
PENDING | Payment for subscription was attempted but not yet marked successful. This status is specific for e-mandates. |
FAILED | Payment failed for subscription. |
A description of all the various different subscription plan types that are available currently and their operation model.
Status | Description |
PERIODIC | Payments are triggered automatically at fixed intervals defined by the merchant |
ON_DEMAND | Merchant needs to trigger /charge the customer explicitly with the required amount. |
Use the following examples as illustrations for how to generate a signature. If the language you are using is not mentioned here, contact us at care@cashfree.com.
Do not go live without signature verification.
data = "";iterate keys as key in POST request alphabetically:if (key starts with "cf_"):data = data + key + POST[key]computedSignature = base64 of (hash of (data) with secretKey as hashKey)if (computedSignature != POST["signature"]):// An invalid/fraud request do not mark subscription as successfull
<?php$data = "";$postData = $_POST;ksort($postData);foreach ($postData as $key => $value) {if (substr($key, 0, 3) == "cf_") {$data .= $key . $value;} }$hash_hmac = hash_hmac('sha256', $data, $secretkey, true) ;$computedSignature = base64_encode($hash_hmac);if ($postData["signature"] != $computedSignature) {// An invalid/fraud request do not mark subscription as successfull}?>
import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import javax.servlet.*;import javax.servlet.http.*;import java.io.*;import java.util.*;public class ChecksumServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {try {String secretKey = "ac7960e7995536f0177fd210f3b3937fc2d974a4";Map<String, String[]> postData = request.getParameterMap();// ensuring appId gets initializedString data = "";SortedSet<String> keys = new TreeSet<String>(postData.keySet());for (String key : keys) {if ((key.length() > 3) && (key.substring(0, 3).equals("cf_"))) {data = data + key + ((String[])postData.get(key))[0];}}Mac sha256_HMAC = Mac.getInstance("HmacSHA256");SecretKeySpec secret_key_spec = newSecretKeySpec(secretKey.getBytes(),"HmacSHA256");sha256_HMAC.init(secret_key_spec);String computedSignature =Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(data.getBytes()));if (!computedSignature.equals(postData.get("signature"))) {// An invalid/fraud request do not mark subscription as successfull} }catch (Exception ex) {// handle} }}