Currency ManagementExchange Rate Sync

Exchange Rate Sync

BillHive automatically fetches and stores exchange rates from an external provider using a scheduled batch job. This ensures that currency conversions in billing and reporting always reflect recent market rates.

Data Source

PropertyValue
ProviderOpenExchangeRates
EndpointGET /api/latest.json?app_id={appId}
Base CurrencyUSD (provider default)
Target CurrenciesEUR, INR, AUD, CAD
Update FrequencyEvery 6 hours (4 daily slots)

Schedule

The batch service runs on the following cron schedule (Asia/Kolkata timezone):

SlotTime (IST)Cron Expression
100:00 (Midnight)0 0 * * *
206:00 (Morning)0 6 * * *
312:00 (Noon)0 12 * * *
418:00 (Evening)0 18 * * *

API Response Format

The OpenExchangeRates API returns exchange rates in the following format:

{
  "base": "USD",
  "rates": {
    "EUR": 0.9234,
    "INR": 82.5100,
    "AUD": 1.4500,
    "CAD": 1.3500
  }
}

Transformed Data

The batch service transforms the raw API response into individual records before persisting:

{
  "baseCurrency": "USD",
  "targetCurrency": "EUR",
  "exchangeRate": 0.9234
}

Each currency pair is stored as a separate record in the currency_conversions table. Exchange rates are stored with 4-decimal precision.

Service Details

ExchangeRateService

Located in batch-service/src/services/exchange-rate.service.ts, this service provides two methods:

MethodDescription
getExchangeRates(appId)Makes an HTTP GET request to the OpenExchangeRates API and returns the raw response
transformExchangeRates(data)Iterates through the API rates and creates an array of { baseCurrency, targetCurrency, exchangeRate } objects

SubscriptionService (Proxy)

Located in batch-service/src/services/subscription.service.ts, this service acts as a proxy to persist exchange rates:

MethodDescription
addExchangeRate(correlationId, body)Sends a POST request to the subscription-service’s /currency-conversions endpoint to persist a single exchange rate record

Error Handling

  • Each exchange rate record is saved individually in a loop
  • If one record fails to save, the error is logged and the remaining records continue processing
  • The batch job has built-in retry support: 1 attempt with a 5-second fixed backoff delay