Skip to main content
Matcher lets you reconciliation of 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.
Multi-currency matching flow.

Enabling multi-currency


Context configuration

Enable multi-currency matching at the context level:
cURL
curl -X POST "https://api.matcher.example.com/v1/contexts" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "name": "International Treasury Reconciliation",
   "type": "MULTI_CURRENCY",
   "settings": {
     "multi_currency": {
       "enabled": true,
       "base_currency": "USD",
       "fx_rate_source": "external_provider",
       "fx_tolerance_percent": 2.0,
       "fx_tolerance_absolute": 10.0
     }
   }
 }'

Response

{
  "id": "ctx_intl_001",
  "name": "International Treasury Reconciliation",
  "type": "MULTI_CURRENCY",
  "settings": {
    "multi_currency": {
      "enabled": true,
      "base_currency": "USD",
      "fx_rate_source": "external_provider",
      "fx_tolerance_percent": 2.0,
      "fx_tolerance_absolute": 10.0
    }
  },
  "status": "ACTIVE",
  "created_at": "2024-01-15T10:00:00Z"
}

Multi-currency settings

SettingTypeDescription
enabledBooleanEnable multi-currency matching
base_currencyStringISO 4217 code for comparison currency
fx_rate_sourceStringSource for FX rates
fx_tolerance_percentDecimalPercentage tolerance for FX variance
fx_tolerance_absoluteDecimalAbsolute tolerance in base currency
rate_date_strategyStringHow to determine which date’s rate to use
fallback_behaviorStringAction when FX rate unavailable

Base currency


The base currency is used as the common denominator for all comparisons.

Choosing a base currency

ScenarioRecommended BaseRationale
US-based companyUSDMatches reporting currency
EU-based companyEURMatches reporting currency
Multi-region operationsUSDMost liquid, widely available rates
Brazil domestic + internationalBRLMatches local reporting

Changing base currency

Changing the base currency affects all pending matches. Complete or archive existing matches before changing.
curl -X PATCH "https://api.matcher.example.com/v1/contexts/ctx_intl_001" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "settings": {
     "multi_currency": {
       "base_currency": "EUR"
     }
   }
 }'

FX rate sources


Matcher lets you multiple sources for foreign exchange rates.

External provider

Connect to third-party FX rate APIs:
cURL
curl -X PUT "https://api.matcher.example.com/v1/contexts/ctx_intl_001/fx-source" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "type": "external_provider",
   "provider": "openexchangerates",
   "settings": {
     "api_key_id": "secret_fx_001",
     "base_url": "https://openexchangerates.org/api/",
     "cache_duration_minutes": 60,
     "fallback_to_previous_day": true
   }
 }'

Response

{
  "context_id": "ctx_intl_001",
  "fx_source": {
    "type": "external_provider",
    "provider": "openexchangerates",
    "status": "CONNECTED",
    "last_sync": "2024-01-20T10:00:00Z",
    "available_currencies": 170,
    "cache_expires_at": "2024-01-20T11:00:00Z"
  }
}
Supported Providers:
ProviderFeaturesUpdate Frequency
Open Exchange Rates170+ currenciesHourly
Fixer.io170+ currenciesHourly
Currency Layer168 currenciesHourly
XE185+ currenciesReal-time
European Central BankEUR crossesDaily

Midaz asset rate engine (optional)

If you’re using Midaz Ledger, you can query FX rates directly from it:
{
  "type": "midaz",
  "settings": {
    "ledger_id": "ldg_001",
    "rate_type": "spot",
    "fallback_to_closing": true
  }
}
This option is only available if you have Midaz integrated. See Midaz Integration for setup instructions.

Manual entry

Upload rates manually for controlled environments:
cURL
curl -X POST "https://api.matcher.example.com/v1/contexts/ctx_intl_001/fx-rates" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "rates": [
     {
       "from_currency": "EUR",
       "to_currency": "USD",
       "rate": 1.085,
       "effective_date": "2024-01-20",
       "source": "treasury_desk"
     },
     {
       "from_currency": "GBP",
       "to_currency": "USD",
       "rate": 1.27,
       "effective_date": "2024-01-20",
       "source": "treasury_desk"
     }
   ]
 }'

