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

# Multi-currency matching

> Reconcile transactions in different currencies by converting amounts to a common base before applying Matcher's matching rules.

Matcher lets you reconcile transactions in different currencies by converting amounts to a common base currency before comparison. This enables matching across international transactions, treasury operations, and multi-entity reconciliations.

## Overview

***

Multi-currency matching converts both transaction amounts to a base currency using the appropriate FX rate, then applies standard matching rules. If the converted amounts fall within tolerance, Matcher creates a match. Otherwise, it creates an exception for review.

<Frame caption="Multi-currency matching flow.">
  <img src="https://mintcdn.com/lerian-49cb71fc/UsUgoha8b-OkDZPH/images/en/docs/matcher-multicurrency-matching.jpg?fit=max&auto=format&n=UsUgoha8b-OkDZPH&q=85&s=2776b9983b0415aaae8e6e1cfe6c2ea0" alt="Multi-currency matching flow." width="2295" height="680" data-path="images/en/docs/matcher-multicurrency-matching.jpg" />
</Frame>

## How it works

***

Multi-currency support is built into the existing context types (`1:1`, `1:N`, `N:M`) and match rules — there is no separate "multi-currency" context type.

When transactions have different currencies, Matcher uses the `amountBase` and `currencyBase` fields on each transaction to compare converted amounts. The FX conversion happens at ingestion time or through an external FX source.

### Key components

| Component                               | Where it lives     | Purpose                                                  |
| --------------------------------------- | ------------------ | -------------------------------------------------------- |
| `amountBase` / `currencyBase`           | Transaction fields | Pre-converted amounts for comparison                     |
| `matchBaseAmount` / `matchBaseCurrency` | Rule config        | Tell a rule to compare base amounts instead of originals |
| `FXSource` interface                    | Integration port   | Pluggable interface for fetching exchange rates          |

## Configuring rules for multi-currency

***

Enable multi-currency comparison by setting `matchBaseAmount` and `matchBaseCurrency` to `true` in the rule config.

### Exact rule with base amount matching

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/contexts/{contextId}/rules" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "type": "EXACT",
   "priority": 1,
   "config": {
     "matchBaseAmount": true,
     "matchBaseCurrency": true,
     "matchDate": true,
     "matchReference": false,
     "matchScore": 100,
     "matchBaseScore": 90
   }
 }'
```

When `matchBaseAmount` is `true`, the rule compares `amountBase` fields instead of `amount`. When `matchBaseCurrency` is `true`, it compares `currencyBase` instead of `currency`.

### Tolerance rule with base amount matching

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/contexts/{contextId}/rules" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "type": "TOLERANCE",
   "priority": 2,
   "config": {
     "matchBaseAmount": true,
     "matchBaseCurrency": true,
     "percentTolerance": 0.02,
     "absTolerance": 10.0,
     "matchScore": 85,
     "matchBaseScore": 80
   }
 }'
```

### Confidence scoring

When a rule matches on base amounts, the confidence score uses `matchBaseScore` instead of `matchScore`. This allows you to assign lower confidence to FX-converted matches to reflect the additional uncertainty.

| Match type            | Default score                        |
| --------------------- | ------------------------------------ |
| Original amount match | `matchScore` (e.g. 100 for EXACT)    |
| Base amount match     | `matchBaseScore` (e.g. 90 for EXACT) |

## FX source integration

***

Matcher defines an `FXSource` port interface for fetching exchange rates at runtime. You can implement this interface to connect any FX rate provider to Matcher.

```go theme={null}
// FXSource port interface (internal/matching/ports/fx_source.go)
type FXSource interface {
    GetRate(ctx context.Context, from, to string, date time.Time) (Rate, error)
}
```

### Using the FX source

1. Implement the `FXSource` interface with your preferred rate provider.
2. Register the implementation at application startup.

<Info>
  The FX source integration is optional. If not configured, multi-currency matching relies on pre-converted `amountBase` and `currencyBase` fields provided at ingestion time.
</Info>

## Transaction fields

***

For multi-currency matching, transactions should include both original and base currency fields:

| Field          | Type    | Description                       |
| -------------- | ------- | --------------------------------- |
| `amount`       | Decimal | Original transaction amount       |
| `currency`     | String  | Original ISO 4217 currency code   |
| `amountBase`   | Decimal | Amount converted to base currency |
| `currencyBase` | String  | Base currency ISO 4217 code       |

### Example transaction

```json theme={null}
{
  "transaction_id": "txn_001",
  "amount": 1000.00,
  "currency": "EUR",
  "amountBase": 1085.00,
  "currencyBase": "USD",
  "date": "2024-01-15",
  "reference": "PAY-2024-001"
}
```

## Example: cross-currency reconciliation

***

**Source (EUR account):**

| ID       | Amount   | Currency | Base Amount | Base Currency |
| -------- | -------- | -------- | ----------- | ------------- |
| txn\_001 | 1,000.00 | EUR      | 1,085.00    | USD           |

**Target (USD account):**

| ID       | Amount   | Currency | Base Amount | Base Currency |
| -------- | -------- | -------- | ----------- | ------------- |
| txn\_002 | 1,095.00 | USD      | 1,095.00    | USD           |

With a TOLERANCE rule (`matchBaseAmount: true`, `percentTolerance: 0.02`):

* Base amounts: $1,085.00 vs $1,095.00
* Variance: \$10.00 (0.92%)
* Tolerance: 2%
* Result: **Match** (0.92% \< 2%)

## Best practices

***

<AccordionGroup>
  <Accordion title="Pre-convert amounts at ingestion">
    Populate amountBase and currencyBase during file upload or ingestion. This avoids runtime FX lookups and ensures reproducible results.
  </Accordion>

  <Accordion title="Use matchBaseScore to reflect FX uncertainty">
    Set matchBaseScore lower than matchScore so that FX-converted matches receive lower confidence, flagging them for review when appropriate.
  </Accordion>

  <Accordion title="Combine with tolerance rules">
    FX conversions introduce small variances. Use TOLERANCE rules with matchBaseAmount to allow for rounding and rate timing differences.
  </Accordion>

  <Accordion title="Document your base currency choice">
    Use a consistent base currency across all contexts. USD is common for international operations; use your reporting currency for domestic + international.
  </Accordion>
</AccordionGroup>

## Next steps

***

<CardGroup cols={2}>
  <Card title="Confidence Scoring" icon="chart-simple" href="/en/matcher/reference/matcher-confidence-scoring">
    How match scores work and what thresholds apply.
  </Card>

  <Card title="Match Rules" icon="scale-balanced" href="/en/matcher/configuration/matcher-match-rules">
    Full reference for rule types and config fields.
  </Card>
</CardGroup>
