Bulk Upload Refunds
Upload multiple refunds in a single API call. Supports all the same beneficiary fields as the Confirm Refund Intent endpoint. Use Create Refund Intent to discover the required fields first.
https://api.zenpayz.com/merchant/api/v1/refund-intents/bulk-uploadRequest
Headers
| Header | Description |
|---|---|
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 |
Body Parameters
| Parameter | Type | Description |
|---|---|---|
refunds REQUIRED | array | Array of refund requests |
Call Create Refund Intent for any transaction to discover the required fields. You can also use the template response to generate a CSV file for bulk uploads — the fieldName values in requiredFields, optionalFields, and oneOfGroups map directly to column headers.
Response
Success (201 Created)
{
"success": true,
"data": {
"successful": [
{
"refundId": "refund_1774683026458_oann5ibjf",
"merchantId": "ZP_FIN_1774592804_0781001264",
"customerId": "cust_mn8yfewm_37ntht",
"transactionId": "txn_1774619159530_1_mn8yfmph_5iwb9b",
"amount": 30,
"originalAmount": 100,
"currency": "INR",
"refundType": "partial",
"status": "pending_approval",
"tspProvider": "sulifu_pay",
"reason": "Customer requested refund",
"createdAt": "2026-03-28T07:30:26.479Z"
}
],
"failed": [
{
"transactionId": "txn_invalid",
"error": "Transaction not found"
}
],
"totalRequested": 2,
"totalSuccessful": 1,
"totalFailed": 1
}
}
Requires Beneficiary Details
If any refund in the batch requires beneficiary details that were not provided, that item will appear in the successful array with requiresBeneficiary: true and field definitions. Re-submit that item with the required fields.
{
"requiresBeneficiary": true,
"status": "requires_beneficiary",
"tspProvider": "sulifu_pay",
"currency": "INR",
"transactionId": "txn_xxxxx",
"requiredFields": [...],
"optionalFields": [...],
"oneOfGroups": [["beneficiaryVpa"], ["beneficiaryAccount", "beneficiaryIfsc"]]
}
To avoid this, call Create Refund Intent first for a sample transaction and include the required beneficiary fields in every batch item.
CSV Upload Workflow
For bulk refunds, you can use a CSV file workflow:
- Create refund intent: Call
POST /refund-intentswith a sampletransactionIdto discover required fields - Build CSV: Use
fieldNamevalues fromrequiredFields,optionalFields, andoneOfGroupsas column headers, alongside base columns (transactionId,amount,reason) - Fill CSV: Populate rows with refund data — one row per refund
- Submit: Parse the CSV and POST the rows as a JSON array to
POST /refund-intents/bulk-upload
Example CSV
transactionId,amount,reason,beneficiaryEmail,beneficiaryVpa,beneficiaryAccount,beneficiaryIfsc,beneficiaryName,beneficiaryMobile,beneficiaryCity
txn_aaa,20,Customer request,john@example.com,john@upi,,,John Doe,+919876543210,Mumbai
txn_bbb,500,Duplicate charge,alice@example.com,,1234567890,HDFC0001234,Alice Smith,+919123456789,Delhi
txn_ccc,250,Item not received,bob@example.com,bob@ybl,,,Bob Johnson,+918765432109,Bangalore
The CSV column headers must match the fieldName values from the template response (e.g., beneficiaryVpa, beneficiaryAccount, beneficiaryIfsc). Leave columns empty for fields you don't need — for example, if using UPI (VPA), leave beneficiaryAccount and beneficiaryIfsc empty.
Examples
- cURL
- SDK (Recommended)
curl -X POST https://api.zenpayz.com/merchant/api/v1/refund-intents/bulk-upload \
-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 '{
"refunds": [
{
"transactionId": "txn_aaaaa",
"amount": 500,
"reason": "Customer request",
"beneficiaryEmail": "john@example.com",
"beneficiaryVpa": "john@upi",
"beneficiaryName": "John Doe",
"beneficiaryMobile": "+919876543210"
},
{
"transactionId": "txn_bbbbb",
"amount": 1000,
"reason": "Duplicate charge",
"beneficiaryEmail": "alice@example.com",
"beneficiaryAccount": "1234567890",
"beneficiaryIfsc": "HDFC0001234",
"beneficiaryName": "Alice Smith"
}
]
}'
const result = await zenpays.refunds.bulkUpload({
refunds: [
{
transactionId: 'txn_aaaaa',
amount: 500,
reason: 'Customer request',
beneficiaryEmail: 'john@example.com',
beneficiaryVpa: 'john@upi',
beneficiaryName: 'John Doe',
},
{
transactionId: 'txn_bbbbb',
amount: 1000,
reason: 'Duplicate charge',
beneficiaryEmail: 'alice@example.com',
beneficiaryAccount: '1234567890',
beneficiaryIfsc: 'HDFC0001234',
beneficiaryName: 'Alice Smith',
},
],
});
console.log(`Succeeded: ${result.totalSuccessful}, Failed: ${result.totalFailed}`);
Error Responses
| Code | HTTP | Message |
|---|---|---|
| VALIDATION_ERROR | 400 | Invalid request body |
| UNAUTHORIZED | 401 | Invalid API key |
Individual item errors are returned in the failed array, not as HTTP errors.
Related Endpoints
- Create Refund Intent — Discover required fields before batch upload
- Confirm Refund Intent — Confirm a single refund
- List Refunds
- Get Refund