UPI subscriptions let you collect recurring payments from customers using subscription mandates.
This guide walks through how to create and manage subscriptions using EximPe Merchant APIs.
Prerequisites
Before you begin, ensure you have:
- Credentials: Your Client ID and Client Secret
- Domain Whitelist: Whitelisted your website domain for integration
- Webhook URL: A secure endpoint to receive payment status updates
- UPI Subscription enablement: UPI recurring subscription enabled and approved by EximPe.
- Server environment: Ability to make HTTPS
POST and GET requests from your backend.
- JSON & HTTP Client: Familiarity with JSON request bodies and HTTP client libraries.
Integration Steps
The integration consists of four steps:
- Create Subscription
- Check Mandate Status
- Trigger Recurring Payment
- Modify or Cancel Mandate
Step 1: Create Subscription
Test/Sandbox Environment Limits: In test/sandbox environment, there is a lower limit of ₹100 for the amount field and ₹200 for the billing_amount field in the standing instruction. These limits apply to both Intent Flow and Collection Flow subscriptions.
Use the Create UPI Subscription API to create a subscription order and standing instruction. You can use either Intent Flow (QR code/intent) or Collection Flow (requires VPA).
Intent Flow
Production Only: Intent Flow can be tested only in production environment. This feature is not available in test/sandbox environments.
Use the Intent Flow to create subscriptions without requiring the customer’s VPA upfront. The Intent flow allows customers to approve the mandate by scanning a QR code or using a UPI payment intent.
Sample Request (Intent Flow)
curl -X POST https://api-pacb.eximpe.com/pg/subscriptions/intent/ \
-H "Content-Type: application/json" \
-H "X-Client-ID: <your-client-id>" \
-H "X-Client-Secret: <your-client-secret>" \
-H "X-Merchant-ID: <your-merchant-id>" \
-H "X-API-Version: 1.0.0" \
-d '{
"amount": "1000.00",
"collection_mode": "s2s",
"currency": "INR",
"reference_id": "SUBR8QRLW",
"buyer": {
"name": "John Doe",
"email": "[email protected]",
"phone": "+919876543210",
"address": {
"line_1": "123 Main Street",
"line_2": "Apt 4B",
"city": "Mumbai",
"state": "Maharashtra",
"postal_code": "400001"
},
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
},
"product": {
"name": "Monthly Subscription Plan",
"description": "Monthly subscription for premium services",
"hs_code": "98051000",
"hs_code_description": "Subscription services",
"type_of_goods": "service"
},
"invoice": {
"number": "INVMVLSVW",
"date": "2025-12-15"
},
"standing_instruction": {
"billing_amount": "1000.00",
"billing_currency": "INR",
"billing_cycle": "MONTHLY",
"billing_interval": 1,
"payment_start_date": "2026-01-15",
"payment_end_date": "2027-01-15",
"billing_date": 1,
"billing_limit": "AFTER",
"billing_rule": "MAX",
"remarks": "Monthly subscription for premium services"
},
"mop_type": "UPI",
"upi_flow_type": "intent",
"upi_app_name": "others"
}'
Response (Intent Flow)
{
"success": true,
"message": "UPI Subscription created successfully",
"data": {
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"subscription_id": "660e8400-e29b-41d4-a716-446655440001",
"subscription_type": "UPI_RECURRING",
"intent_uri": "pa=merchant@payu&pn=Merchant%20Name&am=1000.00&cu=INR&tn=Order%20Description&tr=ORD-2024-001",
"qr_code": {
"url": "upi://pay?pa=merchant@payu&pn=Merchant%20Name&am=1000.00&cu=INR&tn=Order%20Description&tr=ORD-2024-001",
"base64": "iVBORw0KGgoAAAANSUhEUgAA..."
},
"subscription": {
"billing_cycle": "MONTHLY",
"billing_interval": 1,
"payment_start_date": "2025-01-01",
"payment_end_date": "2025-12-31",
"status": "PENDING"
}
}
}
Key differences between Collection and Intent flow:
- Collection Flow: Requires customer’s VPA upfront. Payment request is sent directly to the customer’s UPI app.
- Intent Flow: No VPA required. Customer approves mandate by scanning QR code or using payment intent. Returns QR code in base64 format for display.
The Intent flow is ideal when you want to let customers approve mandates without collecting their VPA first.
Display QR Code
The response includes a base64-encoded QR code that can be displayed directly:
<img src="data:image/png;base64,{data.qr_code.base64}" alt="UPI Payment QR Code" />
Alternatively, you can use the intent_uri to generate a QR code client-side or use the provided qr_code.url for UPI app deep linking.
For full request and response schema, see the Create UPI Subscription (Intent Flow) endpoint in API Reference.
Collection Flow
Alternatively, you can use the Collection Flow which requires the customer’s VPA upfront. Payment request is sent directly to the customer’s UPI app.
To start with, the request is raised from the Merchant to EximPe with the required transaction mandatory/optional parameters. This needs to be a server-to-server curl call request.
Sample Request (Collection Flow)
curl -X POST https://api-pacb.eximpe.com/pg/subscriptions/ \
-H "Content-Type: application/json" \
-H "X-Client-ID: <your-client-id>" \
-H "X-Client-Secret: <your-client-secret>" \
-H "X-Merchant-ID: <your-merchant-id>" \
-H "X-API-Version: 1.0.0" \
-d '{
"amount": "1000.00",
"collection_mode": "s2s",
"currency": "INR",
"reference_id": "SUB6ACIQ7",
"buyer": {
"name": "John Doe",
"email": "[email protected]",
"phone": "+919876543210",
"address": {
"line_1": "123 Main Street",
"line_2": "Apt 4B",
"city": "Mumbai",
"state": "Maharashtra",
"postal_code": "400001"
},
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
},
"product": {
"name": "Monthly Subscription Plan",
"description": "Monthly subscription for premium services",
"hs_code": "98051000",
"hs_code_description": "Subscription services",
"type_of_goods": "service"
},
"invoice": {
"number": "INVW72Z2G",
"date": "2025-12-12"
},
"standing_instruction": {
"billing_amount": "1000.00",
"billing_currency": "INR",
"billing_cycle": "MONTHLY",
"billing_interval": 1,
"payment_start_date": "2026-01-12",
"payment_end_date": "2027-01-12",
"billing_date": 1,
"billing_limit": "AFTER",
"billing_rule": "MAX",
"remarks": "Monthly subscription for premium services"
},
"mop_type": "UPI",
"upi_flow_type": "collection",
"vpa": "9999999999@upi",
"upi_app_name": "others"
}'
Response (Collection Flow)
{
"success": true,
"message": "UPI Subscription created successfully",
"data": {
"order_id": "ORD_xxx",
"subscription_type": "UPI_RECURRING",
"intent_uri": "upi://pay?...",
"subscription_id": "SUB_xxx"
}
}
For full request and response schema, see the Create UPI Subscription endpoint in API Reference.
Step 2: Check Mandate Status
After the customer approves the UPI mandate, use the Get Subscription Mandate Status API to verify that it is active.
Sample Request
curl -X GET "https://api-pacb.eximpe.com/pg/subscriptions/SUB_xxx/mandate_status/" \
-H "X-Client-ID: <your-client-id>" \
-H "X-Client-Secret: <your-client-secret>" \
-H "X-Merchant-ID: <your-merchant-id>" \
-H "X-API-Version: 1.0.0"
Response
{
"success": true,
"message": "Subscription mandate status fetched successfully",
"data": {
"subscription_id": "SUB_xxx",
"mandate_is_active": true
}
}
Only proceed to debit the customer when mandate_is_active is true.
Step 3: Trigger Recurring Payment
3.1 Send Pre-Debit Notification
Use the Pre-Debit Notification API to inform the customer about an upcoming debit, in line with UPI subscription compliance. This should be sent at least 48 hours before triggering the actual recurring payment. If the billing cycle is daily, the notification should be sent at least 24 hours before triggering the payment.
Sample Request
curl -X POST "https://api-pacb.eximpe.com/pg/subscriptions/SUB_xxx/pre_debit_notification/" \
-H "Content-Type: application/json" \
-H "X-Client-ID: <your-client-id>" \
-H "X-Client-Secret: <your-client-secret>" \
-H "X-Merchant-ID: <your-merchant-id>" \
-H "X-API-Version: 1.0.0" \
-d '{
"debit_date": "2025-06-10",
"amount": 1000.00,
"invoice_display_number": "inv"
}'
Response
{
"success": true,
"message": "Pre-debit notification triggered successfully",
"data": {
"subscription_id": "SUB_xxx",
"debit_date": "2025-06-10",
"amount": "1000.00",
"notification_sent": true
}
}
3.2 Trigger Recurring Payment
Test/Sandbox Environment: In test/sandbox environment, the recurring payment can be called immediately after the pre-debit notification is sent. The 48-hour (or 24-hour for daily billing) waiting period requirement applies only to production environment.
On the scheduled billing date, trigger the recurring payment using the Trigger Recurring Payment API.
Sample Request
curl -X POST "https://api-pacb.eximpe.com/pg/subscriptions/SUB_xxx/recurring_payment/" \
-H "Content-Type: application/json" \
-H "X-Client-ID: <your-client-id>" \
-H "X-Client-Secret: <your-client-secret>" \
-H "X-Merchant-ID: <your-merchant-id>" \
-H "X-API-Version: 1.0.0" \
-d '{
"amount": 1000.00,
"invoice_display_number": "INV-2025-001"
}'
Response
{
"success": true,
"message": "Recurring payment triggered successfully",
"data": {
"order_id": "ORD_xxx",
"message": "UPI Collection request sent to somevpa@upi"
}
}
Use the standard Get Payment or Get Order APIs or webhooks to track installment success and failures.
Step 4: Modify or Cancel Mandate
Production Only: Cancel mandate and modify mandate operations are only supported in production environment. These features are not available in test/sandbox environments.
4.1 Modify Mandate
To change the billing amount or end date of an active subscription, use the Modify Subscription Mandate API.
Sample Request
curl -X POST "https://api-pacb.eximpe.com/pg/subscriptions/SUB_xxx/modify_mandate/" \
-H "Content-Type: application/json" \
-H "X-Client-ID: <your-client-id>" \
-H "X-Client-Secret: <your-client-secret>" \
-H "X-Merchant-ID: <your-merchant-id>" \
-H "X-API-Version: 1.0.0" \
-d '{
"amount": 1500.00,
"end_date": "2025-12-31"
}'
Response
{
"success": true,
"message": "Subscription mandate modification request sent successfully",
"data": {
"subscription_id": "SUB_xxx",
"mandate_modified": true,
"updated_amount": "1500.00",
"updated_end_date": "2025-12-31"
}
}
At least one of amount or end_date must be provided to modify the mandate.
4.2 Cancel Mandate
To fully stop future debits and revoke the subscription mandate, use the Cancel Subscription Mandate API.
Sample Request
curl -X POST "https://api-pacb.eximpe.com/pg/subscriptions/SUB_xxx/cancel_mandate/" \
-H "X-Client-ID: <your-client-id>" \
-H "X-Client-Secret: <your-client-secret>" \
-H "X-Merchant-ID: <your-merchant-id>" \
-H "X-API-Version: 1.0.0"
Response
{
"success": true,
"message": "Subscription mandate cancel request sent successfully",
"data": {
"subscription_id": "SUB_xxx",
"mandate_cancelled": true,
"subscription_status": "CANCELLED"
}
}
The subscription will be marked as CANCELLED on success.
Webhooks
EximPe sends webhook notifications when subscription status changes occur. You can configure webhooks to receive real-time updates about subscription lifecycle events.
Subscription Status Webhook
The Subscription Status webhook is triggered when a subscription status changes or subscription information is updated. This allows you to track subscription lifecycle events and update your billing records accordingly.
For detailed webhook payload specifications, event types, and implementation details, refer to the Subscription Status Webhook in API Reference.