Skip to main content

Step 2: Normalize Currency

Convert all transaction amounts to USD while preserving original values. This replaces DataStage Lookup Stages with inline conversion logic.

The Goal​

  • Convert AMOUNT from any currency to USD
  • Preserve original_amount and original_currency for reconciliation
  • Create amount_usd as the normalized field

DataStage Equivalent​

In DataStage, currency conversion typically requires:

  1. Lookup Stage reading from a rates table
  2. Transformer Stage applying the conversion
  3. Database connection to fetch current rates
  4. Caching logic to avoid repeated lookups

Expanso simplifies this with inline rate maps or external API calls.

Implementation​

The canonical reference owns the currency processor, including the branch result mapping that returns converted fields to the original message. Inspect its input and output in the Explorer.

Understanding the Code​

ExpressionWhat It Does
let rates = {...}Define a local variable with rate map
$rates.get(this.CURRENCY)Look up rate by currency code
.or(1.0)Default to 1.0 if currency not found
this.AMOUNT * $rates...Apply the conversion

Why Use branch?​

The branch processor creates an isolated scope:

  • Variables defined with let don't leak to other processors
  • Cleaner separation of concerns
  • Easier debugging and testing

Expected Output​

Use the Explorer checkpoints for the sample input and converted fields.

Production Considerations​

Dynamic Rate Fetching​

For real-time rates, adapt the branch in the canonical reference to call a reviewed rate API. Preserve the original amount and currency before replacing the branch payload with the API response, and retain the result mapping that returns converted fields to the original message.

Rate Caching​

Cache rates to reduce API calls:

- cache:
resource: exchange_rates
operator: get
key: ${! this.CURRENCY }
- mapping: |
root.exchange_rate = content().string().number().catch(1.0)

Handling Unknown Currencies​

Log and flag records with unknown currencies:

- mapping: |
let rates = {
"USD": 1.0,
"EUR": 1.08,
"GBP": 1.27,
"JPY": 0.0067,
"CHF": 1.13,
"CAD": 0.74
}
root = this
root._warnings = if $rates.get(this.CURRENCY).or(null) == null {
this._warnings.or([]).append("Unknown currency: " + this.CURRENCY)
} else {
this._warnings.or([])
}
root.amount_usd = this.AMOUNT * $rates.get(this.CURRENCY).or(1.0)

Next Step​