Setup Subscription using API
This API allows you to simultaneously create a user subscription and set up its payment mandate within the web interface.
API Endpoint
| Environment | HTTP Method | API |
| Sandbox | POST | https://api-preprod.phonepe.com/apis/pg-sandbox/checkout/v2/pay |
| Production | POST | https://api.phonepe.com/apis/pg/checkout/v2/pay |
Request
| Header Name | Header Value | Description |
Content-Type | application/json | |
Authorization | O-Bearer <access_token> | Pass access_token received in Authorization call |
⚠️ For Partner Integrations!
It is mandatory to include the X-MERCHANT-ID header with the MerchantID of the end merchant.
Sample Request for Transaction
{
"merchantOrderId": "Tx123",
"amount": 47900,
"paymentFlow": {
"type": "SUBSCRIPTION_CHECKOUT_SETUP",
"merchantUrls": {
"redirectUrl": "www.google.com"
},
"subscriptionDetails": {
"subscriptionType": "RECURRING",
"merchantSubscriptionId": "Sub123",
"authWorkflowType": "TRANSACTION",
"amountType": "FIXED",
"maxAmount": 47900,
"frequency": "ON_DEMAND",
"productType": "UPI_MANDATE",
"expireAt": 1779689282000
}
},
"expireAfter": 3000,
"metaInfo": {
"udf1": "some meta info of max length 256",
"udf2": "some meta info of max length 256",
"udf3": "some meta info of max length 256",
"udf4": "some meta info of max length 256",
"udf5": "some meta info of max length 256",
"udf6": "some meta info of max length 256",
"udf7": "some meta info of max length 256",
"udf8": "some meta info of max length 256",
"udf10": "some meta info of max length 256",
"udf11": "some meta info of max length 50",
"udf12": "some meta info of max length 50",
"udf13": "some meta info of max length 50",
"udf14": "some meta info of max length 50",
"udf15": "some meta info of max length 50"
}
}Sample Request for Penny drop
{
"merchantOrderId": "Tx123",
"amount": 200,
"paymentFlow": {
"type": "SUBSCRIPTION_CHECKOUT_SETUP",
"merchantUrls": {
"redirectUrl": "www.google.com"
},
"subscriptionDetails": {
"subscriptionType": "RECURRING",
"merchantSubscriptionId": "Sub123",
"authWorkflowType": "PENNY_DROP",
"amountType": "FIXED",
"maxAmount": 200,
"frequency": "ON_DEMAND",
"productType": "UPI_MANDATE",
"expireAt": 1779689282000
}
},
"expireAfter": 3000,
"metaInfo": {
"udf1": "some meta info of max length 256",
"udf2": "some meta info of max length 256",
"udf3": "some meta info of max length 256",
"udf4": "some meta info of max length 256",
"udf5": "some meta info of max length 256",
"udf6": "some meta info of max length 256",
"udf7": "some meta info of max length 256",
"udf8": "some meta info of max length 256",
"udf10": "some meta info of max length 256",
"udf11": "some meta info of max length 50",
"udf12": "some meta info of max length 50",
"udf13": "some meta info of max length 50",
"udf14": "some meta info of max length 50",
"udf15": "some meta info of max length 50"
}
}Request Parameters
| Parameter Name | Data Type | Description | Mandatory | Constraints |
merchantOrderId | String | Unique orderId generated by the merchant to track the transactions. | Yes | • Max Length: 63 characters. • Only Alphanumeric characters, underscore “_” and hyphen “-“ are allowed. |
amount | Long | Transaction order amount in paise. This value is used to set up the mandate based on the selected authWorkflowType. | Yes | • For PENNY_DROP flow, the amount should be equal to 200 (In Paise) • For TRANSACTION flow, the amount should be greater than or equal to 100 or the first debit amount(In Paise) |
paymentFlow | Object | Contains additional details required to process the selected payment flow. | Yes | |
paymentFlow.type | String | Specifies the type of payment flow to be executed. | Yes | Allowed value: “SUBSCRIPTION_CHECKOUT_SETUP” |
paymentFlow.merchantUrls | Object | Object containing URLs for handling user redirection during the payment flow: • redirectUrl | Yes | |
paymentFlow.merchantUrls.redirectUrl | String | URL where the user is redirected after payment completion (success or failure). | Yes | |
paymentFlow.subscriptionDetails | Object | Contains all configuration details related to the subscription setup. | Yes | |
paymentFlow.subscriptionDetails.subscriptionType | String | Specifies the type of subscription being created. | Yes | Allowed value: “RECURRING” |
paymentFlow.subscriptionDetails.merchantSubscriptionId | String | Unique ID for the subscription, generated by the merchant. | Yes | Max Length: 63 characters. |
paymentFlow.subscriptionDetails.authWorkflowType | String | Specifies the setup flow to be used (e.g., TRANSACTION or PENNY_DROP). | Yes | Allowed values: “TRANSACTION” or “PENNY DROP” |
paymentFlow.subscriptionDetails.amountType | String | Defines how the debit amount is determined throughout the subscription lifecycle. | Yes | Allowed values: “FIXED” or “VARIABLE” |
paymentFlow.subscriptionDetails.maxAmount | Long | Maximum amount that can be debited during the subscription cycle. Value should be in paise. | Yes | Max Limit: 1500000 paisa(i.e., ₹15,000) |
paymentFlow.subscriptionDetails.frequency | String | Specifies how often the subscription amount will be debited. | Yes | Allowed values: • DAILY • WEEKLY • MONTHLY • FORTNIGHTLY • BIMONTHLY • QUARTERLY • HALFYEARLY • YEARLY • ON_DEMAND |
paymentFlow.subscriptionDetails.productType | String | Specifies the type of mandate or payment instrument being used. | Yes | Allowed value: UPI_MANDATE |
paymentFlow.subscriptionDetails.expireAt | epoch | Defines the expiry time of the subscription. | No | Max value: 30 Years. |
expireAfter | Long | Time(in seconds) after which the order expires. If not provided, a default value is applied. | No | • Min Value: 300 secs • Max Value: 3600 secs |
metaInfo | Object | Additional information defined by merchant. This data is returned in both status and callback responses. | No | • For udf1 to udf10, there is no constraint. Maximum length: 256 characters • For udf11 to udf15, alphanumeric values with _-+@. are allowed. Maximum length: 50 characters Note: It is mandatory to keep the parameter names udf1, udf2, etc., exactly as they are in the metainfo block. Renaming these key values will result in a production error. |
Response
Sample Response
{
"orderId": "OMO2604141019329833275508V",
"state": "PENDING",
"redirectUrl": "https://mercury-t2.phonepe.com/transact/pgv3?token=hq4wOGdzX31IuPyyh7/7AYOLiipO42P8QtgmusudZHta7zUAMbV5uMV5f6kF1hmvheryrKRViCFFSkJeROPrWmJGwyjdAOSX/S4alFsnngRPJb+0KaVOQHl05cRKh4d0V8ZYg/xHnLD08kBbDlCfqU0tgrmLOJ0DrhRK0siw5UpJJpQXkHpiZN+57O51IFhul0WhaRLYJ9RFhzokD2PmfF5Knx1w7xJNhPfUWZeOx5T8f0WdkvZF0Wk8PFvILPXPOlhETsQsyT0JtrvK/Be0XFf2OHsi+bG16v9kaB+CDkpnZsvwa7EgAbaine9iV3Xm0m+wPQKHd9u8v37ipkpCIx2STkASi6RHNouf8MJoiECLE+8go4oQnjjuvmreW/KCQIgbZaqUSoc+CLI76P/GYB0SeuctzAJw9IdWlVPfQ9WZd6L05BB32nGx1qzPptsUAkFcErnN+NStWY+qw5f3+shNSZ2Fc84Nd+mKYnQDOLG6thPuR4M=&routingKey=V",
"expireAt": 1776145172971
}Response Parameters
| Field Name | Data Type | Description |
orderId | String | Unique internal orderId generated by PhonePe Payment Gateway. |
state | String | Current status of the order (e.g., PENDING). |
expiryAt | Long | Expiry time of the order represented as an epoch timestamp. |
redirectUrl | String | URL used to invoke the payment app to initiate and complete the mandate. |
Try it yourself!
headers
body params
What’s Next?
In the next section, you will learn how to check the status of a mandate after a subscription has been successfully set up.