Response

{
  "imported": 2,
  "rates": [
    {
      "id": "rate_001",
      "pair": "EUR/USD",
      "rate": 1.085,
      "effective_date": "2024-01-20"
    },
    {
      "id": "rate_002",
      "pair": "GBP/USD",
      "rate": 1.27,
      "effective_date": "2024-01-20"
    }
  ]
}

Bulk rate upload

For daily rate files from treasury systems:
curl -X POST "https://api.matcher.example.com/v1/contexts/ctx_intl_001/fx-rates/upload" \
 -H "Authorization: Bearer $TOKEN" \
 -F "file=@daily_rates_20240120.csv" \
 -F "format=csv" \
 -F "date_column=effective_date" \
 -F "from_column=from_ccy" \
 -F "to_column=to_ccy" \
 -F "rate_column=rate"

Rate date strategy


Determine which date’s FX rate to use for conversion.

Strategy options

StrategyDescriptionUse Case
earlier_dateUse rate from earlier transaction dateDefault, conservative
later_dateUse rate from later transaction dateWhen settlement date matters
source_dateUse rate from internal source dateWhen internal is authoritative
target_dateUse rate from external source dateWhen external is authoritative
averageAverage of both dates’ ratesReduce single-day volatility

Configure rate date strategy

{
  "settings": {
    "multi_currency": {
      "rate_date_strategy": "earlier_date",
      "rate_time": "closing",
      "timezone": "America/New_York"
    }
  }
}

Rate time options

OptionDescription
openingDay’s opening rate
closingDay’s closing rate (default)
midday12:00 rate
spotReal-time rate at transaction time

Tolerance configuration


Multi-currency matching uses combined tolerance to account for FX fluctuations.

Tolerance formula

converted_amount_a = amount_a * fx_rate_a_to_base
converted_amount_b = amount_b * fx_rate_b_to_base

diff = abs(converted_amount_a - converted_amount_b)
max_amount = max(abs(converted_amount_a), abs(converted_amount_b))

passes = diff <= max(tolerance_absolute, tolerance_percent * max_amount)

Tolerance examples

Example 1: Within Tolerance
TransactionOriginalFX RateBase (USD)
A (EUR)1,000.001.08501,085.00
B (USD)1,095.001.00001,095.00
  • Difference: $10.00 (0.92%)
  • Tolerance: max(10.00,210.00, 2% × 1,095) = max(10.00,10.00, 21.90) = $21.90
  • Result: Match (10.00<=10.00 <= 21.90)
Example 2: Outside Tolerance
TransactionOriginalFX RateBase (USD)
A (EUR)1,000.001.08501,085.00
B (USD)1,150.001.00001,150.00
  • Difference: $65.00 (5.99%)
  • Tolerance: max(10.00,210.00, 2% × 1,150) = max(10.00,10.00, 23.00) = $23.00
  • Result: No Match (65.00>65.00 > 23.00)

Custom tolerance by currency pair

Set different tolerances for volatile currency pairs:
{
  "settings": {
    "multi_currency": {
      "fx_tolerance_percent": 2.0,
      "fx_tolerance_absolute": 10.0,
      "currency_pair_overrides": [
        {
          "pair": "BRL/USD",
          "tolerance_percent": 5.0,
          "tolerance_absolute": 50.0
        },
        {
          "pair": "ARS/USD",
          "tolerance_percent": 10.0,
          "tolerance_absolute": 100.0
        }
      ]
    }
  }
}

Handling missing FX rates


When an FX rate is unavailable, Matcher follows the configured fallback behavior.

Fallback options

BehaviorDescriptionRisk Level
exceptionCreate exception for manual handlingLowest
skipSkip match attempt, continue processingLow
previous_dayUse previous available rateMedium
interpolateEstimate from surrounding datesMedium
failFail the entire jobHighest

