All the code found in this article is considered a customisation. As such, it's outside the scope of our support service. Should you need assistance implementing the code, please feel free to contact us to request a consultation.


To use the code in the examples, simply place it in your theme's functions.php. See How to Safely Add Custom Code to WordPress Sites for more information on how to do that.


There are many plugins for WooCommerce that provide additional coupon types, to cater for different needs. The types can be divided in two broad categories:

  • Percentage coupons. These are coupons that give a discount based on a percentage over an amount (order total, product price, etc). Their value is unaffected by the currency, as the X% discount will always be applied to the price is active at the moment. This type of coupon works correctly with the Currency Switcher, without further modifications.
  • Fixed amount coupons. These are coupons which represent a fixed amount (e.g. 10 USD). When the active currency changes, their value must be converted appropriately before being applied to the order. To make the Currency Switcher aware of these new types of coupons, you will have to pass them to the plugin, so that it will convert them as needed. You can find below the instructions to do so.

1. Passing new coupon types to the Currency Switcher
The Currency Switcher implements a hook that can be intercepted with a filter to alter the list of coupon types that should be converted. The filter should accept and return a list of coupons, as in the example below.     
/**
 * Adds new types to the list of coupon types that should be converted by the
 * Currency Switcher.
 *
 * @param array coupon_types A list of coupon types.
 * @return array The list of coupon types, including the new ones.
 */
add_filter('wc_aelia_cs_coupon_types_to_convert', function($coupon_types) {
  // Smart Coupons - Shop coupon
  $coupon_types[] = 'shop_coupon';
  $coupon_types[] = 'smart_coupon';

  // Other coupon types
  $coupon_types[] = 'new_coupon_type';
  $coupon_types[] = 'another_coupon_type';

  return $coupon_types;
}, 10, 1);


How to determine the coupon types to add

The coupon types are just string identifiers, used by the 3rd party coupon plugins to distinguish their own coupons from the standard WooCommerce ones. The best way to find out what coupon types are used by an external plugin is to contact its developer(s). This will ensure that you will get the complete list, with the correct codes.


2. Important notes about "store credit" coupon types

The Smart Coupons plugin, as well as other "coupon" plugins, add a coupon type called "store credit". That coupon is more complex, and it won't be sufficient to just pass it to the Currency Switcher for conversion. The reason is that Smart Coupons doesn't keep track of the currency in which store credit is purchased or spent. This affects the process in multiple ways:


1. Adding store credit

If you buy store credit for "100 USD", Smart Coupons will simply save "100", and assume that such value is in base currency. For example, if your base currency is USD, if store credit is added for 100 USD, 100 EUR, 100 GBP, Smart Coupons will simply save "100" and assume that it's "100 USD".


2. Spending store credit

The same issue described above occurs when spending the coupon. If you have a credit for "100", Smart Coupons will apply that absolute value no matter what the active currency is. Therefore, the credit could be used as 100 USD/GBP/EUR. 


3. Tracking spending

After a coupon has been spent, Smart Coupons tracks the amount, to deduct it from the available credit. The amount is again tracked as an absolute value, and that could cause discrepancies. That is, if you have a store credit of "100" and customer spends "50" of it (which could be 50 USD/GBP/EUR, depending on the active currency), Smart Coupons will track that "50" was used. The store credit balance will then become "50".


The logic described above is internal to the Smart Coupons, and other "coupons" plugins. The Currency Switcher doesn't alter it, because it doesn't know how other plugins work.


2.1 How to handle multi-currency store credit

Handling store credit in multiple currencies involves adding the appropriate calls to the conversion functions within the Smart Coupons plugin.


1. Adding store credit

Check in which currency the store credit was added and convert the amount to shop's base currency before storing it. Examples:

- 100 USD -> 100 USD

- 100 EUR -> 110.73 USD


2. Spending store credit

When the credit is spent, convert the amount to the active currency. For example, if the customer uses 100 USD, the spent amount should be converted to 90.31 EUR.


3. Tracking spent credit
Convert the spent credit to USD before storing the transaction, so that the correct USD amount is deducted from the available total. If the Smart Coupons plugin shows a history of transactions, ideally such history should also show the original currency of each credit and expenditure, so that it's clear what credit was collected and spent in the original currency (e.g. something like "Used credit: 30 EUR (33.22 USD)").


How to implement the above changes

The easiest and most robust way to implement the changes required to handle store credit in multiple currencies would be to add it directly to the Smart Coupons plugin, or whatever "coupon" plugin is used.


An alternative solution, if that plugin provides actions and filters to alter its logic and interfaces, would be to write a customisation for it. The drawback of this approach is that an external integration would be limited to what the main plugin allows, and it could break if the target "coupon" plugin introduces significant changes. This is why, at Aelia, we always encourage 3rd party developers to add native multi-currency support directly to their plugins.


2.2 Store credit handling in the Smart Coupons plugin

Our tests indicate that, out of the box, the Smart Coupons plugin doesn't update the declining balance correctly. Since March 2021, this issue can be patched with a filter, described ad the bottom of this section. 

The following example illustrates the issue:
  1. Shop's base currency is EUR. A "store credit" coupon for 1000 EUR is added.
  2. The customers tries to place an order for 113 CAD and applies the coupon. The coupon amount is converted to CAD (about 1547.66 CAD), then capped to 113 CAD.
  3. The customer completes the order, using 113 CAD from the coupon.
  4. The Smart Coupons plugin doesn't keep a history of the coupon usage. It updates the balance of the coupon directly, by taking the original amount and deducting the total used. In our example, Smart Coupons does the following:
    1. Fetch the original store credit: 1547.66 (in CAD, as that's the active currency. This amount is calculated thanks to the filter described in section #1).
    2. Deduct the used amount, i.e. 113, from the balance. The new coupon balance is 1434.66, and it's still in CAD.
    3. Store the new amount (1434.66, which is still in CAD) against the coupon. This amount should be converted to store's base currency, before being saved.
    4. The coupon has now a balance of 1434.66, which will be interpreted as EUR at the next use: https://prnt.sc/vpq7q3
For this logic to work in a multi-currency environment, the new balance should be converted to store's base currency, which, in our example, would be about 926.96 EUR.

How to ensure that the correct balance is calculated after using some store credit
The Smart Coupons plugin deducts the balance upon the creation of an order. Starting from version 4.18, that plugin offers a filter that can be used to convert the remaining balance to store's base currency before the coupon is updated. 

Below you can find a code snippet provided by StoreApps, the Team behind the Smart Coupons plugin, which should serve that purpose. 
/**
 * Converts the remaining store credit from the currency used to place an order to shop's base currency.
 *
 * @param float $credit_remaining
 * @param array $args
 * @return float
 * @author StoreApps <support@storeapps.org>
 */  
add_filter('wc_sc_credit_remaining', function($credit_remaining = 0, $args = array()) {
  $order = $args['order_obj'];
  $credit_remaining = apply_filters('wc_aelia_cs_convert', $credit_remaining, $order->get_currency(), get_option('woocommerce_currency'));
  return $credit_remaining;
}, 10, 2);

With this code snippet, every time a store credit coupon is used against an order, the remaining balance is calculated in the order's currency, then converted to the shop's base currency before updating the coupon. 


3. Need help with a customisation?

If you need assistance with the implementation of a customisation to add multi-currency support to a "coupons" plugin , please feel free to contact us for a consultation. We will gather the details of the customisation you need, and get back to you with a quote.


You can purchase the Currency Switcher from our online shop.