| # Exchange Rate Management Guide | |
| ## Overview | |
| **Paystack does NOT automatically adapt to exchange rate fluctuations.** Paystack processes all payments in Naira (NGN) - the local currency. Exchange rate conversion is handled by our backend system. | |
| ## Current Implementation | |
| The system now uses **dynamic exchange rates** that automatically fetch the current NGN to USD rate from external APIs, with intelligent caching and fallback mechanisms. | |
| ## How It Works | |
| ### 1. Exchange Rate Fetching | |
| When a payment is processed, the system: | |
| 1. Checks cache (1-hour cache duration) | |
| 2. If cache expired or missing, fetches from external API | |
| 3. Falls back to fixed rate if APIs fail | |
| ### 2. Rate Sources (Priority Order) | |
| 1. **ExchangeRate-API** (Free, no API key needed) | |
| - URL: `https://api.exchangerate-api.com/v4/latest/USD` | |
| - Rate limit: Generous free tier | |
| - Reliability: High | |
| 2. **CurrencyAPI** (Free tier available) | |
| - Requires: `CURRENCY_API_KEY` environment variable | |
| - More reliable, better rate limits | |
| - Sign up at: https://currencyapi.com | |
| 3. **Fixer.io** (Paid, but very reliable) | |
| - Requires: `FIXER_API_KEY` environment variable | |
| - Best for production | |
| - Sign up at: https://fixer.io | |
| 4. **Fallback Rate** | |
| - Uses `NGN_PER_USD` from `.env` (default: 750) | |
| - Used when all APIs fail | |
| ## Configuration | |
| ### Basic Setup (No API Keys) | |
| Works out of the box with ExchangeRate-API (free): | |
| ```env | |
| NGN_PER_USD=750 # Fallback rate if APIs fail | |
| ``` | |
| ### Recommended Setup (With API Keys) | |
| For better reliability, add one or more API keys: | |
| ```env | |
| # Primary: CurrencyAPI (recommended) | |
| CURRENCY_API_KEY=your_currencyapi_key_here | |
| # Alternative: Fixer.io (if you have it) | |
| FIXER_API_KEY=your_fixer_key_here | |
| # Fallback (always required) | |
| NGN_PER_USD=750 | |
| ``` | |
| ## How Rates Are Used | |
| ### Payment Flow | |
| 1. **User funds wallet** with 1000 NGN | |
| 2. **System fetches current rate** (e.g., 850 NGN/USD) | |
| 3. **Converts to USD**: 1000 / 850 = $1.18 | |
| 4. **Converts to points**: $1.18 / $0.05 = 23.6 β 24 points | |
| ### Rate Locking | |
| - **At payment initiation**: Rate is calculated and stored in metadata | |
| - **At payment verification**: Rate is recalculated (may differ slightly) | |
| - **Final rate**: Uses the rate at verification time (more accurate) | |
| ## Cache Management | |
| ### Cache Duration | |
| - **1 hour** by default | |
| - Prevents excessive API calls | |
| - Balances accuracy vs. API rate limits | |
| ### Cache Behavior | |
| - Cache is checked before API calls | |
| - Cache is updated after successful API fetch | |
| - Cache is cleared on server restart | |
| ### Manual Cache Clear | |
| ```typescript | |
| // In code | |
| exchangeRateService.clearCache(); | |
| ``` | |
| ## Rate Fluctuation Handling | |
| ### Scenario 1: NGN Depreciates (Rate goes up) | |
| - Example: 750 β 850 NGN/USD | |
| - Impact: Users get **fewer points** for same NGN amount | |
| - Example: 1000 NGN = 26 points (at 750) vs 23 points (at 850) | |
| ### Scenario 2: NGN Appreciates (Rate goes down) | |
| - Example: 750 β 650 NGN/USD | |
| - Impact: Users get **more points** for same NGN amount | |
| - Example: 1000 NGN = 26 points (at 750) vs 30 points (at 650) | |
| ### Why This Matters | |
| - **Fixed rate (old)**: Always gives same points regardless of real exchange rate | |
| - **Dynamic rate (new)**: Adjusts automatically, keeps pricing accurate | |
| ## Monitoring | |
| ### Check Current Rate | |
| ```typescript | |
| const rate = await exchangeRateService.getNGNToUSDRate(); | |
| console.log('Current rate:', rate); | |
| ``` | |
| ### Log Rate in Transactions | |
| Rates are stored in transaction metadata: | |
| ```json | |
| { | |
| "fx": 850, | |
| "pointValueUsd": 0.05, | |
| "amountInNaira": 1000, | |
| "amountInDollars": 1.18 | |
| } | |
| ``` | |
| ## Best Practices | |
| ### 1. Use Fallback Rate | |
| Always set `NGN_PER_USD` in `.env` as a safety net: | |
| ```env | |
| NGN_PER_USD=750 # Update monthly or as needed | |
| ``` | |
| ### 2. Monitor Rate Changes | |
| - Check logs for rate fetching failures | |
| - Update fallback rate quarterly | |
| - Consider paid API for production | |
| ### 3. Handle Rate Discrepancies | |
| - Small differences between initiation and verification are normal | |
| - System uses verification-time rate (more accurate) | |
| - Both rates stored in metadata for audit | |
| ### 4. Production Recommendations | |
| - Use CurrencyAPI or Fixer.io for reliability | |
| - Monitor API rate limits | |
| - Set up alerts for API failures | |
| - Update fallback rate monthly | |
| ## Troubleshooting | |
| ### APIs Failing | |
| If all APIs fail: | |
| 1. Check internet connectivity | |
| 2. Verify API keys (if using) | |
| 3. Check rate limits | |
| 4. System automatically uses fallback rate | |
| ### Rate Too High/Low | |
| If rate seems incorrect: | |
| 1. Check cache (might be stale) | |
| 2. Verify API is working | |
| 3. Check fallback rate in `.env` | |
| 4. Clear cache and retry | |
| ### Rate Not Updating | |
| 1. Check cache duration (1 hour default) | |
| 2. Restart server to clear cache | |
| 3. Verify API is returning fresh data | |
| ## Alternative Approaches | |
| ### Option 1: Fixed Rate (Old) | |
| - Simple but inaccurate | |
| - Requires manual updates | |
| - Use if APIs are unreliable | |
| ### Option 2: Dynamic Rate (Current) | |
| - Automatic updates | |
| - More accurate | |
| - Requires API access | |
| ### Option 3: Fixed at Payment Time | |
| - Lock rate when payment initiated | |
| - More predictable for users | |
| - Requires storing rate in payment metadata | |
| ### Option 4: Manual Update | |
| - Admin updates rate daily/weekly | |
| - Most control | |
| - Requires admin interface | |
| ## API Key Setup | |
| ### CurrencyAPI (Recommended) | |
| 1. Sign up: https://currencyapi.com | |
| 2. Get free API key | |
| 3. Add to `.env`: `CURRENCY_API_KEY=your_key` | |
| ### Fixer.io | |
| 1. Sign up: https://fixer.io | |
| 2. Choose plan (free tier available) | |
| 3. Add to `.env`: `FIXER_API_KEY=your_key` | |
| ## Summary | |
| β **Paystack processes in NGN** - no exchange rate handling | |
| β **Our system handles conversion** - NGN β USD β Points | |
| β **Dynamic rates** - automatically fetched from APIs | |
| β **Intelligent caching** - 1-hour cache, prevents excessive calls | |
| β **Fallback protection** - uses fixed rate if APIs fail | |
| β **Rate stored in metadata** - for audit and transparency | |
| The system now automatically adapts to exchange rate fluctuations while maintaining reliability through caching and fallback mechanisms. | |