> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paymend.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Reconciliation guide

> Join the four reports and prove every processed event was paid out.

The four reports form a chain. Each stage is joined to the next by an
identifier that both files carry.

```
payments_created ──payment_id──▶ transactions_succeeded ──event_id──▶ settlement_paid_out
       │                                                                      ▲
       └────────────payment_id──▶ payments_disputed ──event_id────────────────┘
```

## Join keys

| From                   | To                     | Key                                                             |
| ---------------------- | ---------------------- | --------------------------------------------------------------- |
| Payments created       | Transactions succeeded | `payments_created.event_id = transactions_succeeded.payment_id` |
| Payments created       | Payments disputed      | `payments_created.event_id = payments_disputed.payment_id`      |
| Transactions succeeded | Settlement paid out    | `event_id = event_id`                                           |
| Payments disputed      | Settlement paid out    | `event_id = event_id`                                           |

<Note>
  The final two joins are on `event_id` in both files. `event_id` is globally
  unique and never reused, so no composite key is needed and no type or period
  qualifier is required.
</Note>

## Reconciling settlement

Every row in a settlement report matches exactly one row in a transactions or
disputes report. The relationship is one-to-one in both directions: no
settlement row exists without a corresponding processed event, and within a
settled period no processed event is missing from settlement.

<Steps>
  <Step title="Collect the processed events for the period">
    Take the transactions and disputes reports whose periods overlap the
    settlement period, and union their `event_id` values.
  </Step>

  <Step title="Join on event_id">
    Left join the settlement file's `event_id` against that set. Expect a
    complete match on both sides.
  </Step>

  <Step title="Check the amounts">
    Sum `event_amount` for `SALE` rows in the settlement file and compare with
    the transactions report. They tie exactly. Remember that refunds are signed
    negative in settlement and unsigned in transactions.
  </Step>

  <Step title="Foot each row">
    Confirm the five component columns sum to `payout_amount`. Any row failing
    this indicates a corrupted file — re-download before investigating further.
  </Step>
</Steps>

### Period alignment

A settlement report covers events whose `event_effective_at` falls within the
settlement period. `event_effective_at` equals the date of the underlying event,
so a transaction processed on 14 August settles in the period containing
14 August.

<Note>
  Settlement periods follow your payout schedule, which may not be calendar
  months. Where your schedule is more frequent than monthly, one calendar month of
  transactions spans multiple settlement reports.
</Note>

## Reconciling creation against processing

Unlike settlement, this relationship is **not** one-to-one and is not expected
to be.

* A created payment may never be processed, so it appears in the creation report
  and nowhere else.
* A created payment may be processed in a later period, so the two rows sit in
  reports covering different periods.
* One payment may produce several transaction rows (e.g., a sale and one or more
  refunds).

## Reconciling disputes against payments

Dispute events are frequently raised months after the payment was processed.
The disputes report for August will contain events against payments created in
June, March, or earlier.

Never expect the disputes report for a period to join only to payments from the
same period. Join on `payment_id` across your full payment history, and where a
dispute references a payment you do not hold, extend the range of creation
reports you have ingested rather than treating it as an orphan.

<Note>
  The reverse direction also fails by design: a payment disputed in September
  will not appear in any August dispute report, even though the payment itself
  was processed in August. Dispute coverage is bounded by when the event was
  recorded, not when the payment was processed.
</Note>

## Worked example

Tracing payment `PAYM_123` across all four reports.

<CodeGroup>
  ```report 1: payments_created theme={null}
  event_id,event_created_at,event_type,event_amount,currency,...
  PAYM_123,2026-08-01 09:14:02.000000 UTC,PAYMENT_CREATION,49.00,USD,...
  ```

  ```report 2: transactions_succeeded theme={null}
  event_id,event_processed_at,event_type,payment_id,event_amount,...
  SALE_456,2026-08-01 09:15:44 UTC,SALE,PAYM_123,49.00,...
  REFN_789,2026-08-04 14:22:10 UTC,REFUND,PAYM_123,49.00,...
  ```

  ```report 3: payments_disputed theme={null}
  event_id,event_created_at,payment_id,event_type,event_status,event_amount,...
  FRAD_999,2026-08-03 02:11:07.412900 UTC,PAYM_123,ALERT,REFUNDED,49.00,...
  ```

  ```report 4: settlement_paid_out theme={null}
  event_id,event_effective_at,payment_id,event_type,event_amount,...
  SALE_456,2026-08-01,PAYM_123,SALE,49.00,...
  FRAD_999,2026-08-03,PAYM_123,ALERT,0,...
  REFN_789,2026-08-04,PAYM_123,REFUND,-49.00,...
  ```
</CodeGroup>

The payment was created and captured on 1 August, flagged by an Ethoca alert on
3 August, and refunded on 4 August in response to that alert. All three events
settle in the same period.

## Common pitfalls

<AccordionGroup>
  <Accordion title="Joining refunds on payment_id">
    A refund's `payment_id` is the original payment, not the refund. Two refunds
    against one payment share a `payment_id`. Join on `event_id` to keep rows
    distinct.
  </Accordion>

  <Accordion title="Grouping dispute events by payment">
    One payment can attract multiple fraud events. Grouping by `payment_id`
    collapses them and understates dispute fees. Aggregate on `event_id`.
  </Accordion>

  <Accordion title="Reading the period from a settlement filename">
    The date in a settlement filename is the payout date. The events inside it
    fall in the preceding settlement period. Use `event_effective_at` but note
    that in the case of settlement being delayed (e.g. while under Risk review),
    the pay-out may include events from a previous period.
  </Accordion>

  <Accordion title="Subtracting fees in the settlement report">
    Fees are already negative. Subtracting them inverts the sign and doubles the
    error. Add all five component columns.
  </Accordion>

  <Accordion title="Expecting creation and processing counts to match">
    Created payments may never be processed, or may process in a later period.
    Age unmatched rows across several periods before treating them as a break.
  </Accordion>
</AccordionGroup>
