Setup Subscription
This API is used to set up a subscription for a customer.
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 |
Sample Request
{
"merchantOrderId": "ORD37835658271956985065",
"amount": 200,
"metaInfo": {
"udf1": "dummy1",
"udf2": "dummy2",
"udf3": "dummy3",
"udf4": "dummy4"
},
"paymentFlow": {
"type": "SUBSCRIPTION_CHECKOUT_SETUP",
"merchantUrls": {
"redirectUrl": "https://www.phonepe.com",
"cancelRedirectUrl": "https://www.google.com"
},
"subscriptionDetails": {
"subscriptionType": "RECURRING",
"amountType": "VARIABLE",
"merchantSubscriptionId": "MSUB931119373059899079",
"authWorkflowType": "PENNY_DROP",
"maxAmount": 15000,
"expireAt": 2105507164917,
"frequency": "ON_DEMAND"
},
"paymentModeConfig": {
"version": "V2",
"enabledPaymentModes": [
{
"type": "UPI",
"flows": ["INTENT", "QR"]
},
{
"type": "ENACH",
"authInstrumentTypes": ["NET_BANKING", "DEBIT_CARD"]
}
]
}
}
}Request Parameter
| Parameter Name | Data Type | Mandatory | Description | Constraints |
| merchantOrderId | String | Yes | Merchant’s unique identifier for the order | Max Length: 63 characters No Special characters are allowed except underscore “_” and hyphen “-“ |
| amount | Long | Yes | Initial setup amount in paisa | |
| paymentFlow.type | String | Yes | Type of flow | Allowed value: SUBSCRIPTION_CHECKOUT_SETUP |
| paymentFlow.merchantUrls.redirectUrl | String | Yes | Success redirect URL | |
| paymentFlow.merchantUrls.cancelRedirectUrl | String | Yes | Failure/Cancel redirect URL | |
| subscriptionDetails.subscriptionType | String | Yes | Specifies the type of subscription being created. | Allowed value: “RECURRING” |
| subscriptionDetails.amountType | String | Yes | Type of recurring charge (e.g., FIXED or VARIABLE) | |
| subscriptionDetails.merchantSubscriptionId | String | Yes | Merchant’s unique identifier for the subscription | |
| subscriptionDetails.authWorkflowType | ||||
| subscriptionDetails.maxAmount | Long | Yes | Maximum limit for recurring debits in paisa | |
| subscriptionDetails.expireAt | Long | Yes | Mandate expiry timestamp in epoch | |
| subscriptionDetails.frequency | String | Yes | Frequency of debit (e.g., ON_DEMAND, MONTHLY) | |
| paymentModeConfig.version | string | Yes | ||
| paymentModeConfig.enabledPaymentModes.type | Yes | |||
| paymentModeConfig.enabledPaymentModes.flow | Array | Yes | ||
| paymentModeConfig.enabledPaymentModes.authInstrumentTypes | Yes |
Response
Sample Response
{
"orderId": "OMO2609241434205711014273W",
"state": "PENDING",
"redirectUrl": "https://mercury-t2.phonepe.com/transact/pgv3?token=hq4wOGdzX31IuPyyh7/7AYOLiipO42P8QtgmusudZHta7zUAMbV5uMV5f6kF1hmvheryrKRViCFFSkJeROPrWmJEugXgAvXFgi0yl3Enmh9OIKu7L6FwTDJ09eoNh4dgE8VLreJqh7T+2Bl5DkyxtX0VjaWFK6w5rjtkocKIhHsTJpI6sXcXTvC6ich/JVlMkkvGbSDcJ9NqnhAnF3DTdEJ3wCd81BMlneL+WuSR+ffkfEPlu/ZC8HoCPF/CLs6nI01uTbcz914Rtb2y1RewHlb2Amg/7Iu2meBaCweBCDJOZszVN7YvOKi3p+w/e0+Bj2+KFxyvSeG8qWXAvWZgDQyTXmYTiaRXfoiP8ItBjQKBdI0mzr4HkGLkjkL8YPKQBoN4Vu6dSdVET5JenLvAS1x4JaVe9CZRn8x7zxXNG+2TSKzdwi1My0HjqNGMn8dCKksdM/jn6vypQM65+daT5Ylodr3aeO7K7NwdL6H3+rUA+4qMxnV+TA==&routingKey=W",
"expireAt": 1790241560571
}Response Parameters
| Parameter Name | Data Type | Description |
orderId | String | PG generated internal order ID |
state | String | Current state (e.g., PENDING) |
redirectUrl | String | URL to redirect user for bank authentication |
| expireAt | Long | Order expiry date in epoch. |
API Endpoint
| Environment | HTTP Method | API |
| Sandbox | POST | https://api-preprod.phonepe.com/apis/pg-sandbox/subscriptions/v2/setup |
| Production | POST | https://api.phonepe.com/apis/pg/subscriptions/v2/setup |
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.
Request for UPI Intent
Sample Request
{
"merchantOrderId": "M27",
"amount": 100,
"expireAt": 1807681114000,
"paymentFlow": {
"type": "SUBSCRIPTION_SETUP",
"merchantSubscriptionId": "MS27",
"authWorkflowType": "TRANSACTION",
"amountType": "FIXED",
"maxAmount": 100,
"frequency": "ON_DEMAND",
"expireAt": 1807681114000,
"paymentMode": {
"type": "UPI_INTENT",
"targetApp": "com.phonepe.app"
}
},
"deviceContext": {
"deviceOS": "ANDROID"
},
"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 in CURL
curl --location 'https://api-preprod.phonepe.com/apis/pg-sandbox/subscriptions/v2/setup' \
--header 'Accept: application/json' \
--header 'Authorization: O-Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVzT24iOjE3MTIyNTM2MjU2NDQsIm1lcmNoYW50SWQiOiJWMlNVQlVBVCJ9.7aVzYI_f_77-bBicEcRNuYx093b2wCsgl_WFNkKqAPY' \
--header 'Content-Type: application/json' \
--data '{
"merchantOrderId": "MO1443709025658932",
"amount": 200,
"expireAt": 170905854,
"paymentFlow": {
"type": "SUBSCRIPTION_SETUP",
"merchantSubscriptionId": "MS1709025658932",
"authWorkflowType": "TRANSACTION",
"amountType": "FIXED",
"maxAmount": 200,
"frequency": "ON_DEMAND",
"expireAt": 1737278524000,
"paymentMode": {
"type": "UPI_INTENT",
"targetApp": "com.phonepe.app"
}
},
"deviceContext" : {
"deviceOS" : "ANDROID"
}
}'Request Parameters
| Parameter Name | Data Type | Description | Mandatory | Constraints |
| merchantOrderId | String | Unique merchant order id generated by merchant. | Yes | • Max Length = 63 characters. • No Special characters allowed except underscore “_” and hyphen “-“ |
| amount | Long | Order amount in paisa to setup a mandate based on the 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) |
| expireAt | DateTime | Order expiry in milliseconds. | No | max limit is 15 min for intent expiry. |
| metaInfo | Object | Merchant defined meta info to store additional information. Same data will be returned in status and callback response. | 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. |
| paymentFlow | Object | Additional details required by this flow | Yes | |
| paymentFlow.type | String | Type of payment flow. | Yes | Allowed values = [SUBSCRIPTION_SETUP] |
| paymentFlow.merchantSubscriptionId | String | Unique merchant reference subscription ID – used for subscription status. | Yes | |
| paymentFlow.authWorkflowType | String | Defines the type of workflow verification whether it is TRANSACTION or PENNY DROP | Yes | Allowed values = “TRANSACTION” or “PENNY DROP” |
| paymentFlow.amountType | String | Nature of redemption amount. | Yes | Possible Values : • FIXED • VARIABLE |
| paymentFlow.maxAmount | Long | Max amount upto which redemptions will be allowed. | Yes | The MAXIMUM debit/redemption amount for the mandate. The amount is in Paise. Note: • For VARIABLE recurring debit, this amount would be considered as Max Cap Amount |
| paymentFlow.frequency | String | Defines the Redemption Frequency. | Yes | Allowed values = • DAILY • WEEKLY • MONTHLY • FORTNIGHTLY • BIMONTHLY • QUARTERLY • HALFYEARLY • YEARLY • ON_DEMAND |
| paymentFlow.expireAt | DateTime | Defines Subscription cycle expiry. No operation allowed after subscription expires. (epoch in milliseconds) | No | Default Value= 30 years |
| paymentFlow.paymentMode | Object | Defines payment mode details for setup. | Yes | Allowed Value = { “type”: “UPI_INTENT” } |
| paymentFlow.paymentMode.targetApp | String | Defines target app for intent payment mode. | Yes | • Android: Package Name of the UPI app. { “targetApp”: “com.phonepe.app” } • iOS: Static Values like [PHONEPE, GPAY, PAYTM, CRED, SUPERMONEY, BHIM, AMAZON] |
| deviceContext.deviceOS | String | The type of device OS. | Yes | Allowed values: • Android • iOS |
Response for UPI Intent
Sample Response
{
"orderId": "OMO2604141111125363306797V",
"state": "PENDING",
"intentUrl": "upi://mandate?mn=Autopay&ver=01&rev=Y&purpose=14&validityend=14042027&QRts=2026-04-14T11:11:12.582158634+05:30&QRexpire=2026-04-14T11:26:11.582158634+05:30&txnType=CREATE&am=1.00&validitystart=14042026&orgId=180001&mode=04&pa=PRODTEST1@ybl&cu=INR&amrule=MAX&fam=1.00&mc=5262&qrMedium=00&recur=ASPRESENTED&mg=ONLINE&share=Y&block=N&tr=OM2604141111125613306810V&pn=Infinity%20Prod%20Test%201",
"nativeOtpEnabled": false
}Response Parameters
| Field Name | Data Type | Description |
orderId | String | Internal order ID generated by PhonePe Payment Gateway. |
state | String | State of the order created, expected value is PENDING. |
intentUrl | String | Intent url to invoke the payment app that initiates the mandate and completes the payment. |
API Endpoint
| Environment | HTTP Method | API |
| Sandbox | POST | https://api-preprod.phonepe.com/apis/pg-sandbox/subscriptions/v2/setup |
| Production | POST | https://api.phonepe.com/apis/pg/subscriptions/v2/setup |
Request
| Header Name | Header Value | Description |
| Content-Type | application/json | |
| Authorization | O-Bearer <access_token> | Pass access_token received in Authorization call |
Sample Debit Card Transaction Request
{
"merchantOrderId": "MO1769085791683",
"amount": 200,
"paymentFlow": {
"type": "SUBSCRIPTION_SETUP",
"merchantSubscriptionId": "MS1769085791683",
"authWorkflowType": "ZERO",
"amountType": "FIXED",
"maxAmount": 20000000,
"frequency": "MONTHLY",
"expireAt": 1769341171278,
"paymentMode": {
"type": "ENACH_ACCOUNT",
"authInstrumentType": "DEBIT_CARD"
},
"merchantUrls": {
"redirectUrl": "https://www.google.com",
"cancelRedirectUrl": "https://www.google.com"
}
},
"constraints": [
{ "type":"ACCOUNT",
"accountNumber": "XXXXXXXX0223",
"ifsc": "HDFC0000523",
"accountType": "SAVINGS",
"bankCustomerName": "Davneet"
}
],
"metaInfo": {
"udf1": "udf1",
"udf2": "udf2"
}
}Sample NetBanking Transaction Request
{
"merchantOrderId": "MO1769085791683",
"amount": 200,
"paymentFlow": {
"type": "SUBSCRIPTION_SETUP",
"merchantSubscriptionId": "MS1769085791683",
"authWorkflowType": "ZERO",
"amountType": "FIXED",
"maxAmount": 20000000,
"frequency": "MONTHLY",
"expireAt": 1769341171278,
"paymentMode": {
"type": "ENACH_ACCOUNT",
"authInstrumentType": "NET_BANKING"
},
"merchantUrls": {
"redirectUrl": "https://www.google.com",
"cancelRedirectUrl": "https://www.google.com"
}
},
"constraints": [
{ "type":"ACCOUNT",
"accountNumber": "XXXXXXXX0223",
"ifsc": "HDFC0000523",
"accountType": "SAVINGS",
"bankCustomerName": "Davneet"
}
],
"metaInfo": {
"udf1": "udf1",
"udf2": "udf2"
}
}Request Parameter
| Parameter Name | Data Type | Mandatory | Description | Constraints |
merchantOrderId | String | Yes | Merchant’s unique identifier for the order | Max Length = 63 characters No Special characters are allowed except underscore “_” and hyphen “-“ |
amount | Long | Yes | Initial setup amount in paisa | |
paymentFlow.type | String | Yes | Type of flow (e.g., SUBSCRIPTION_SETUP) | |
paymentFlow.merchantSubscriptionId | String | Yes | Merchant’s unique identifier for the subscription | |
paymentFlow.authWorkflowType | String | Yes | Authentication method (e.g., ZERO) | |
paymentFlow.amountType | String | Yes | Type of recurring charge (e.g., FIXED or VARIABLE) | |
paymentFlow.maxAmount | Long | Yes | Maximum limit for recurring debits in paisa | |
paymentFlow.frequency | String | Yes | Frequency of debit (e.g., ON_DEMAND, MONTHLY) | |
paymentFlow.expireAt | Long | Yes | Mandate expiry timestamp in epoch | |
paymentFlow.paymentMode.type | String | Yes | Payment method (e.g., ENACH_ACCOUNT) | |
paymentFlow.paymentMode.authInstrumentType | String | Yes | Auth channel (e.g., NET_BANKING/DEBIT_CARD) | |
paymentFlow.merchantUrls.redirectUrl | String | Yes | Success redirect URL | |
paymentFlow.merchantUrls.cancelRedirectUrl | String | Yes | Failure/Cancel redirect URL | |
constraints[].type | String | No | Type of account constraint (e.g., ENACH_ACCOUNT) | |
constraints[].accountNumber | String | No | Customer bank account number | Account number length should be min = 8, max = 20 |
constraints[].ifsc | String | No | Bank IFSC code | |
constraints[].accountType | String | No | Account type (e.g., SAVINGS) | |
constraints[].bankCustomerName | String | No | Name as per bank records | |
metaInfo.udf1 | String | No | User Defined Field 1 | |
metaInfo.udf2 | String | No | User Defined Field 2 |
Response
Sample Response
{
"orderId" : "OMO123",
"state" : "PENDING",
"redirectUrl" : "http-redirect-url",
}Response Parameters
| Parameter Name | Data Type | Description |
orderId | String | PG generated internal order ID |
state | String | Current state (e.g., PENDING) |
redirectUrl | String | URL to redirect user for bank authentication |