# Batch Processing

Work with settlement batches, the daily settle schedule, and funding.

---

## Overview

AuxCORE groups a merchant's card transactions into **settlement batches**. A batch is opened as transactions arrive and closed (settled) at the merchant's daily cut-off, or on demand.

All endpoints below are admin API routes: `Authorization: Bearer <JWT>` (or an API key in `x-api-key`). A merchant user only sees its own merchant's batches; admin callers may pass `merchantId`. `/api/v1/batches/*` is gated by the tenant's `batch` feature (`403` `SERVICE_UNAVAILABLE` without it); `/deposits` and `/settlements` are not gated.

> **Note:** There is no file-upload ("Batch Terminal") API for submitting many transactions from a CSV. The portal's Batch Terminal page redirects to the Batches list. Submit transactions individually with [`POST /api/v1/public/transaction`](../core/transactions.md).

---

## Batch Statuses

| Status | Meaning |
|--------|---------|
| `open` | Accepting transactions |
| `pending` | Closed, waiting to be submitted |
| `processing` | Being submitted to the processor |
| `settled` | Settled |
| `failed` | Settlement failed |
| `cancelled` | Cancelled |
| `resubmit` | Marked for resubmission |
| `host_settlement_pending` | Host-capture batch (TSYS) waiting for the processor's own cut-off |

---

## List Batches

```http
GET /api/v1/batches
```

| Query | Description |
|-------|-------------|
| `merchantId` | Admin only; merchant users are always scoped to their own merchant |
| `status` | One of the statuses above |
| `dateFrom` / `dateTo` | Created date range |
| `page` / `limit` | Default `1` / `50` |

```bash
curl "https://uat.auxcore.net/api/v1/batches?status=settled&page=1&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

**Response:**
```json
{
  "success": true,
  "data": [
    {
      "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
      "merchantId": "3f2a9c1e-7b4d-4e8a-9f10-2c5d6e7f8a90",
      "batchNumber": "001",
      "batchId": "BATCH-20260222-001",
      "status": "settled",
      "gatewayName": "NMI",
      "saleCount": 45,
      "refundCount": 2,
      "voidCount": 0,
      "transactionCount": 47,
      "saleAmount": "5900.00",
      "refundAmount": "75.25",
      "netAmount": "5824.75",
      "totalAmount": "5824.75",
      "currency": "USD",
      "settledAt": "2026-02-22T23:00:00Z",
      "createdAt": "2026-02-22T08:12:00Z"
    }
  ],
  "meta": { "page": 1, "limit": 20, "total": 89 }
}
```

Amount fields are decimal strings. The full object also carries `authCount` / `captureCount` / `totalCount`, the matching `…Amount` fields, `gatewayBatchId`, `openedAt`, `closedAt`, `submittedAt`, `settledDate`, `scheduledSettleTime`, `resubmitCount`, `settlementReference`, `errorMessage` and `updatedAt`.

---

## Get Batch

```http
GET /api/v1/batches/:id
```

`404` if the batch does not exist (or belongs to another merchant).

### Batch Transactions

```http
GET /api/v1/batches/:id/transactions
```

**Response:** `{ "success": true, "data": { "batch": { … }, "transactions": [ … ] } }`. Returns `502` `UPSTREAM_ERROR` if the transaction list cannot be loaded.

### Export a Batch

```http
GET /api/v1/batches/:id/export
```

### Export the Batch List

```http
GET /api/v1/batches/export
```

The list export takes `merchantId`, `startDate`, `endDate`.

---

## Create a Batch

```http
POST /api/v1/batches
```

```json
{
  "merchantId": "3f2a9c1e-7b4d-4e8a-9f10-2c5d6e7f8a90",
  "scheduledSettleTime": "2026-02-24T23:00:00Z"
}
```

Both fields are optional for merchant users; an admin must send `merchantId` (`400` `VALIDATION_ERROR` otherwise). Returns `201`.

---

## Settle a Batch Now

```http
POST /api/v1/batches/:id/settle
```

Optional body `submissionConfig` (`gatewayType` and `method` required when sent; `https_post` needs `endpoint`, `socket` needs `host` and `port`). If settlement fails the response is `422`:

```json
{
  "success": false,
  "error": { "code": "SETTLEMENT_FAILED", "message": "Batch settlement failed" },
  "data": { "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b", "status": "failed" }
}
```

### Resubmit a Failed Batch

```http
POST /api/v1/batches/:id/resubmit
```

---

## Daily Settle Schedule

### Get Schedule

```http
GET /api/v1/batches/schedule
```

```bash
curl "https://uat.auxcore.net/api/v1/batches/schedule?merchantId=3f2a9c1e-7b4d-4e8a-9f10-2c5d6e7f8a90" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

