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

# Settlement File Specification

> Column-by-column reference for the three reconciliation report files plus the Settlement Statement and Invoice PDFs: every field's meaning, decimal precision, when it is empty, the file naming rules, where files are delivered, and how to bulk-download a date range.

[Settlement Reports & Exports](/docs/en/support/settlement-reports-faq) explains how the amounts are
calculated and how to pull a report on demand.
[Report Delivery & Email Subscription](/docs/en/support/report-delivery-and-subscription-faq) covers how
files reach you on a schedule. **This page is the field-level contract**: what every column means,
how many decimals it carries, when it is legitimately empty, and how each file is named.

## Which report files do I get, and when is each one produced?

| Report | Covers | Produced |
| - | - | - |
| **Transaction Details** | Every transaction on transaction day T, regardless of settlement | On T+1 |
| **Settlement Details** | One row per transaction inside one settlement period | The day after the settlement bank receipt is received |
| **Settlement Summary** | Totals per transaction type for one settlement currency in one settlement period | The day after the settlement bank receipt is received |

All three are **CSV, UTF-8 encoded**. The two settlement reports are keyed to a settlement batch;
the transaction report is keyed to a transaction day and is independent of your settlement cycle.

Two behaviours follow from that split and cause most "my file is missing" tickets:

* **A day with no transactions still produces a Transaction Details file** — containing the header
  row only.
* **A settlement date with no net settlement produces no settlement files at all**, because no
  settlement batch exists. If you need a placeholder on every scheduled date instead, that is a
  per-merchant configuration — see
  [Settlement Reports & Exports](/docs/en/support/settlement-reports-faq).

## What are the exact file names?

| File | Name |
| - | - |
| Transaction Details | `transaction_details_{merchant id}_{transaction date}.csv` |
| Settlement Details | `settlement_details_{merchant id}_{settlement batch id}_{settlement date}_{settlement currency}.csv` |
| Settlement Summary | `settlement_summary_{merchant id}_{settlement batch id}_{settlement date}_{settlement currency}.csv` |
| Settlement Statement (PDF) | `settlement_statement_{merchant id}_{currency}_{date}.pdf` |
| Withdrawal Statement (PDF) | `{merchant id}-{withdraw order id}_{account type}.pdf` — a timestamp is appended when the statement is regenerated; downloadable again at any time from **Withdrawal History** |
| Invoice (PDF) | `invoice_{currency}_{date1}_{date2}.pdf` |

* `transaction date` and `settlement date` are `YYYYMMDD` in **UTC+8**; PDF dates are `YYYYMMDD`.
* `settlement currency` is part of the settlement file names precisely because a batch is packed by
  settlement currency. If one settlement date carries two settlement currencies you receive **two
  sets of files**, distinguishable by that last component.
* A file that has to be regenerated is **not overwritten**: it is written again under a new version
  suffix (`..._v2.0_1.csv` follows `..._v1.0_1.csv`), so an existing download you already picked up
  never changes underneath you.

## Where are the files delivered, and how long do they stay there?

Files are available in the Merchant Portal and, if you use SFTP delivery, under the documented
transaction and settlement directories — see
[Reconciliation reports](/docs/en/developer-docs/tools-and-references/references/reconciliation-reports)
for the exact paths.

**Reconciliation reports are kept on the SFTP server for a limited period only. They remain
downloadable from the Merchant Portal.** If your pull job has been offline for a while, recover the
gap from the Portal rather than from SFTP.

SFTP access supports two login methods, **username and password** or **key-based authentication**.
Key-based authentication is the recommended one.

## Transaction Details — field dictionary

