Merchant API – Access & Security Specification
Overview
Bridg.Money Merchant APIs use HMAC-SHA256 authentication to ensure request authenticity, payload integrity, replay-attack prevention, and response integrity
End Points
| Environment | Base URL |
| Production | https://api.bridg.money |
| Beta | https://api-beta.bridg.money |
Beneficiaries
Add Beneficiary
Use this API to add a beneficiary to your Bridg.Money account by providing the beneficiary’s name, phone number, and bank account details. Only active beneficiaries can receive payouts.
Body
application/jsonBeneficiary name. Max 100 characters; letters, numbers, spaces, and common special characters allowed.
sample - Ravi Traders Pvt Ltd
Valid email address (optional).
sample - ravi@merchant.com
Beneficiary mobile number (valid Indian mobile number).
sample - 9876543210
Bank account number (9–18 digits). Must be unique for active beneficiaries under the same business.
sample - 0002053000010425
Bank IFSC (11 characters. Format: AAAA0XXXXXX).
sample - UTIB0000123
Response
application/json{
"success": true,
"message": "Beneficiary created successfully",
"data": {
"beneficiaryId": "123e4567-e89b-12d3-a456-426614174000",
"beneficiaryCode": "BEN000123"
}
}{
"success": false,
"message": "Duplicate active beneficiary account"
}{
"success": false,
"message": "Unauthorized"
}{
"success": false,
"message": "Something went wrong"
}Delete Beneficiary
This operation performs a soft delete by setting the beneficiary status to Inactive (0). Inactive beneficiaries cannot receive payouts, but historical payout records remain preserved.
Path Parameters
Unique ID of the beneficiary to deactivate
sample - 123e4567-e89b-12d3-a456-426614174000
Response
application/json{
"success": true,
"message": "Beneficiary deleted successfully",
"data": {
"beneficiaryId": "123e4567-e89b-12d3-a456-426614174000",
"status": 0
}
}{
"success": false,
"message": "Beneficiary not found"
}{
"success": false,
"message": "Internal server error"
}Payouts
Initiate Payout Transaction
Initiates a payout transfer to a vendor. Wallet balance is validated and debited during processing.
Processing Flow:
• Step 1: Payout record created in database
• Step 2: Wallet validation and debit
• Step 3: Webhook triggered (if configured)
• Step 4: Bank transfer initiated
• Step 5: Final status persisted
⚠️ Final payout status should be verified using the Get Payout API.
Body
application/jsonBeneficiary unique identifier (UUID). Beneficiary must exist, be active, and belong to the authenticated business.
sample - 123e4567-e89b-12d3-a456-426614174001
Payout amount as a string with exact decimal format (e.g., "1000.00"). Must match configured decimal precision and business limits.
sample - 1000.00
Transaction mode. Allowed values: I (IMPS), N (NEFT), R (RTGS), S (SELF). Must match business configuration.
sample - N
Response
application/json{
"success": true,
"message": "Payout initiated and is being processed",
"data": {
"payoutTransactionId": "e4df91c1-4180-43d7-8de4-6e0a20a86db9",
"amount": "1000.00",
"status": "InProgress",
"commissionAmount": "10.00",
"commissionGSTAmount": "1.80"
}
}{
"success": true,
"message": "Payout failed",
"data": {
"payoutTransactionId": "e4df91c1-4180-43d7-8de4-6e0a20a86db9",
"amount": "1000.00",
"status": "Failed",
"commissionAmount": "10.00",
"commissionGSTAmount": "1.80"
}
}{
"success": false,
"message": "Failed to initiate payout"
}{
"success": false,
"message": "Unauthorized"
}Transaction Types
- I – IMPS
- N – NEFT
- R – RTGS
- S – SELF
Payout Transaction
Fetches complete payout transaction details including vendor information, transaction reference, commission details, and current payout status.
Path Parameters
Unique payout transaction identifier (UUID).
sample - 5f8f75b4-8bc6-4c08-b90c-f90a34df2ec9
Response
application/json{
"success": true,
"data": [
{
"payoutTransactionId": "5f8f75b4-8bc6-4c08-b90c-f90a34df2ec9",
"businessId": "123e4567-e89b-12d3-a456-426614174000",
"merchantId": "123e4567-e89b-12d3-a456-426614174999",
"vendorId": "123e4567-e89b-12d3-a456-426614174001",
"vendorCode": "VEND001",
"name": "Ravi Traders",
"ifsc": "HDFC0001234",
"accountNumber": "123456789012",
"transactionType": "N",
"transactionTypeName": "NEFT",
"amount": "1000.00",
"commissionAmount": "10.00",
"commissionGSTAmount": "1.80",
"status": "Successful",
"responseCode": "100",
"responseMessage": "Transfer completed",
"transactionReference": "BANKREF12345",
"createdDate": "2025-01-10T10:30:00Z",
"updatedDate": "2025-01-10T10:31:00Z"
}
]
}{
"success": false,
"message": "Data does not exist"
}{
"success": false,
"message": "Server error"
}- Response returns an array containing the payout record.
- If no record is found, API may return an empty array unless 404 mode is explicitly enabled.
Postman Collection
Use the official Postman collection to quickly test and integrate Bridg.Money Payout APIs.
Postman Setup Instructions
- Set base_url in environment Variables.
- Set api_key in environment Variables.
- Set api_secret in environment Variables.
- All request URLs use {{base_url}}
Payout API Call with Signature
Important
- Delimiter must be pipe (|)
- Method must be uppercase
- Timestamp must be in milliseconds
- Sign the exact JSON string sent in the request
- HMAC algorithm: SHA256 (hex output)
/**
* Initiate Payout - Bridg.Money API
* Canonical format:
* METHOD | PATH | TIMESTAMP | BODY
*/
import axios from "axios";
import crypto from "crypto";
const API_KEY = "YOUR_API_KEY";
const API_SECRET = "YOUR_API_SECRET";
async function initiatePayout() {
const method = "POST";
const path = "/v1/payouts";
const baseUrl = "https://api-beta.bridg.money";
const body = {
beneficiaryId: "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
amount: "100.00",
transactionType: "I"
};
const timestamp = Date.now().toString();
const payload = JSON.stringify(body);
const canonical = [
method.toUpperCase(),
path,
timestamp,
payload
].join("|");
const signature = crypto
.createHmac("sha256", API_SECRET)
.update(canonical)
.digest("hex");
const response = await axios.post(
baseUrl + path,
body,
{
headers: {
"Content-Type": "application/json",
"x-api-key": API_KEY,
"x-timestamp": timestamp,
"x-signature": signature
}
}
);
console.log(response.data);
}
initiatePayout();
Payout Testing Accounts
SELF BANK TESTING
Beneficiary Account Number: 0002053000010425
Account Name: BEENA DENNY
NEFT / OTHER BANK TESTING
Beneficiary Account Number: 0574050000000449
Beneficiary IFSC: CSBK0000237
IMPS / OTHER BANK TESTING
Beneficiary Account Number: 123456041
Beneficiary IFSC: UTIB0000119
Authentication Headers
| Headers | Description |
| x-api-key | Public API key |
| x-timestamp | Unix epoch milliseconds as string (Date.now().toString()) |
| x-signature | HMAC-SHA256 signature |
Timestamp Rules
- Format: Unix epoch milliseconds string
- Validity: ±5 minutes
Canonical Request Format
METHOD | PATH | TIMESTAMP | BODY
Signature Algorithm
HMAC-SHA256 with hex encoding
Generate Request Signature
Canonical Request Format
METHOD | PATH | TIMESTAMP | BODY
• Delimiter must be pipe (|) • Timestamp must be in milliseconds • GET/DELETE/HEAD/OPTIONS must have empty body • Signature algorithm: HMAC-SHA256 (hex)
/**
* Generates HMAC-SHA256 signature for Bridg.Money API
* Canonical format:
* METHOD | PATH | TIMESTAMP | BODY
*/
import crypto from "crypto";
export function generateApiSignature({
method,
path,
body,
apiSecret,
}) {
const timestamp = Date.now().toString();
const canonicalBody =
["GET", "DELETE", "HEAD", "OPTIONS"].includes(method.toUpperCase())
? ""
: body
? JSON.stringify(body)
: "";
const canonicalString = [
method.toUpperCase(),
path,
timestamp,
canonicalBody,
].join("|");
const signature = crypto
.createHmac("sha256", apiSecret)
.update(canonicalString)
.digest("hex");
return { timestamp, signature };
}
Verify Response Signature
Response Signature Verification
TIMESTAMP | RAW_RESPONSE_STRING
• Delimiter must be pipe (|)
• Use the exact raw response body (do NOT re-stringify JSON)
• Signature algorithm: HMAC-SHA256 (hex)
• Use constant-time comparison
/**
* Verifies response signature from Bridg.Money API
* Canonical format:
* TIMESTAMP | RAW_RESPONSE_STRING
*/
import crypto from "crypto";
export function verifyResponseSignature({
timestamp,
rawBody, // MUST be raw response string
signature,
apiSecret,
}) {
const canonicalString = [
timestamp,
rawBody
].join("|");
const expectedSignature = crypto
.createHmac("sha256", apiSecret)
.update(canonicalString)
.digest("hex");
const sigBuf = Buffer.from(signature, "hex");
const expBuf = Buffer.from(expectedSignature, "hex");
if (sigBuf.length !== expBuf.length) return false;
return crypto.timingSafeEqual(sigBuf, expBuf);
}
IP Whitelisting
Follow the instructions below to configure IP whitelisting:
- Log in to your dashboard using your credentials.
- Navigate to Settings > IP Whitelist.
- You will see the IP Whitelisting page with no IPs added.