**Response:**
```json
{
  "success": true,
  "data": { "settleTime": "23:00", "settleTimezone": "America/New_York" }
}
```

If nothing is saved the default `23:00` / `America/New_York` is returned. An admin call with no `merchantId` returns `data: null`.

### Set Schedule

```http
POST /api/v1/batches/schedule
```

```bash
curl -X POST https://uat.auxcore.net/api/v1/batches/schedule \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "3f2a9c1e-7b4d-4e8a-9f10-2c5d6e7f8a90",
    "settleTime": "23:30",
    "settleTimezone": "America/Chicago"
  }'
```

| Field | Required | Description |
|-------|----------|-------------|
| `settleTime` | Yes | `HH:MM` (24-hour) |
| `settleTimezone` | No | IANA timezone, default `America/New_York` |
| `merchantId` | Admin only | Required when an admin sets the schedule |

Invalid `settleTime` returns `400` (`settleTime must be in HH:MM format`).

---

## Batch Summaries

### Settlement Summary

```http
GET /api/v1/batches/settlement-summary
```

### Net Deposits

```http
GET /api/v1/batches/net-deposits
```

Both take `merchantId` (admin), `startDate`, `endDate`; `startDate` and `endDate` are required (`400` `VALIDATION_ERROR` otherwise).

### List Deposits

Deposits recorded against batches.

```http
GET /api/v1/deposits
```

Query: `merchantId` (admin), `dateFrom`, `dateTo`, `limit` (default `100`, max `500`). **Response:** `{ "success": true, "data": [ { "id", "date", "depositDate", "amount", "grossAmount", "refundAmount", "chargebackAmount", "transactionCount", "fees", "net", "netAmount", "status", "bankAccount", "reference", "merchantId", "gateway" } ] }` — one row per batch; `id` is the batch id.

### Get a Deposit

```http
GET /api/v1/deposits/:id
```

---

## Funding and Payouts

These live on the settlement service under `/api/v1/settlements`.

### Funding Report

```http
GET /api/v1/settlements/funding-report
```

```bash
curl "https://uat.auxcore.net/api/v1/settlements/funding-report?merchantId=3f2a9c1e-7b4d-4e8a-9f10-2c5d6e7f8a90&dateFrom=2026-02-01&dateTo=2026-02-28" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

Query: `merchantId` (or `merchantIds`, comma-separated), `dateFrom`, `dateTo` (or a single `date`; one of the two is required, `400` `VALIDATION_ERROR` otherwise), optional `gatewayType`, `processorId`, `riskLevel`, `includeOneTimeFees`. With a single `merchantId` that yields one report, the response is `{ "success": true, "msg": "Daily Summary with Fees Found Successfully", "data": { … } }`; otherwise (`merchantIds`, `all=true`, or no merchant) `data` is an array of reports and `msg` is `Generated N funding reports`.

### Export Funding Report as CSV

```http
GET /api/v1/settlements/funding-report/export/csv
```

```bash
curl "https://uat.auxcore.net/api/v1/settlements/funding-report/export/csv?merchantId=3f2a9c1e-7b4d-4e8a-9f10-2c5d6e7f8a90&dateFrom=2026-02-01&dateTo=2026-02-28" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -o funding-report.csv
```

### Email Funding Report

```http
POST /api/v1/settlements/funding-report/email
```

```json
{
  "merchantId": "3f2a9c1e-7b4d-4e8a-9f10-2c5d6e7f8a90",
  "dateFrom": "2026-02-01",
  "dateTo": "2026-02-28",
  "recipientEmail": "accounting@example.com"
}
```

`dateFrom`, `dateTo` and `recipientEmail` are required (`400` `VALIDATION_ERROR` otherwise).

### Initiate a Manual Payout

```http
POST /api/v1/settlements/payout
```

```json
{
  "merchantId": "3f2a9c1e-7b4d-4e8a-9f10-2c5d6e7f8a90",
  "date": "2026-02-22",
  "amount": 5824.75
}
```

`merchantId`, `date` and `amount` are required (`400` `VALIDATION_ERROR` otherwise). **Response:** `{ "success": true, "data": { "payoutId": "PAYOUT-1771761600000-7f8a90", "merchantId", "amount", "status": "initiated", "estimatedDate": "2026-02-23" } }`. This only records an `initiated` payout reference (billing-ledger write is best effort and its failure is ignored); it does not move money.

### Settlement History

```http
GET /api/v1/settlements/history/:merchantId
```

---

## Best Practices

- **Pick a settle time after your last expected sale** of the day
- **Check batch status** after the cut-off — `failed` batches need `resubmit`
- **Reconcile** batches against the funding report

---

**Need help?** Contact support@auxcore.net
