Skip to main content

Create Payout Intent

Create a payout intent. Returns the fields you need to collect before confirming the payout.

A payout intent returns the beneficiary fields that corridor requires. You confirm within 30 minutes, supplying those fields, and funds are held. The payout is sent to the provider, and on the provider callback the held funds are debited and the intent succeeds.
How a payout is confirmed, sent and debited
POSThttps://api.zenpayz.com/payment/api/v1/payout-intents
Bearer · API key

Request

Headers

HeaderDescription
Authorization
REQUIRED
Bearer {api_key}
X-Signature
REQUIRED
HMAC-SHA256 signature
X-Timestamp
REQUIRED
ISO 8601 timestamp
X-Secret-Salt
REQUIRED
Secret salt for HMAC validation
Content-Type
REQUIRED
application/json
X-Idempotency-Key
OPTIONAL
Unique key to prevent duplicates

Body Parameters

ParameterTypeDescription
amount
REQUIRED
numberPayout amount (must be > 0)
currency
REQUIRED
stringCurrency code (e.g. USD, INR, USDT)
country
OPTIONAL
stringISO 3166-1 alpha-2 country code
beneficiaryName
REQUIRED
stringBeneficiary full name
beneficiaryEmail
OPTIONAL
stringBeneficiary email
beneficiaryPhone
OPTIONAL
stringBeneficiary phone
payoutType
OPTIONAL
stringbank_transfer, upi, imps, neft, rtgs
purpose
OPTIONAL
stringPurpose (e.g. PAYOUT, SALARY, REFUND)
description
OPTIONAL
stringDescription
customerId
OPTIONAL
stringYour customer ID
webhookUrl
OPTIONAL
stringURL for payout status webhooks
metadata
OPTIONAL
objectCustom key-value pairs (e.g. { "order_no": "ORD-001" }). Echoed back in all webhook callbacks for this payout.

Response

Success (200 OK)

{
"success": true,
"data": {
"intentId": "poi_xxxxx",
"status": "requires_confirmation",
"amount": 10000,
"currency": "INR",
"beneficiaryName": "John Doe",
"requiredFields": [
{
"fieldName": "beneficiaryAccount",
"label": "Account Number",
"type": "text",
"required": true,
"placeholder": "Bank account number"
},
{
"fieldName": "beneficiaryIfsc",
"label": "IFSC Code",
"type": "text",
"required": true,
"placeholder": "e.g. HDFC0001234"
}
],
"optionalFields": [
{
"fieldName": "beneficiaryEmail",
"label": "Email",
"type": "text",
"required": false
}
],
"expiresAt": "2024-01-15T11:00:00.000Z",
"createdAt": "2024-01-15T10:30:00.000Z"
}
}

For crypto payouts (e.g. currency: "USDT"), the required fields will be:

{
"requiredFields": [
{
"fieldName": "chain",
"label": "Network / Chain",
"type": "select",
"required": true,
"options": ["ethereum", "tron", "bitcoin", "solana", "polygon"]
},
{
"fieldName": "walletAddress",
"label": "Wallet Address",
"type": "text",
"required": true
}
]
}

Error Responses

CodeHTTPMessage
PAYOUT_INTENT_CREATE_FAILED400Invalid request or insufficient wallet balance
UNAUTHORIZED401Invalid API key

Examples

curl -X POST https://api.zenpayz.com/payment/api/v1/payout-intents \
-H "Authorization: Bearer zp_test_xxxxx" \
-H "X-Timestamp: 2024-01-15T10:30:00.000Z" \
-H "X-Signature: a1b2c3d4e5f6..." \
-H "X-Secret-Salt: your_secret_salt" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"currency": "INR",
"country": "IN",
"beneficiaryName": "John Doe",
"beneficiaryEmail": "john@example.com",
"purpose": "PAYOUT"
}'

How It Works

  1. You send basic payout details (amount, currency, beneficiary name)
  2. ZenPays returns the exact fields you need to collect
  3. You collect those fields from your user or your system
  4. You confirm the intent with those fields
  5. The payout is executed

The intent expires after 30 minutes. If not confirmed, create a new one.