Multi-Currency Projects in Laravel/PHP: 3 Ways to Structure

For multi-currency projects, there's no single solution. In this tutorial, we'll take a look at different approaches to this problem: DB schema, currency rate calculation, and more.

We will compare three models for PHP/Laravel projects:

  • Converting Currencies in Real-Time
  • Store Prices per Currency: Prestashop Example
  • Mixed Approach: Building a Multi-Currency System

Let's go!


Converting Currencies in Real-Time

When attempting to find a solution for this - you might encounter a suggestion to use real-time currency exchange API. This approach looks into converting your base currency (like USD or EUR) to another currency based on a real-time exchange rate.

General Workflow Would Look Something Like this:

  • You have a base currency (like USD or EUR)
  • You have a currency that you want to convert to (like GBP)
  • You call the API to get the exchange rate for the currency you want to convert to (or in some cases already converted amount)
  • You show the price in the currency that the user requested (either by multiplying the price by the exchange rate, or by using the already converted amount)
  • You store the price in the currency that the user requested
  • You store the exchange rate that you used to convert the price (to be able to convert it back to the base currency)

Of course, there are many things that you need to save/modify in your database:

  • Have allowed currencies list (like USD, EUR, GBP, etc.)
  • Save the currency that the user requested (like GBP) in the database - Two simple columns should do it charged_currency and charged_amount.
  • Save the exchange rate that you used to convert the price (like 0.8) - Two simple columns should do it exchange_rate and exchange_rate_date.
  • Save the original currency (like USD) - Two simple columns should do it original_currency and original_amount.

How Does It Look in the Database?

Your migration might look something like this:

Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->integer('price');
$table->timestamps();
});
 
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->integer('original_price');
$table->string('original_currency');
$table->integer('charged_price');
$table->string('charged_currency');
$table->float('exchange_rate')->nullable();
$table->timestamps();
});
 
Schema::create('order_products', function (Blueprint $table) {
$table->id();
$table->foreignId('order_id')->constrained();
$table->foreignId('product_id')->constrained();
$table->integer('original_price');
$table->string('original_currency');
$table->integer('charged_price');
$table->string('charged_currency');
$table->float('exchange_rate')->nullable();
$table->integer('quantity')->default(1);
$table->timestamps();
});

Which would result in a database schema like this:

Pay attention to the saving of original currency and...

The full tutorial [12 mins, 2395 words] is only for Premium Members

Login Or Become a Premium Member for $129/year or $29/month
What else you will get:
  • 42 courses (796 lessons, total 45 h 33 min)
  • 49 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials