Batch Payments
Send up to 20 payments atomically in a single request with automatic rollback on failure.
Overview
Batch payments let you send multiple payments in a single API call. The batch is atomic: if any individual payment fails, all payments that already succeeded within the batch are automatically reversed, leaving no partial state.
Use cases:
- Payroll distribution: pay multiple agents their earnings at the end of a period
- Revenue sharing: split a payment across multiple stakeholder wallets
- Bulk rewards: distribute tokens or credits to a list of recipients
- Marketplace settlement: pay multiple sellers in one operation
The batch endpoint supports up to 20 payments per request.
Sending a Batch
POST /v1/payments/batchRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
payments | array | Yes | Array of payment objects (1–20 items) |
Payment Object
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Source wallet ID |
to | string | Yes | Destination wallet ID |
amount | string | Yes | Amount as decimal string |
description | string | No | Payment description (max 1,024 chars) |
idempotencyKey | string | No | Per-payment idempotency key |
import Wallgent from '@wallgent/sdk'
const wg = new Wallgent({ apiKey: process.env.WALLGENT_API_KEY })
const response = await fetch('https://api.wallgent.com/v1/payments/batch', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.WALLGENT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
payments: [
{ from: 'wal_treasury', to: 'wal_agent1', amount: '100.00', description: 'March payroll' },
{ from: 'wal_treasury', to: 'wal_agent2', amount: '200.00', description: 'March payroll' },
{ from: 'wal_treasury', to: 'wal_agent3', amount: '150.00', description: 'March payroll' },
],
}),
})Successful Response
When all payments succeed, the API returns HTTP 200:
{
"batchId": "bat_01J...",
"results": [
{ "index": 0, "status": "success", "transactionId": "txn_01J..." },
{ "index": 1, "status": "success", "transactionId": "txn_01J..." },
{ "index": 2, "status": "success", "transactionId": "txn_01J..." }
],
"summary": {
"total": 3,
"succeeded": 3,
"failed": 0
}
}Partial Failure and Automatic Rollback
If any payment in the batch fails, the API automatically reverses all payments that already succeeded. This keeps the batch atomic — you never end up in a state where half the recipients were paid.
The response returns HTTP 207 with a BATCH_PARTIAL_FAILURE error code:
{
"batchId": "bat_01J...",
"error": {
"code": "BATCH_PARTIAL_FAILURE",
"message": "One or more payments failed. Succeeded payments have been reversed."
},
"results": [
{ "index": 0, "status": "reversed", "transactionId": "txn_01J..." },
{ "index": 1, "status": "failed", "error": "INSUFFICIENT_FUNDS" },
{ "index": 2, "status": "reversed", "transactionId": "txn_01J..." }
],
"summary": {
"total": 3,
"succeeded": 0,
"reversed": 2,
"failed": 1
}
}Note: In rare cases a reversal itself can fail (e.g. the receiving wallet was frozen between payment and reversal). If this happens, the affected payment's status remains "success" in the results and must be handled manually. Always check for "status": "success" entries in a failed batch response.
Error Handling
const response = await fetch('https://api.wallgent.com/v1/payments/batch', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.WALLGENT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ payments }),
})
const result = await response.json()
if (response.status === 207) {
// Partial failure — all succeeded payments have been reversed
console.error('Batch failed:', result.error.message)
// Log per-payment outcomes
for (const item of result.results) {
if (item.status === 'failed') {
console.error(`Payment ${item.index} failed: ${item.error}`)
}
if (item.status === 'success') {
// Reversal itself failed — requires manual intervention
console.error(`Payment ${item.index} succeeded but reversal failed. Manual action required.`)
}
}
} else {
console.log(`Batch ${result.batchId} completed: ${result.summary.succeeded} payments succeeded`)
}Idempotency
Pass an Idempotency-Key header for the entire batch request to make retries safe. If the request times out, you can retry with the same key and the server will return the original result without re-executing the batch.
const response = await fetch('https://api.wallgent.com/v1/payments/batch', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.WALLGENT_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': `payroll-${payPeriod}-${batchRunId}`,
},
body: JSON.stringify({ payments }),
})API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /v1/payments/batch | Execute a batch of payments atomically |
Permissions
| Permission | Required For |
|---|---|
payments:write | Send batch payments |