# Reconciliation files (/docs/reconciliation)

Precium delivers reconciliation data as CSV over SFTP. This page describes the
files as they are produced today, against **Recon File Specification v3**.

<Callout type="warning">
The recon file format is versioned and has changed twice. Column names differ
between versions, so a parser written against an older file will not find its
columns in a newer one. Confirm which version your SFTP account receives before
you build against this page.
</Callout>

## The three files [#the-three-files]

| File | What it contains | Settlement required |
|---|---|---|
| **Recon** | Transactions reconciled against settlement data, ready for settlement in an upcoming cycle. The authoritative comparison dataset for a cycle. | Yes |
| **Markoff** | Transactions reconciled between Precium's gateways and the providers, within the timeframe the file covers. | No |
| **Exception** | Transactions that could not be reconciled within the expected timeframe. Populated best effort, because only partial data exists. | n/a |

An exception row is not a failed payment. It means settlement for that
transaction was still outstanding when the file for that date was cut, so it
appears in the exception file instead of the recon file. It may reconcile
normally in a later cycle.

## Parsing rules [#parsing-rules]

These apply to every file unless stated otherwise.

| Rule | Value |
|---|---|
| Encoding | UTF-8 |
| Format | CSV, header row always present |
| Delimiter | Comma. Values containing a comma are quoted with `"` |
| Line terminator | CRLF |
| Dates | `YYYY-MM-DD` |
| Datetimes | `YYYY-MM-DD HH:MM` |
| Timezone | UTC throughout |
| Monetary values | Period decimal separator, rounded to **4 decimal places** |

<Callout type="warning">
**Two things will break a naive parser.**

**Leading apostrophes.** Numeric-looking values that must be read as strings are
prefixed with a single quote (`'`) so that Excel does not reformat them. In the
v3 file this affects `settlement_bank_account_number`,
`gateway_transaction_reference`, `transaction_rrn` and `transaction_auth_code`.
Strip the leading `'` before matching.

**Amounts are in major units, not cents.** `transaction_amount` is `40.0000`
for ZAR 40.00. This is the opposite of the API, where amounts are in cents.
Refunds and chargebacks carry a **negative** amount.
</Callout>

## Recon file v3.0 [#recon-file-v30]

27 columns. One row per transaction.

### Identification [#identification]

| Column | Type | Notes |
|---|---|---|
| `merchant_name` | string | Merchant display name |
| `merchant_id` | uuid | Merchant identifier |
| `brand_name` | string | Brand display name |
| `brand_id` | uuid | Brand identifier |
| `gateway_transaction_id` | uuid | **Precium gateway transaction identifier. This is your primary matching key.** |
| `gateway_transaction_reference` | string | Your own reference, as supplied on the purchase. Prefixed with `'` |

### Transaction [#transaction]

| Column | Type | Notes |
|---|---|---|
| `transaction_type` | enum | `PURCHASE`, `REFUND`, `CHARGEBACK` |
| `transaction_amount` | decimal | Major units, 4 dp. Negative for refunds and chargebacks. Defaults to `0.0000` |
| `transaction_currency` | string | ISO 4217 |
| `transaction_date_time_utc` | datetime | `YYYY-MM-DD HH:MM`, UTC |
| `transaction_payment_method` | enum | For example `CARD` |
| `transaction_rrn` | string | Retrieval Reference Number. Prefixed with `'` |
| `transaction_auth_code` | string | Authorisation code. Prefixed with `'` |

### Card [#card]

Every field below is populated **only** when `transaction_payment_method` is
`CARD`, and is empty otherwise.

| Column | Type | Notes |
|---|---|---|
| `card_country` | string | Issuing country, ISO 3166-1 alpha-2 |
| `card_type` | enum | `DEBIT`, `CREDIT` |
| `card_authenticated` | boolean | `TRUE` / `FALSE`. Whether 3D Secure authentication was applied |
| `card_tokenized` | boolean | `TRUE` / `FALSE`. Whether tokenisation was applied |
| `card_issuer` | string | Card scheme or issuer, for example `VISA`, `MASTERCARD` |

### Settlement and fees [#settlement-and-fees]

| Column | Type | Notes |
|---|---|---|
| `settlement_acquiring_bank` | enum | `ABSA`, `STANDARD_BANK`, `FNB`, `UNKNOWN` |
| `settlement_bank_account_number` | string | Destination account. Prefixed with `'` |
| `settlement_date` | date | Reporting settlement date |
| `fee_codes` | string | Comma-separated list of fee codes applied. Quoted when it contains commas. Empty when no fees apply |
| `invoiced_fee_total_ex_vat` | decimal | Defaults to `0.0000` |
| `invoiced_fee_total_incl_vat` | decimal | Defaults to `0.0000` |
| `settlement_fee_total_ex_vat` | decimal | Defaults to `0.0000` |
| `settlement_fee_total_incl_vat` | decimal | Defaults to `0.0000` |
| `fee_currency_code` | string | ISO 4217. Empty when no fees apply |

## Matching a transaction [#matching-a-transaction]

Match on `gateway_transaction_id`. It is the purchase identifier Precium
returns when you create a purchase, so it is the one value that is stable from
your API call through to settlement.

Keep `transaction_rrn`, `transaction_auth_code` and the amount as secondary
data. You will need them if a transaction has to be investigated at the
acquiring bank, where the Precium identifier means nothing.

<Callout type="warning">
**A refund does not carry its original purchase identifier in v3.0.**

A refund is a separate payment transaction with its own `gateway_transaction_id`,
its own RRN and its own authorisation code. Recon **v2.1** carried a
`related_transaction_reference` column linking it back to the original purchase.
**That column does not exist in v3.0.**

If you need refund-to-purchase linkage, hold it on your side from the refund
call, or ask your account contact which file version you are receiving.
</Callout>

### Granularity [#granularity]

| Event | Rows |
|---|---|
| A purchase | One |
| A hold followed by a capture | One. It is a single purchase |
| A refund | Its own row, `transaction_type` `REFUND`, negative amount |
| A chargeback | Its own row, `transaction_type` `CHARGEBACK`, negative amount |

## Column names across versions [#column-names-across-versions]

A column changed name more than once. If you are reading an older file, or
older documentation, this is the mapping.

| v1.0 | v2.1 | v3.0 (current) |
|---|---|---|
| `purchase_id` | `gateway_transaction_id` | `gateway_transaction_id` |
| `purchase_reference` | `gateway_transaction_reference` | `gateway_transaction_reference` |
| `auth_code` | `auth_code` | `transaction_auth_code` |
| `rrn` | `rrn` | `transaction_rrn` |
| `is_3DS` | `three_ds` | `card_authenticated` |
| `is_tokenized` | `tokenization` | `card_tokenized` |
| `paid_at` | `transaction_date_time_utc` | `transaction_date_time_utc` |
| `type` | `type` | `transaction_type` |
| `related_to_purchase` | `related_transaction_reference` | *(removed)* |
| `settlement_id` | `settlement_id` | *(removed)* |

So `auth_code`, `transaction_auth_code` and the
`authorisation_approval_code` you may see in other material are the same
value under three names, from three different file versions.

## Delivery [#delivery]

Files are delivered daily by SFTP. A captured transaction appears once it has
been fully reconciled with the acquirer, which can be a few days after it was
processed. Inclusion in the recon file means Precium has matched the transaction
to acquiring bank data and considers it reconciled; reconciled transactions are
then eligible for settlement under the agreed settlement schedule.