| Column | Meaning | Format / precision | When empty |
| - | - | - | - |
| `Merchant Id` | The identifier Waffo assigns to you | String, up to 64 | Never |
| `Sub Merchant Id` | The identifier Waffo assigns to a secondary merchant that supplies the goods or services directly | String, up to 64 | When you do not use sub-merchants |
| `Order Id` | Waffo's identifier for the transaction — the payment id, refund id or chargeback id depending on `Transaction Type` | String, up to 32 | Never |
| `Merchant Order Id` | Your own identifier for the transaction | String, up to 32 | When you did not send one |
| `Payment Request Id` | Your own identifier for the payment request | String, up to 32 | When you did not send one |
| `Original Order Id` | The original payment transaction id | String, up to 32 | **Always empty when `Transaction Type` is `PAYMENT`**; populated for `REFUND` and `CHARGEBACK` |
| `Order Amount` | Transaction amount in the order currency | Decimals of the order currency | Never |
| `Order Currency` | Currency of `Order Amount` | ISO 4217 3-letter code | Never |
| `Transaction Type` | `PAYMENT`, `REFUND` or `CHARGEBACK` | Enum | Never |
| `Payment Method` | The payment method used | String, up to 32; same values as the API | Never |
| `Payment Option` | The sub-method under the payment method — for example paying from a wallet balance rather than a linked card | String, up to 32 | When the method has no sub-method |
| `Payment Request Datetime` | When Waffo received the payment request from you | `YYYY-MM-DD hh:mm:ss`, UTC+8 | Never |
| `Payment Date` | Date the transaction reached success | `YYYY-MM-DD`, UTC+8 | Never |
| `Payment Time` | Time of day the transaction reached success | `hh:mm:ss`, UTC+8 | Never |
| `Order Description` | Your description of the transaction | String, up to 128 | When you did not send one |
| `Product Name` | The contracted payment product, e.g. `ONE_TIME_PAYMENT` | Enum | Never |
| `Merchant User Id` | Your own identifier for your end user | String, up to 64 | When you did not send one |

`Payment Date` and `Payment Time` are two separate columns on purpose: the date column is the one
that determines which transaction day — and therefore which settlement — a transaction belongs to,
so it can be used as a grouping key without parsing a timestamp.

## Settlement Details — field dictionary

Same row grain as Transaction Details, plus the settlement result for each transaction.

| Column | Meaning | Format / precision | When empty |
| - | - | - | - |
| `Merchant Id` | Your merchant identifier | String, up to 64 | Never |
| `Sub Merchant Id` | Sub-merchant identifier | String, up to 64 | When you do not use sub-merchants |
| `Settlement Batch Id` | Waffo's identifier for this settlement within the period | String, up to 64 | Never (an all-zero value marks a placeholder file — see below) |
| `Settlement Date` | Date the settlement file is generated | `YYYY-MM-DD`, UTC+8 | Never |
| `Order Id` | Payment, refund or chargeback id, per `Transaction Type` | String, up to 32 | Never |
| `Merchant Order Id` | Your own transaction identifier | String, up to 32 | When you did not send one |
| `Payment Request Id` | Your own payment-request identifier | String, up to 32 | **Always empty when `Transaction Type` is `CHARGEBACK`**, and when you did not send one |
| `Original Order Id` | The original payment transaction id | String, up to 32 | **Always empty for `PAYMENT`**; populated for `REFUND` and `CHARGEBACK` |
| `Order Amount` | Transaction amount in the order currency | Decimals of the order currency | Never |
| `Order Amount (Settlement Currency)` | The same amount converted into the settlement currency | Your settlement decimal place — 2 or 6, zero-padded | Never |
| `Order Currency` | Currency of `Order Amount` | ISO 4217 | Never |
| `Transaction Type` | `PAYMENT`, `REFUND`, `CHARGEBACK` or `CHARGEBACK_ALERT` | Enum | Never |
| `Event Type` | `PAY_SUCCESS`, or the billed failure stage on a failed-attempt row — see [Billing for Failed Card Transactions](/docs/en/support/failed-transaction-billing-faq) | Enum | Never |
| `Payment Method Type` | The category of the payment method | String, up to 32 | Never |
| `Payment Method` | The payment method used | String, up to 32 | Never |
| `Payment Option` | Sub-method under the payment method | String, up to 32 | When the method has no sub-method |
| `Payment Request Datetime` | When Waffo received your payment request | `YYYY-MM-DD hh:mm:ss`, UTC+8 | Never |
| `Payment Date` | Date the transaction succeeded | `YYYY-MM-DD`, UTC+8 | Never |
| `Payment Time` | Time the transaction succeeded | `hh:mm:ss`, UTC+8 | Never |
| `Product Name` | Contracted payment product | Enum | Never |
| `Forex Currency Pair` | The pair used for the FX step in this row, as `AAA/BBB` | ISO 4217 codes, slash-separated | When no FX was involved — see the priority table below |
| `Forex Rate` | Rate for `Forex Currency Pair`, supplied by the foreign exchange partner | 8 decimals, zero-padded | Whenever `Forex Currency Pair` is empty |
| `Fee Amount` | Waffo's processing fee, in the fee currency | 6 decimals, zero-padded | Never |
| `Fee Amount (Settlement Currency)` | The same fee converted into the settlement currency | Settlement decimal place, zero-padded | Never |
| `Fee Currency` | Currency of `Fee Amount` | ISO 4217 | Never |
| `Tax Amount` | Transaction tax (VAT and/or withholding tax) on this transaction, in the tax currency | 6 decimals, zero-padded | When no transaction tax applies to you |
| `Tax Amount (Settlement Currency)` | The same tax converted into the settlement currency | Settlement decimal place | When no transaction tax applies |
| `Tax Currency` | Currency of `Tax Amount` | ISO 4217 | When no transaction tax applies |
| `Settlement Amount` | Net settlement for this row | Settlement decimal place, zero-padded; **negative for `REFUND` and `CHARGEBACK`** | Never |
| `Settlement Currency` | Currency of `Settlement Amount` | ISO 4217 | Never |
| `Comments` | A marker on rows that belong to a refund-reserve settlement | String | On an ordinary settlement |

