# Settlement & reconciliation

Close the day into a batch, then tie every captured payment back to the money that actually landed.

Captures accumulate through the trading day. At close, BaxPay rolls them into a **settlement
batch**, with an itemised breakdown your finance team or ERP can reconcile line by line.

These calls use the [connection credential](https://developers.baxpay.com/connections) (`bxc_…`), like the rest of the in-store
API. A batch belongs to the connection's mode: a test connection only ever settles, lists and
exports test sessions.

## Closing a day

- `POST /integration/reconciliation/close`

The business day is a **Europe/Paris calendar date**. Closing it folds every captured session of
that day (in this mode, optionally for one `terminalId`) that isn't in a batch yet into a new batch.
Closing the same date again later picks up only what was captured since.

In sandbox, first capture a sale so there is something to settle:

```bash
SESSION=$(curl -s -X POST https://sandbox-api.baxpay.com/v1/integration/sessions \
  -H "Authorization: Bearer $BAXPAY_CONNECTION" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "saleReferenceId": "till-04-receipt-99200", "amountMinor": 4730 }' | jq -r .data.sessionId)
curl -X POST "https://sandbox-api.baxpay.com/v1/integration/sessions/$SESSION/simulate" \
  -H "Authorization: Bearer $BAXPAY_CONNECTION" -H "Content-Type: application/json" \
  -d '{ "outcome": "APPROVED" }'
```

Then close today:

```bash
BUSINESS_DATE=$(TZ=Europe/Paris date +%F)

curl -X POST https://sandbox-api.baxpay.com/v1/integration/reconciliation/close \
  -H "Authorization: Bearer $BAXPAY_CONNECTION" \
  -H "Content-Type: application/json" \
  -d "{ \"businessDate\": \"$BUSINESS_DATE\" }"
```

```json
{
  "success": true,
  "data": {
    "batchId": "682e9bd4-…",
    "settlementRef": "STL-20260714-628FEF",
    "totals": {
      "grossMinor": 4730,
      "refundMinor": 0,
      "feeMinor": 0,
      "netMinor": 4730,
      "txnCount": 1
    }
  }
}
```

`netMinor` is `grossMinor − refundMinor − feeMinor`, where `feeMinor` is the sum of the fees
actually charged on those sales (always `0` in sandbox). It's the figure to reconcile against your
bank statement. A day with nothing left to settle answers `400`.

## Reading batches

- `GET /integration/reconciliation/batches` — the last 90, newest day first
- `GET /integration/reconciliation/batches/{id}` — the batch and its sessions

```bash
curl https://sandbox-api.baxpay.com/v1/integration/reconciliation/batches/682e9bd4-… \
  -H "Authorization: Bearer $BAXPAY_CONNECTION"
```

```json
{
  "success": true,
  "data": {
    "batch": {
      "id": "682e9bd4-…",
      "livemode": false,
      "status": "CLOSED",
      "businessDate": "2026-07-14",
      "settlementRef": "STL-20260714-628FEF",
      "grossMinor": 4730,
      "feeMinor": 0,
      "netMinor": 4730,
      "txnCount": 1,
      "currency": "EUR"
    },
    "sessions": [
      { "id": "4fba7ed1-…", "saleReferenceId": "till-04-receipt-99200", "status": "CAPTURED", "capturedAmountMinor": 4730 }
    ]
  }
}
```

A batch is `CLOSED` until its first export, then `EXPORTED`.

## Exporting for your ERP

- `GET /integration/reconciliation/batches/{id}/export.csv` — text/csv
- `GET /integration/reconciliation/batches/{id}/export.camt053` — JSON

```bash
curl https://sandbox-api.baxpay.com/v1/integration/reconciliation/batches/682e9bd4-…/export.csv \
  -H "Authorization: Bearer $BAXPAY_CONNECTION" -o batch.csv && cat batch.csv
```

```text
settlement_ref,business_date,session_id,sale_reference,method,currency,amount,status,auth_code,transaction_id,captured_at
STL-20260714-628FEF,2026-07-14,4fba7ed1-…,till-04-receipt-99200,,EUR,47.30,CAPTURED,TEST31EC,,2026-07-14T10:02:11.000Z
,,,,,EUR,TOTAL_NET=47.30,FEE=0.00,GROSS=47.30,COUNT=1,
```

One row per session, amounts in euros, then a totals row. The file is plain CSV, ready for a
spreadsheet or a bank-reconciliation import.

```bash
curl https://sandbox-api.baxpay.com/v1/integration/reconciliation/batches/682e9bd4-…/export.camt053 \
  -H "Authorization: Bearer $BAXPAY_CONNECTION"
```

```json
{
  "success": true,
  "data": {
    "statement": { "id": "STL-20260714-628FEF", "currency": "EUR" },
    "balances": [{ "type": "OPBD", "amount": 0 }],
    "summary": {
      "totalCreditEntries": { "count": 1, "sum": 47.3 },
      "charges": 0,
      "net": 47.3
    },
    "entries": [
      { "reference": "till-04-receipt-99200", "amount": 47.3, "currency": "EUR", "creditDebitIndicator": "CRDT", "status": "BOOK" }
    ]
  }
}
```

> **camt.053-style, not camt.053**
> The JSON mirrors the camt.053 *structure* so it's easy to map, with amounts in euros. It is **not**
> a bank-issued camt.053 XML statement. If your ERP requires canonical XML from your bank, keep using
> that as the system of record and use this for the per-payment detail it doesn't give you.

## The three-way match

**1. Your ERP**

Expected takings per till or pump, from your own system.

**2. The BaxPay batch**

Captured payments, matched on `saleReferenceId`, which is why it's worth putting the till, lane
or site into the reference when you open the session.

**3. Your bank statement**

The net payout that actually arrived. `netMinor` is the bridge between the batch and the
statement line.

If the three agree, the day is closed. If they don't, the per-payment CSV is where you'll find the
discrepancy: usually a session that was authorized but never captured.