Configure fallback

{
  "settings": {
    "multi_currency": {
      "fallback_behavior": "previous_day",
      "max_fallback_days": 3,
      "alert_on_fallback": true
    }
  }
}

Missing rate exception

When fallback is exception, the transaction becomes an exception with specific details:
{
  "exception_id": "exc_fx_001",
  "type": "FX_RATE_UNAVAILABLE",
  "severity": "HIGH",
  "details": {
    "from_currency": "TRY",
    "to_currency": "USD",
    "required_date": "2024-01-20",
    "nearest_available": "2024-01-18",
    "gap_days": 2
  },
  "resolution_options": [
    "Provide manual rate",
    "Use fallback rate from 2024-01-18",
    "Mark as no match"
  ]
}

Provide manual rate for exception

curl -X POST "https://api.matcher.example.com/v1/exceptions/exc_fx_001/resolve" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "resolution_type": "PROVIDE_RATE",
   "fx_rate": 0.0312,
   "rate_source": "manual_treasury",
   "notes": "Rate obtained from treasury desk"
 }'

Confidence scoring impact


Multi-currency matching affects confidence scoring through the currency component.

Currency score calculation

ScenarioCurrency Score
Same currency30/30 (100%)
Different currency, exact FX match28/30 (93%)
Different currency, within 1% FX variance25/30 (83%)
Different currency, within 2% FX variance22/30 (73%)
Different currency, >2% FX variance15-20/30
FX rate unavailable (fallback used)10/30 (33%)

Score example

Multi-currency match with slight FX variance:
{
  "confidence": 82,
  "confidence_breakdown": {
    "amount": {
      "score": 36,
      "weighted_score": 14.4,
      "details": {
        "source_amount": "EUR 1,000.00",
        "target_amount": "USD 1,095.00",
        "converted_source": "USD 1,085.00",
        "variance_percent": 0.91
      }
    },
    "currency": {
      "score": 22,
      "weighted_score": 6.6,
      "details": {
        "source_currency": "EUR",
        "target_currency": "USD",
        "fx_rate_used": 1.085,
        "fx_rate_date": "2024-01-15",
        "fx_variance_from_market": 0.8
      }
    },
    "date": {
      "score": 18,
      "weighted_score": 3.6
    },
    "rule": {
      "score": 10,
      "weighted_score": 1.0
    }
  }
}

Reporting


FX variance report

Track FX-related variances across matches:
curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_intl_001/reports/fx-variance" \
 -H "Authorization: Bearer $TOKEN" \
 -G \
 -d "date_from=2024-01-01" \
 -d "date_to=2024-01-31"
{
  "period": {
    "from": "2024-01-01",
    "to": "2024-01-31"
  },
  "summary": {
    "total_multi_currency_matches": 450,
    "total_fx_variance_amount": 12500.0,
    "average_fx_variance_percent": 1.2,
    "matches_with_fallback_rate": 15
  },
  "by_currency_pair": [
    {
      "pair": "EUR/USD",
      "matches": 200,
      "avg_variance_percent": 0.8,
      "total_variance": 4200.0
    },
    {
      "pair": "GBP/USD",
      "matches": 150,
      "avg_variance_percent": 1.1,
      "total_variance": 5100.0
    },
    {
      "pair": "BRL/USD",
      "matches": 100,
      "avg_variance_percent": 2.1,
      "total_variance": 3200.0
    }
  ],
  "missing_rate_incidents": [
    {
      "date": "2024-01-15",
      "pair": "TRY/USD",
      "resolution": "manual_rate_provided"
    }
  ]
}

Currency exposure summary