Tax is reported as a single `Tax Amount` column whichever tax it is; there is no separate VAT or
withholding-tax column — see [Fee & Tax Treatment](/docs/en/support/fee-and-tax-treatment-faq).

## Settlement Summary — field dictionary

One row per transaction type, plus a `TOTAL` row, for a single settlement currency.

| Column | Meaning | Format / precision | When empty |
| - | - | - | - |
| `Merchant Id` | Your merchant identifier | String, up to 64 | Never |
| `Settlement Batch Id` | Identifier of this settlement | String, up to 64 | Never |
| `Settlement Date` | Date the file is generated | `YYYY-MM-DD`, UTC+8 | Never |
| `Transaction Type` | `TOTAL` (all transactions), `PAYMENT`, `REFUND`, `CHARGEBACK`, `CHARGEBACK_ALERT` | Enum | Never |
| `Transaction Count` | Number of transactions of that type | Integer | Never |
| `Fee Amount (Settlement Currency)` | Processing fee for that type, in the settlement currency | Settlement decimal place | When that type carried no fee |
| `Tax Amount (Settlement Currency)` | Transaction tax for that type, in the settlement currency | Settlement decimal place | When no transaction tax applies |
| `Settlement Amount` | Net settlement total for that type | Settlement decimal place; negative for `REFUND` and `CHARGEBACK` | Never |
| `Settlement Currency` | Currency of the amounts | ISO 4217 | Never |
| `Comments` | Marker for a refund-reserve settlement | String | On an ordinary settlement |

There is **no `Order Amount` column in the summary**. Every monetary column is already expressed in
the settlement currency, which is what makes the rows addable — amounts in different order, fee and
tax currencies are never summed in their original currencies.

## Why does my file show six decimal places when the currency has two?

Because settlement precision is a per-merchant configuration. Your account is set to either **2 or 6
decimal places**, and it is fixed once configured. On a 6-decimal account, settlement-currency
amounts are written with six decimals and **zero-padded** to that width, so a whole number appears as
`99.000000`. `Order Amount` in the *original* order currency keeps that currency's own decimals and
is not padded.

Fixed widths, always zero-padded when the value is shorter:

| Value | Decimals |
| - | - |
| Forex rate | 8 |
| Fee and tax amounts | 6 |
| Settlement-currency amounts | your settlement decimal place (2 or 6) |

On a 6-decimal account this is what makes the detail rows tie exactly to the batch: the sum of the
detail `Settlement Amount` values equals the batch amount without a residual.

## When does Forex Currency Pair have a value, and which pair?

Fees and taxes can be billed in a currency that is neither your order currency nor your settlement
currency, so the pair is resolved by priority — **the first condition that matches wins**:

| Order of evaluation | Condition | Pair |
| - | - | - |
| 1 | Settlement Currency ≠ Order Currency | `Settlement/Order` |
| 2 | Settlement Currency ≠ Fee Currency | `Settlement/Fee` |
| 3 | Settlement Currency ≠ Tax Currency | `Settlement/Tax` |
| — | None of the above | empty — no FX was involved |

Rows that carry no order amount — a billed failed attempt, or a chargeback alert — evaluate the fee
currency only; a chargeback that was won evaluates the order currency only.

So a row can carry a pair even when your order currency already equals your settlement currency: the
FX step in that row was for the fee or the tax, not for the order. `Forex Rate` is empty exactly when
the pair is empty.

