<?php
namespace Svea_Webpay_For_Woocommerce\Gateways;

use Svea\WebPay\WebPay;
use Svea\WebPay\WebPayItem;
use Svea\WebPay\WebPayAdmin;
use Svea\WebPay\Constant\DistributionType;
use Svea_Webpay_For_Woocommerce\Cron_Functions;
use Svea_Webpay_For_Woocommerce\Helper;
use Svea_Webpay_For_Woocommerce\Traits\Gateway_Username;
use Svea_Webpay_For_Woocommerce\Traits\Singleton;
use Svea_Webpay_For_Woocommerce\Traits\Strong_Auth;
use WC_Countries;
use WC_Order;
use WC_Order_Item_Fee;
use WC_Tax;
use WP_Error;

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

/**
 * Class to handle invoice payments through Svea WebPay
 */
class WC_Gateway_Svea_Invoice extends WC_Gateway_Abstract {
	use Singleton, Gateway_Username, Strong_Auth;

	/**
	 * Id of this gateway
	 *
	 * @var     string
	 */
	const GATEWAY_ID = 'sveawebpay_invoice';

	/**
	 * @inheritDoc
	 */
	public $id = self::GATEWAY_ID;

	/**
	 * Is the log enabled
	 *
	 * @var bool
	 */
	public static $log_enabled = false;

	/**
	 * Invoice fee label
	 *
	 * @var string
	 */
	public $invoice_fee_label;

	/**
	 * Invoice fee
	 *
	 * @var float
	 */
	public $invoice_fee;

	/**
	 * Invoice fee tax
	 *
	 * @var float
	 */
	public $invoice_fee_tax;

	/**
	 * Invoice fee taxable
	 *
	 * @var bool
	 */
	public $invoice_fee_taxable;

	/**
	 * svea_invoice_currencies
	 *
	 * @var array
	 */
	public $svea_invoice_currencies;

	/**
	 * same shipping as billing
	 *
	 * @var bool
	 */
	public $same_shipping_as_billing;

	/**
	 * Array of enabled countries
	 *
	 * @var array
	 */
	public $enabled_countries;

	/**
	 * Distribution type
	 *
	 * @var string
	 */
	private $distribution_type;

	/**
	 * Constructor for the class and setup of hooks and object variables
	 */
	public function __construct() {
		if ( is_null( self::$instance ) ) {
			self::$instance = $this;
		}

		$this->supports = [
			'products',
			'subscriptions',
			'subscription_cancellation',
			'subscription_suspension',
			'subscription_reactivation',
			'multiple_subscriptions',
			'subscription_amount_changes',
			'subscription_date_changes',
			'subscription_payment_method_change',
			'subscription_payment_method_change_customer',
			'subscription_payment_method_change_admin',
			//'refunds'
		];

		$this->method_title = $this->get_payment_method_title();
		$this->icon = apply_filters( 'woocommerce_sveawebpay_invoice_icon', 'https://cdn.svea.com/webpay/Svea_Primary_RGB_large.png', $this->id );

		$this->svea_invoice_currencies = [
			'DKK' => 'DKK', // Danish Kroner
			'EUR' => 'EUR', // Euro
			'NOK' => 'NOK', // Norwegian Kroner
			'SEK' => 'SEK',  // Swedish Kronor
		];

		$this->init_form_fields();
		$this->init_settings();

		$this->title = __( $this->get_option( 'title' ), 'svea-webpay-for-woocommerce' ); // phpcs:ignore

		add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, [ $this, 'process_admin_options' ] );
		add_action( 'woocommerce_scheduled_subscription_payment_' . $this->id, [ $this, 'scheduled_subscription_payment' ], 10, 2 );
		add_action( 'woocommerce_admin_order_data_after_billing_address', [ $this, 'add_subscription_order_fields' ], 10, 1 );
		add_action( 'woocommerce_process_shop_subscription_meta', [ $this, 'save_subscription_meta' ], 10, 1 );
		add_action( 'woocommerce_api_wc_gateway_svea_invoice_strong_auth_confirmed', [ $this, 'handle_callback_request_confirmed' ] );
		add_action( 'woocommerce_api_wc_gateway_svea_invoice_strong_auth_rejected', [ $this, 'handle_callback_request_rejected' ] );

		self::$log_enabled = $this->get_option( 'debug' ) === 'yes';

		$this->same_shipping_as_billing = $this->get_option( 'same_shipping_as_billing' ) === 'yes';

		if ( ! isset( WC()->customer ) ) {
			return;
		}

		$customer_country = strtolower( WC()->customer->get_billing_country() );

		// Merchant set fields
		$this->enabled = $this->get_option( 'enabled' );

		$wc_countries = new WC_Countries();

		$this->base_country = $wc_countries->get_base_country();

		$this->enabled_countries = is_array( $this->get_option( 'enabled_countries' ) ) ? $this->get_option( 'enabled_countries' ) : [];

		$this->testmode = $this->get_option( 'testmode_' . $customer_country ) === 'yes';
		$this->distribution_type = $this->get_option( 'distribution_type_' . $customer_country );
		$this->invoice_fee_label = $this->get_option( 'invoice_fee_label_' . $customer_country );
		$this->invoice_fee = $this->get_option( 'invoice_fee_' . $customer_country );
		$this->invoice_fee_tax = $this->get_option( 'invoice_fee_tax_' . $customer_country );
		$this->invoice_fee_taxable = $this->get_option( 'invoice_fee_taxable_' . $customer_country ) === 'yes';

