EMI
This API allows you to offer EMI through a Custom Checkout flow, giving you full control over how EMI options and subventions are displayed to your customers.
Environment
| Environment | HTTP Method | API |
| Sandbox | POST | https://api-preprod.phonepe.com/apis/pg-sandbox/payments/v2/pay |
| Production | POST | https://cards.phonepe.com/apis/pg/payments/v2/pay |
⚠️ Setup Required to Avoid Errors!
Before initiating a payment, install the PhonePe Test App and configure the payment template. Skipping this step may result in HTTP 500 errors.
Request
Request Header
| Header Name | Header Value | Description |
| Content-Type | application/json | |
Authorization | O-Bearer <access_token> | Pass access_token received in Authorization call |
Request Parameters
| Parameter Name | Data Type | Mandatory | Description | Constraints |
merchantOrderId | String | Yes | Unique merchant order id generated by merchant. | Max Length = 63 charactersNo Special characters allowed except underscore “_” and hyphen “-“ |
amount | Long | Yes | Order amount in paisa. | Min Value = 100 (In paise) |
metaInfo | Object | No | Merchant defined meta info to store additional information. same data will be returned in status and callback response. | • Maximum length for Udf1-10 = 256 characters • Maximum length for Udf11-15 = 50 characters. • 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 | Yes | Additional details required by this flow. | |
paymentFlow.type | String | Yes | Type of payment mode. | Allowed Value = PG |
paymentFlow.paymentMode.authMode | String | Yes | Type of Authentication mode. | Allowed Value = 3DS |
paymentFlow.paymentMode.cardDetails.encryptedCardNumber | String | Yes | Encrypted 16 digit card number which merchant passes to process card transaction. | |
paymentFlow.paymentMode.cardDetails.encryptionKeyId | Integer | Yes | KeyId of key which merchant uses to encrypt card number & CVV. | |
paymentFlow.paymentMode.cardDetails.cardHolderName | String | No | Card Holder Name. | |
paymentFlow.paymentMode.cardDetails.expiry.month | String | Yes | Card Expiry Month. | |
paymentFlow.paymentMode.cardDetails.expiry.year | String | Yes | Card Expiry Year. | |
paymentFlow.paymentMode.encryptedCvv | String | Yes | Encrypted CVV of the card with which payment is being initiated. | |
paymentFlow..paymentMode.merchantUserId | String | No | Unique merchant User Id generated by merchant. | |
paymentFlow.paymentMode.type | String | Yes | Type of payment mode | Allowed Value = CARD/TOKEN/ALT_ID |
paymentFlow.paymentMode.emiDetails.tenureInMonths | Integer | Yes | EMI tenure in months | |
paymentFlow.paymentMode.emiDetails.interestPercentagePerAnnum | BigDecimal | No | Annual interest rate |
Sample Request: paymentMode.type = “CARD”
{
"merchantOrderId": "TEST_ORD43166295132490004064",
"amount": 100,
"metaInfo":
{
"udf1": "dummy1",
"udf2": "dummy2",
"udf3": "dummy3",
"udf4": "dummy4"
},
"paymentFlow":
{
"type": "PG",
"paymentMode":
{
"type": "TOKEN",
"authMode": "3DS",
"tokenDetails":
{
"encryptedToken": "<encryptedToken>",
"encryptionKeyId": 122,
"expiry":
{
"month": "12",
"year": "2029"
},
"panSuffix": "<panSuffix>",
"cardHolderName": "Dummy Name",
"cryptogram": "<cryptogram>",
"encryptedCvv": "<encryptedCvv>"
},
"emiDetails":
{
"tenureInMonths": 6,
"interestPercentagePerAnnum": 13.0
}
}
}
}Sample Request: paymentMode.type = “TOKEN” or paymentMode.type = “ALT_ID”
{
"merchantOrderId": "TEST_ORD43166295132490004064",
"amount": 100,
"metaInfo":
{
"udf1": "dummy1",
"udf2": "dummy2",
"udf3": "dummy3",
"udf4": "dummy4"
},
"paymentFlow":
{
"type": "PG",
"paymentMode":
{
"type": "TOKEN",
"authMode": "3DS",
"tokenDetails":
{
"encryptedToken": "<encryptedToken>",
"encryptionKeyId": 122,
"expiry":
{
"month": "12",
"year": "2029"
},
"panSuffix": "<panSuffix>",
"cardHolderName": "Dummy Name",
"cryptogram": "<cryptogram>",
"encryptedCvv": "<encryptedCvv>"
},
"emiDetails":
{
"tenureInMonths": 6,
"interestPercentagePerAnnum": 13.0
}
}
}
}Response Parameters for TOKEN
| Field | DataType | Mandatory | Description |
| tokenDetails.encryptionKeyId | Integer | Yes | KeyId of key which merchant uses to encrypt card number & cvv |
| tokenDetails.encryptedToken | String | Yes | Encrypted TOKEN number which merchant passes to process card transaction |
| tokenDetails.encryptedCvv | String | Yes | Encrypted CVV of the card with which payment is being initiated. |
| tokenDetails.cryptogram | String | Yes | The cryptogram fetched from the gateway where the card was tokenized. |
| tokenDetails.panSuffix | String | Yes | Last four digits of cardNumber |
| tokenDetails.cardHolderName | String | No | Card Holder Name |
| tokenDetails.expiry.month | String | Yes | Token expiry month |
| tokenDetails.expiry.year | String | Yes | Token expiry year |
| emiDetails | Object | No | emiDetails block needs to be passed if emi is required on the transaction |
| emiDetails.tenureInMonths | Integer | Yes | EMI tenure in months |
| emiDetails.interestPercentagePerAnnum | BigDecimal | No | Annual interest rate |
Response
Sample Response
{
"orderId": "OMO2608101347310515326548BW",
"state": "PENDING",
"expireAt": 1786350570581,
"redirectUrl": "https://pg-testing.phonepe.com/pg-transport/v1/redirect/dummy?id=8a62b7e3-3892-4b11-a941-85e878a39404",
"nativeOtpEnabled": false
}| Field Name | Data Type | Description |
orderId | String | PG generated internal order id. |
state | String | State of the order created, Expected value is CREATED. |
expiryAt | Long | Order expiry date in epoch (in milliseconds). |
redirectUrl | String | Url where merchant is supposed to redirect user to complete payment. |
Try it yourself!
headers
body params