Files
formipay/MULTICURRENCY_AUDIT.md
dwindown af2b3c2bf4 docs: add multicurrency implementation audit
- Comprehensive trace of multicurrency functionality
- Identified gaps: frontend currency selector, ExchangeRateAPI implementation, conversion logic
- Documented defects: hardcoded IDR, empty API class, missing Bank Transfer currency column
- Provided implementation order and testing checklist
2026-04-18 11:04:48 +07:00

12 KiB
Raw Permalink Blame History

Formipay — Multicurrency Implementation Audit

Date: April 18, 2026 Scope: Complete trace of multicurrency functionality Purpose: Identify gaps, defects, and opportunities before Phase 4 implementation


Executive Summary

The multicurrency system has a solid foundation in the admin (settings UI, data structures, per-currency pricing) but is incomplete for end-users. The framework exists but critical pieces are missing: frontend currency selection, exchange rate API integration, and actual conversion logic.

Status: 🟡 Partial — Works in admin, broken on frontend


1. What Works

1.1 Admin Settings & Configuration

Location: includes/Settings.php lines 56-133

Feature Status Details
Enable/disable toggle enable_multicurrency checkbox
Currency management multicurrencies repeater with full config
Default currency default_currency setting
Per-currency decimals Custom decimal_digits, decimal_symbol, thousand_separator
Exchange rate fields Manual rate input (API integration non-functional)
Gateway association Link currencies to payment gateways

Data Structure: Currencies stored as code:::name:::symbol (e.g., USD:::United States Dollar:::$)

1.2 Currency Data Source

Location: admin/assets/json/currencies.json

  • 196 currencies available
  • Loaded via formipay_currency_array()
  • Cached via static variable (F1.13 optimization)
  • Includes code, name, symbol, flag

1.3 Product Pricing Per Currency

Location: includes/Product.php lines 386-432

Products can have different prices for each currency:

  • Static items: amount_{currency_code} field
  • Default currency price: setting_product_price_regular_{code}
  • Sale price: setting_product_price_sale_{code}

1.4 Price Formatting

Location: admin/functions.php lines 179-200

formipay_price_format() properly handles:

  • Product-specific currency metadata
  • Custom decimal digits, symbols, separators
  • Format: {symbol} {formatted_number}

2. What's Broken/Incomplete

2.1 Frontend Currency Selection — MISSING

Problem: Users have NO way to select currency on forms.

What exists:

  • formipay.currency_code hardcoded to 'IDR' in form-action.js:224
  • Currency data passed to admin via wp_localize_script() (Form.php:1289-1292)
  • No UI element rendered on frontend forms

Impact: Multicurrency is admin-only; frontend users always see default currency prices.

2.2 Exchange Rate API — EMPTY CLASS

Location: includes/Integration/ExchangeRateAPI.php

Status: Completely empty class (8 lines total):

class ExchangeRateAPI extends Payment {
    use SingletonTrait;
    protected function __construct() {
        parent::__construct();
        // Empty - no implementation
    }
}

What's missing:

  • No API integration (ExchangeRate-API.io, Fixer.io, etc.)
  • No rate fetching logic
  • No caching mechanism
  • No error handling
  • Settings UI exists but non-functional

2.3 Currency Conversion Logic — NOT IMPLEMENTED

Problem: No actual conversion calculations anywhere.

What exists:

  • Framework for per-currency prices in products
  • Manual exchange rate fields in settings (unused)
  • formipay_price_format() displays but doesn't convert

Missing:

  • Conversion calculation functions
  • Dynamic price switching based on user selection
  • Conversion indicators on frontend

2.4 Bank Transfer — Missing Currency Tracking

Location: includes/Payment/BankTransfer.php create_db()

Problem: Bank transfer transaction table has NO currency column:

CREATE TABLE `formipay_bank_transfer_trx` (
    ...
    `total` float(10, 2) DEFAULT 0,
    -- Missing: `currency_code` text
    ...
)

Impact: Can't determine which currency was used for bank transfer payments.

2.5 Order Storage — Inconsistent

Gateway Currency Stored Location
PayPal currency_code Paypal.php:84
Bank Transfer Missing
General ⚠️ $this->currency Order.php:95 (not in DB schema)

3. Gaps & Missing Features

3.1 Critical Gaps

# Gap Impact Priority
1 Frontend currency selector Users can't choose currency 🔴 High
2 ExchangeRateAPI implementation No live rates 🔴 High
3 Conversion calculation logic Prices don't convert 🔴 High
4 Bank Transfer currency tracking Data loss 🟡 Medium
5 Dynamic price display on frontend Always shows default currency 🔴 High

3.2 Data Flow Gaps

Expected Flow:
User selects currency → Fetch exchange rate → Convert prices → Display converted prices

Actual Flow:
User selects currency → [NOT IMPLEMENTED] → [NOT IMPLEMENTED] → Shows default currency only

3.3 Missing Validation

  • No currency validation on form submission
  • No check if selected currency is in allowed currencies
  • No validation that required currencies have prices set

4. Defects & Bugs

4.1 Critical Bugs

