Introduction
Getting Started With Your API
This guide helps you get started with the Payment System API integration.
API Base URL
We provide separate base URLs for two environments:
-
UAT (Testing): https://api-uat.makemypayment.in
Use this environment to test your API calls, integrations, and development workflow. -
Production: https://api.makemypayment.in
Use this environment to interact with live data in production.
Recommended Steps:
- Start with the UAT base URL to explore the API and test requests.
- Once your integration works as expected, switch to the Production base URL.
Key Features
- ✅ Initiate Payout – Initiate a payout for your account.
- 🔎 Check Payout Status – Track the status of any payout in real time.
- 💰 Retrieve Account Balances – Get your current available balance instantly.
🔐 Authentication
All endpoints require authentication using two credentials:
api_key– Your unique API key.api_secret– Used with AES encryption for secure request signing.
Every request must include your credentials in the headers or request body as defined per endpoint.
🔒 Encryption
All sensitive request data is encrypted using AES-256-CBC.
- Algorithm: AES-256-CBC
- Default IV:
0g7H#8X2mTqjvLwR
Ensure your client application implements the same encryption and decryption logic before sending the payload. The API expects the payload to be base64 encoded after encryption.
Example workflow:
- Prepare your request data as JSON.
- Encrypt using AES-256-CBC with your
api_secretand the default IV. - Base64 encode the encrypted string.
- Send it in the request body or as defined by the endpoint.
💡 Tip for Developers
Use the provided code examples (on the right in desktop view or below on mobile) to quickly test requests
in your preferred programming language.
Following the examples ensures correct headers, encryption, and payload structure.
Authenticating requests
This API is not authenticated.
Account
Get account balance.
Retrieve the current balance of the authenticated merchant's virtual account.
Note:
- Response will be AES encrypted using the merchant's API secret.
- API key and secret must be sent in request headers for authentication.
Example request:
curl --request GET \
--get "https://api-uat.makemypayment.in/api/v1/balance" \
--header "X-API-KEY: string required Your API key for authentication." \
--header "X-API-SECRET: string required Your API secret for encryption and authentication." \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://api-uat.makemypayment.in/api/v1/balance"
);
const headers = {
"X-API-KEY": "string required Your API key for authentication.",
"X-API-SECRET": "string required Your API secret for encryption and authentication.",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api-uat.makemypayment.in/api/v1/balance';
$response = $client->get(
$url,
[
'headers' => [
'X-API-KEY' => 'string required Your API key for authentication.',
'X-API-SECRET' => 'string required Your API secret for encryption and authentication.',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://api-uat.makemypayment.in/api/v1/balance'
headers = {
'X-API-KEY': 'string required Your API key for authentication.',
'X-API-SECRET': 'string required Your API secret for encryption and authentication.',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()
Example response (200):
{
"status": true,
"message": "Account balance retrieved successfully",
"data": {
"result": 15000.5
},
"errors": null
}
Example response (400):
{
"status": false,
"message": "API key and secret are required",
"data": null,
"errors": []
}
Example response (401):
{
"status": false,
"message": "Invalid API key or secret",
"data": null,
"errors": []
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Payouts
Initiate a payout.
Start a new payout transaction for the authenticated merchant.
Note: The request body must be:
- AES encrypted (AES/CBC/PKCS5Padding)
- Base64 encoded after encryption
- Raw JSON payload before encryption should include: account_holder, account_number, bank_name, ifsc_code, amount, email, mobile
Example request:
curl --request POST \
"https://api-uat.makemypayment.in/api/v1/payouts/initiate" \
--header "X-API-KEY: string required Your API key for authentication." \
--header "X-API-SECRET: string required Your API secret for decryption and authentication." \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"account_holder\": \"John Doe\",
\"account_number\": \"1234567890\",
\"bank_name\": \"HDFC Bank\",
\"ifsc_code\": \"HDFC0001234\",
\"amount\": \"500\",
\"email\": \"user@example.com\",
\"mobile\": \"9876543210\"
}"
const url = new URL(
"https://api-uat.makemypayment.in/api/v1/payouts/initiate"
);
const headers = {
"X-API-KEY": "string required Your API key for authentication.",
"X-API-SECRET": "string required Your API secret for decryption and authentication.",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"account_holder": "John Doe",
"account_number": "1234567890",
"bank_name": "HDFC Bank",
"ifsc_code": "HDFC0001234",
"amount": "500",
"email": "user@example.com",
"mobile": "9876543210"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api-uat.makemypayment.in/api/v1/payouts/initiate';
$response = $client->post(
$url,
[
'headers' => [
'X-API-KEY' => 'string required Your API key for authentication.',
'X-API-SECRET' => 'string required Your API secret for decryption and authentication.',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'account_holder' => 'John Doe',
'account_number' => '1234567890',
'bank_name' => 'HDFC Bank',
'ifsc_code' => 'HDFC0001234',
'amount' => '500',
'email' => 'user@example.com',
'mobile' => '9876543210',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://api-uat.makemypayment.in/api/v1/payouts/initiate'
payload = {
"account_holder": "John Doe",
"account_number": "1234567890",
"bank_name": "HDFC Bank",
"ifsc_code": "HDFC0001234",
"amount": "500",
"email": "user@example.com",
"mobile": "9876543210"
}
headers = {
'X-API-KEY': 'string required Your API key for authentication.',
'X-API-SECRET': 'string required Your API secret for decryption and authentication.',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()
Example response (200):
{
"status": true,
"message": "Payout initiated successfully",
"data": "TXN987654321",
"errors": null
}
Example response (400):
{
"status": false,
"message": "API key and secret are required",
"data": null,
"errors": []
}
Example response (400):
{
"status": false,
"message": "Request body is not valid base64 encoded",
"data": null,
"errors": []
}
Example response (400):
{
"status": false,
"message": "Failed to decrypt data",
"data": null,
"errors": []
}
Example response (400):
{
"status": false,
"message": "Invalid JSON format after decryption",
"data": null,
"errors": []
}
Example response (401):
{
"status": false,
"message": "Invalid API key or secret",
"data": null,
"errors": []
}
Example response (422):
{
"status": false,
"message": "Validation failed",
"data": null,
"errors": {
"account_number": [
"The account number field is required."
],
"amount": [
"The amount must be at least 100."
]
}
}
Example response (500):
{
"status": false,
"message": "Failed to initiate payout. Please try again.",
"data": null,
"errors": []
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Check payout status.
Get the status of a specific payout transaction for the authenticated merchant.
Note:
- Response will be AES encrypted using the merchant's API secret.
- API key and secret must be sent in request headers for authentication.
Example request:
curl --request GET \
--get "https://api-uat.makemypayment.in/api/v1/payouts/TXN123456/status" \
--header "X-API-KEY: string required Your API key for authentication." \
--header "X-API-SECRET: string required Your API secret for encryption and authentication." \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://api-uat.makemypayment.in/api/v1/payouts/TXN123456/status"
);
const headers = {
"X-API-KEY": "string required Your API key for authentication.",
"X-API-SECRET": "string required Your API secret for encryption and authentication.",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api-uat.makemypayment.in/api/v1/payouts/TXN123456/status';
$response = $client->get(
$url,
[
'headers' => [
'X-API-KEY' => 'string required Your API key for authentication.',
'X-API-SECRET' => 'string required Your API secret for encryption and authentication.',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://api-uat.makemypayment.in/api/v1/payouts/TXN123456/status'
headers = {
'X-API-KEY': 'string required Your API key for authentication.',
'X-API-SECRET': 'string required Your API secret for encryption and authentication.',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()
Example response (200):
{
"status": true,
"message": "Payout status retrieved successfully",
"data": {
"transaction_id": "TXN123456",
"beneficiary": {
"account_holder": "John Doe",
"account_number": "1234567890",
"bank_name": "HDFC Bank",
"ifsc_code": "HDFC0001234"
},
"amount": "1000.00",
"status": "success",
"utr": "UTR123456789",
"remarks": "Payment processed successfully"
},
"errors": null
}
Example response (400):
{
"status": false,
"message": "API key and secret are required",
"data": null,
"errors": []
}
Example response (401):
{
"status": false,
"message": "Invalid API key or secret",
"data": null,
"errors": []
}
Example response (404):
{
"status": false,
"message": "Payout not found",
"data": null,
"errors": []
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Payout Webhook Guide for Merchants
This guide explains how your system should handle payout webhooks sent by our platform whenever a payout status changes to success. The payload is encrypted and must be decrypted using your secret key.
Webhook URL
Please provide your Webhook URL. Our platform will send a POST request to this URL whenever a payout is processed successfully.
HTTP Request
- Method: POST
- Headers:
x-signature: <your_merchant_webhook_secret>
Content-Type: application/json
- Note: Use the
x-signatureheader to verify the authenticity of the request using your custom webhook secret.
Request Body
The webhook payload will be sent as encrypted text. You need to decrypt this payload using your secret key to retrieve the JSON object containing the payout details.
Example Decrypted Payload:
{
"transaction_id": "TXN12345",
"beneficiary_account_holder": "John Doe",
"beneficiary_account_number": "1234567890",
"beneficiary_bank_name": "HDFC Bank",
"beneficiary_ifsc_code": "HDFC0001234",
"amount": 1000.50,
"status": "success",
"utr": "UTR123456789",
"remarks": "Monthly payout"
}
Payload Fields
| Field | Type | Description |
|---|---|---|
| transaction_id | string | Unique identifier for the payout |
| beneficiary_account_holder | string | Beneficiary account holder name |
| beneficiary_account_number | string | Bank account number |
| beneficiary_bank_name | string | Bank name |
| beneficiary_ifsc_code | string | IFSC code |
| amount | float | Payout amount |
| status | string | Payout status (success, failed, etc.) |
| utr | string | Unique Transaction Reference (nullable) |
| remarks | string | Optional notes or remarks (nullable) |
Processing Steps
- Verify the
x-signatureheader using your secret key to ensure request authenticity. - Decrypt the payload using your secret key.
- Parse the JSON object to retrieve payout details.
- Process the payout according to your internal logic.
- Optionally, log the webhook request and response for auditing.
Notes
- Retries: The platform automatically retries failed webhook requests.
- Payload is always encrypted and must be decrypted before use.
{
"transaction_id": "TXN12345",
"beneficiary_account_holder": "John Doe",
"beneficiary_account_number": "1234567890",
"beneficiary_bank_name": "HDFC Bank",
"beneficiary_ifsc_code": "HDFC0001234",
"amount": 1000.5,
"status": "success",
"utr": "UTR123456789",
"remarks": "Monthly payout"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.