medusa-plugin-unirate
v0.1.0
Published
UniRate API exchange-rate integration for Medusa v2 — currency service module, API proxy routes, and VAT rates. Zero runtime deps.
Downloads
162
Maintainers
Readme
medusa-plugin-unirate
UniRate API exchange-rate integration for Medusa v2 — register a currency service module in your Medusa app to get real-time FX rates, currency conversion, historical rates (Pro), and VAT rates, with zero runtime dependencies.
Install
npm install medusa-plugin-unirateGet a free API key at unirateapi.com.
Quick start
1. Register the module in medusa-config.ts
import { defineConfig } from "@medusajs/framework/utils"
export default defineConfig({
// ... your existing config
modules: [
{
resolve: "medusa-plugin-unirate",
options: {
apiKey: process.env.UNIRATE_API_KEY,
baseCurrency: "USD", // default base for getRates() calls
},
},
],
})Or use the typed helper:
import { createUniRateModule } from "medusa-plugin-unirate"
export default defineConfig({
modules: [
createUniRateModule({ apiKey: process.env.UNIRATE_API_KEY }),
],
})2. Use the service in a workflow or API route
import { UNIRATE_MODULE } from "medusa-plugin-unirate"
import type { UniRateCurrencyModuleService } from "medusa-plugin-unirate"
// In a Medusa workflow step:
export const convertCurrencyStep = createStep(
"convert-currency",
async (input: { amount: number; from: string; to: string }, { container }) => {
const unirate = container.resolve<UniRateCurrencyModuleService>(UNIRATE_MODULE)
const converted = await unirate.convert(input.amount, input.from, input.to)
return new StepResponse({ converted })
},
)
// In a custom API route:
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
const unirate = req.scope.resolve<UniRateCurrencyModuleService>(UNIRATE_MODULE)
const rates = await unirate.getRates("USD")
res.json({ base: "USD", rates })
}API reference
All methods are on UniRateCurrencyModuleService, resolved from Medusa's container via UNIRATE_MODULE.
Exchange rates
// All rates relative to a base currency (defaults to module's baseCurrency)
const rates: Record<string, number> = await unirate.getRates()
const rates: Record<string, number> = await unirate.getRates("EUR")
// Single currency pair
const rate: number = await unirate.getRate("USD", "EUR") // e.g. 0.92Conversion
// Convert an amount between two currencies
const result: number = await unirate.convert(100, "USD", "EUR") // e.g. 92.00Currencies
// List all supported currency codes
const currencies: string[] = await unirate.listCurrencies()
// ["USD", "EUR", "GBP", "JPY", ...]Historical rates (Pro)
Historical endpoints require a UniRate Pro subscription.
// Single historical rate
const rate: number = await unirate.getHistoricalRate("2024-01-15", "USD", "EUR")
// All historical rates for a date
const rates: Record<string, number> = await unirate.getHistoricalRates("2024-01-15", "USD")
// Historical conversion
const result: number = await unirate.convertHistorical(500, "USD", "EUR", "2024-01-15")
// Date range series
const series: Record<string, Record<string, number>> = await unirate.getTimeSeries(
"2024-01-01",
"2024-01-07",
"USD", // base (optional, defaults to module's baseCurrency)
["EUR", "GBP"], // filter currencies (optional)
)
// Per-currency data availability
const limits = await unirate.getHistoricalLimits()VAT rates
// All countries
const all = await unirate.getVatRates()
// { total_countries: 50, date: "...", vat_rates: { DE: { vat_rate: 19, ... }, ... } }
// Single country (ISO 3166-1 alpha-2)
const de = await unirate.getVatRates("DE")
// { country: "DE", vat_data: { country_code: "DE", country_name: "Germany", vat_rate: 19 } }Configuration
| Option | Type | Default | Description |
|---|---|---|---|
| apiKey | string | UNIRATE_API_KEY env var | UniRate API key |
| baseCurrency | string | "USD" | Default base for getRates() and time-series calls |
| baseUrl | string | https://api.unirateapi.com | Override the API base URL |
| timeoutMs | number | 30000 | Request timeout in milliseconds |
Error handling
All errors extend UniRateError. Specific subtypes:
| Class | HTTP status | When |
|---|---|---|
| AuthenticationError | 401 | Missing or invalid API key |
| ProRequiredError | 403 | Endpoint requires a Pro subscription |
| InvalidCurrencyError | 404 | Currency not found or no data |
| InvalidRequestError | 400 | Invalid request parameters |
| RateLimitError | 429 | Rate limit exceeded |
| UniRateError | — | Network error or unexpected response |
import { ProRequiredError, UniRateError } from "medusa-plugin-unirate"
try {
const rate = await unirate.getHistoricalRate("2024-01-01", "USD", "EUR")
} catch (err) {
if (err instanceof ProRequiredError) {
// endpoint needs Pro subscription
} else if (err instanceof UniRateError) {
console.error(err.status, err.message)
}
}Related UniRate packages
UniRate client libraries: Python · Node.js · Go · Rust · Ruby · PHP · Java · Swift · .NET
Framework integrations: Next.js · NestJS · SvelteKit · Nuxt · Vue · React · Astro · Eleventy · Hugo · Jekyll
Backend / data integrations: Django · FastAPI · Flask · Wagtail · LangChain · Airflow · dbt · Directus · Laravel
Money library adapters: Ruby Money gem
Tools: CLI · MCP server · VS Code · Obsidian · n8n
License
MIT — see LICENSE.