# Bug Location Impact
1 formipay.currency_code hardcoded to 'IDR' public/assets/js/form-action.js:224 Frontend always uses IDR
2 ExchangeRateAPI class is empty includes/Integration/ExchangeRateAPI.php Settings UI does nothing
3 Bank transfer has no currency column includes/Payment/BankTransfer.php:40-50 Lost currency data

4.2 Minor Issues

# Issue Location
1 Fallback pattern conflicts Multiple files
2 No currency flag in frontend Render.php
3 Mixed code/symbol usage Inconsistent display

5. Architecture & Data Flow

5.1 Current Architecture

┌─────────────────────────────────────────────────────┐
│  Admin Settings (WPCFTO)                              │
│  - enable_multicurrency toggle                          │
│  - multicurrencies[] repeater (currencies + rates)      │
│  - default_currency                                    │
└─────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────┐
│  Product Editor (Vue)                                 │
│  - Per-currency pricing fields                          │
│  - Variation pricing per currency                      │
└─────────────────────────────────────────────────────┘
                          │
                          ▼
┌<>─────────────────────────────────────────────────────┐
│  Form Rendering (PHP SSR)                             │
│  - formipay.currency_code = 'IDR' (HARDCODED ❌)       │
│  - formipay_price_format($amount, $post_id)           │
│  - Shows: {symbol} {formatted_amount}                 │
└─────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────┐
│  Order Storage                                         │
│  - PayPal: has currency_code ✅                        │
│  - Bank Transfer: no currency ❌                         │
│  - General: $this->currency (not in DB) ⚠️            │
└─────────────────────────────────────────────────────┘

5.2 Data Structures

Currency Format: code:::name:::symbol

  • Example: USD:::United States Dollar:::$
  • Example with symbol: IDR:::Indonesian Rupiah:::Rp

Product Price Storage:

// Per currency (static items)
$static_item['amount_USD'] = '29.99';
$static_item['amount_IDR'] = '450000';

// Default currency
get_post_meta($post_id, 'product_currency'); // "USD:::..."
get_post_meta($post_id, 'product_currency_decimal_digits'); // 2

Order Currency Storage:

// PayPal (correct)
$currency_code = $currency_parts[0]; // 'USD'

// Bank Transfer (missing)
// No currency stored ❌

6. Opportunities for Improvement

6.1 High Priority (Phase 4)

# Opportunity Benefit Effort
1 Frontend currency dropdown selector Users can finally use multicurrency Medium
2 Complete ExchangeRateAPI with live rates Accurate pricing, manual entry backup Medium
3 Currency conversion calculation layer Dynamic pricing, better UX Medium
4 Add currency column to Bank Transfer table Data completeness Low
5 Real-time price updates on currency change Better UX, clearer pricing Medium

6.2 Medium Priority

# Opportunity Benefit Effort
1 Currency flag icons in frontend Visual clarity, UX improvement Low
2 Currency validation on form submit Data integrity Low
3 Conversion rate history/audit trail Accounting, debugging Medium
4 Multi-currency reports in dashboard Business insights Medium
5 Auto-fetch rates on schedule Always-current rates without manual entry Low

6.3 Nice-to-Have

# Opportunity Benefit
1 Display original + converted prices (e.g., "$29.99 (~Rp 450.000)") Transparency
2 Currency switcher widget (cookies remember preference) UX convenience
3 GEO IP detection to auto-select currency Personalization
4 Admin-side currency conversion calculator Admin convenience
5 Support for 3+ decimal currencies (e.g., cryptocurrencies) Future-proofing

Phase 4A — Core Multicurrency (Weeks 11-12)

1. Frontend currency selector dropdown
2. ExchangeRateAPI implementation (one API provider)
3. Conversion calculation functions
4. Fix Bank Transfer currency column
5. Dynamic price display on forms

Phase 4B — Enhanced Features (Weeks 15-16)

6. Currency validation
7. Conversion rate history
8. Multi-currency dashboard reports
9. GEO IP auto-detection
10. Admin conversion calculator

8. Code Locations Reference

File Lines Purpose
includes/Settings.php 56-133 Multicurrency settings UI
admin/functions.php 28-36, 47-81, 179-200, 202-218 Currency utility functions
admin/assets/json/currencies.json Currency data source (196 currencies)
public/assets/js/form-action.js 224 Currency code (hardcoded bug)
includes/Product.php 386-432 Product pricing per currency
includes/Order.php 95 Order currency property
includes/Integration/Paypal.php 75, 84 PayPal currency handling
includes/Payment/BankTransfer.php 40-50 Bank transfer schema (missing currency)
includes/Integration/ExchangeRateAPI.php all Empty class (needs implementation)

9. Testing Checklist

When implementing multicurrency features:

  • Enable multicurrency in settings
  • Add 3+ currencies
  • Set prices for default currency
  • Set prices for additional currencies
  • Submit form with each currency selected
  • Verify order currency stored correctly
  • Verify payment gateway receives correct currency
  • Test ExchangeRateAPI rate fetching
  • Test manual exchange rate override
  • Test price conversion calculations
  • Test currency formatting display
  • Test Bank Transfer with currency column
  • Test frontend currency dropdown
  • Test GEO IP auto-detection (if implemented)

End of Multicurrency Audit.