WooCommerce: disable Klarna payment gateway by country or currency

I have for a customer met this scenario. Klarna Bank says "We do not offer Klarna in Canada or the US for your payment solution at the moment, that is why US/CA customers cannot pay with Klarna" In addition, Klarna says the following: "You have the following markets available on your account: AT, BE, DK, FR, DE, IT, NL, ES. In addition, we do NOT accept USD as currency, no matter where."

In this case, we would like to disable Klarna Gateway for those customers who do not live in the countries mentioned, not just Canada and the USA. It is important to note that although we are using Klarna Bank as an example here, this situation applies to many payment solutions when shopping internationally, as not all countries or currencies can be accepted.

I have developed a small code to ensure that the Klarna Gateway only appears for the accepted countries and for customers who have not selected USD as their currency. Please note that you will need to customise this code example for your own solution to suit your needs. You need to use slugs to identify the selected gateway solution that you want to disable (in this case ['klarna']). So the slug for Klarna Gateway is "klarna". In the two arrays, enter the currencies that are not accepted and the countries where the payment solution is accepted. This PHP code example should be placed in the functions.php file of your WordPress theme (or child theme).


add_filter('woocommerce_available_payment_gateways', 'Klarna_CCO_woo_filter_gateways', 1);
function Klarna_CCO_woo_filter_gateways($gateway_list) {
   	if (!isset($gateway_list['klarna']) or is_admin()) return $gateway_list;
   $klarnaCountries = ['AT', 'BE', 'DK','FR','DE', 'IT','NL', 'ES']; // insert allowed countries
   $klarnaValuatas = ['USD']; // insert unallowed currencies
   if (in_array(get_woocommerce_currency(), $klarnaValuatas)) {unset($gateway_list['klarna']);} // unset if currency not allowed
   if (!in_array(WC()->customer->get_billing_country(), $klarnaCountries)) {unset($gateway_list['klarna']);} //unset gateway if not allowed country
   return $gateway_list;
}

Update: PHP Fatal error: Uncaught Error: Call to a member function: WC()->customer returns null and throws an error

If no customer is loaded, WC()->customer will be null instead of a WC_Customer object. This can occur in different scenarios. When WC()->customer is null, it can cause unpredictable issues or errors in your code that relies on customer data. If you encounter this situation in your code, you can use the method_exists(WC()->customer,'get_billing_country') workaround to avoid potential issues. This workaround checks if the method "get_billing_country" is available in the WC()->customer object before attempting to use it.

Specifically, I discovered the error when I experienced problems connecting to the API (wp-json/wc/v2/). While using the API, I noticed that errors related to missing customer data or a null value in WC()->customer were occurring.

This led me to investigate the code further and identify that WC()->customer could be null when no customer was loaded. I realised that this was the underlying cause of the API connection issues.

By using the method_exists() function, you can ensure that you only work with customer data when the method is available. This helps avoid errors and unwanted behaviour in your code when no customer is loaded.

Here's an example of how you can implement the solution in your code:


// Exclude if customer data is not available
if(!is_object(WC()->customer) OR !method_exists(WC()->customer,'get_billing_country') ){
      return $available_gateways;
   }

And here's the full updated code snippet that also excludes if customer data is not available.


add_filter('woocommerce_available_payment_gateways', 'Klarna_CCO_woo_filter_gateways', 1);
function Klarna_CCO_woo_filter_gateways($gateway_list) {
   	if (!isset($gateway_list['klarna']) or is_admin() or !is_object(WC()->customer) OR !method_exists(WC()->customer,'get_billing_country'))) return $gateway_list;
   $klarnaCountries = ['AT', 'BE', 'DK', 'FR', 'DE', 'IT', 'NL', 'ES']; // insert allowed countries
   $klarnaValuatas = ['USD']; // insert not allowed currencies
   if (in_array(get_woocommerce_currency(), $klarnaValuatas)) {unset($gateway_list['klarna']);} // unset if currency not allowed
   if (!in_array(WC()->customer->get_billing_country(), $klarnaCountries))) {unset($gateway_list['klarna']);} //unset gateway if not allowed country
   return $gateway_list;
}