Currency Conversion Blueprint
Convert amounts between currencies using live or cached exchange rates
| Feature | currency-conversion |
| Category | Payment |
| Version | 1.0.0 |
| Tags | currency, exchange-rate, multi-currency, localization, payment, finance |
| YAML Source | View on GitHub |
| JSON API | currency-conversion.json |
Fields
| Name | Type | Required | Label | Description |
|---|---|---|---|---|
from_currency | text | Yes | From Currency | Validations: required, pattern |
to_currency | text | Yes | To Currency | Validations: required, pattern |
amount | number | Yes | Amount | Validations: required, min, max |
converted_amount | number | No | Converted Amount | |
exchange_rate | number | No | Exchange Rate | |
rate_source | select | No | Rate Source | |
rate_timestamp | datetime | No | Rate Timestamp |
Rules
- rate_cache:
- ttl_seconds: 3600
- fallback_to_last_known: true
- max_stale_hours: 24
- supported_currencies:
- base_currency: USD
- list: USD, EUR, GBP, JPY, CAD, AUD, CHF, CNY, INR, BRL, ZAR, SGD, HKD, KRW, MXN, NZD, SEK, NOK, DKK, PLN
- rounding:
- method: bankers
- decimal_places: 2
- zero_decimal_currencies: JPY, KRW
- display:
- format_per_locale: true
- show_currency_symbol: true
- show_rate_source: false
- settlement:
- currency: USD
- convert_on_capture: true
Outcomes
Unsupported_currency (Priority: 1) — Error: CONVERSION_UNSUPPORTED_CURRENCY
Given:
- ANY:
from_currency(input) not_inUSD,EUR,GBP,JPY,CAD,AUD,CHF,CNY,INR,BRL,ZAR,SGD,HKD,KRW,MXN,NZD,SEK,NOK,DKK,PLNORto_currency(input) not_inUSD,EUR,GBP,JPY,CAD,AUD,CHF,CNY,INR,BRL,ZAR,SGD,HKD,KRW,MXN,NZD,SEK,NOK,DKK,PLN
Result: show “Currency not supported. Please select a supported currency.”
Same_currency (Priority: 2) — Error: CONVERSION_SAME_CURRENCY
Given:
from_currency(input) eqto_currency
Result: return original amount with exchange rate 1.0
Rate_unavailable (Priority: 3) — Error: CONVERSION_RATE_UNAVAILABLE
Given:
exchange_rate(computed) not_existsrate_timestamp(db) ltnow - 24h
Then:
- emit_event event:
rate.fetch_failed
Result: show “Exchange rate temporarily unavailable. Please try again later.”
Rate_stale_fallback (Priority: 4)
Given:
exchange_rate(computed) not_existsrate_timestamp(db) gtenow - 24h
Then:
- set_field target:
rate_sourcevalue:fallback - emit_event event:
rate.fallback_used
Result: convert using last known cached rate with fallback indicator
Successful_conversion (Priority: 10) | Transaction: atomic
Given:
from_currency(input) inUSD,EUR,GBP,JPY,CAD,AUD,CHF,CNY,INR,BRL,ZAR,SGD,HKD,KRW,MXN,NZD,SEK,NOK,DKK,PLNto_currency(input) inUSD,EUR,GBP,JPY,CAD,AUD,CHF,CNY,INR,BRL,ZAR,SGD,HKD,KRW,MXN,NZD,SEK,NOK,DKK,PLNamount(input) gt0exchange_rate(computed) exists
Then:
- set_field target:
converted_amountvalue:amount * exchange_rate - set_field target:
rate_sourcevalue:live - emit_event event:
conversion.executed
Result: return converted amount with rate details and formatted display
Errors
| Code | Status | Message | Retry |
|---|---|---|---|
CONVERSION_UNSUPPORTED_CURRENCY | 400 | The selected currency is not supported | No |
CONVERSION_SAME_CURRENCY | 400 | Source and target currencies must be different | No |
CONVERSION_RATE_UNAVAILABLE | 503 | Exchange rate temporarily unavailable. Please try again later. | Yes |
CONVERSION_INVALID_AMOUNT | 422 | Please enter a valid amount | Yes |
CONVERSION_VALIDATION_ERROR | 422 | Please check your input and try again | Yes |
Events
| Event | Description | Payload |
|---|---|---|
rate.updated | Exchange rate cache refreshed from external source | from_currency, to_currency, old_rate, new_rate, rate_source, timestamp |
conversion.executed | Currency conversion completed successfully | from_currency, to_currency, amount, converted_amount, exchange_rate, rate_source, rate_timestamp, timestamp |
rate.fetch_failed | Failed to fetch live exchange rate from provider | from_currency, to_currency, timestamp, error_reason |
rate.fallback_used | Conversion used cached fallback rate instead of live rate | from_currency, to_currency, rate_timestamp, exchange_rate |
Related Blueprints
| Feature | Relationship | Reason |
|---|---|---|
| cart-checkout | recommended | Cart totals may need multi-currency display |
| invoicing-payments | recommended | Invoices in foreign currencies require conversion for settlement |
| payment-gateway | optional | Gateway may handle conversion at capture time |
AGI Readiness
Goals
Reliable Currency Conversion
Convert amounts between currencies using live or cached exchange rates
Success Metrics:
| Metric | Target | Measurement |
|---|---|---|
| policy_violation_rate | 0% | Operations that violate defined policies |
| audit_completeness | 100% | All decisions have complete audit trails |
Constraints:
- regulatory (non-negotiable): All operations must be auditable and traceable
Autonomy
Level: supervised
Human Checkpoints:
- before making irreversible changes
Escalation Triggers:
error_rate > 5consecutive_failures > 3
Verification
Invariants:
- error messages never expose internal system details
Tradeoffs
| Prefer | Over | Reason |
|---|---|---|
| accuracy | speed | financial transactions must be precise and auditable |
Safety
| Action | Permission | Cooldown | Max Auto |
|---|---|---|---|
| unsupported_currency | autonomous | - | - |
| same_currency | autonomous | - | - |
| rate_unavailable | autonomous | - | - |
| rate_stale_fallback | autonomous | - | - |
| successful_conversion | autonomous | - | - |