Wallgent
Guides

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/batch

Request Body

FieldTypeRequiredDescription
paymentsarrayYesArray of payment objects (1–20 items)

Payment Object

FieldTypeRequiredDescription
fromstringYesSource wallet ID
tostringYesDestination wallet ID
amountstringYesAmount as decimal string
descriptionstringNoPayment description (max 1,024 chars)
idempotencyKeystringNoPer-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

MethodPathDescription
POST/v1/payments/batchExecute a batch of payments atomically

Permissions

PermissionRequired For
payments:writeSend batch payments

On this page