- IP: Enter the IP address from which you want to allow API access.
- Click Add IP to whitelist the entered IP address.

Once IP addresses are added to the whitelist, only requests originating from these IPs will be allowed to access your APIs. This helps ensure that only trusted systems can interact with your account, reducing the risk of unauthorized access. You can add or remove whitelisted IPs at any time, giving you full control over API access.
Response Signing
Responses include:
x-response-timestamp
x-response-signature
Canonical Response Format
STATUS | PATH | RESPONSE_TIMESTAMP | RESPONSE_BODY
Error Codes
| Code | Description |
| 200 | Request successful |
| 400 | Invalid request format or malformed signature |
| 401 | Missing authentication headers or request expired |
| 403 | Invalid API key, signature, or IP not whitelisted |
| 500 | Internal server error |
Webhook
Webhooks allow your application to receive real-time updates about payout status changes.
Webhook Payload
{
"payoutWebhookId": "1ee3be28-0330-48eb-b89c-8290413c81f8",
"event": "Successful",
"data": {
"status": 11,
"timestamp": "2026-03-04 17:05:15.000000",
"businessId": "1b313206-049a-11f1-8a8e-0a0c26167b3f",
"responseCode": "100",
"transactionId": "BMPT2026030400007",
"responseMessage": "Operation Success",
"payoutTransactionId": "45e254c0-17ec-11f1-8a8e-0a0c26167b3f"
}
}Webhook Event Types
| Event | Status Code | Description |
|---|---|---|
| Initiated | 3 | The payout request has been created and submitted for processing. |
| Successful | 11 | The payout has been processed successfully and funds were transferred. |
| Failed | 12 | The payout failed during processing. |
Webhook Headers
- x-webhook-timestamp
- x-webhook-signature
- x-webhook-alg (sha256)
Canonical String
TIMESTAMP | RAW_REQUEST_BODY
Use the exact raw request body received by your server when verifying the webhook signature.
import crypto from "crypto";
export function verifyWebhookSignature({
timestamp,
rawBody,
signature,
webhookSecret,
}) {
const tolerance = 5 * 60 * 1000;
const diff = Math.abs(Date.now() - Number(timestamp));
if (diff > tolerance) {
throw new Error("Webhook timestamp expired");
}
const canonical = `${timestamp}|${rawBody}`;
const expectedSignature = crypto
.createHmac("sha256", webhookSecret)
.update(canonical)
.digest("hex");
return expectedSignature === signature;
}
Version
- API Security Spec: v1.1
- Last Updated: Jan 2026