Currency Risk Detection and Action Guidance
FX Intelligence monitors the hidden cost of foreign currency invoices: creation time rate snapshots, current value changes, overdue loss alerts, monthly exposure reporting, and optional external action links.
InvoiceGuardHQ Does Not Move Money
This is the most important thing to understand about FX Intelligence. Read it once and it will make everything else clear.
InvoiceGuardHQ is purely an intelligence layer. Full stop.
Think of it like a weather forecast. A weather app tells you it will rain tomorrow. It does not make it rain. It does not stop the rain. It just shows you information so you can decide what to do.
FX Intelligence works the same way. It watches exchange rates, notices when a rate moves against your invoice, calculates exactly how much you are losing, and tells you. That is it.
InvoiceGuardHQ does not hold your funds. It does not touch your money. It does not execute transfers. It does not connect to your bank. It does not need Wise or Airwallex API credentials. It is a data and reporting tool, nothing else.
| Term | What it means inside InvoiceGuardHQ | What it does NOT mean |
|---|---|---|
| Protect this invoice | Opens FX guidance and may show an outbound link to a provider site you choose. | InvoiceGuardHQ does not execute any conversion, transfer, or funded hedge. |
| Protected exposure | Exposure the user manually marked as handled outside InvoiceGuardHQ. | InvoiceGuardHQ did not lock funds, guarantee a rate, or move money. |
| Wise and Airwallex link | An outbound link to the provider site. The user acts directly with that provider. | InvoiceGuardHQ does not hold their API credentials or access their accounts. |
One Rate Feed, Smart Math, Clear Alerts
The entire FX feature depends on a single external data source: ExchangeRate-API. No bank connection. No payment processor. Just an exchange rate feed, stored snapshots, and calculations.
Invoice Creation Risk Warning
The moment a foreign currency invoice is created or imported, an inline risk explanation appears. The user sees what their invoice is worth right now, what it could be worth if payment is delayed, and a link to external guidance if they want to act.
🔴 FX Risk: At current rate (3.71) this invoice is worth ₪11,130. If payment arrives in 30 days and the rate shifts 2%, you receive ₪10,907. Protect this invoice →
Every number in this message is calculated live from data already in the system:
| Field | Meaning | Source |
|---|---|---|
| 3.71 | The live exchange rate fetched from ExchangeRate-API at the moment the invoice is being created. Cached up to one hour. | fx_rates most recent row for this currency pair |
| ₪11,130 | Invoice amount in foreign currency multiplied by the current rate. Here: 3,000 USD × 3.71 = ₪11,130. | Calculated in real time as the user types the amount |
| 30 days | The projection window. Defaults to 30 days. Adjusts to match the invoice payment terms if set. | invoice.payment_terms_days or system default |
| 2% shift | The alert threshold configured in Settings → FX Intelligence. Used as the projection scenario so the user sees their worst case. | merchant_fx_settings.alert_threshold_percentage |
| ₪10,907 | What the invoice is worth if the rate drops 2% before payment. Calculated as: ₪11,130 × (1 − 0.02). | Projection formula, calculated in real time |
| Protect this invoice → | Opens FX guidance and may show an outbound link to an external provider. InvoiceGuardHQ does not execute anything on the user's behalf. | Outbound hyperlink only |
Overdue Invoice FX Alert
When a foreign currency invoice is overdue and the exchange rate has moved against the merchant beyond their alert threshold, InvoiceGuardHQ sends an alert. Late payment is no longer just a cash flow problem, it is now an active, compounding currency loss, and the merchant sees exactly how much per day.
Invoice #1047 is 18 days overdue. In that time the USD/ILS rate has moved 1.4% against you. Current additional loss: ₪156 and growing ₪8 per day. Recommended action: follow up today.
| Field | Meaning | Source |
|---|---|---|
| 18 days overdue | Days elapsed since the invoice payment due date, not since invoice creation. | NOW() − invoice.due_date |
| 1.4% against you | The percentage change in the USD/ILS pair from the rate snapshot taken at invoice creation to the current rate. | invoice_fx_exposure.fx_loss_percentage |
| ₪156 additional loss | The domestic value of the invoice at creation minus the domestic value at the current rate. This is real money lost due to rate movement alone, on top of the late payment. | invoice_fx_exposure.fx_loss_domestic |
| ₪8 per day | The total loss to date divided by the number of days since the invoice was created. Shows how fast the loss is compounding. | invoice_fx_exposure.daily_loss_rate |
Monthly FX Intelligence Report
On the first of each month, a consolidated digest covers all foreign currency invoicing activity from the previous month. Total exposure, how much was handled externally, how much was absorbed as a real loss, and what that loss means in practical working time.
Last month your invoicing activity carried ₪4,200 in currency exposure. You protected ₪2,800 of it. ₪1,400 was absorbed as FX loss, equivalent to 2.3 additional unbilled hours of your time.
| Field | Meaning | Source |
|---|---|---|
| ₪4,200 exposure | Total value at risk across all open foreign currency invoices during the report period, measured from their creation rate to the rate at month end. | Summed from invoice_fx_exposure records |
| ₪2,800 protected | The portion the user manually marked as handled outside InvoiceGuardHQ. Recordkeeping only. No funds were moved by the app. | fx_monthly_reports.best_protected_amount |
| ₪1,400 absorbed loss | The unprotected exposure that was absorbed as real rate movement loss, calculated against the domestic baseline at invoice creation. | fx_monthly_reports.total_fx_loss_domestic |
| 2.3 unbilled hours | The total FX loss divided by the merchant's configured hourly rate. Converts abstract currency loss into working time so the impact feels real. Only shown when the hourly rate is set in Settings. | ABS(total_fx_loss) / merchant_hourly_rate |
Wise and Airwallex: Optional External Links
When a user sees FX movement and wants to act, InvoiceGuardHQ can show them an outbound link to Wise or Airwallex. The user opens their own provider account and acts directly with that provider. InvoiceGuardHQ is not involved beyond showing the link.
| Capability | Allowed | Notes |
|---|---|---|
| Show provider link | ✓ Yes | Outbound URL to Wise or Airwallex only. |
| Add tracking parameters to outbound link | ✓ Yes | Attribution only. No account access. |
| User opens provider site and acts directly | ✓ Yes | User leaves InvoiceGuardHQ. Any action happens entirely with the provider. |
| Mark exposure as externally handled | ✓ Yes | Recordkeeping only. Useful for the monthly protected vs unprotected breakdown. |
| Collect Wise or Airwallex API credentials | ✗ No | Not needed. Outside product scope permanently. |
| Create a provider quote from InvoiceGuardHQ | ✗ No | Users request quotes directly on the provider site. |
| Execute a conversion or transfer | ✗ No | Outside product scope permanently. |
| Hold funds or custody a balance | ✗ No | Outside product scope permanently. |
Test Data Configuration
Use these values in your local or staging environment to reproduce all three use cases exactly as shown above. No real provider action is required.
Simulate the Invoice Risk Warning
-
1Insert a live USD/ILS rate into the rate cache
Insert a row in
fx_rates: baseUSD, targetILS, rate3.71000000, fetched_at = NOW(). This is the rate the UI will read. -
2Open the Create Invoice form and select USD
Navigate to
/invoices/new. Set currency to USD. The FX risk widget should appear immediately below the amount field. -
3Enter the invoice amount as $3,000
As you type, the widget updates in real time. At $3,000 with rate 3.71 the domestic value shows as ₪11,130. The projected value at a 2% shift shows as ₪10,907.
-
4Verify the "Protect this invoice" link appears
If a provider link is configured in Settings, the outbound link should be visible. Clicking it opens the external provider site in a new tab.
fx_rates or trigger a fetch via POST /api/admin/fx/fetch-rates.
Simulate the Overdue FX Alert
-
1Create a USD invoice that is 18 days overdue
Create an invoice for $3,000 USD. Set the due date to 18 days ago. The creation rate snapshot should record
3.68 USD/ILS, giving a domestic value at creation of ₪11,040. -
2Inject a moved rate to simulate 1.4% loss
Insert a current rate of
3.62880intofx_rateswith fetched_at = NOW(). This represents a 1.4% drop from 3.68: calculated as 3.68 × (1 − 0.014) = 3.629. -
3Trigger exposure recalculation
Call
POST /api/admin/fx/recalculate?invoiceId=1047. The system writes a newinvoice_fx_exposurerecord. Expected values: fx_loss_domestic = ₪156, daily_loss_rate = ₪8 per day, alert_threshold_breached = true. -
4Trigger the alert check
Call
POST /api/admin/fx/check-alerts?merchantId={id}. Because the 1.4% loss exceeds the 1.0% threshold (lower your test threshold to 1.0% in Settings to trigger it), the alert fires and sends the email.
Simulate the Monthly FX Report
-
1Create three USD invoices dated within last month
Invoice A: $2,000 USD. Invoice B: $500 USD. Invoice C: $800 USD. Record the USD/ILS rate at creation for each. Total foreign invoiced: $3,300.
-
2Simulate a rate drop of approximately 1.6%
Insert a current rate that is 1.6% lower than the creation rates in
fx_rates. The scheduler will recalculate exposure on next run and produce a combined FX loss of approximately ₪1,400 across all three invoices. -
3Mark Invoice A as externally protected
Manually set the protected flag on Invoice A's exposure record to simulate the user having handled ₪2,800 of exposure outside InvoiceGuardHQ. This populates the "protected" figure in the report.
-
4Generate the monthly report manually
Call
POST /api/admin/fx/generate-monthly-report?month=2025-04. This bypasses the cron schedule and generates immediately for the specified month. -
5Verify the output
Preview the email at
GET /api/admin/fx/report-preview?month=2025-04. Confirm: exposure ₪4,200, protected ₪2,800, loss ₪1,400, unbilled hours 2.3.
Calculation Logic
Every FX figure shown in InvoiceGuardHQ is derived from these formulas. There is no external financial calculation. All math runs inside the application.
domestic_at_creation = foreign_amount × rate_at_creation
// Current domestic value based on latest fetched rate
domestic_current = foreign_amount × current_rate
// FX movement: negative means loss, positive means gain
fx_loss_domestic = domestic_current − domestic_at_creation
// Loss expressed as a percentage
fx_loss_percentage = (fx_loss_domestic / domestic_at_creation) × 100
// Daily rate of loss
daily_loss_rate = fx_loss_domestic / days_since_invoice
// Equivalent unbilled hours (only when hourly rate is set)
hours_lost = ABS(fx_loss_domestic) / merchant_hourly_rate
// Projected value at creation time risk warning
projected_value = domestic_at_creation × (1 − alert_threshold_pct)
Settings Reference
All FX Intelligence behaviour is controlled from Settings → FX Intelligence.
| Setting | Default | Effect |
|---|---|---|
| Domestic Currency | USD |
All FX exposure and loss figures are displayed in this currency. Set it to match your primary bank account currency. |
| Alert Threshold (%) | 2.00 |
An FX alert fires when the rate has moved this percentage against you. This value is also used as the projection scenario in the invoice creation warning. |
| FX Alerts Enabled | true |
Turning this off stops FX alert emails. Exposure is still tracked and visible on the dashboard. |
| Monthly Report Enabled | true |
Turning this off stops the monthly email report. Data is still generated and visible on the FX Intelligence page. |
| Hourly Rate | Not set | When set, enables the "equivalent unbilled hours" language in the monthly report. Optional but highly recommended as it makes the loss feel tangible. |
| External Provider Preference | None | Controls which optional external link appears on the "Protect this invoice" action. Setting this to Wise or Airwallex shows the corresponding outbound link. InvoiceGuardHQ does not access the provider account. |