curl -X GET "https://api.matcher.example.com/v1/contexts/ctx_intl_001/reports/currency-exposure" \
 -H "Authorization: Bearer $TOKEN"
{
  "base_currency": "USD",
  "exposure_by_currency": [
    {
      "currency": "EUR",
      "unmatched_amount": 125000.0,
      "unmatched_base": 135625.0,
      "transaction_count": 45
    },
    {
      "currency": "GBP",
      "unmatched_amount": 80000.0,
      "unmatched_base": 101600.0,
      "transaction_count": 28
    }
  ],
  "total_unmatched_exposure_base": 237225.0
}

Variable rates by transaction attributes


Advanced Feature: Variable rate matching allows rates to change based on transaction attributes like MCC, card type, transaction method, and merchant segment. This is commonly used in acquiring/card network reconciliation.
In some reconciliation scenarios, particularly in acquiring and card network processing, the applicable rate varies based on multiple transaction attributes rather than being fixed.

Common use cases

Acquiring Reconciliation (Interchange Plus)
  • Rate varies by MCC (Merchant Category Code)
  • Different rates for credit vs. debit cards
  • Segment-based pricing (retail, restaurant, fuel)
  • Transaction method (physical vs. link/online)
Telecommunications
  • Different rates per carrier
  • Rate varies by plan type and region
  • Promotional vs. standard pricing
Multi-Tier Pricing
  • Volume-based rate tiers
  • Customer segment pricing
  • Time-based rate variations

Rate lookup configuration

Configure rate lookup based on transaction metadata:
cURL
curl -X POST "https://api.matcher.example.com/v1/contexts/ctx_acquiring_001/rate-rules" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "name": "Interchange Plus Rate Lookup",
   "rate_type": "variable",
   "lookup_strategy": "multi_attribute",
   "attributes": [
     {
       "field": "metadata.mcc",
       "type": "string",
       "required": true
     },
     {
       "field": "metadata.card_type",
       "type": "string",
       "required": true,
       "values": [
         "credit",
         "debit"
       ]
     },
     {
       "field": "metadata.transaction_method",
       "type": "string",
       "required": true,
       "values": [
         "physical",
         "online",
         "link"
       ]
     }
   ],
   "rate_source": {
     "type": "api",
     "endpoint": "https://rates-api.example.com/interchange/v1/rate",
     "method": "POST",
     "auth_type": "bearer",
     "cache_ttl_seconds": 3600
   },
   "fallback": {
     "strategy": "default_rate",
     "default_rate": 2.5,
     "alert_on_fallback": true
   }
 }'

Mcc-based rate tables

Upload rate tables for common MCC patterns:
cURL
curl -X POST "https://api.matcher.example.com/v1/rate-tables" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "name": "Visa Interchange 2024 Q1",
   "effective_from": "2024-01-01",
   "effective_to": "2024-03-31",
   "rates": [
     {
       "mcc": "5812",
       "mcc_description": "Restaurants",
       "card_type": "credit",
       "transaction_method": "physical",
       "rate": 2.75
     },
     {
       "mcc": "5812",
       "mcc_description": "Restaurants",
       "card_type": "debit",
       "transaction_method": "physical",
       "rate": 1.5
     },
     {
       "mcc": "5411",
       "mcc_description": "Grocery Stores",
       "card_type": "credit",
       "transaction_method": "physical",
       "rate": 1.95
     }
   ]
 }'

Best practices for variable rates

Enable caching for rate API calls to reduce latency. Most rates don’t change within a day.
Use versioned rate tables (e.g., “2024Q1”) and track which version was used for each match.
Network fees can vary slightly. Set tolerance to 1-2% to avoid false exceptions.
Alert when rate lookups fail frequently - may indicate missing MCC codes or API issues.

Best practices


Connect to established FX providers with historical data. Avoid sources with gaps or delayed updates.
Volatile currencies (emerging markets) need higher tolerances. Stable pairs (EUR/USD) can use tighter tolerances.
Record why specific rate sources and strategies were chosen. This helps during audits and troubleshooting.
Configure sensible fallback behavior and alerts. Have a process for providing manual rates when needed.
FX rates can shift between transaction and settlement dates. Choose rate date strategy based on your accounting requirements.

Next steps