Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.wiseyield.co/llms.txt

Use this file to discover all available pages before exploring further.

WiseYield has two distinct currency concerns:
  1. Billing currency — what the user pays for their subscription. EUR-denominated, displayed in the buyer’s local currency at checkout.
  2. Operational currency — what gets stored on every financial row (expenses, sales, invoices, etc.) and how aggregations roll up to a single per-farm display currency.

Billing currency

Each pricing tier has a single EUR-denominated product in Dodo Payments. At checkout, Dodo Adaptive Currency renders the EUR amount in the user’s local currency based on the billing.country passed during checkout-session creation. There is no manual currency selector.
ConceptValue
Authoritative product priceEUR
Display at checkoutBuyer’s local currency (auto-detected from country)
Supported display currencies12 groups (auto-detected)
FX cache TTL24 hours
Rate sourcesECB primary, open.er-api.com canary fallback
The pricing page mirrors the same EUR-to-local conversion so the dashboard price and the checkout price match.

Operational currency

Every financial row in the platform carries a currency column (crop_expenses, crop_sales, farm_expenses, farm_income, farmer_invoices, etc.) with USD as the schema-level default. A farm has an optional currency override and a country for fallback inference.

Display currency precedence

When the API rolls aggregations up to a single per-farm “base” currency, it resolves in this order:
  1. farms.currency (explicit override set in farm settings).
  2. Country-derived default via the country → currency map.
  3. USD as final fallback.
This guarantees a coherent total even when a farm was misconfigured or rows were imported with free-form currency codes.

Row-level conversion

Aggregations do not sum raw amounts across different currencies. They convert each row individually using today’s spot rate (EUR-bridged via the rate map), then sum the converted values. A financial endpoint response carries three fields that make the aggregation transparent:
{
  "baseCurrency": "EUR",
  "total": 12345.67,
  "byCurrency": {
    "EUR": { "original": 8000.00, "converted": 8000.00, "rate": 1 },
    "USD": { "original": 4500.00, "converted": 4140.50, "rate": 0.92011 },
    "EGP": { "original": 9000.00, "converted": 205.17, "rate": 0.022797 }
  },
  "unconvertedCurrencies": []
}
  • total — sum of every byCurrency[*].converted, in the resolved base currency.
  • byCurrency — per-original-currency breakdown with the rate that was applied. original is the raw sum; converted is the base-currency value.
  • unconvertedCurrencies — any free-form currency strings (e.g. "eg pounds") that didn’t match a known code. Their amounts are summed at rate=1; surface this list in your UI so the user knows the total under-represents reality.

What “today’s spot rate” means

  • Rates are EUR-base, refreshed daily from ECB.
  • All conversions use the same snapshot for the whole request, so two reads at the same moment return the same total.
  • Historical row-date rates are not yet applied — a row from six months ago is converted at today’s rate. This is acceptable for live P&L; historical accounting exports should be computed at the time of export and stored separately.

Currency in API payloads

Operational endpoints expect and return currency as an ISO 4217 code (USD, EUR, EGP, GBP, …). Free-form strings will round-trip but won’t participate in aggregation correctly — always pass canonical codes when creating financial rows via the API.

See also