		$this->description = __( $this->get_option( 'description' ), 'svea-webpay-for-woocommerce' ); // phpcs:ignore
	}

	/**
	 * Get the payment method title
	 *
	 * @return string
	 */
	public function get_payment_method_title() {
		return esc_html__( 'Svea Invoice Payment', 'svea-webpay-for-woocommerce' );
	}

	/**
	 * Check whether or not this payment gateway is available
	 *
	 * @return boolean
	 */
	public function is_available() {
		if ( ! parent::is_available() ) {
			return false;
		}

		if ( ! is_admin() ) {
			if ( ! $this->check_customer_country() ) {
				return false;
			} else if ( ! $this->check_customer_currency() ) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Check if the current currency is supported
	 *
	 * @return  boolean
	 */
	public function check_customer_currency() {
		if ( isset( WC()->customer ) ) {
			$country_currency = Helper::get_country_currency( WC()->customer->get_billing_country() );

			if (
				! isset( $country_currency[0] ) ||
				$country_currency !== get_woocommerce_currency()
			) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Check if the current currency is supported and enabled
	 *
	 * @return  boolean
	 */
	public function check_customer_country() {
		if ( isset( WC()->customer ) ) {
			$customer_country = strtoupper( WC()->customer->get_billing_country() );
			$this->enabled_countries = is_array( $this->get_option( 'enabled_countries' ) ) ? $this->get_option( 'enabled_countries' ) : [];

			if ( ! in_array( $customer_country, $this->enabled_countries, true ) ) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Check if the Svea Invoice payment gateway is enabled.
	 *
	 * @return bool Returns true if the gateway is enabled, false otherwise.
	 */
	public function is_enabled() {
		if ( $this->enabled !== 'yes' ) {
			return false;
		}

		return true;
	}

	/**
	 * Display payment fields at checkout
	 *
	 * @return void
	 */
	public function payment_fields() {
		echo wp_kses_post( $this->description );

		$post_data = [];

		if ( isset( $_POST['post_data'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
			parse_str( sanitize_text_field( wp_unslash( $_POST['post_data'] ) ), $post_data ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
		}

		$post_data = array_map( 'sanitize_text_field', $post_data );

		$country = strtoupper( WC()->customer->get_billing_country() );

		$invoice_checkout_template = locate_template( 'woocommerce-gateway-svea-webpay/invoice/checkout.php' );

		$b2b_text = $this->get_option( 'description_b2b' );
		$b2c_text = $this->get_option( 'description_b2c' );

		if ( $invoice_checkout_template === '' ) {
			$invoice_checkout_template = WC_SVEAWEBPAY_GATEWAY_PLUGIN_DIR . '/partials/invoice/checkout.php';
		}

		include $invoice_checkout_template;
	}

	/**
	 * Adds a fee to the cart if the payment method is Svea Invoice
	 *
	 * @return void
	 */
	public function add_invoice_fee() {
		if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
			return;
		}

		$fees_total = 0.0;

		foreach ( WC()->cart->get_fees() as $fee ) {
			$fees_total += $fee->amount;
		}

		/**
		 * Calculate totals of the cart based on
		 * cart contents total, cart shipping total and cart fees total
		 */
		$cart_total = WC()->cart->cart_contents_total + WC()->cart->shipping_total + $fees_total;

		$customer_type = WC()->session->get( 'svea_customer_type' );
		$suffix = '';

		if ( $customer_type === 'company' ) {
			$suffix = '_b2b';
		}

		$customer_country = strtolower( WC()->customer->get_billing_country() );
		$invoice_fee_label = $this->get_option( 'invoice_fee_label_' . $customer_country . $suffix );
		$invoice_fee = (float) $this->get_option( 'invoice_fee_' . $customer_country . $suffix );
		$invoice_fee_taxable = $this->get_option( 'invoice_fee_taxable_' . $customer_country . $suffix ) === 'yes';

		if ( isset( WC()->cart )
			&& strlen( (string) $invoice_fee ) > 0
			&& is_numeric( $invoice_fee )
			&& $cart_total > 0
			&& $invoice_fee > 0
		) {
			WC()->cart->add_fee( $invoice_fee_label, floatval( $invoice_fee ), $invoice_fee_taxable, '' );
		}
	}

	/**
	 * See if we can ship to a different address
	 *
	 * @return  boolean
	 */
	public function can_ship_to_different_address() {
		if ( ! isset( $this->same_shipping_as_billing ) ) {
			return false;
		}

		return $this->same_shipping_as_billing === false;
	}

	/**
	 * Validates posted fields
	 *
	 * @param array $fields
	 * @param object $errors
	 * @return void
	 */
	public function checkout_validation_handler( $fields, $errors ) {
		$customer_country = strtoupper( $fields['billing_country'] );

		if ( ! isset( $_POST['iv_billing_customer_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
			$errors->add( 'validation', __( 'Please select either company or individual customer type.', 'svea-webpay-for-woocommerce' ) );
			return;
		}

		$customer_type = sanitize_text_field( wp_unslash( $_POST['iv_billing_customer_type'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing

		switch ( $customer_country ) {
			case 'SE':
				$request = WebPay::getAddresses( $this->get_config( $customer_country, $customer_type ) );
				$request->setCountryCode( $customer_country );

				if ( $customer_type === 'company' ) {
					if ( ! isset( $_POST['address_selector'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( '<strong>Organisation number</strong> is a required field', 'svea-webpay-for-woocommerce' ) );
						return;
					} else if ( ! isset( $_POST['iv_billing_org_number'] ) || $_POST['iv_billing_org_number'] === '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( '<strong>Organisation number</strong> is a required field.', 'svea-webpay-for-woocommerce' ) );
						return;
					}

					$request->setCustomerIdentifier( sanitize_text_field( wp_unslash( $_POST['iv_billing_org_number'] ) ) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
						->getCompanyAddresses();
				} else if ( $customer_type === 'individual' ) {
					if ( ! isset( $_POST['iv_billing_ssn'] ) || $_POST['iv_billing_ssn'] === '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( '<strong>Personal number</strong> is a required field.', 'svea-webpay-for-woocommerce' ) );
						return;
					}

					$request->setCustomerIdentifier( sanitize_text_field( wp_unslash( $_POST['iv_billing_ssn'] ) ) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
						->getIndividualAddresses();
				} else {
					$errors->add( 'validation', __( 'Invalid customer type', 'svea-webpay-for-woocommerce' ) );
					return;
				}

				$response = $request->doRequest();
				$result_code = $response->resultcode;

				if ( $result_code === 'Accepted' ) {
					if ( ! empty( $_POST['address_selector'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						foreach ( $response->customerIdentity as $ci ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
							if ( $ci->addressSelector === $_POST['address_selector'] ) { // phpcs:ignore
								$selected_address = $ci;
								break;
							}
						}
					} else {
						$selected_address = $response->customerIdentity[0]; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
					}

					if ( ! isset( $selected_address ) ) {
						$errors->add( 'validation', __( 'We could not find your address in our database.', 'svea-webpay-for-woocommerce' ) );
						return;
					}

					// Update the order with the correct data after creation
					$update_order_data = function ( $wc_order ) use ( $selected_address ) {
						if ( ! empty( $selected_address->firstName ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
							$wc_order->set_billing_first_name( $selected_address->firstName ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
						}

						if ( ! empty( $selected_address->lastName ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
							$wc_order->set_billing_last_name( $selected_address->lastName ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
						}

						$wc_order->set_billing_company( $selected_address->fullName ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
						$wc_order->set_billing_address_1( $selected_address->street );
						$wc_order->set_billing_address_2( $selected_address->coAddress ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
						$wc_order->set_billing_postcode( $selected_address->zipCode ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
						$wc_order->set_billing_city( $selected_address->locality );
					};

					add_action( 'woocommerce_checkout_create_order', $update_order_data, 10, 1 );
				} else if ( $result_code === 'Error' || $result_code === 'NoSuchEntity' ) {
					if ( $customer_type === 'company' ) {
						$errors->add( 'validation', __( 'The <strong>Organisation number</strong> is not valid.', 'svea-webpay-for-woocommerce' ) );
					} else if ( $customer_type === 'individual' ) {
						$errors->add( 'validation', __( 'The <strong>Personal number</strong> is not valid.', 'svea-webpay-for-woocommerce' ) );
					}

					return;
				} else {
					if ( $_POST['iv_billing_customer_type'] === 'company' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( 'An unknown error occurred while trying to lookup your Organisation number.', 'svea-webpay-for-woocommerce' ) );
					} else if ( $_POST['iv_billing_customer_type'] === 'individual' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( 'An unknown error occurred while trying to lookup your Personal number.', 'svea-webpay-for-woocommerce' ) );
					} else {
						$errors->add( 'validation', __( 'An unknown error occurred.', 'svea-webpay-for-woocommerce' ) );
					}

					return;
				}
				break;
			case 'NO':
				if ( $customer_type === 'company' ) {
					$request = WebPay::getAddresses( $this->get_config( $customer_country, $customer_type ) )
						->setCountryCode( $customer_country );

					if ( ! isset( $_POST['address_selector'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( '<strong>Organisation number</strong> is a required field.', 'svea-webpay-for-woocommerce' ) );
						return;
					} else if ( ! isset( $_POST['iv_billing_org_number'] ) || strlen( sanitize_text_field( wp_unslash( $_POST['iv_billing_org_number'] ) ) ) <= 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( '<strong>Organisation number</strong> is a required field.', 'svea-webpay-for-woocommerce' ) );
						return;
					}

					$request->setCustomerIdentifier( sanitize_text_field( wp_unslash( $_POST['iv_billing_org_number'] ) ) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
						->getCompanyAddresses();

					$response = $request->doRequest();
					$result_code = $response->resultcode;

					if ( $result_code === 'Accepted' ) {
						foreach ( $response->customerIdentity as $ci ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
							if ( $ci->addressSelector === $_POST['address_selector'] ) { // phpcs:ignore
								$selected_address = $ci;
								break;
							}
						}

						if ( ! isset( $selected_address ) ) {
							$errors->add( 'validation', __( '<strong>Organisation number</strong> is a required field.', 'svea-webpay-for-woocommerce' ) );
							return;
						}

						// Update the order with the correct data after creation
						$update_order_data = function ( $wc_order ) use ( $selected_address ) {
							if ( ! empty( $selected_address->firstName ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
								$wc_order->set_billing_first_name( $selected_address->firstName ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
							}

							if ( ! empty( $selected_address->lastName ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
								$wc_order->set_billing_last_name( $selected_address->lastName ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
							}

							$wc_order->set_billing_company( $selected_address->fullName ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
							$wc_order->set_billing_address_1( $selected_address->street );
							$wc_order->set_billing_address_2( $selected_address->coAddress ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
							$wc_order->set_billing_postcode( $selected_address->zipCode ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
							$wc_order->set_billing_city( $selected_address->locality );
						};

						add_action( 'woocommerce_checkout_create_order', $update_order_data, 10, 1 );
					} else if ( $result_code === 'Error' || $result_code === 'NoSuchEntity' ) {
						$errors->add( 'validation', __( $response['errormessage'], 'svea-webpay-for-woocommerce' ) ); // phpcs:ignore
					} else {
						$errors->add( 'validation', __( 'An unknown error occurred while trying to lookup your Organisation number.', 'svea-webpay-for-woocommerce' ) );
						return;
					}
				} else if ( $customer_type === 'individual' ) {
					if ( ! isset( $_POST['iv_billing_ssn'] ) || $_POST['iv_billing_ssn'] === '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( '<strong>Personal number</strong> is a required field.', 'svea-webpay-for-woocommerce' ) );
						return;
					}
				} else {
					$errors->add( 'validation', __( 'Invalid customer type', 'svea-webpay-for-woocommerce' ) );
					return;
				}
				break;
			case 'FI':
				if ( $customer_type === 'company' ) {
					if ( ! isset( $_POST['iv_billing_org_number'] ) || $_POST['iv_billing_org_number'] === '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( '<strong>Organisation number</strong> is a required field.', 'svea-webpay-for-woocommerce' ) );
						return;
					} else if ( strlen( sanitize_text_field( wp_unslash( $_POST['iv_billing_org_number'] ) ) ) < 8 ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( 'The <strong>Organisation number</strong> entered is not correct.', 'svea-webpay-for-woocommerce' ) );
						return;
					}
				} else if ( $customer_type === 'individual' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
					if ( ! isset( $_POST['iv_billing_ssn'] ) || $_POST['iv_billing_ssn'] === '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$errors->add( 'validation', __( '<strong>Personal number</strong> is a required field.', 'svea-webpay-for-woocommerce' ) );
						return;
					}
				} else {
					$errors->add( 'validation', __( 'Invalid customer type', 'svea-webpay-for-woocommerce' ) );
					return;
				}
				break;
		}

		// If we can only ship to the billing address, prevent shipping address
		if ( ! $this->can_ship_to_different_address() ) {
			// Transfer all order functions
			$update_order_data = function ( $wc_order ) {
				$props = [
					'first_name',
					'last_name',
					'country',
					'state',
					'postcode',
					'city',
					'address_1',
					'address_2',
				];

				foreach ( $props as $prop ) {
					$wc_order->{'set_shipping_' . $prop}( '' );
				}
			};

			add_action( 'woocommerce_checkout_create_order', $update_order_data, 10, 1 );
		}
	}

	/**
	 * Check if the invoice gateway is active and set
	 *
	 * @return boolean
	 */
	public function invoice_is_active_and_set() {
		if ( ! array_key_exists( get_woocommerce_currency(), $this->svea_invoice_currencies ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Display options in admin or an error if something is not right
	 *
	 * @return  void
	 */
	public function admin_options() {
		?>
		<h3> <?php esc_html_e( 'Svea Invoice Payment', 'svea-webpay-for-woocommerce' ); ?> </h3>
		<p> <?php esc_html_e( 'Process invoice payments through Svea.', 'svea-webpay-for-woocommerce' ); ?> </p>
		<?php if ( $this->invoice_is_active_and_set() ) : ?>
		<table class="form-table">
			<?php
				// Generate the HTML For the settings form.
				$this->generate_settings_html();
			?>
		</table>
		<h3><?php esc_html_e( 'Get Address Shortcode', 'svea-webpay-for-woocommerce' ); ?></h3>
		<p>
			<?php esc_html_e( 'If you want to move the Get-Address box on the checkout page you can do so with the shortcode', 'svea-webpay-for-woocommerce' ); ?> <code>[svea_get_address]</code>
		</p>
		<p>
			<?php esc_html_e( 'By using the shortcode on the checkout page, you automatically disable the Get-Address box in the gateways. You can only use the shortcode if you have a valid Svea Invoice account.', 'svea-webpay-for-woocommerce' ); ?>
		</p>
		<p>
			<?php esc_html_e( 'The shortcode is usable for the countries in which you are using Svea Invoice, independentenly of the payment method.', 'svea-webpay-for-woocommerce' ); ?>
		</p>
		<?php else : ?>
		<div class="inline error"><p><?php esc_html_e( 'Sveawebpay does not support your currency and or country.', 'svea-webpay-for-woocommerce' ); ?></p></div>
			<?php
		endif;
	}

	/**
	 * Initialize our options for this gateway
	 *
	 * @return  void
	 */
	public function init_form_fields() {
		$this->form_fields = [
			'enabled'                    => [
				'title'   => __( 'Enable/disable', 'svea-webpay-for-woocommerce' ),
				'type'    => 'checkbox',
				'label'   => __( 'Enable Svea Invoice Payment', 'svea-webpay-for-woocommerce' ),
				'default' => 'no',
			],
			'title'                      => [
				'title'       => __( 'Title', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'This controls the title which the user sees during checkout', 'svea-webpay-for-woocommerce' ),
				'default'     => __( 'Invoice 14 days', 'svea-webpay-for-woocommerce' ),
			],
			'description'                => [
				'title'       => __( 'Description', 'svea-webpay-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'This controls the description the user sees during checkout', 'svea-webpay-for-woocommerce' ),
				'default'     => __( 'Pay with invoice through Svea', 'svea-webpay-for-woocommerce' ),
			],
			'description_b2b'            => [
				'title'       => __( 'Extra description for B2B', 'svea-webpay-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'This controls the description the user selects "company" after choosing invoice', 'svea-webpay-for-woocommerce' ),
			],
			'description_b2c'            => [
				'title'       => __( 'Extra description for B2C', 'svea-webpay-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'This controls the description the user selects "individual" after choosing invoice', 'svea-webpay-for-woocommerce' ),
			],
			'enabled_countries'          => [
				'title'       => __( 'Enabled countries', 'svea-webpay-for-woocommerce' ),
				'type'        => 'multiselect',
				'description' => __( 'Choose the countries you want Svea Invoice Payment to be active in', 'svea-webpay-for-woocommerce' ),
				'options'     => [
					'FI' => __( 'Finland', 'svea-webpay-for-woocommerce' ),
					'NO' => __( 'Norway', 'svea-webpay-for-woocommerce' ),
					'SE' => __( 'Sweden', 'svea-webpay-for-woocommerce' ),
				],
				'default'     => '',
			],
			'same_shipping_as_billing'   => [
				'title'       => __( 'Same shipping address as billing address', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'description' => __( 'If checked, billing address will override the shipping address', 'svea-webpay-for-woocommerce' ),
				'default'     => 'yes',
			],

			// Finland
			'merchant_fi_hr'             => [
				'title'       => '<hr>' . __( 'Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'title',
				'description' => __( 'These credentials can be used for both B2B and B2C', 'svea-webpay-for-woocommerce' ),
			],
			'testmode_fi'                => [
				'title'       => __( 'Test mode Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'label'       => __( 'Enable/disable test mode in Finland', 'svea-webpay-for-woocommerce' ),
				'description' => __( 'When testing out the gateway, this option should be enabled', 'svea-webpay-for-woocommerce' ),
				'default'     => 'no',
			],
			'distribution_type_fi'       => [
				'title'       => __( 'Distribution type Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'select',
				'description' => __( 'This controls which distribution type you will be using for invoices in Finland', 'svea-webpay-for-woocommerce' ),
				'options'     => [
					DistributionType::POST  => __( 'Post', 'svea-webpay-for-woocommerce' ),
					DistributionType::EMAIL => __( 'E-mail', 'svea-webpay-for-woocommerce' ),
				],
				'default'     => DistributionType::EMAIL,
			],
			'username_fi'                => [
				'title'       => __( 'Username Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Username for invoice payments in Finland', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'password_fi'                => [
				'title'       => __( 'Password Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'password',
				'description' => __( 'Password for invoice payments in Finland', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'client_nr_fi'               => [
				'title'       => __( 'Client number Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Client number for invoice payments in Finland', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'invoice_fee_label_fi'       => [
				'title'       => __( 'Invoice fee label Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'Label for the invoice fee for Finland', 'svea-webpay-for-woocommerce' ),
				'default'     => 'Invoice fee Finland',
			],
			'invoice_fee_fi'             => [
				'title'       => __( 'Invoice fee Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Invoice fee for Finland, this should be entered exclusive of tax', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'invoice_fee_taxable_fi'     => [
				'title'       => __( 'Invoice fee taxable Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'description' => __( 'If the invoice fee is taxable in Finland, check the box.' ),
				'default'     => '',
			],

			// Finland - B2B alternative
			'merchant_fi_b2b_hr'         => [
				'title'       => '<hr>' . __( 'Alternative Finland B2B account', 'svea-webpay-for-woocommerce' ),
				'type'        => 'title',
				'description' => __( 'If the fields above is only for B2C you can use these settings to separate B2B and B2C merchant credentials', 'svea-webpay-for-woocommerce' ),
			],
			'merchant_fi_use_b2b'        => [
				'title' => __( 'Use alternative B2B credentials', 'svea-webpay-for-woocommerce' ),
				'type'  => 'checkbox',
				'class' => 'use-b2b',
			],
			'testmode_fi_b2b'            => [
				'title'       => __( 'Test mode Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'label'       => __( 'Enable/disable test mode in Finland', 'svea-webpay-for-woocommerce' ),
				'description' => __( 'When testing out the gateway, this option should be enabled', 'svea-webpay-for-woocommerce' ),
				'default'     => 'no',
				'class'       => 'b2b-setting',
			],
			'distribution_type_fi_b2b'   => [
				'title'       => __( 'Distribution type Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'select',
				'description' => __( 'This controls which distribution type you will be using for invoices in Finland', 'svea-webpay-for-woocommerce' ),
				'options'     => [
					DistributionType::POST  => __( 'Post', 'svea-webpay-for-woocommerce' ),
					DistributionType::EMAIL => __( 'E-mail', 'svea-webpay-for-woocommerce' ),
				],
				'default'     => DistributionType::EMAIL,
				'class'       => 'b2b-setting',
			],
			'username_fi_b2b'            => [
				'title'       => __( 'Username Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Username for invoice payments in Finland', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'password_fi_b2b'            => [
				'title'       => __( 'Password Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'password',
				'description' => __( 'Password for invoice payments in Finland', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'client_nr_fi_b2b'           => [
				'title'       => __( 'Client number Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Client number for invoice payments in Finland', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'invoice_fee_label_fi_b2b'   => [
				'title'       => __( 'Invoice fee label Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'Label for the invoice fee for Finland', 'svea-webpay-for-woocommerce' ),
				'default'     => 'Invoice fee Finland',
				'class'       => 'b2b-setting',
			],
			'invoice_fee_fi_b2b'         => [
				'title'       => __( 'Invoice fee Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Invoice fee for Finland, this should be entered exclusive of tax', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'invoice_fee_taxable_fi_b2b' => [
				'title'       => __( 'Invoice fee taxable Finland', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'description' => __( 'If the invoice fee is taxable in Finland, check the box.' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],

			// Norway
			'merchant_no_hr'             => [
				'title'       => '<hr>' . __( 'Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'title',
				'description' => __( 'These credentials can be used for both B2B and B2C', 'svea-webpay-for-woocommerce' ),
			],
			'testmode_no'                => [
				'title'       => __( 'Test mode Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'label'       => __( 'Enable/disable test mode in Norway', 'svea-webpay-for-woocommerce' ),
				'description' => __( 'When testing out the gateway, this option should be enabled', 'svea-webpay-for-woocommerce' ),
				'default'     => 'no',
			],
			'distribution_type_no'       => [
				'title'       => __( 'Distribution type Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'select',
				'description' => __( 'This controls which distribution type you will be using for invoices in Norway', 'svea-webpay-for-woocommerce' ),
				'options'     => [
					DistributionType::POST  => __( 'Post', 'svea-webpay-for-woocommerce' ),
					DistributionType::EMAIL => __( 'E-mail', 'svea-webpay-for-woocommerce' ),
				],
				'default'     => DistributionType::EMAIL,
			],
			'username_no'                => [
				'title'       => __( 'Username Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Username for invoice payments in Norway', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'password_no'                => [
				'title'       => __( 'Password Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'password',
				'description' => __( 'Password for invoice payments in Norway', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'client_nr_no'               => [
				'title'       => __( 'Client number Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Client number for invoice payments in Norway', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'invoice_fee_label_no'       => [
				'title'       => __( 'Invoice fee label Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'Label for the invoice fee for Norway', 'svea-webpay-for-woocommerce' ),
				'default'     => 'Invoice fee Norway',
			],
			'invoice_fee_no'             => [
				'title'       => __( 'Invoice fee Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Invoice fee for Norway, this should be entered exclusive of tax', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'invoice_fee_taxable_no'     => [
				'title'       => __( 'Invoice fee taxable Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'description' => __( 'If the invoice fee is taxable in Norway, check the box.' ),
				'default'     => '',
			],

			// Norway - B2B alternative
			'merchant_no_b2b_hr'         => [
				'title'       => '<hr>' . __( 'Alternative Norway B2C account', 'svea-webpay-for-woocommerce' ),
				'type'        => 'title',
				'description' => __( 'If the fields above is only for B2C you can use these settings to separate B2B and B2C merchant credentials', 'svea-webpay-for-woocommerce' ),
			],
			'merchant_no_use_b2b'        => [
				'title' => __( 'Use alternative B2B credentials', 'svea-webpay-for-woocommerce' ),
				'type'  => 'checkbox',
				'class' => 'use-b2b',
			],
			'testmode_no_b2b'            => [
				'title'       => __( 'Test mode Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'label'       => __( 'Enable/disable test mode in Norway', 'svea-webpay-for-woocommerce' ),
				'description' => __( 'When testing out the gateway, this option should be enabled', 'svea-webpay-for-woocommerce' ),
				'default'     => 'no',
				'class'       => 'b2b-setting',
			],
			'distribution_type_no_b2b'   => [
				'title'       => __( 'Distribution type Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'select',
				'description' => __( 'This controls which distribution type you will be using for invoices in Norway', 'svea-webpay-for-woocommerce' ),
				'options'     => [
					DistributionType::POST  => __( 'Post', 'svea-webpay-for-woocommerce' ),
					DistributionType::EMAIL => __( 'E-mail', 'svea-webpay-for-woocommerce' ),
				],
				'default'     => DistributionType::EMAIL,
				'class'       => 'b2b-setting',
			],
			'username_no_b2b'            => [
				'title'       => __( 'Username Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Username for invoice payments in Norway', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'password_no_b2b'            => [
				'title'       => __( 'Password Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'password',
				'description' => __( 'Password for invoice payments in Norway', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'client_nr_no_b2b'           => [
				'title'       => __( 'Client number Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Client number for invoice payments in Norway', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'invoice_fee_label_no_b2b'   => [
				'title'       => __( 'Invoice fee label Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'Label for the invoice fee for Norway', 'svea-webpay-for-woocommerce' ),
				'default'     => 'Invoice fee Norway',
				'class'       => 'b2b-setting',
			],
			'invoice_fee_no_b2b'         => [
				'title'       => __( 'Invoice fee Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Invoice fee for Norway, this should be entered exclusive of tax', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'invoice_fee_taxable_no_b2b' => [
				'title'       => __( 'Invoice fee taxable Norway', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'description' => __( 'If the invoice fee is taxable in Norway, check the box.' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],

			// Sweden
			'merchant_sv_hr'             => [
				'title'       => '<hr>' . __( 'Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'title',
				'description' => __( 'These credentials can be used for both B2B and B2C', 'svea-webpay-for-woocommerce' ),
			],
			'testmode_se'                => [
				'title'       => __( 'Test mode Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'label'       => __( 'Enable/disable test mode in Sweden', 'svea-webpay-for-woocommerce' ),
				'description' => __( 'When testing out the gateway, this option should be enabled', 'svea-webpay-for-woocommerce' ),
				'default'     => 'no',
			],
			'distribution_type_se'       => [
				'title'       => __( 'Distribution type Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'select',
				'description' => __( 'This controls which distribution type you will be using for invoices in Sweden', 'svea-webpay-for-woocommerce' ),
				'options'     => [
					DistributionType::POST  => __( 'Post', 'svea-webpay-for-woocommerce' ),
					DistributionType::EMAIL => __( 'E-mail', 'svea-webpay-for-woocommerce' ),
				],
				'default'     => DistributionType::EMAIL,
			],
			'username_se'                => [
				'title'       => __( 'Username Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Username for invoice payments in Sweden', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'password_se'                => [
				'title'       => __( 'Password Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'password',
				'description' => __( 'Password for invoice payments in Sweden', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'client_nr_se'               => [
				'title'       => __( 'Client number Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Client number for invoice payments in Sweden', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'invoice_fee_label_se'       => [
				'title'       => __( 'Invoice fee label Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'Label for the invoice fee for Sweden', 'svea-webpay-for-woocommerce' ),
				'default'     => 'Invoice fee Sweden',
			],
			'invoice_fee_se'             => [
				'title'       => __( 'Invoice fee Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Invoice fee for Sweden, this should be entered exclusive of tax', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
			],
			'invoice_fee_taxable_se'     => [
				'title'       => __( 'Invoice fee taxable Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'description' => __( 'If the invoice fee is taxable in Sweden, check the box.' ),
				'default'     => '',
			],

			// Sweden - B2B alternative
			'merchant_se_b2b_hr'         => [
				'title'       => '<hr>' . __( 'Alternative Sweden B2B account', 'svea-webpay-for-woocommerce' ),
				'type'        => 'title',
				'description' => __( 'If the fields above is only for B2C you can use these settings to separate B2B and B2C merchant credentials', 'svea-webpay-for-woocommerce' ),
			],
			'merchant_se_use_b2b'        => [
				'title' => __( 'Use alternative B2B credentials', 'svea-webpay-for-woocommerce' ),
				'type'  => 'checkbox',
				'class' => 'use-b2b',
			],
			'testmode_se_b2b'            => [
				'title'       => __( 'Test mode Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'label'       => __( 'Enable/disable test mode in Sweden', 'svea-webpay-for-woocommerce' ),
				'description' => __( 'When testing out the gateway, this option should be enabled', 'svea-webpay-for-woocommerce' ),
				'default'     => 'no',
				'class'       => 'b2b-setting',
			],
			'distribution_type_se_b2b'   => [
				'title'       => __( 'Distribution type Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'select',
				'description' => __( 'This controls which distribution type you will be using for invoices in Sweden', 'svea-webpay-for-woocommerce' ),
				'options'     => [
					DistributionType::POST  => __( 'Post', 'svea-webpay-for-woocommerce' ),
					DistributionType::EMAIL => __( 'E-mail', 'svea-webpay-for-woocommerce' ),
				],
				'default'     => DistributionType::EMAIL,
				'class'       => 'b2b-setting',
			],
			'username_se_b2b'            => [
				'title'       => __( 'Username Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Username for invoice payments in Sweden', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'password_se_b2b'            => [
				'title'       => __( 'Password Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'password',
				'description' => __( 'Password for invoice payments in Sweden', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'client_nr_se_b2b'           => [
				'title'       => __( 'Client number Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Client number for invoice payments in Sweden', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'invoice_fee_label_se_b2b'   => [
				'title'       => __( 'Invoice fee label Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'Label for the invoice fee for Sweden', 'svea-webpay-for-woocommerce' ),
				'default'     => 'Invoice fee Sweden',
				'class'       => 'b2b-setting',
			],
			'invoice_fee_se_b2b'         => [
				'title'       => __( 'Invoice fee Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'Invoice fee for Sweden, this should be entered exclusive of tax', 'svea-webpay-for-woocommerce' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'invoice_fee_taxable_se_b2b' => [
				'title'       => __( 'Invoice fee taxable Sweden', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'description' => __( 'If the invoice fee is taxable in Sweden, check the box.' ),
				'default'     => '',
				'class'       => 'b2b-setting',
			],
			'strong_auth_se'             => [
				'title'       => __( 'Strong authentication', 'svea-webpay-for-woocommerce' ),
				'label'       => __( 'Enable strong authentication for company invoice orders in Sweden (this is already forced for individuals)', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'description' => __( 'For this to work, the setting must also be toggled on in your Svea account.', 'svea-webpay-for-woocommerce' ) . '<br />' ,
				'default'     => '',
			],

			// Other settings
			'merchant_other_hr'          => [
				'title' => '<hr>',
				'type'  => 'title',
			],
			'debug'                      => [
				'title'       => __( 'Debug log', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'label'       => __( 'Enable logging', 'svea-webpay-for-woocommerce' ),
				'default'     => 'no',
				'description' => __( 'Log Svea events, such as payment requests', 'svea-webpay-for-woocommerce' ),
			],
			'disable_order_sync'         => [
				'title'       => __( 'Disable automatic order sync', 'svea-webpay-for-woocommerce' ),
				'type'        => 'checkbox',
				'description' => __(
					"Disable automatic syncing of orders in WooCommerce to Svea. <br />
						If you enable this option, your refunded orders will not be refunded in Svea. <br />
						Your delivered orders will not be delivered in Svea and your cancelled orders will not be cancelled in Svea. <br />
						<strong>Don't touch this if you don't know what you're doing</strong>.",
					'svea-webpay-for-woocommerce'
				),
				'default'     => 'no',
			],
		];
	}/** @noinspection PhpUndefinedClassInspection */

	/**
	 * Fetches the distribution type for the provided country
	 *
	 * @param   $country    the country that we are getting distribution type from
	 * @return  string      the distribution type for the provided country
	 */
	public function get_distribution_type( $country = '', $is_b2b = false ) {
		$country = strtolower( $country );
		$suffix = $is_b2b ? '_b2b' : '';
		return $this->get_option( 'distribution_type_' . $country . $suffix );
	}

	/**
	 * Process refunds
	 *
	 * @param   string  $order_id   id of the order being refunded
	 * @param   float   $amount     amount being refunded
	 * @param   string  $reason     reason of the refund
	 *
	 * @return  boolean
	 */
	public function process_refund( $order_id, $amount = null, $reason = '' ) {
		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			return false;
		}

		$svea_order_id = $order->get_meta( '_svea_order_id', true );

		if ( ! $svea_order_id || strlen( (string) $svea_order_id ) <= 0 ) {
			return false;
		}

		$response = WebPayAdmin::queryOrder( $this->config )
			->setOrderId( $svea_order_id )
			->setCountryCode( $order->get_billing_country() )
			->queryInvoiceOrder()
			->doRequest();

		if ( ! $response || ! isset( $response->accepted ) || ! $response->accepted ) {
			return new WP_Error( 'error', $response->errormessage ?? __( 'Unknown error', 'svea-webpay-for-woocommerce' ) );
		}

		if ( ! isset( $response->numberedOrderRows ) || count( $response->numberedOrderRows ) === 0 ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
			return new WP_Error( 'no_items', __( 'Couldn\'t find any order rows in Svea', 'svea-webpay-for-woocommerce' ) );
		}

		$invoice_id = $response->numberedOrderRows[0]->invoiceId; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase

		if ( is_null( $invoice_id ) )
			return new WP_Error( 'not_delivered', __( 'You have to deliver the order at Svea first', 'svea-webpay-for-woocommerce' ) );

		$credit_name = __( 'Refund', 'svea-webpay-for-woocommerce' );

		if ( strlen( $reason ) > 0 )
			$credit_name .= ': ' . $reason;

		$response = WebPayAdmin::creditOrderRows( $this->config )
			->setInvoiceId( $invoice_id )
			->setCountryCode( $order->get_billing_country() )
			->setInvoiceDistributionType( $this->get_distribution_type() )
			->addCreditOrderRow(
				WebPayItem::orderRow()
					->setAmountExVat( (float) $amount )
					->setVatPercent( 0 )
					->setDiscountPercent( 0 )
					->setName( $credit_name )
					->setQuantity( 1 )
			)
			->creditInvoiceOrderRows()
			->doRequest();

		if ( ! $response || ! isset( $response->accepted ) || ! $response->accepted ) {
			return new WP_Error( 'error', $response->errormessage ?? __( 'Unknown error', 'svea-webpay-for-woocommerce' ) );
		}

		return true;
	}

	/**
	 * This function handles the payment processing
	 *
	 * @param   int     $order_id   id of the order being processed
	 * @return  array   an array containing the result of the payment
	 */
	public function process_payment( $order_id ) {
		$wc_order = wc_get_order( $order_id );

		$customer_first_name = $wc_order->get_billing_first_name();
		$customer_last_name = $wc_order->get_billing_last_name();
		$customer_address_1 = $wc_order->get_billing_address_1();
		$customer_address_2 = $wc_order->get_billing_address_2();
		$customer_zip_code = $wc_order->get_billing_postcode();
		$customer_city = $wc_order->get_billing_city();
		$customer_country = $wc_order->get_billing_country();
		$customer_email = $wc_order->get_billing_email();
		$customer_phone = $wc_order->get_billing_phone();
		$payment_method = $wc_order->get_payment_method();

		if ( ! isset( $_POST['iv_billing_customer_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
			return [
				'result' => 'failure',
			];
		}

		$customer_type = $_POST['iv_billing_customer_type'] === 'individual' ? 'individual' : 'company'; // phpcs:ignore WordPress.Security.NonceVerification.Missing

		// Update customer type. This will be saved later on
		$wc_order->update_meta_data( '_svea_customer_type', $customer_type );
		$strong_auth = $this->uses_strong_auth( $customer_country, $customer_type );

		$this->testmode = $this->get_option( 'testmode_' . strtolower( $customer_country ) ) === 'yes';

		$config = $this->get_config( $customer_country, $customer_type );

		$subscriptions = false;

		/**
		 * We need to recalculate totals to include
		 * the invoice fee in the total amount in
		 * WooCommerce
		 */
		if ( class_exists( 'WC_Subscriptions_Order' ) ) {
			if ( ( wcs_order_contains_subscription( $wc_order )
				|| wcs_order_contains_switch( $wc_order )
				|| wcs_order_contains_resubscribe( $wc_order )
				|| wcs_order_contains_renewal( $wc_order ) ) ) {
				$subscriptions = wcs_get_subscriptions_for_order( $wc_order->get_id(), [ 'order_type' => 'any' ] );
			} else if ( wcs_is_subscription( $wc_order->get_id() ) ) {
				$subscriptions = [ wcs_get_subscription( $wc_order->get_id() ) ];
			}
		}

		/**
		 * Convert our WooCommerce order to Svea
		 */
		$svea_order = Helper::create_svea_order( $wc_order, $config );

		$svea_order
			->setClientOrderNumber( apply_filters( 'woocommerce_sveawebpay_invoice_client_order_number', $wc_order->get_order_number() ) )
			->setCurrency( get_woocommerce_currency() )
			->setCountryCode( $customer_country )
			->setOrderDate( date( 'c' ) );

		switch ( strtoupper( $customer_country ) ) {
			case 'SE':
			case 'NO':
			case 'FI':
				if ( isset( $_POST['iv_billing_customer_type'] ) && $_POST['iv_billing_customer_type'] === 'company' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
					if ( ! isset( $_POST['iv_billing_org_number'][0] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wc_add_notice( __( 'Organisation number is required.', 'svea-webpay-for-woocommerce' ), 'error' );
						return [
							'result' => 'failure',
						];
					}

					$customer_information = WebPayItem::companyCustomer()
						->setNationalIdNumber( sanitize_text_field( wp_unslash( $_POST['iv_billing_org_number'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing

					if ( $subscriptions ) {
						foreach ( $subscriptions as $subscription ) {
							$subscription->update_meta_data( '_svea_iv_billing_org_number', sanitize_text_field( wp_unslash( $_POST['iv_billing_org_number'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
							$subscription->save();
						}
					}

					if ( isset( $_POST['address_selector'] ) && strlen( sanitize_text_field( wp_unslash( $_POST['address_selector'] ) ) ) > 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$customer_information->setAddressSelector( sanitize_text_field( wp_unslash( $_POST['address_selector'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing

						if ( $subscriptions ) {
							foreach ( $subscriptions as $subscription ) {
								$subscription->update_meta_data( '_svea_address_selector', sanitize_text_field( wp_unslash( $_POST['address_selector'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
								$subscription->save();
							}
						}
					}
				} else if ( isset( $_POST['iv_billing_customer_type'] ) && $_POST['iv_billing_customer_type'] === 'individual' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
					if ( ! isset( $_POST['iv_billing_ssn'][0] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wc_add_notice( __( 'Personal number is required.', 'svea-webpay-for-woocommerce' ), 'error' );
						return [
							'result' => 'failure',
						];
					}

					$customer_information = WebPayItem::individualCustomer()
						->setName( $customer_first_name, $customer_last_name )
						->setNationalIdNumber( sanitize_text_field( wp_unslash( $_POST['iv_billing_ssn'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing

					if ( $subscriptions ) {
						foreach ( $subscriptions as $subscription ) {
							$subscription->update_meta_data( '_svea_iv_billing_ssn', sanitize_text_field( wp_unslash( $_POST['iv_billing_ssn'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
							$subscription->save();
						}
					}
				} else {
					wc_add_notice( __( 'Personal/organisation number is required.', 'svea-webpay-for-woocommerce' ), 'error' );
					return [
						'result' => 'failure',
					];
				}

				if ( $subscriptions ) {
					foreach ( $subscriptions as $subscription ) {
						$subscription->update_meta_data( '_svea_customer_type', sanitize_text_field( wp_unslash( $_POST['iv_billing_customer_type'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
						$subscription->save();
					}
				}

				$customer_information->setStreetAddress( $customer_address_1 );
				break;
			// Handle countries not supported by the payment gateway
			default:
				wc_add_notice( __( 'Country is not supported for invoice payments.', 'svea-webpay-for-woocommerce' ), 'error' );

				return [
					'result' => 'failure',
				];
		}

		$return_url = $wc_order->get_checkout_order_received_url();

		if ( isset( $_POST['iv_billing_customer_type'] ) && $_POST['iv_billing_customer_type'] === 'company' // phpcs:ignore WordPress.Security.NonceVerification.Missing
			&& ! $this->same_shipping_as_billing && strlen( $wc_order->get_shipping_first_name() ) > 0
			&& strlen( $wc_order->get_shipping_last_name() ) > 0 ) {
			$customer_reference = $wc_order->get_shipping_first_name() . ' ' . $wc_order->get_shipping_last_name();

			if ( function_exists( 'mb_strlen' ) ) {
				if ( mb_strlen( $customer_reference ) > 32 ) {
					$customer_reference = mb_substr( $customer_reference, 0, 29 ) . '...';
				}
			} else if ( strlen( $customer_reference ) > 32 ) {
				$customer_reference = substr( $customer_reference, 0, 29 ) . '...';
			}

			$svea_order->setCustomerReference( $customer_reference );
		}

		/**
		 * Set customer information in the Svea Order
		 */
		$customer_information
			->setZipCode( $customer_zip_code )
			->setLocality( $customer_city )
			->setIpAddress( isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '' ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
			->setEmail( $customer_email )
			->setPhoneNumber( $customer_phone )
			->setCoAddress( $customer_address_2 );

		$svea_order->addCustomerDetails( $customer_information );

		/**
		 * If we are hooked into WooCommerce subscriptions,
		 * see if any payment is required right now
		 */
		if ( $subscriptions && $wc_order->get_total() <= 0 ) {
			$wc_order->payment_complete();

			// Remove cart
			WC()->cart->empty_cart();

			if ( class_exists( '\WC_Subscriptions_Change_Payment_Gateway' ) ) {
				foreach ( $subscriptions as $subscription ) {
					\WC_Subscriptions_Change_Payment_Gateway::update_payment_method( $subscription, $this->id );
				}
			}

			return [
				'result'   => 'success',
				'redirect' => $return_url,
			];
		}

		self::log( 'Issuing payment for order: #' . $wc_order->get_id() );

		if ( $strong_auth ) {
			$confirmation_url = $this->get_strong_auth_callback_url(
				$wc_order,
				'wc_gateway_svea_invoice_strong_auth_confirmed',
				'confirmed',
				true
			);

			$rejection_url = $this->get_strong_auth_callback_url(
				$wc_order,
				'wc_gateway_svea_invoice_strong_auth_rejected',
				'rejected'
			);

			$svea_order->setIdentificationConfirmationUrl( $confirmation_url );
			$svea_order->setIdentificationRejectionUrl( $rejection_url );
		}

		try {
			$response = $svea_order->useInvoicePayment()->doRequest();
		} catch ( \Exception $e ) {
			self::log( 'Error message for order #' . $wc_order->get_id() . ', ' . $e->getMessage() );
			wc_add_notice( __( 'An error occurred whilst connecting to Svea. Please contact the store owner and display this message.', 'svea-webpay-for-woocommerce' ), 'error' );

			return [
				'result' => 'failure',
			];
		}

		if ( ! $response || ! isset( $response->accepted ) || ! $response->accepted ) {
			if ( isset( $response->resultcode ) ) {
				if ( isset( $response->errormessage ) ) {
					self::log( 'Error message for order #' . $wc_order->get_id() . ', ' . $response->errormessage );
				}

				wc_add_notice( Helper::get_svea_error_message( $response->resultcode ), 'error' );
				$wc_order->add_order_note(
					sprintf(
						// translators: %s is the error that the customer received
						__( 'Customer received error: %s', 'svea-webpay-for-woocommerce' ),
						Helper::get_svea_error_message( $response->resultcode )
					)
				);

			} else {
				self::log( 'Unknown error occurred for payment with order number: #' . $wc_order->get_id() );
				wc_add_notice( __( 'An unknown error occurred. Please contact the store owner about this issue.', 'svea-webpay-for-woocommerce' ), 'error' );
			}

			return [
				'result' => 'failure',
			];
		}

		if ( $subscriptions ) {
			foreach ( $subscriptions as $subscription ) {
				if ( $subscription->get_payment_method() !== $this->id ) {
					$subscription->set_payment_method( $this->id );
					$subscription->save();
				}
			}
		}

		$svea_order_id = $response->sveaOrderId; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase

		$wc_order->update_meta_data( '_svea_order_id', $svea_order_id );
		$wc_order->save();

		if ( $strong_auth && ! empty( $response->redirectUrl ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
			self::log( 'Redirecting to identification url for order #' . $wc_order->get_id() );

			Cron_Functions::setup_strong_auth_check_cron( $order_id, $svea_order_id, 'invoice' );

			return [
				'result'   => 'success',
				'redirect' => $response->redirectUrl, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
			];
		}

		self::log( 'Payment complete for order #' . $wc_order->get_id() );

		$wc_order->payment_complete( $svea_order_id );

		// Remove cart
		WC()->cart->empty_cart();

		return [
			'result'   => 'success',
			'redirect' => $return_url,
		];
	}

	/**
	 * Check if we should use strong auth in this payment
	 *
	 * @param string $country
	 * @param string $customer_type
	 * @return bool
	 */
	public function uses_strong_auth( string $country, string $customer_type ) {
		$strong_auth = false;

		if ( strtoupper( $country ) === 'SE' ) {
			// For individual customers in Sweden, strong auth is always required
			if (
				$customer_type === 'individual' ||
				$this->get_option( 'strong_auth_se' ) === 'yes'
			) {
				$strong_auth = true;
			}
		}

		return $strong_auth;
	}

	/**
	 * Adds fields to subscription orders
	 *
	 * @return  void
	 */
	public function add_subscription_order_fields( $subscription ) {
		if ( ! function_exists( 'wcs_is_subscription' ) || ! wcs_is_subscription( $subscription ) ) {
			return;
		}

		$post_data = [
			'iv_billing_customer_type'    => $subscription->get_meta( '_svea_customer_type' ) ?: $subscription->get_meta( '_svea_iv_billing_customer_type' ),
			'iv_billing_address_selector' => $subscription->get_meta( '_svea_address_selector' ),
			'iv_billing_org_number'       => $subscription->get_meta( '_svea_iv_billing_org_number' ),
			'iv_billing_ssn'              => $subscription->get_meta( '_svea_iv_billing_ssn' ),
			'iv_billing_vat_number'       => $subscription->get_meta( '_svea_iv_billing_vat_number' ),
			'iv_birth_date_year'          => $subscription->get_meta( '_svea_iv_birth_date_year' ),
			'iv_birth_date_month'         => $subscription->get_meta( '_svea_iv_birth_date_month' ),
			'iv_birth_date_day'           => $subscription->get_meta( '_svea_iv_birth_date_day' ),
			'iv_billing_initials'         => $subscription->get_meta( '_svea_iv_billing_initials' ),
		];

		include( WC_SVEAWEBPAY_GATEWAY_PLUGIN_DIR . '/partials/invoice/admin-subscription.php' );
	}

	/**
	 * Validate order fields passed in subscriptions
	 *
	 * @return mixed
	 */
	public function validate_subscription_order_fields( $payment_method_id, $payment_meta, $subscription ) {
		return $payment_meta;
	}

	/**
	 * Save meta on subscription
	 *
	 * @param int $post_id
	 * @param WP_Post $post
	 *
	 * @return void
	 */
	public function save_subscription_meta( $post_id ) {
		if ( isset( $_POST['wc_order_action'] ) && strlen( sanitize_text_field( wp_unslash( $_POST['wc_order_action'] ) ) ) > 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
			return;
		}

		$subscription = wcs_get_subscription( $post_id );

		if ( ! isset( $_POST['_billing_country'] ) || ! isset( $_POST['_iv_billing_customer_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
			return;
		}

		if ( ! isset( $_POST['_payment_method'] ) || $_POST['_payment_method'] !== $this->id ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
			return;
		}

		$customer_country = strtoupper( sanitize_text_field( wp_unslash( $_POST['_billing_country'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
		$customer_type = sanitize_text_field( wp_unslash( $_POST['_iv_billing_customer_type'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing

		switch ( strtoupper( $customer_country ) ) {
			case 'SE':
			case 'DK':
			case 'NO':
			case 'FI':
				if ( $customer_type === 'company' ) {
					if ( ! isset( $_POST['_address_selector'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>Organisation number</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					} else if ( ! isset( $_POST['_iv_billing_org_number'] ) || strlen( sanitize_text_field( wp_unslash( $_POST['_iv_billing_org_number'] ) ) ) <= 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>Organisation number</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					}
				} else if ( $customer_type === 'individual' ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
					if ( ! isset( $_POST['_iv_billing_ssn'] ) || strlen( sanitize_text_field( wp_unslash( $_POST['_iv_billing_ssn'] ) ) ) <= 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>Personal number</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					}
				} else {
					wcs_add_admin_notice( __( 'Invalid customer type', 'svea-webpay-for-woocommerce' ), 'error' );
					return;
				}
				break;
			case 'NL':
				if ( $customer_type === 'company' ) {
					if ( ! isset( $_POST['_iv_billing_vat_number'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>VAT number</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					}

					if ( ! isset( $_POST['_billing_company'] ) || strlen( sanitize_text_field( wp_unslash( $_POST['_billing_company'] ) ) ) <= 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>Company Name</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					}
				} else if ( $customer_type === 'individual' ) {
					if ( ! isset( $_POST['_iv_billing_initials'] ) || strlen( sanitize_text_field( wp_unslash( $_POST['_iv_billing_initials'] ) ) ) < 2 ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>Initials</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					}

					if ( ! isset( $_POST['_iv_birth_date_year'] ) || ! isset( $_POST['_iv_birth_date_month'] ) || ! isset( $_POST['_iv_birth_date_day'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>Date of birth</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					}
				} else {
					wcs_add_admin_notice( __( 'Invalid customer type', 'svea-webpay-for-woocommerce' ), 'error' );
					return;
				}
				break;
			case 'DE':
				if ( $customer_type === 'company' ) {
					if ( ! isset( $_POST['_iv_billing_vat_number'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>VAT number</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					}

					if ( ! isset( $_POST['_billing_company'] ) || strlen( sanitize_text_field( wp_unslash( $_POST['_billing_company'] ) ) ) <= 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>Company Name</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					}
				} else if ( $customer_type === 'individual' ) {
					if ( ! isset( $_POST['_iv_birth_date_year'] ) || ! isset( $_POST['_iv_birth_date_month'] ) || ! isset( $_POST['_iv_birth_date_day'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
						wcs_add_admin_notice( __( '<strong>Date of birth</strong> is a required field.', 'svea-webpay-for-woocommerce' ), 'error' );
						return;
					}
				} else {
					wcs_add_admin_notice( __( 'Invalid customer type', 'svea-webpay-for-woocommerce' ), 'error' );
					return;
				}
				break;
		}

		$fields = [
			'_svea_customer_type'         => '_iv_billing_customer_type',
			'_svea_address_selector'      => '_address_selector',
			'_svea_iv_billing_ssn'        => '_iv_billing_ssn',
			'_svea_iv_billing_initials'   => '_iv_billing_initials',
			'_svea_iv_billing_vat_number' => '_iv_billing_vat_number',
			'_svea_iv_birth_date_day'     => '_iv_birth_date_day',
			'_svea_iv_birth_date_month'   => '_iv_birth_date_month',
			'_svea_iv_birth_date_year'    => '_iv_birth_date_year',
			'_svea_iv_billing_org_number' => '_iv_billing_org_number',
		];

		foreach ( $fields as $field_key => $field_value ) {
			if ( ! isset( $_POST[ $field_value ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
				continue;
			}

			$subscription->update_meta_data( $field_key, sanitize_text_field( wp_unslash( $_POST[ $field_value ] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
		}
		$subscription->save();
	}

	/**
	 * Handles scheduled subscription payments
	 *
	 * @param   float       $amount_to_charge   the amount that should be charged
	 * @param   WC_Order    $wc_order           the original order
	 * @param   int         $product_id         id of the subscription product
	 * @return  void
	 */
	public function scheduled_subscription_payment( $amount_to_charge, $wc_order ) {

		self::log( 'Scheduled subscription payment initiated' );

		/**
		 * Get the subscription from the WooCommerce order
		 */
		$subscriptions = wcs_get_subscriptions_for_order( $wc_order->get_id(), [ 'order_type' => 'any' ] );

		$subscription = array_shift( $subscriptions );

		$wc_original_order = false;

		if ( $subscription->get_parent() !== false ) {
			$wc_original_order = $subscription->get_parent();
		}

		$customer_first_name = $wc_order->get_billing_first_name();
		$customer_last_name = $wc_order->get_billing_last_name();
		$customer_address_1 = $wc_order->get_billing_address_1();
		$customer_address_2 = $wc_order->get_billing_address_2();
		$customer_zip_code = $wc_order->get_billing_postcode();
		$customer_city = $wc_order->get_billing_city();
		$customer_country = $wc_order->get_billing_country();
		$customer_email = $wc_order->get_billing_email();
		$customer_phone = $wc_order->get_billing_phone();
		$customer_company = $wc_order->get_billing_company();

		$customer_type = $subscription->get_meta( '_svea_customer_type' ) ?: $subscription->get_meta( '_svea_iv_billing_customer_type' );

		$invoice_fee_label = $this->get_option( 'invoice_fee_label_' . strtolower( $customer_country ) );
		$invoice_fee = floatval( $this->get_option( 'invoice_fee_' . strtolower( $customer_country ) ) );
		$invoice_fee_taxable = $this->get_option( 'invoice_fee_taxable_' . strtolower( $customer_country ) ) === 'yes';

		if ( strlen( $invoice_fee_label ) > 0 && is_numeric( $invoice_fee ) ) {
			$invoice_fee_exists = false;

			foreach ( $wc_order->get_fees() as $fee ) {
				if ( $fee->get_name() === $invoice_fee_label ) {
					$invoice_fee_exists = true;
					break;
				}
			}

			if ( $invoice_fee > 0 && ! $invoice_fee_exists ) {
				$fee = new WC_Order_item_Fee();
				$fee->set_name( $invoice_fee_label );
				$fee->set_total( $invoice_fee );
				$fee->set_order_id( $wc_order->get_id() );

				if ( $invoice_fee_taxable ) {
					$invoice_tax_rates = WC_Tax::find_rates(
						[
							'country'  => $wc_order->get_billing_country(),
							'state'    => $wc_order->get_billing_state(),
							'city'     => $wc_order->get_billing_city(),
							'postcode' => $wc_order->get_billing_postcode(),
						]
					);

					$invoice_fee_tax = 0;

					if ( count( $invoice_tax_rates ) > 0 ) {
						$invoice_tax_rate = array_shift( $invoice_tax_rates );

						$fee_total = $invoice_fee * ( $invoice_tax_rate['rate'] / 100 + 1 );

						$invoice_fee_tax = $fee_total - $invoice_fee;
					} else {
						$invoice_fee_tax = 0;
					}

					$fee->set_tax_status( 'taxable' );
					$fee->set_tax_class( '' );
					$fee->set_total_tax( $invoice_fee_tax );
				}

				$fee->save();

				$wc_order->add_item( $fee );

				/**
				 * We need WooCommerce to recalculate the totals after we have added our fee
				 */
				$wc_order->calculate_totals();
			}
		}

		$this->testmode = $this->get_option( 'testmode_' . strtolower( $customer_country ) ) === 'yes';

		$config = $this->get_config( $customer_country, $customer_type );

		/**
		 * Convert our WooCommerce order to Svea
		 */
		// $svea_order = WC_Gateway_Svea_Helper::create_svea_subscription_order( $wc_order, $config );
		// Use same helper function for both subscription payments and regular ones
		$svea_order = Helper::create_svea_order( $wc_order, $config );

		$svea_order
			->setClientOrderNumber( apply_filters( 'woocommerce_sveawebpay_invoice_client_order_number', $wc_order->get_order_number() ) )
			->setCurrency( get_woocommerce_currency() )
			->setCountryCode( $customer_country )
			->setOrderDate( date( 'c' ) );

		/**
		 * Ensure that data is fetched from both the old and the new system
		 */
		$svea_data = [
			'customer_type'    => $subscription->get_meta( '_svea_customer_type' ) ?: $subscription->get_meta( '_svea_iv_billing_customer_type' ),
			'address_selector' => $subscription->get_meta( '_svea_address_selector' ),
			'org_number'       => $subscription->get_meta( '_svea_iv_billing_org_number' ),
			'initials'         => $subscription->get_meta( '_svea_iv_billing_initials' ),
			'ssn'              => $subscription->get_meta( '_svea_iv_billing_ssn' ),
			'vat_number'       => $subscription->get_meta( '_svea_iv_billing_vat_number' ),
			'birth_date_year'  => $subscription->get_meta( '_svea_iv_birth_date_year' ),
			'birth_date_month' => $subscription->get_meta( '_svea_iv_birth_date_month' ),
			'birth_date_day'   => $subscription->get_meta( '_svea_iv_birth_date_day' ),
		];

		switch ( strtoupper( $customer_country ) ) {
			case 'SE':
			case 'NO':
			case 'FI':
				if ( $svea_data['customer_type'] === 'company' ) {
					$customer_information = WebPayItem::companyCustomer()
						->setNationalIdNumber( $svea_data['org_number'] );

					if ( $svea_data['address_selector']
						&& strlen( (string) $svea_data['address_selector'] ) > 0 ) {
						$customer_information->setAddressSelector( $svea_data['address_selector'] );
					}
				} else if ( $svea_data['customer_type'] === 'individual' ) {
					$customer_information = WebPayItem::individualCustomer()
						->setName( $customer_first_name, $customer_last_name )
						->setNationalIdNumber( $svea_data['ssn'] );
				}

				$customer_information->setStreetAddress( $customer_address_1 );
				break;
		}

		if ( $svea_data['customer_type']
			&& ! $this->same_shipping_as_billing && strlen( $wc_order->get_shipping_first_name() ) > 0
			&& strlen( $wc_order->get_shipping_last_name() ) > 0 ) {
			$customer_reference = $wc_order->get_shipping_first_name() . ' ' . $wc_order->get_shipping_last_name();

			if ( function_exists( 'mb_strlen' ) ) {
				if ( mb_strlen( $customer_reference ) > 32 ) {
					$customer_reference = mb_substr( $customer_reference, 0, 29 ) . '...';
				}
			} else if ( strlen( $customer_reference ) > 32 ) {
				$customer_reference = substr( $customer_reference, 0, 29 ) . '...';
			}

			$svea_order->setCustomerReference( $customer_reference );
		}

		$customer_information
			->setZipCode( $customer_zip_code )
			->setLocality( $customer_city )
			->setIpAddress( isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '' ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
			->setEmail( $customer_email )
			->setPhoneNumber( $customer_phone )
			->setCoAddress( $customer_address_2 );

		$svea_order->addCustomerDetails( $customer_information );

		try {
			$response = $svea_order->useInvoicePayment()->doRequest();
		} catch ( \Exception $e ) {
			\WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $wc_order );

			$wc_order->update_status( 'failed' );

			self::log( 'Error: ' . $e->getMessage() );

			$wc_order->add_order_note( __( 'Error occurred whilst processing subscription:', 'svea-webpay-for-woocommerce' ) . ' ' . $e->getMessage() );
			return;
		}

		/**
		 * See if the response was accepted and successful
		 */
		if ( ! $response || ! isset( $response->accepted ) || ! $response->accepted ) {

			\WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $wc_order );

			$wc_order->update_status( 'failed' );

			self::log( 'Payment failed' );

			if ( isset( $response->resultcode ) ) {
				$wc_order->add_order_note(
					sprintf(
						// translators: %s is the error that occurred when processing the subscription
						__( 'Error occurred whilst processing subscription: %s', 'svea-webpay-for-woocommerce' ),
						Helper::get_svea_error_message( $response->resultcode )
					)
				);
			} else {
				$wc_order->add_order_note(
					sprintf(
						// translators: %s is the error that occurred when processing the subscription
						__( 'Error occurred whilst processing subscription: %s', 'svea-webpay-for-woocommerce' ),
						__( 'An unknown error occurred. Please contact the store owner about this issue.', 'svea-webpay-for-woocommerce' )
					)
				);
			}

			return;
		}

		/**
		 * Retrieve Svea's order id, we will use this to track
		 * and administrate this order in the future
		 */
		$svea_order_id = $response->sveaOrderId; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase

		\WC_Subscriptions_Manager::process_subscription_payments_on_order( $wc_order );

		/**
		 * Save Svea's order id on the newly created subscription order
		 * so that we can administrate it in the future
		 */
		$wc_order->update_meta_data( '_svea_order_id', $svea_order_id );
		$wc_order->payment_complete( $svea_order_id );
		$wc_order->save();

		self::log( 'Payment successful' );
	}

	/**
	 * Cancels the order in svea
	 *
	 * @param   WC_Order    $order  the order being cancelled
	 * @param   string      $svea_order_id  id of the svea order
	 * @return  array       an array containing result and message
	 */
	public function cancel_order( $order, $svea_order_id ) {
		$customer_type = $order->get_meta( '_svea_customer_type' ) ?: $order->get_meta( '_svea_iv_billing_customer_type' );
		$config = $this->get_config( $order->get_billing_country(), $customer_type );

		$response = WebPayAdmin::cancelOrder( $config )
					->setCountryCode( $order->get_billing_country() )
					->setOrderId( $svea_order_id )
					->cancelInvoiceOrder()
					->doRequest();

		if ( ! $response || ! isset( $response->accepted ) || ! $response->accepted ) {
			return [
				'success' => false,
				'message' => $response->errormessage ?? '',
			];
		}

		/**
		 * The request was successful
		 */
		$order->add_order_note(
			__( 'The order has been cancelled in Svea.', 'svea-webpay-for-woocommerce' )
		);

		$order->update_status( 'cancelled' );

		return [
			'success' => true,
			'message' => __( 'The order has been cancelled in Svea.', 'svea-webpay-for-woocommerce' ),
		];
	}

	/**
	 * Credits the order in svea
	 *
	 * @param   WC_Order    $order  the order being credited
	 * @param   string      $svea_order_id  id of the svea order
	 * @return  array       an array containing result and message
	 */
	public function credit_order( $order, $svea_order_id ) {
		$customer_type = $order->get_meta( '_svea_customer_type' ) ?: $order->get_meta( '_svea_iv_billing_customer_type' );
		$config = $this->get_config( $order->get_billing_country(), $customer_type );

		$response = WebPayAdmin::queryOrder( $config )
			->setOrderId( $svea_order_id )
			->setCountryCode( $order->get_billing_country() )
			->queryInvoiceOrder()
			->doRequest();

		if ( ! $response || ! isset( $response->accepted ) || ! $response->accepted ) {
			return [
				'success' => false,
				'message' => $response->errormessage ?? '',
			];
		}

		$numbered_order_rows = $response->numberedOrderRows; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase

		$row_numbers = [];

		foreach ( $numbered_order_rows as $row ) {
			$row_numbers[] = $row->rowNumber; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
		}

		$invoice_ids = [];

		foreach ( $numbered_order_rows as $numbered_order_row ) {
			if ( is_null( $numbered_order_row->invoiceId ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
				return [
					'success' => false,
					'message' => __( 'An invoice could not be found, deliver the order first', 'svea-webpay-for-woocommerce' ),
				];
			}

			if ( ! isset( $invoice_ids[ $numbered_order_row->invoiceId ] ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
				$invoice_ids[ $numbered_order_row->invoiceId ] = [ // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
					'row_numbers'         => [],
					'numbered_order_rows' => [],
				];
			}

			$invoice_ids[ $numbered_order_row->invoiceId ]['row_numbers'][] = $numbered_order_row->rowNumber; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
			$invoice_ids[ $numbered_order_row->invoiceId ]['numbered_order_rows'][] = $numbered_order_row; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
		}

		foreach ( $invoice_ids as $invoice_id => $data ) {
			$response = WebPayAdmin::creditOrderRows( $config )
				->setCountryCode( $order->get_billing_country() )
				->setRowsToCredit( $data['row_numbers'] )
				->addNumberedOrderRows( $data['numbered_order_rows'] )
				->setInvoiceId( $invoice_id )
				->setInvoiceDistributionType( $this->get_distribution_type( $order->get_billing_country() ) )
				->creditInvoiceOrderRows()
				->doRequest();

			if ( ! $response || ! isset( $response->accepted ) || ! $response->accepted ) {
				return [
					'success' => false,
					'message' => $response->errormessage ?? '',
				];
			}
		}

		foreach ( array_keys( $order->get_items( [ 'line_item', 'fee', 'shipping' ] ) ) as $order_item_id ) {
			if ( wc_get_order_item_meta( $order_item_id, 'svea_credited' ) ) {
				continue;
			}

			wc_add_order_item_meta( $order_item_id, 'svea_credited', date( 'Y-m-d H:i:s' ) );
		}

		/**
		 * The request was successful
		 */
		$number_of_rows = count( $row_numbers );

		$order->update_status( 'refunded' );

		if ( $number_of_rows === 1 ) {
			$order->add_order_note(
				sprintf(
					// translators: %s is the number of items
					__( '%d item has been credited in Svea.', 'svea-webpay-for-woocommerce' ),
					$number_of_rows
				)
			);

			return [
				'success' => true,
				'message' => sprintf(
					// translators: %s is the number of items
					__( '%d item has been credited in Svea.', 'svea-webpay-for-woocommerce' ),
					$number_of_rows
				),
			];
		} else {
			$order->add_order_note(
				sprintf(
					// translators: %s is the number of items
					__( '%d items have been credited in Svea.', 'svea-webpay-for-woocommerce' ),
					$number_of_rows
				)
			);

			return [
				'success' => true,
				'message' => sprintf(
					// translators: %s is the number of items
					__( '%d items have been credited in Svea.', 'svea-webpay-for-woocommerce' ),
					$number_of_rows
				),
			];
		}
	}

	/**
	 * Query the Svea order used to verify a confirmed strong authentication callback.
	 *
	 * @param WC_Order $wc_order The WooCommerce order.
	 * @param string   $svea_order_id The Svea order ID.
	 * @return object
	 */
	protected function query_strong_auth_svea_order( WC_Order $wc_order, string $svea_order_id ) {
		$customer_type = $wc_order->get_meta( '_svea_customer_type' );
		$config = $this->get_config( $wc_order->get_billing_country(), $customer_type );

		return WebPayAdmin::queryOrder( $config )
			->setOrderId( $svea_order_id )
			->setCountryCode( $wc_order->get_billing_country() )
			->queryInvoiceOrder()
			->doRequest();
	}

	/**
	 * Delivers the order in svea
	 *
	 * @param   WC_Order    $order  the order being delivered
	 * @param   string      $svea_order_id  id of the svea order
	 * @return  array       an array containing result and message
	 */
	public function deliver_order( $order, $svea_order_id ) {
		$customer_type = $order->get_meta( '_svea_customer_type' ) ?: $order->get_meta( '_svea_iv_billing_customer_type' );
		$config = $this->get_config( $order->get_billing_country(), $customer_type );
		$is_b2b = $customer_type === 'company';

		$response = WebPay::deliverOrder( $config )
			->setOrderId( $svea_order_id )
			->setCountryCode( $order->get_billing_country() )
			->setInvoiceDistributionType( $this->get_distribution_type( $order->get_billing_country(), $is_b2b ) )
			->deliverInvoiceOrder()
			->doRequest();

		if ( ! $response || ! isset( $response->accepted ) || ! $response->accepted ) {
			return [
				'success' => false,
				'message' => $response->errormessage ?? '',
			];
		}

		foreach ( $order->get_items( [ 'line_item', 'fee', 'shipping' ] ) as $order_item_id => $order_item ) {
			wc_add_order_item_meta( $order_item_id, 'svea_delivered', date( 'Y-m-d H:i:s' ) );
		}

		$order->update_status( 'completed' );

		$order->add_order_note(
			__( 'All items have been delivered in Svea.', 'svea-webpay-for-woocommerce' )
		);

		return [
			'success' => true,
			'message' => __( 'All items have been delivered in Svea.', 'svea-webpay-for-woocommerce' ),
		];
	}

	/**
	 * Displays a thank you message for paying with Svea Invoice Payment on the receipt page.
	 *
	 * @param WC_Order $order The order object.
	 * @return void
	 */
	public function receipt_page( $order ) {
		echo '<p>' . esc_html__( 'Thank you for paying with Svea Invoice Payment', 'svea-webpay-for-woocommerce' ) . '</p>';
	}
}