## I received a settlement file with a batch id of all zeros. What is it?

That is a **placeholder**, produced only if your account is configured to generate a file on every
scheduled settlement date rather than only when a settlement happened:

```
settlement_details_{merchant id}_S000...000_{settlement date}_{settlement currency}.csv
settlement_summary_{merchant id}_S000...000_{settlement date}_{settlement currency}.csv
```

It contains the header row and nothing else. The all-zero batch id is deliberate — no settlement
batch exists, so there is no real id to put there, and **no Settlement Batch record appears in the
Merchant Portal**. Treat it as a delivery heartbeat that separates "there was nothing to settle" from
"the file did not arrive", not as a settlement event.

## Can I download a whole month of settlement details in one go?

Yes, from the Settlement Batch list. Select a range of **Actual Settlement Date** and download the
batches together:

| Rule | Value |
| - | - |
| Maximum span per request | **1 month** — a longer selection is rejected before the task is created |
| Row order | By settlement date, **ascending** |
| Rows per file | **60,000** data rows, excluding the header |
| One file result | `settlement_details_{merchant id}_{min settlement date}_{max settlement date}.csv`, no sequence suffix, downloaded directly |
| Multiple file result | `settlement_details_{merchant id}_{min settlement date}_{max settlement date}.zip`, containing `..._001.csv`, `..._002.csv`, … |

`min settlement date` and `max settlement date` are the earliest and latest settlement dates in your
selection, `YYYYMMDD` UTC+8. The request runs asynchronously — collect the result from the Reports
module, as described in [Exports & Report Downloads](/docs/en/support/export-center-faq).

For a range you want to slice differently — by payment date, by order currency, or as a daily summary
rather than transaction by transaction — use Customized Export instead; its options are listed in
[Settlement Reports & Exports](/docs/en/support/settlement-reports-faq).

## What formatting conventions do the PDF documents follow?

The Settlement Statement, Withdrawal Statement and Invoice share one layout and one set of
conventions, so a value means the same thing in all three:

| Convention | Rule |
| - | - |
| Amounts | Thousands separator, **2 decimals** |
| Currency position | **Before** the amount: `{Currency} {Amount}` |
| Country/Region | **ISO 3166-1 alpha-3** — `USA`, `CHN`, `HKG` |
| Labels | Each word capitalised |
| Totals | `Total` is **not** a row inside the table; it is stated separately below it |
| Rate column name | Always **`Forex Rate`** — never `Fx` |
| Rate with no conversion | Shown as `--`; the column is kept rather than dropped |

The page order is fixed as well: the issuing Waffo entity's name and address, then the document block
(date and number), then your company name and address, then the business detail table.

## What is in the Settlement Statement, and how is its rate calculated?

Columns are **Country/Region, Transaction Amount, Fee Amount, Tax Amount, Avg. Forex Rate and
Settlement Amount**, with the totals stated below the table. `Tax Amount` is formatted like every
other amount, `{Tax Currency} {Tax Amount}`.

`Avg. Forex Rate` is a **weighted average, not a simple mean**. Each component rate is weighted by
its own settlement amount:

```
Avg. Forex Rate = Σ (settlement amount ᵢ × forex rate ᵢ) / Σ (settlement amount ᵢ)
```

carried to 8 decimals. Dividing total original amount by total settlement amount gives a slightly
different figure, which is why recomputing it that way will not reproduce the statement.

## What is in the Invoice, and why are there several attachments?

The Invoice covers **fees**, grouped by fee currency:

| Field | Rule |
| - | - |
| `Invoice No` | Your Merchant ID + the latest actual settlement time in the covered set + the fee currency |
| `Invoice Date` | The **latest actual settlement date** among the settlements covered |
| `Commission` | The fee amount with its currency |
| Multiple fee currencies | **One attachment per fee currency** — the amounts are never merged across currencies |

Statement and Invoice emails are sent from a Waffo finance mailbox; reply to
[support](mailto:support@waffo.com) rather than to the sender if you have a question about one.

**IOF is not on the Invoice.** Where IOF applies to a transaction, Waffo cannot issue an invoice for
it, so it is excluded from the invoice document. It still appears in the settlement calculation.

***

Reconciling a specific file and something still does not tie?
[Contact support](mailto:support@waffo.com) with the file name — the settlement batch id and
settlement currency in it are enough to locate the settlement.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.