diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bff56eb..1caf5c69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.6.0] - 2026-01-28 +### Added +- Added support for manual activation of invoices for payments made with Walley and Klarna invoice methods. +### Fixed +- Fixed compatibility issue with Visma Pay. + ## [2.5.3] - 2025-07-02 ### Added - Added missing accessibility features diff --git a/package-lock.json b/package-lock.json index 2532214e..40aee09b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "paytrail-for-woocommerce", - "version": "2.5.2", + "version": "2.6.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "paytrail-for-woocommerce", - "version": "2.5.2", + "version": "2.6.0", "license": "MIT", "dependencies": { "babel-runtime": "^6.23.0", diff --git a/package.json b/package.json index 7e3c47a0..941a9a1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "paytrail-for-woocommerce", - "version": "2.5.3", + "version": "2.6.0", "description": "Paytrail is a payment gateway that offers 20+ payment methods for Finnish customers.", "private": true, "dependencies": { diff --git a/plugin.php b/plugin.php index e5d90161..9599b4ba 100644 --- a/plugin.php +++ b/plugin.php @@ -3,13 +3,13 @@ * Plugin Name: Paytrail for WooCommerce * Plugin URI: https://github.com/paytrail/paytrail-for-woocommerce * Description: Paytrail is a payment gateway that offers 20+ payment methods for Finnish customers. - * Version: 2.5.3 + * Version: 2.6.0 * Requires at least: 4.9 * Requires Plugins: woocommerce - * Tested up to: 6.8 + * Tested up to: 6.9 * Requires PHP: 7.3 * WC requires at least: 3.5 - * WC tested up to: 9.9 + * WC tested up to: 10.4.3 * Author: Paytrail * Author URI: https://www.paytrail.com/ * Text Domain: paytrail-for-woocommerce @@ -23,7 +23,7 @@ // Ensure that the file is being run within the WordPress context. if ( ! defined( 'ABSPATH' ) ) { - die; + die; } /** @@ -31,414 +31,460 @@ */ final class Plugin { - /** - * WooCommerce payment gateway ID. - */ - public const GATEWAY_ID = 'paytrail'; - - /** - * Merchant ID for the test mode. - */ - public const TEST_MERCHANT_ID = 375917; - - /** - * Secret key for the test mode. - */ - public const TEST_SECRET_KEY = 'SAIPPUAKAUPPIAS'; - - public const PAYMENT_METHOD_IMG_URL = 'https://static.paytrail.com/static/img/payment-methods'; - - public const BASE_URL = 'paytrail/'; - - public const ADD_CARD_REDIRECT_SUCCESS_URL = 'card-success'; - - public const ADD_CARD_REDIRECT_CANCEL_URL = 'card-cancel'; - - public const ADD_CARD_CONTEXT_MY_ACCOUNT = 'my_account'; - - public const ADD_CARD_CONTEXT_CHECKOUT= 'checkout'; - - public const ADD_CARD_CONTEXT_CHANGE_PAYMENT_METHOD = 'change_payment_method'; - - public const CARD_ENDPOINT = 'card'; - - public const CALLBACK_URL = 'callback'; - - /** - * Singleton instance. - * - * @var Plugin - */ - private static $instance; - - /** - * Plugin version. - * - * @var string - */ - public static $version; - - /** - * Plugin directory. - * - * @var string - */ - protected $plugin_dir; - - /** - * Plugin directory URL. - * - * @var string - */ - protected $plugin_dir_url; - - /** - * Container array for possible initialization errors. - * - * @var array - */ - protected $errors = []; - - /** - * Plugin info - * - * @var array - */ - protected $plugin_info = [ - 'Plugin Name', - 'Plugin URI', - 'Description', - 'Version', - 'Author', - 'Author URI', - 'Text Domain', - 'Domain Path', - ]; - public function enqueue_jquery() { - // Enqueue jQuery script - wp_enqueue_script('jquery'); - } - - /** - * Constructor function - */ - protected function __construct() { - $this->plugin_dir = __DIR__; - $this->plugin_dir_url = plugin_dir_url( __FILE__ ); - $this->plugin_info = array_combine( $this->plugin_info, get_file_data( __FILE__, $this->plugin_info ) ); - - self::$version = $this->plugin_info['Version']; - - // Load the plugin textdomain. - load_plugin_textdomain( 'paytrail-for-woocommerce', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); - - // Register customizations - add_action( 'customize_register', [ $this, 'checkout_customizations' ] ); - // Add custom styles - add_action( 'wp_head', [ $this, 'paytrail_checkout_customize_css' ] ); - // Enable WP Dashicons on frontend - add_action( 'wp_enqueue_scripts', function() { - wp_enqueue_style( 'dashicons' ); - } ); - - add_action( 'before_woocommerce_init', function() { - if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { - \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); - \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks',__FILE__, true ); - } - } ); - - // Blocks compatibility - add_action( 'woocommerce_blocks_loaded', [__CLASS__,'register_blocks_support'] ); - - // Enqueue jQuery - add_action('admin_enqueue_scripts', array($this, 'enqueue_jquery')); - add_action('admin_enqueue_scripts', array($this, 'enque_jquery_scripts')); - - //Add OP Lasku calculator to the product and cart page - add_action('woocommerce_init', array($this, 'op_lasku_init')); - } - - /** - * Register intro scripts - */ - public static function register_intro_scripts() { - // Get plugin directory URL - $plugin_instance = Plugin::instance(); - $plugin_dir_url = $plugin_instance->get_plugin_dir_url(); - $plugin_version = $plugin_instance->get_plugin_info()['Version']; - - // Register the custom script - wp_register_script( - 'introScripts', - $plugin_dir_url . 'dist/assets/frontend/intro-scripts.js', - ['jquery'], // Dependency on jQuery - $plugin_version, - true // Enqueue in the footer - ); - - // Enqueue the custom script - wp_enqueue_script('introScripts'); - } - - /** - * Enqueue jQuery UI from WordPress core - */ - public function enque_jquery_scripts($hook) { - if ($hook == 'woocommerce_page_wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'checkout' && isset($_GET['section']) && $_GET['section'] == 'paytrail') { - - wp_enqueue_script('jquery'); - // Enqueue jQuery UI Core - wp_enqueue_script('jquery-ui-core'); - // Enqueue jQuery UI Dialog - wp_enqueue_script('jquery-ui-dialog'); - // Add jQuery UI styles - wp_enqueue_style('jquery-ui-css', 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css'); - // Enqueue intro scripts - self::register_intro_scripts(); - - } - } - - /** - * Print custom styles - */ - public function paytrail_checkout_customize_css() { - ?> - - add_setting( 'paytrail_group_background' , array( - 'default' => '#ebebeb', - 'transport' => 'refresh', - ) ); - $wp_customize->add_setting( 'paytrail_group_text' , array( - 'default' => '#515151', - 'transport' => 'refresh', - ) ); - $wp_customize->add_setting( 'paytrail_group_highlighted_background' , array( - 'default' => '#33798d', - 'transport' => 'refresh', - ) ); - $wp_customize->add_setting( 'paytrail_group_highlighted_text' , array( - 'default' => '#ffffff', - 'transport' => 'refresh', - ) ); - $wp_customize->add_setting( 'paytrail_group_hover_background' , array( - 'default' => '#d0d0d0', - 'transport' => 'refresh', - ) ); - $wp_customize->add_setting( 'paytrail_group_hover_text' , array( - 'default' => '#313131', - 'transport' => 'refresh', - ) ); - $wp_customize->add_setting( 'paytrail_method_highlighted' , array( - 'default' => '#33798d', - 'transport' => 'refresh', - ) ); - $wp_customize->add_setting( 'paytrail_method_hover' , array( - 'default' => '#5399ad', - 'transport' => 'refresh', - ) ); - // Section - $wp_customize->add_section( 'paytrail_checkout_customize_section' , array( - 'title' => __( 'Payment page personalization', 'paytrail-for-woocommerce' ), - 'priority' => 30, - ) ); - // Controls - $wp_customize->add_control( new \WP_Customize_Color_Control( $wp_customize, 'paytrail_bgcolor', array( - 'label' => __( 'Payment method group background', 'paytrail-for-woocommerce' ), - 'section' => 'paytrail_checkout_customize_section', - 'settings' => 'paytrail_group_background', - ) ) ); - $wp_customize->add_control( new \WP_Customize_Color_Control( $wp_customize, 'paytrail_fgcolor', array( - 'label' => __( 'Payment method group text', 'paytrail-for-woocommerce' ), - 'section' => 'paytrail_checkout_customize_section', - 'settings' => 'paytrail_group_text', - ) ) ); - $wp_customize->add_control( new \WP_Customize_Color_Control( $wp_customize, 'paytrail_bgcolor_selected', array( - 'label' => __( 'Selected payment method group background', 'paytrail-for-woocommerce' ), - 'section' => 'paytrail_checkout_customize_section', - 'settings' => 'paytrail_group_highlighted_background', - ) ) ); - $wp_customize->add_control( new \WP_Customize_Color_Control( $wp_customize, 'paytrail_fgcolor_selected', array( - 'label' => __( 'Selected payment method group text', 'paytrail-for-woocommerce' ), - 'section' => 'paytrail_checkout_customize_section', - 'settings' => 'paytrail_group_highlighted_text', - ) ) ); - $wp_customize->add_control( new \WP_Customize_Color_Control( $wp_customize, 'paytrail_bgcolor_hover', array( - 'label' => __( 'Payment method group background hover', 'paytrail-for-woocommerce' ), - 'section' => 'paytrail_checkout_customize_section', - 'settings' => 'paytrail_group_hover_background', - ) ) ); - $wp_customize->add_control( new \WP_Customize_Color_Control( $wp_customize, 'paytrail_fgcolor_hover', array( - 'label' => __( 'Payment method group text hover', 'paytrail-for-woocommerce' ), - 'section' => 'paytrail_checkout_customize_section', - 'settings' => 'paytrail_group_hover_text', - ) ) ); - $wp_customize->add_control( new \WP_Customize_Color_Control( $wp_customize, 'paytrail_bordercolor_selected', array( - 'label' => __( 'Selected payment method', 'paytrail-for-woocommerce' ), - 'section' => 'paytrail_checkout_customize_section', - 'settings' => 'paytrail_method_highlighted', - ) ) ); - $wp_customize->add_control( new \WP_Customize_Color_Control( $wp_customize, 'paytrail_bordercolor_hover', array( - 'label' => __( 'Payment method hover', 'paytrail-for-woocommerce' ), - 'section' => 'paytrail_checkout_customize_section', - 'settings' => 'paytrail_method_hover', - ) ) ); - } - - /** - * Singleton instance getter function - * - * @return Plugin - */ - public static function instance() { - if ( is_null( self::$instance ) ) { - // Construct the object. - self::$instance = new self(); - - // Run initialization checks. If any of the checks - // fails, interrupt the execution. - if ( ! self::$instance->initialization_checks() ) { - return; - } - - // Check if Composer has been initialized in this directory. - // Otherwise we just use global composer autoloading. - if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { - require_once __DIR__ . '/vendor/autoload.php'; - } - - // Create new instance of Router class - new Router(); - - // Add the gateway class to WooCommerce. - add_filter( 'woocommerce_payment_gateways', function( $gateways ) { - $gateways[] = Gateway::CLASS; - - return $gateways; - }); - - } - - return self::$instance; - } - - /** - * Run checks for plugin requirements. - * - * Returns false if checks failed. - * - * @return bool - */ - protected function initialization_checks() { - $errors = []; - - $errors[] = self::check_php_version(); - $errors[] = self::check_woocommerce_active_status(); - $errors[] = self::check_woocommerce_version(); - - $errors = array_filter( $errors ); - - if ( ! empty( $errors ) ) { - add_action( 'admin_notices', function() use ( $errors ) { - echo '
'; - array_walk( $errors, 'esc_html_e' ); - echo '
'; - }); - - return false; - } - else { - return true; - } - } - - /** - * Checks to run on plugin activation - * - * @return void - */ - public static function activation_check() { - $checks = [ - 'check_php_version', - 'check_woocommerce_active_status', - 'check_woocommerce_version', - ]; - - array_walk( $checks, function( $check ) { - $error = call_user_func( __CLASS__ . '::' . $check ); - - if ( $error ) { - wp_die( esc_html( $error ) ); - } - }); - } - - /** - * Ensure that the PHP version is at least 7.3. - * - * @return string|null - */ - public static function check_php_version() : ?string { - if ( ! version_compare( PHP_VERSION, '7.3.0', '>=' ) ) { - return sprintf( - // translators: The placeholder contains the current PHP version. - esc_html__( 'Paytrail payment gateway plugin requires a PHP version of at least 7.3. You are currently running version %1$s.', 'paytrail-for-woocommerce' ), - esc_html( PHP_VERSION ) - ); - } - - return null; - } - - /** - * Ensure that the WooCommerce plugin is active. - * - * @return string|null - */ - public static function check_woocommerce_active_status() : ?string { - if ( ! class_exists( '\WC_Payment_Gateway' ) ) { - return esc_html__( 'Paytrail payment gateway plugin requires WooCommerce to be activated.', 'paytrail-for-woocommerce' ); - } - - return null; - } - - /** + /** + * WooCommerce payment gateway ID. + */ + public const GATEWAY_ID = 'paytrail'; + + /** + * Merchant ID for the test mode. + */ + public const TEST_MERCHANT_ID = 375917; + + /** + * Secret key for the test mode. + */ + public const TEST_SECRET_KEY = 'SAIPPUAKAUPPIAS'; + + public const PAYMENT_METHOD_IMG_URL = 'https://static.paytrail.com/static/img/payment-methods'; + + public const BASE_URL = 'paytrail/'; + + public const ADD_CARD_REDIRECT_SUCCESS_URL = 'card-success'; + + public const ADD_CARD_REDIRECT_CANCEL_URL = 'card-cancel'; + + public const ADD_CARD_CONTEXT_MY_ACCOUNT = 'my_account'; + + public const ADD_CARD_CONTEXT_CHECKOUT = 'checkout'; + + public const ADD_CARD_CONTEXT_CHANGE_PAYMENT_METHOD = 'change_payment_method'; + + public const CARD_ENDPOINT = 'card'; + + public const CALLBACK_URL = 'callback'; + + /** + * Singleton instance. + * + * @var Plugin + */ + private static $instance; + + /** + * Plugin version. + * + * @var string + */ + public static $version; + + /** + * Plugin directory. + * + * @var string + */ + protected $plugin_dir; + + /** + * Plugin directory URL. + * + * @var string + */ + protected $plugin_dir_url; + + /** + * Container array for possible initialization errors. + * + * @var array + */ + protected $errors = array(); + + /** + * Plugin info + * + * @var array + */ + protected $plugin_info = array( + 'Plugin Name', + 'Plugin URI', + 'Description', + 'Version', + 'Author', + 'Author URI', + 'Text Domain', + 'Domain Path', + ); + + /** + * Gateway instance + * + * @var Gateway + */ + protected $gateway; + + /** + * Enqueue jQuery script + */ + public function enqueue_jquery() { + // Enqueue jQuery script + wp_enqueue_script( 'jquery' ); + } + + /** + * Constructor function + */ + protected function __construct() { + $this->plugin_dir = __DIR__; + $this->plugin_dir_url = plugin_dir_url( __FILE__ ); + $this->plugin_info = array_combine( $this->plugin_info, get_file_data( __FILE__, $this->plugin_info ) ); + + self::$version = $this->plugin_info['Version']; + + // Load the plugin textdomain. + load_plugin_textdomain( 'paytrail-for-woocommerce', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); + + // Register customizations. + add_action( 'customize_register', array( $this, 'checkout_customizations' ) ); + // Add custom styles. + add_action( 'wp_head', array( $this, 'paytrail_checkout_customize_css' ) ); + // Enable WP Dashicons on frontend. + add_action( + 'wp_enqueue_scripts', + function () { + wp_enqueue_style( 'dashicons' ); + } + ); + + add_action( + 'before_woocommerce_init', + function () { + if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { + \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); + \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true ); + } + } + ); + + // Blocks compatibility. + add_action( 'woocommerce_blocks_loaded', array( __CLASS__, 'register_blocks_support' ) ); + + // Enqueue jQuery. + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_jquery' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_jquery_scripts' ) ); + + // Add OP Lasku calculator to the product and cart page. + add_action( 'woocommerce_init', array( $this, 'op_lasku_init' ) ); + + add_action( 'init', array( $this, 'initialize_gateway' ) ); + } + + /** + * Initialize the gateway + */ + public function initialize_gateway() { + $this->gateway(); + + add_filter( + 'woocommerce_payment_gateways', + function ( $gateways ) { + $gateways[] = $this->gateway(); + add_action( 'template_redirect', array( $this->gateway, 'on_redirect_to_thankyou_page' ) ); + + return $gateways; + } + ); + } + + /** + * Register intro scripts + */ + public static function register_intro_scripts() { + // Get plugin directory URL + $plugin_instance = self::instance(); + $plugin_dir_url = $plugin_instance->get_plugin_dir_url(); + $plugin_version = $plugin_instance->get_plugin_info()['Version']; + + // Register the custom script + wp_register_script( + 'introScripts', + $plugin_dir_url . 'dist/assets/frontend/intro-scripts.js', + array( 'jquery' ), // Dependency on jQuery + $plugin_version, + true // Enqueue in the footer + ); + + // Enqueue the custom script + wp_enqueue_script( 'introScripts' ); + } + + /** + * Enqueue jQuery UI from WordPress core + */ + public function enqueue_jquery_scripts( $hook ) { + if ( $hook == 'woocommerce_page_wc-settings' && isset( $_GET['tab'] ) && $_GET['tab'] == 'checkout' && isset( $_GET['section'] ) && $_GET['section'] == 'paytrail' ) { + + wp_enqueue_script( 'jquery' ); + // Enqueue jQuery UI Core + wp_enqueue_script( 'jquery-ui-core' ); + // Enqueue jQuery UI Dialog + wp_enqueue_script( 'jquery-ui-dialog' ); + // Add jQuery UI styles + wp_enqueue_style( 'jquery-ui-css', 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css' ); + // Enqueue intro scripts + self::register_intro_scripts(); + + } + } + + /** + * Print custom styles + */ + public function paytrail_checkout_customize_css() { + ?> + + add_setting( + 'paytrail_group_background', + array( + 'default' => '#ebebeb', + 'transport' => 'refresh', + ) + ); + $wp_customize->add_setting( + 'paytrail_group_text', + array( + 'default' => '#515151', + 'transport' => 'refresh', + ) + ); + $wp_customize->add_setting( + 'paytrail_group_highlighted_background', + array( + 'default' => '#33798d', + 'transport' => 'refresh', + ) + ); + $wp_customize->add_setting( + 'paytrail_group_highlighted_text', + array( + 'default' => '#ffffff', + 'transport' => 'refresh', + ) + ); + $wp_customize->add_setting( + 'paytrail_group_hover_background', + array( + 'default' => '#d0d0d0', + 'transport' => 'refresh', + ) + ); + $wp_customize->add_setting( + 'paytrail_group_hover_text', + array( + 'default' => '#313131', + 'transport' => 'refresh', + ) + ); + $wp_customize->add_setting( + 'paytrail_method_highlighted', + array( + 'default' => '#33798d', + 'transport' => 'refresh', + ) + ); + $wp_customize->add_setting( + 'paytrail_method_hover', + array( + 'default' => '#5399ad', + 'transport' => 'refresh', + ) + ); + // Section + $wp_customize->add_section( + 'paytrail_checkout_customize_section', + array( + 'title' => __( 'Payment page personalization', 'paytrail-for-woocommerce' ), + 'priority' => 30, + ) + ); + // Controls + $wp_customize->add_control( + new \WP_Customize_Color_Control( + $wp_customize, + 'paytrail_bgcolor', + array( + 'label' => __( 'Payment method group background', 'paytrail-for-woocommerce' ), + 'section' => 'paytrail_checkout_customize_section', + 'settings' => 'paytrail_group_background', + ) + ) + ); + $wp_customize->add_control( + new \WP_Customize_Color_Control( + $wp_customize, + 'paytrail_fgcolor', + array( + 'label' => __( 'Payment method group text', 'paytrail-for-woocommerce' ), + 'section' => 'paytrail_checkout_customize_section', + 'settings' => 'paytrail_group_text', + ) + ) + ); + $wp_customize->add_control( + new \WP_Customize_Color_Control( + $wp_customize, + 'paytrail_bgcolor_selected', + array( + 'label' => __( 'Selected payment method group background', 'paytrail-for-woocommerce' ), + 'section' => 'paytrail_checkout_customize_section', + 'settings' => 'paytrail_group_highlighted_background', + ) + ) + ); + $wp_customize->add_control( + new \WP_Customize_Color_Control( + $wp_customize, + 'paytrail_fgcolor_selected', + array( + 'label' => __( 'Selected payment method group text', 'paytrail-for-woocommerce' ), + 'section' => 'paytrail_checkout_customize_section', + 'settings' => 'paytrail_group_highlighted_text', + ) + ) + ); + $wp_customize->add_control( + new \WP_Customize_Color_Control( + $wp_customize, + 'paytrail_bgcolor_hover', + array( + 'label' => __( 'Payment method group background hover', 'paytrail-for-woocommerce' ), + 'section' => 'paytrail_checkout_customize_section', + 'settings' => 'paytrail_group_hover_background', + ) + ) + ); + $wp_customize->add_control( + new \WP_Customize_Color_Control( + $wp_customize, + 'paytrail_fgcolor_hover', + array( + 'label' => __( 'Payment method group text hover', 'paytrail-for-woocommerce' ), + 'section' => 'paytrail_checkout_customize_section', + 'settings' => 'paytrail_group_hover_text', + ) + ) + ); + $wp_customize->add_control( + new \WP_Customize_Color_Control( + $wp_customize, + 'paytrail_bordercolor_selected', + array( + 'label' => __( 'Selected payment method', 'paytrail-for-woocommerce' ), + 'section' => 'paytrail_checkout_customize_section', + 'settings' => 'paytrail_method_highlighted', + ) + ) + ); + $wp_customize->add_control( + new \WP_Customize_Color_Control( + $wp_customize, + 'paytrail_bordercolor_hover', + array( + 'label' => __( 'Payment method hover', 'paytrail-for-woocommerce' ), + 'section' => 'paytrail_checkout_customize_section', + 'settings' => 'paytrail_method_hover', + ) + ) + ); + } + + /** + * Singleton instance getter function + * + * @return Plugin + */ + public static function instance() { + if ( is_null( self::$instance ) ) { + // Check if Composer has been initialized in this directory. + // Otherwise we just use global composer autoloading. + if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { + require_once __DIR__ . '/vendor/autoload.php'; + } + + // Construct the object. + self::$instance = new self(); + + // Create new instance of Router class. + new Router(); + } + + return self::$instance; + } + + /** + * Ensure that the PHP version is at least 7.3. + * + * @return string|null + */ + public static function check_php_version(): ?string { + if ( ! version_compare( PHP_VERSION, '7.3.0', '>=' ) ) { + return sprintf( + // translators: The placeholder contains the current PHP version. + esc_html__( 'Paytrail payment gateway plugin requires a PHP version of at least 7.3. You are currently running version %1$s.', 'paytrail-for-woocommerce' ), + esc_html( PHP_VERSION ) + ); + } + + return null; + } + + /** + * Ensure that the WooCommerce plugin is active. + * + * @return string|null + */ + public static function check_woocommerce_active_status(): ?string { + if ( ! class_exists( '\WC_Payment_Gateway' ) ) { + return esc_html__( 'Paytrail payment gateway plugin requires WooCommerce to be activated.', 'paytrail-for-woocommerce' ); + } + + return null; + } + + /** * Register blocks support */ public static function register_blocks_support() { @@ -447,57 +493,57 @@ public static function register_blocks_support() { add_action( 'woocommerce_blocks_payment_method_type_registration', - function( \Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry ) { - $payment_method_registry->register( new Paytrail_Blocks_Support() ); + function ( \Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry ) { + $payment_method_registry->register( new Paytrail_Blocks_Support() ); } ); } } - /** - * Ensure that we have at least version 3.5 of the WooCommerce plugin. - * - * @return string|null - */ - public static function check_woocommerce_version() : ?string { - if ( - defined( 'WOO_COMMERCE_VERSION' ) && - version_compare( WOO_COMMERCE_VERSION, '3.5' ) === -1 - ) { - return esc_html__( 'Paytrail gateway plugin requires WooCommerce version of 3.5 or greater.', 'paytrail-for-woocommerce' ); - } - - return null; - } - - /** - * Get plugin directory. - * - * @return string - */ - public function get_plugin_dir() : string { - return $this->plugin_dir; - } - - /** - * Get plugin directory URL. - * - * @return string - */ - public function get_plugin_dir_url() : string { - return $this->plugin_dir_url; - } - - /** - * Get plugin info. - * - * @return array - */ - public function get_plugin_info() : array { - return $this->plugin_info; - } - - /** + /** + * Ensure that we have at least version 3.5 of the WooCommerce plugin. + * + * @return string|null + */ + public static function check_woocommerce_version(): ?string { + if ( + defined( 'WOO_COMMERCE_VERSION' ) && + version_compare( WOO_COMMERCE_VERSION, '3.5' ) === -1 + ) { + return esc_html__( 'Paytrail gateway plugin requires WooCommerce version of 3.5 or greater.', 'paytrail-for-woocommerce' ); + } + + return null; + } + + /** + * Get plugin directory. + * + * @return string + */ + public function get_plugin_dir(): string { + return $this->plugin_dir; + } + + /** + * Get plugin directory URL. + * + * @return string + */ + public function get_plugin_dir_url(): string { + return $this->plugin_dir_url; + } + + /** + * Get plugin info. + * + * @return array + */ + public function get_plugin_info(): array { + return $this->plugin_info; + } + + /** * Plugin url. * * @return string @@ -515,21 +561,31 @@ public static function plugin_abspath() { return trailingslashit( plugin_dir_path( __FILE__ ) ); } - /** - * Initialize OP Lasku calculator for product and cart page - */ - public function op_lasku_init() { - $settings = get_option('woocommerce_paytrail_settings'); - - if(isset($settings['op_lasku_calculator']) && 'yes' === $settings['op_lasku_calculator']) { - new \Paytrail\WooCommercePaymentGateway\Providers\OPLasku(); - } - } -} + /** + * Initialize OP Lasku calculator for product and cart page + */ + public function op_lasku_init() { + $settings = get_option( 'woocommerce_paytrail_settings' ); + + if ( isset( $settings['op_lasku_calculator'] ) && 'yes' === $settings['op_lasku_calculator'] ) { + new \Paytrail\WooCommercePaymentGateway\Providers\OPLasku(); + } + } -add_action( 'plugins_loaded', function() { - Plugin::instance(); -}); + /** + * Get the Gateway class instance. + * + * @return Gateway + */ + public function gateway(): Gateway { + // If the gateway is not initialized, initialize it. + if ( ! isset( $this->gateway ) ) { + $this->gateway = new Gateway(); + } + + return $this->gateway; + } +} -register_activation_hook( __FILE__, __NAMESPACE__ . '\\Plugin::activation_check' ); +$paytrail = Plugin::instance(); diff --git a/readme.txt b/readme.txt index 82549c6c..4cd9f0d4 100644 --- a/readme.txt +++ b/readme.txt @@ -3,8 +3,8 @@ Contributors: loueranta, kotivuori Donate link: https://www.paytrail.com/ Tags: woocommerce Requires at least: 4.9 -Tested up to: 6.8 -Stable tag: 2.5.3 +Tested up to: 6.9 +Stable tag: 2.6.0 Requires PHP: 7.3 License: MIT License URI: https://opensource.org/licenses/MIT @@ -55,6 +55,9 @@ Test credentials: With test credentials, you can test most of the payment methods included in Paytrail’s payment service. You can find the payment method specific credentials needed for testing in Paytrail’s [documentation](https://docs.paytrail.com/#/payment-method-providers). == Changelog == += 2.6.0 = +- Added support for manual activation of invoices for payments made with Walley and Klarna invoice methods. +- Fixed compatibility issue with Visma Pay. = 2.5.3 = - Added missing accessibility features diff --git a/src/Controllers/AbstractController.php b/src/Controllers/AbstractController.php index b9741599..b516f90a 100644 --- a/src/Controllers/AbstractController.php +++ b/src/Controllers/AbstractController.php @@ -7,11 +7,11 @@ abstract class AbstractController { - public function execute( $action = null) { - if (method_exists($this, $action)) { + public function execute( $action = null ) { + if ( method_exists( $this, $action ) ) { $this->$action(); } else { - echo esc_html('Not found'); + echo esc_html( 'Not found' ); return; } } diff --git a/src/Controllers/Callback.php b/src/Controllers/Callback.php index 90712e75..c5f85c90 100644 --- a/src/Controllers/Callback.php +++ b/src/Controllers/Callback.php @@ -5,11 +5,15 @@ namespace Paytrail\WooCommercePaymentGateway\Controllers; -use Paytrail\WooCommercePaymentGateway\Gateway; +use Paytrail\WooCommercePaymentGateway\Plugin; class Callback extends AbstractController { + /** + * Index method for the Callback controller + */ protected function index() { - new Gateway(['callbackMode' => true]); + Plugin::instance()->gateway()->set_callback_mode( true ); + Plugin::instance()->gateway()->check_paytrail_response(); // Trigger the response check to process any potential payment response. } } diff --git a/src/Controllers/Card.php b/src/Controllers/Card.php index c0fb53da..9f3fc2ed 100644 --- a/src/Controllers/Card.php +++ b/src/Controllers/Card.php @@ -5,9 +5,8 @@ namespace Paytrail\WooCommercePaymentGateway\Controllers; -use Paytrail\WooCommercePaymentGateway\Gateway; use Paytrail\WooCommercePaymentGateway\Plugin; -//use Paytrail\WooCommercePaymentGateway\Exception; +// use Paytrail\WooCommercePaymentGateway\Exception; use WC_Payment_Tokens; use WP_Error; use WP_HTTP_Response; @@ -15,10 +14,11 @@ class Card extends AbstractController { protected function add() { - $gateway = new Gateway(); + $gateway = Plugin::instance()->gateway(); + try { $gateway->add_card_form(); - } catch (\Exception $e) { + } catch ( \Exception $e ) { return null; } } @@ -32,17 +32,17 @@ protected function add() { protected function delete() { try { $this->validate_request(); - } catch (\Exception $e) { - wc_add_notice(__('Card could not be deleted', 'paytrail-for-woocommerce'), 'error'); + } catch ( \Exception $e ) { + wc_add_notice( __( 'Card could not be deleted', 'paytrail-for-woocommerce' ), 'error' ); wp_send_json_error(); - return new WP_Error('invalid-request', $e->getMessage(), array('status' => 400)); + return new WP_Error( 'invalid-request', $e->getMessage(), array( 'status' => 400 ) ); } - $body = file_get_contents('php://input'); - $data = json_decode($body, true); + $body = file_get_contents( 'php://input' ); + $data = json_decode( $body, true ); - if (!is_array($data)) { - throw new \Exception('Failed to decode JSON object'); + if ( ! is_array( $data ) ) { + throw new \Exception( 'Failed to decode JSON object' ); } // @var \WP_User $current_user @@ -50,44 +50,44 @@ protected function delete() { $token_id = $data['token_id']; - if (!$current_user->ID || !$token_id) { - return new WP_Error('cant-delete', __('message', 'text-domain'), array('status' => 500)); + if ( ! $current_user->ID || ! $token_id ) { + return new WP_Error( 'cant-delete', __( 'message', 'text-domain' ), array( 'status' => 500 ) ); } - $customer_tokens = WC_Payment_Tokens::get_customer_tokens($current_user->ID, Plugin::GATEWAY_ID); - $customer_token_ids = array_keys($customer_tokens); + $customer_tokens = WC_Payment_Tokens::get_customer_tokens( $current_user->ID, Plugin::GATEWAY_ID ); + $customer_token_ids = array_keys( $customer_tokens ); - if (!in_array($token_id, $customer_token_ids)) { - return new WP_Error('cant-delete', __('message', 'text-domain'), array('status' => 500)); + if ( ! in_array( $token_id, $customer_token_ids ) ) { + return new WP_Error( 'cant-delete', __( 'message', 'text-domain' ), array( 'status' => 500 ) ); } try { - WC_Payment_Tokens::delete($token_id); - wc_add_notice(__('Card was deleted successfully', 'paytrail-for-woocommerce'), 'success'); - wp_send_json_success($data); - return new WP_HTTP_Response(['type' => 'success'], 200); - } catch (\Exception $e) { - wc_add_notice(__('Card could not be deleted', 'paytrail-for-woocommerce'), 'error'); + WC_Payment_Tokens::delete( $token_id ); + wc_add_notice( __( 'Card was deleted successfully', 'paytrail-for-woocommerce' ), 'success' ); + wp_send_json_success( $data ); + return new WP_HTTP_Response( array( 'type' => 'success' ), 200 ); + } catch ( \Exception $e ) { + wc_add_notice( __( 'Card could not be deleted', 'paytrail-for-woocommerce' ), 'error' ); wp_send_json_error(); - return new WP_Error('cant-delete', __('message', 'text-domain'), array('status' => 500)); + return new WP_Error( 'cant-delete', __( 'message', 'text-domain' ), array( 'status' => 500 ) ); } } private function validate_request() { - $request_method = isset($_SERVER['REQUEST_METHOD']) ? sanitize_text_field($_SERVER['REQUEST_METHOD']) : ''; + $request_method = isset( $_SERVER['REQUEST_METHOD'] ) ? sanitize_text_field( $_SERVER['REQUEST_METHOD'] ) : ''; - if (empty($request_method)) { + if ( empty( $request_method ) ) { return; } - if ('POST' !== $request_method) { - throw new \Exception('Only POST requests are allowed'); + if ( 'POST' !== $request_method ) { + throw new \Exception( 'Only POST requests are allowed' ); } - $content_type = isset($_SERVER['CONTENT_TYPE']) ? sanitize_text_field($_SERVER['CONTENT_TYPE']) : ''; + $content_type = isset( $_SERVER['CONTENT_TYPE'] ) ? sanitize_text_field( $_SERVER['CONTENT_TYPE'] ) : ''; - if (stripos($content_type, 'application/json') === false) { - throw new \Exception('Content-Type must be application/json'); + if ( stripos( $content_type, 'application/json' ) === false ) { + throw new \Exception( 'Content-Type must be application/json' ); } } } diff --git a/src/Controllers/CardCancel.php b/src/Controllers/CardCancel.php index eb1077fe..87c885d4 100644 --- a/src/Controllers/CardCancel.php +++ b/src/Controllers/CardCancel.php @@ -8,20 +8,20 @@ class CardCancel extends AbstractController { protected function checkout() { - wc_add_notice(__('Could not add card details', 'paytrail-for-woocommerce'), 'error'); - wp_safe_redirect(wc_get_checkout_url()); + wc_add_notice( __( 'Could not add card details', 'paytrail-for-woocommerce' ), 'error' ); + wp_safe_redirect( wc_get_checkout_url() ); exit; } protected function my_account() { - wc_add_notice(__('Could not add card details', 'paytrail-for-woocommerce'), 'error'); - wp_safe_redirect(wc_get_account_endpoint_url('payment-methods')); + wc_add_notice( __( 'Could not add card details', 'paytrail-for-woocommerce' ), 'error' ); + wp_safe_redirect( wc_get_account_endpoint_url( 'payment-methods' ) ); exit; } protected function change_payment_method() { - wc_add_notice(__('Could not add card details', 'paytrail-for-woocommerce'), 'error'); - wp_safe_redirect(wc_get_account_endpoint_url('subscriptions')); + wc_add_notice( __( 'Could not add card details', 'paytrail-for-woocommerce' ), 'error' ); + wp_safe_redirect( wc_get_account_endpoint_url( 'subscriptions' ) ); exit; } } diff --git a/src/Controllers/CardSuccess.php b/src/Controllers/CardSuccess.php index d60363cc..932b9df5 100644 --- a/src/Controllers/CardSuccess.php +++ b/src/Controllers/CardSuccess.php @@ -7,49 +7,49 @@ use Paytrail\SDK\Exception\HmacException; use Paytrail\SDK\Exception\ValidationException; -use Paytrail\WooCommercePaymentGateway\Gateway; +use Paytrail\WooCommercePaymentGateway\Plugin; class CardSuccess extends AbstractController { protected function checkout() { - $gateway = new Gateway(); + $gateway = Plugin::instance()->gateway(); try { $gateway->process_card_token(); - wc_add_notice(__('Card was added successfully', 'paytrail-for-woocommerce'), 'success'); - } catch (HmacException $e) { - wc_add_notice(__('Could not add card details', 'paytrail-for-woocommerce'), 'error'); - } catch (ValidationException $e) { - wc_add_notice(__('Could not add card details', 'paytrail-for-woocommerce'), 'error'); + wc_add_notice( __( 'Card was added successfully', 'paytrail-for-woocommerce' ), 'success' ); + } catch ( HmacException $e ) { + wc_add_notice( __( 'Could not add card details', 'paytrail-for-woocommerce' ), 'error' ); + } catch ( ValidationException $e ) { + wc_add_notice( __( 'Could not add card details', 'paytrail-for-woocommerce' ), 'error' ); } - wp_safe_redirect(wc_get_checkout_url()); + wp_safe_redirect( wc_get_checkout_url() ); exit; } protected function my_account() { - $gateway = new Gateway(); + $gateway = Plugin::instance()->gateway(); try { $gateway->process_card_token(); - wc_add_notice(__('Card was added successfully', 'paytrail-for-woocommerce'), 'success'); - } catch (HmacException $e) { - wc_add_notice(__('Could not add card details', 'paytrail-for-woocommerce'), 'error'); - } catch (ValidationException $e) { - wc_add_notice(__('Could not add card details', 'paytrail-for-woocommerce'), 'error'); + wc_add_notice( __( 'Card was added successfully', 'paytrail-for-woocommerce' ), 'success' ); + } catch ( HmacException $e ) { + wc_add_notice( __( 'Could not add card details', 'paytrail-for-woocommerce' ), 'error' ); + } catch ( ValidationException $e ) { + wc_add_notice( __( 'Could not add card details', 'paytrail-for-woocommerce' ), 'error' ); } - wp_safe_redirect(wc_get_account_endpoint_url('payment-methods')); + wp_safe_redirect( wc_get_account_endpoint_url( 'payment-methods' ) ); exit; } protected function change_payment_method() { - $gateway = new Gateway(); + $gateway = Plugin::instance()->gateway(); try { $gateway->process_card_token(); - wc_add_notice(__('Card was added successfully', 'paytrail-for-woocommerce'), 'success'); - } catch (HmacException $e) { - wc_add_notice(__('Could not add card details', 'paytrail-for-woocommerce'), 'error'); - } catch (ValidationException $e) { - wc_add_notice(__('Could not add card details', 'paytrail-for-woocommerce'), 'error'); + wc_add_notice( __( 'Card was added successfully', 'paytrail-for-woocommerce' ), 'success' ); + } catch ( HmacException $e ) { + wc_add_notice( __( 'Could not add card details', 'paytrail-for-woocommerce' ), 'error' ); + } catch ( ValidationException $e ) { + wc_add_notice( __( 'Could not add card details', 'paytrail-for-woocommerce' ), 'error' ); } - wp_safe_redirect(wc_get_account_endpoint_url('subscriptions')); + wp_safe_redirect( wc_get_account_endpoint_url( 'subscriptions' ) ); exit; } } diff --git a/src/Controllers/MetaBox.php b/src/Controllers/MetaBox.php new file mode 100644 index 00000000..5f756a79 --- /dev/null +++ b/src/Controllers/MetaBox.php @@ -0,0 +1,126 @@ +ID ) : $order; + if ( Plugin::GATEWAY_ID === $order->get_payment_method() ) { + add_meta_box( + 'paytrail_meta_box', + __( 'Paytrail', 'paytrail-for-woocommerce' ), + function () use ( $order ) { + $this->meta_box_content( $order ); + }, + $screen_id, + 'side', + 'core' + ); + } + } + } + + /** + * Determines whether the success or error content should be printed. + * + * @param \WC_Order $order The WC order. + * @return void + */ + public function meta_box_content( $order ) { + // Note: when this method is called, we've already registered the metabox. Thus, it will appear for the merchant. We should display something, even if it is something as simple as error message that explains why it is empty. + + if ( empty( $order->get_transaction_id() ) ) { + $data = array( 'error' => __( 'The order is missing transaction ID.', 'paytrail-for-woocommerce' ) ); + } else { + + $model = new Model\MetaBox( $order ); + $paytrail_order = $model->get_status(); + if ( empty( $paytrail_order ) ) { + $data = array( 'error' => __( 'Failed to retrieve the order from Paytrail.', 'paytrail-for-woocommerce' ) ); + } else { + $data = array( + 'status' => $model->get_status(), + 'amount' => $model->get_amount(), + 'currency' => $model->get_currency(), + 'transaction_id' => $model->get_transaction_id(), + ); + } + } + + ( new View( 'MetaBox' ) )->render( $data ); + } + + /** + * Handles manual invoice request if submitted. + * + * @param int $order_id The WC order ID. + * @return void + */ + public function maybe_handle_manual_invoice_request( $order_id ) { + $order = wc_get_order( $order_id ); + try { + if ( ! $order ) { + return; + } + + // If the WooCommerce order is not for Paytrail or it has already been paid. + if ( Plugin::GATEWAY_ID !== $order->get_payment_method() ) { + return; + } + + // Only if the order is for a manual invoice order. + $model = new Model\MetaBox( $order ); + $payment_status = $model->get_payment_status(); + $payment_provider = $payment_status ? strtolower( $payment_status->getProvider() ) : ''; + + // Ensure the payment status was retrieved, is still pending, and the provider is one that supports manual invoices. Otherwise skip. + if ( empty( $payment_status ) || 'pending' !== $payment_status->getStatus() || ( ! str_contains( $payment_provider, 'walley' ) && ! str_contains( $payment_provider, 'klarna' ) ) ) { + return; + } + + $gateway = Plugin::instance()->gateway(); + $client = $gateway->get_client(); + $response = $client->activateInvoice( $order->get_transaction_id() ); + Plugin::instance()->gateway()->log( InvoiceActivationResponse::class . " Successfully activated invoice for order $order_id with transaction id {$order->get_transaction_id()}: " . json_encode( $response ) ); + } catch ( \Exception $e ) { + $message = $e->getMessage(); + $gateway->log( "Failed to send manual invoice for order $order_id with transaction id {$order->get_transaction_id()}: $message", 'error' ); + $order->set_status( 'on-hold', __( 'Failed to activate manual invoice: ' . $message, 'paytrail-for-woocommerce' ) ); + $order->save(); + return; + } + } +} diff --git a/src/Gateway.php b/src/Gateway.php index b4f47419..6adb4f7f 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -20,9 +20,7 @@ use Paytrail\SDK\Request\RefundRequest; use Paytrail\SDK\Client; use Paytrail\SDK\Request\EmailRefundRequest; -use Paytrail\SDK\Model\Provider; use Paytrail\SDK\Response\GetTokenResponse; -use Paytrail\SDK\Response\InvoiceActivationResponse; use Paytrail\WooCommercePaymentGateway\Model\PaymentSubscriptionMigration; use Paytrail\WooCommercePaymentGateway\Model\PaymentTokenMigration; use Paytrail\WooCommercePaymentGateway\Providers\OPLasku; @@ -58,8 +56,6 @@ final class Gateway extends \WC_Payment_Gateway { /** * Transaction settlement declaration - * - * */ protected $transaction_settlement_enable; @@ -70,6 +66,7 @@ final class Gateway extends \WC_Payment_Gateway { */ public $enable_test_mode = false; + /** * Whether the debug mode is enabled. * @@ -77,14 +74,19 @@ final class Gateway extends \WC_Payment_Gateway { */ public $debug = false; - public $callbackMode = false; + /** + * Whether we are in callback mode. + * + * @var boolean + */ + public $callback_mode = false; /** * Supported features. * * @var array */ - public $supports = [ + public $supports = array( 'products', 'refunds', 'tokenization', @@ -97,15 +99,15 @@ final class Gateway extends \WC_Payment_Gateway { 'subscription_payment_method_change', 'subscription_payment_method_change_customer', 'subscription_payment_method_change_admin', - 'multiple_subscriptions' - ]; + 'multiple_subscriptions', + ); /** * Dynamic method info that will be populated from an endpoint. * * @var array */ - public $method_info = []; + public $method_info = array(); /** * WooCommerce logger instance @@ -127,14 +129,22 @@ final class Gateway extends \WC_Payment_Gateway { * @var Helper */ protected $helper = null; - const TAX_RATE_PRECISION = 1; - const SUPPORTED_CURRENCIES = ['EUR']; + + /** + * Settlement prefix + * + * @var int + */ + private $settlement_prefix = 10; + + const TAX_RATE_PRECISION = 1; + const SUPPORTED_CURRENCIES = array( 'EUR' ); /** * Object constructor */ - public function __construct( $params = []) { - // Set payment gateway ID + public function __construct() { + // Set payment gateway ID. $this->id = Plugin::GATEWAY_ID; $this->has_fields = $this->use_provider_selection(); @@ -147,8 +157,8 @@ public function __construct( $params = []) { $this->method_description = $this->method_info['description']; // These strings may show in the frontend. - $this->title = !empty($this->get_option('custom_provider_name')) ? $this->get_option('custom_provider_name') : $this->method_info['title']; - $this->description = !empty($this->get_option('custom_provider_description')) ? $this->get_option('custom_provider_description') : $this->method_info['description']; + $this->title = ! empty( $this->get_option( 'custom_provider_name' ) ) ? $this->get_option( 'custom_provider_name' ) : $this->method_info['title']; + $this->description = ! empty( $this->get_option( 'custom_provider_description' ) ) ? $this->get_option( 'custom_provider_description' ) : $this->method_info['description']; // Icon temporarily disabled for size issues // $this->icon = Plugin::ICON_URL; @@ -160,50 +170,56 @@ public function __construct( $params = []) { $this->init_settings(); // Whether we are in test mode or not. - $this->enable_test_mode = 'yes' === $this->get_option('enable_test_mode', 'no'); + $this->enable_test_mode = wc_string_to_bool( $this->get_option( 'enable_test_mode', 'no' ) ); // Set merchant ID and secret key either from the options or for test mode. - if ($this->enable_test_mode) { + if ( $this->enable_test_mode ) { $this->merchant_id = (int) Plugin::TEST_MERCHANT_ID; $this->secret_key = Plugin::TEST_SECRET_KEY; } else { - $this->merchant_id = (int) $this->get_option('merchant_id'); - $this->secret_key = $this->get_option('secret_key'); + $this->merchant_id = (int) $this->get_option( 'merchant_id' ); + $this->secret_key = $this->get_option( 'secret_key' ); } - $platformName = 'paytrail-for-woocommerce-' . \Paytrail\WooCommercePaymentGateway\Plugin::$version; + $platform_name = 'paytrail-for-woocommerce-' . \Paytrail\WooCommercePaymentGateway\Plugin::$version; - // Create SDK client instance + // Create SDK client instance. $this->client = new Client( $this->merchant_id, $this->secret_key, - $platformName + $platform_name ); - // Create Helper instance + // Create Helper instance. $this->helper = new Helper(); // Whether we are in debug mode or not. - $this->debug = 'yes' === $this->get_option('debug', 'no'); + $this->debug = wc_string_to_bool( $this->get_option( 'debug', 'no' ) ); - // Check if transaction settlement is enabled - $this->transaction_settlement_enable = $this->get_option( 'settlement_enablement', 'no' ) === 'yes'; + // Check if transaction settlement is enabled. + $this->transaction_settlement_enable = wc_string_to_bool( $this->get_option( 'settlement_enablement', 'no' ) ); - if (!empty($params) && isset($params['callbackMode'])) { - $this->callbackMode = true; - } + $this->settlement_prefix = $this->get_option( 'settlement_prefix', '10' ); // Add actions and filters. $this->add_actions(); - // Register stylesheet for payment fields + // Register stylesheet for payment fields. $this->register_styles(); - // Register scripts for payment fields + // Register scripts for payment fields. $this->register_scripts(); - // Check if we are in response phase - $this->check_paytrail_response(); + new Controllers\MetaBox(); + } + + /** + * Get Paytrail SDK Client instance. + * + * @return Client + */ + public function get_client() { + return $this->client; } /** @@ -212,41 +228,72 @@ public function __construct( $params = []) { * @return void */ protected function add_actions() { - add_action('woocommerce_update_options_payment_gateways_' . $this->id, [ $this, 'process_admin_options' ]); - add_action('woocommerce_scheduled_subscription_payment_' . Plugin::GATEWAY_ID, [ $this, 'scheduled_subscription_payment' ], 10, 2); - add_action('woocommerce_receipt_' . $this->id, [ $this, 'receipt_page' ]); - add_filter('woocommerce_admin_order_items_after_refunds', [ $this, 'refund_items' ], 10, 1); - add_filter('woocommerce_order_data_store_cpt_get_orders_query', [ $this, 'handle_custom_searches' ], 10, 2); - add_filter('woocommerce_payment_gateway_get_saved_payment_method_option_html', [ $this, 'get_token_payment_option_html' ], 10, 2); - add_action('admin_footer', [$this, 'display_user_data_form']); - add_action('admin_notices', [$this, 'admin_notices']); - add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_scripts']); - add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_styles']); + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_scheduled_subscription_payment_' . Plugin::GATEWAY_ID, array( $this, 'scheduled_subscription_payment' ), 10, 2 ); + add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ) ); + add_filter( 'woocommerce_admin_order_items_after_refunds', array( $this, 'refund_items' ), 10, 1 ); + add_filter( 'woocommerce_order_data_store_cpt_get_orders_query', array( $this, 'handle_custom_searches' ), 10, 2 ); + add_filter( 'woocommerce_payment_gateway_get_saved_payment_method_option_html', array( $this, 'get_token_payment_option_html' ), 10, 2 ); + add_action( 'admin_footer', array( $this, 'display_user_data_form' ) ); + add_action( 'admin_notices', array( $this, 'admin_notices' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) ); + + // Check if we are in response phase. + add_action( 'template_redirect', array( $this, 'on_redirect_to_thankyou_page' ) ); + } + + /** + * Set callback mode + * + * @param boolean $mode Callback mode. + */ + public function set_callback_mode( $mode ) { + $this->callback_mode = $mode; + } + + /** + * Process Paytrail order on redirect to thankyou-page. + * + * @return void + */ + public function on_redirect_to_thankyou_page() { + $order_id = absint( get_query_var( 'order-received', 0 ) ); + $order = wc_get_order( $order_id ); + if ( empty( $order ) ) { + return; + } + + $order_key = filter_input( INPUT_GET, 'key', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); + if ( empty( $order_key ) || ! hash_equals( $order->get_order_key(), $order_key ) ) { + return; + } + $this->check_paytrail_response(); } /** * Display the user_data_form as an overlay */ public function display_user_data_form() { - $merchant_id = $this->get_option('merchant_id'); - $test_mode_enabled = $this->get_option('enable_test_mode', 'no') === 'yes'; - $current_screen = get_current_screen(); + $merchant_id = $this->get_option( 'merchant_id' ); + $test_mode_enabled = $this->get_option( 'enable_test_mode', 'no' ) === 'yes'; + $current_screen = get_current_screen(); $is_paytrail_settings_page = ( - !$test_mode_enabled && + ! $test_mode_enabled && $current_screen && 'woocommerce_page_wc-settings' === $current_screen->id && - isset($_GET['tab']) && 'checkout' === $_GET['tab'] && - isset($_GET['section']) && 'paytrail' === $_GET['section'] + isset( $_GET['tab'] ) && 'checkout' === $_GET['tab'] && + isset( $_GET['section'] ) && 'paytrail' === $_GET['section'] ); // Check if merchant_id is already submitted - if (!empty($merchant_id) || $this->get_option('enable_test_mode', 'no') === 'yes') { + if ( ! empty( $merchant_id ) || $this->get_option( 'enable_test_mode', 'no' ) === 'yes' ) { return; } - if ($is_paytrail_settings_page) { - $template_path = plugin_dir_path(__FILE__) . 'View/Intro-form.php'; - if (file_exists($template_path)) { + if ( $is_paytrail_settings_page ) { + $template_path = plugin_dir_path( __FILE__ ) . 'View/Intro-form.php'; + if ( file_exists( $template_path ) ) { include_once $template_path; } } @@ -258,33 +305,32 @@ public function display_user_data_form() { */ public function user_data_form() { $current_user = wp_get_current_user(); - $user_email = $current_user->user_email; - $first_name = $current_user->first_name; - $last_name = $current_user->last_name; + $user_email = $current_user->user_email; + $first_name = $current_user->first_name; + $last_name = $current_user->last_name; - if (class_exists('WooCommerce')) { - $wc_billing_data = get_user_meta($current_user->ID, 'billing', true); - $company_name = isset($wc_billing_data['company']) ? $wc_billing_data['company'] : ''; - $phone_number = isset($wc_billing_data['phone']) ? $wc_billing_data['phone'] : ''; + if ( class_exists( 'WooCommerce' ) ) { + $wc_billing_data = get_user_meta( $current_user->ID, 'billing', true ); + $company_name = isset( $wc_billing_data['company'] ) ? $wc_billing_data['company'] : ''; + $phone_number = isset( $wc_billing_data['phone'] ) ? $wc_billing_data['phone'] : ''; // Fetch shop's address using WC_Countries - $wc_countries = WC()->countries; - $shop_address = $wc_countries->get_base_address(); - $shop_city = $wc_countries->get_base_city(); + $wc_countries = WC()->countries; + $shop_address = $wc_countries->get_base_address(); + $shop_city = $wc_countries->get_base_city(); $shop_postcode = $wc_countries->get_base_postcode(); } else { - $company_name = ''; - $phone_number = ''; - $shop_address = ''; - $shop_city = ''; + $company_name = ''; + $phone_number = ''; + $shop_address = ''; + $shop_city = ''; $shop_postcode = ''; } + $site_url = esc_url( get_site_url() ); - $site_url = esc_url(get_site_url()); - - $template_path = plugin_dir_path(__FILE__) . 'View/User-data-form.php'; - if (file_exists($template_path)) { + $template_path = plugin_dir_path( __FILE__ ) . 'View/User-data-form.php'; + if ( file_exists( $template_path ) ) { include_once $template_path; } } @@ -296,11 +342,11 @@ public function user_data_form() { * @return array */ protected function get_method_info() { - $method_info = [ - 'title' => __('Paytrail for WooCommerce', 'paytrail-for-woocommerce'), - 'description' => __('Paytrail for WooCommerce - the most comprehensive suite of payment methods in the market with a single contract', 'paytrail-for-woocommerce'), - 'save_card' => 1, - ]; + $method_info = array( + 'title' => __( 'Paytrail for WooCommerce', 'paytrail-for-woocommerce' ), + 'description' => __( 'Paytrail for WooCommerce - the most comprehensive suite of payment methods in the market with a single contract', 'paytrail-for-woocommerce' ), + 'save_card' => 1, + ); return $method_info; } @@ -310,131 +356,138 @@ protected function get_method_info() { * @return void */ protected function set_form_fields() { - $test_mode_enabled = $this->get_option('enable_test_mode', 'no') === 'yes'; - $merchant_id_disabled = $this->get_option( 'enable_test_mode', 'no' ) === 'yes'; - $secret_key_disabled = $this->get_option( 'enable_test_mode', 'no' ) === 'yes'; - $enable_test_mode_disabled = !$test_mode_enabled && ( - !empty($this->get_option('merchant_id')) || - !empty($this->get_option('secret_key')) + $test_mode_enabled = $this->get_option( 'enable_test_mode', 'no' ) === 'yes'; + $merchant_id_disabled = $this->get_option( 'enable_test_mode', 'no' ) === 'yes'; + $secret_key_disabled = $this->get_option( 'enable_test_mode', 'no' ) === 'yes'; + $enable_test_mode_disabled = ! $test_mode_enabled && ( + ! empty( $this->get_option( 'merchant_id' ) ) || + ! empty( $this->get_option( 'secret_key' ) ) ); - $this->form_fields = [ + $this->form_fields = array( // Whether the payment gateway is enabled. - 'enabled' => [ - 'title' => __('Payment gateway status', 'paytrail-for-woocommerce'), + 'enabled' => array( + 'title' => __( 'Payment gateway status', 'paytrail-for-woocommerce' ), 'type' => 'checkbox', - 'label' => __('Enable Paytrail for WooCommerce', 'paytrail-for-woocommerce'), + 'label' => __( 'Enable Paytrail for WooCommerce', 'paytrail-for-woocommerce' ), 'default' => 'yes', - ], + ), // Credentials - 'credentials_title' => [ - 'title' => __('Credentials', 'paytrail-for-woocommerce'), - 'type' => 'title', - ], + 'credentials_title' => array( + 'title' => __( 'Credentials', 'paytrail-for-woocommerce' ), + 'type' => 'title', + ), // Paytrail credentials - 'merchant_id' => [ - 'title' => __('Paytrail Merchant ID', 'paytrail-for-woocommerce'), - 'type' => 'text', - 'label' => __('Merchant ID', 'paytrail-for-woocommerce'), - 'default' => '', + 'merchant_id' => array( + 'title' => __( 'Paytrail Merchant ID', 'paytrail-for-woocommerce' ), + 'type' => 'text', + 'label' => __( 'Merchant ID', 'paytrail-for-woocommerce' ), + 'default' => '', 'disabled' => $merchant_id_disabled, // Disable if enable_test_mode is checked - ], - 'secret_key' => [ - 'title' => __('Paytrail Secret key', 'paytrail-for-woocommerce'), - 'type' => 'password', - 'label' => __('Secret key', 'paytrail-for-woocommerce'), - 'default' => '', - 'description' => __('Credentials can be found in the merchant panel.', 'paytrail-for-woocommerce'), - 'disabled' => $secret_key_disabled, // Disable if enable_test_mode is checked - ], + ), + 'secret_key' => array( + 'title' => __( 'Paytrail Secret key', 'paytrail-for-woocommerce' ), + 'type' => 'password', + 'label' => __( 'Secret key', 'paytrail-for-woocommerce' ), + 'default' => '', + 'description' => __( 'Credentials can be found in the merchant panel.', 'paytrail-for-woocommerce' ), + 'disabled' => $secret_key_disabled, // Disable if enable_test_mode is checked + ), // Whether test mode is enabled - 'enable_test_mode' => [ - 'title' => __('Test mode', 'paytrail-for-woocommerce'), + 'enable_test_mode' => array( + 'title' => __( 'Test mode', 'paytrail-for-woocommerce' ), 'type' => 'checkbox', - 'label' => __('Enable test mode', 'paytrail-for-woocommerce'), + 'label' => __( 'Enable test mode', 'paytrail-for-woocommerce' ), 'default' => 'no', - 'description' => __('You can use test mode to simulate payments with Paytrail\'s test credentials. To enable test mode, please first clear the Credentials and save settings.', 'paytrail-for-woocommerce'), + 'description' => __( 'You can use test mode to simulate payments with Paytrail\'s test credentials. To enable test mode, please first clear the Credentials and save settings.', 'paytrail-for-woocommerce' ), 'disabled' => $enable_test_mode_disabled, // Disable the checkbox if merchant_id or secret_key has a value - ], + ), // General settings - 'general_settings_title' => [ - 'title' => __('General settings', 'paytrail-for-woocommerce'), - 'type' => 'title', - ], + 'general_settings_title' => array( + 'title' => __( 'General settings', 'paytrail-for-woocommerce' ), + 'type' => 'title', + ), // Whether to show the payment provider wall or choose the method in the store - 'provider_selection' => [ - 'title' => __('Payment provider selection', 'paytrail-for-woocommerce'), + 'provider_selection' => array( + 'title' => __( 'Payment provider selection', 'paytrail-for-woocommerce' ), 'type' => 'checkbox', - 'label' => __('Enable payment provider selection in the checkout page', 'paytrail-for-woocommerce'), + 'label' => __( 'Enable payment provider selection in the checkout page', 'paytrail-for-woocommerce' ), 'default' => 'yes', - 'description' => __('Choose whether you want the payment provider selection to happen in the checkout page or in a separate page.', 'paytrail-for-woocommerce'), - ], + 'description' => __( 'Choose whether you want the payment provider selection to happen in the checkout page or in a separate page.', 'paytrail-for-woocommerce' ), + ), // Alternative text + description to show on the Checkout page - 'custom_provider_name' => [ - 'title' => __('Payment provider title', 'paytrail-for-woocommerce'), + 'custom_provider_name' => array( + 'title' => __( 'Payment provider title', 'paytrail-for-woocommerce' ), 'type' => 'text', - 'label' => __('Used on the Checkout page title', 'paytrail-for-woocommerce'), + 'label' => __( 'Used on the Checkout page title', 'paytrail-for-woocommerce' ), 'default' => 'Paytrail for WooCommerce', - 'description' => __('This title is displayed on the Checkout page before the payment provider images.', 'paytrail-for-woocommerce') - ], - 'custom_provider_description' => [ - 'title' => __('Payment provider description', 'paytrail-for-woocommerce'), + 'description' => __( 'This title is displayed on the Checkout page before the payment provider images.', 'paytrail-for-woocommerce' ), + ), + 'custom_provider_description' => array( + 'title' => __( 'Payment provider description', 'paytrail-for-woocommerce' ), 'type' => 'text', - 'label' => __('Used on the Checkout page title', 'paytrail-for-woocommerce'), + 'label' => __( 'Used on the Checkout page title', 'paytrail-for-woocommerce' ), 'default' => 'Paytrail for WooCommerce', - 'description' => __('Depending on your theme, this description might be displayed on the Checkout page before the payment provider images.', 'paytrail-for-woocommerce') - ], + 'description' => __( 'Depending on your theme, this description might be displayed on the Checkout page before the payment provider images.', 'paytrail-for-woocommerce' ), + ), // OP Lasku - 'op_lasku_calculator' => [ + 'op_lasku_calculator' => array( 'title' => OPLasku::settings_title(), 'type' => 'checkbox', - 'label' => __('Enable OP Lasku calculator', 'paytrail-for-woocommerce'), + 'label' => __( 'Enable OP Lasku calculator', 'paytrail-for-woocommerce' ), 'default' => 'no', - 'description' => __('Display OP Lasku calculator on the product and cart page.', 'paytrail-for-woocommerce'), - ], + 'description' => __( 'Display OP Lasku calculator on the product and cart page.', 'paytrail-for-woocommerce' ), + ), // Advanced settings - 'advanced_settings_title' => [ - 'title' => __('Advanced settings', 'paytrail-for-woocommerce'), - 'type' => 'title', - ], - 'settlement_enablement' => [ - 'title' => __( 'Enable individual settlements', 'paytrail-for-woocommerce' ), - 'type' => 'checkbox', - 'default' => 'no', + 'advanced_settings_title' => array( + 'title' => __( 'Advanced settings', 'paytrail-for-woocommerce' ), + 'type' => 'title', + ), + 'manual_invoice_activation' => array( + 'title' => __( 'Manual invoice activation', 'paytrail-for-woocommerce' ), + 'label' => __( 'Enable manual invoice activation', 'paytrail-for-woocommerce' ), + 'type' => 'checkbox', + 'default' => 'no', + 'description' => __( 'For certain invoice payment methods (Walley/Klarna), you can activate the invoice at a later time, for example for pre-ordered products.
Activation window
Walley: Up to 90 days
Klarna: Up to 28 days', 'paytrail-for-woocommerce' ), + ), + 'settlement_enablement' => array( + 'title' => __( 'Enable individual settlements', 'paytrail-for-woocommerce' ), + 'type' => 'checkbox', + 'default' => 'no', 'description' => __( 'This setting is required only if you are using transaction-by-transaction settlements in Paytrail.', 'paytrail-for-woocommerce' ), - ], - 'settlement_prefix' => [ - 'title' => __( 'Bank reference prefix', 'paytrail-for-woocommerce' ), - 'type' => 'text', + ), + 'settlement_prefix' => array( + 'title' => __( 'Bank reference prefix', 'paytrail-for-woocommerce' ), + 'type' => 'text', 'description' => __( 'Add Prefix', 'paytrail-for-woocommerce' ), - 'default' => '10' - ], - 'fallback_country' => [ - 'title' => __('Default country', 'paytrail-for-woocommerce'), - 'type' => 'select', - 'label' => __('Fallback country', 'paytrail-for-woocommerce'), - 'default' => '', - 'description' => __('Select country to be used as fallback if no country specified in checkout.', 'paytrail-for-woocommerce'), - 'options' => array_merge(['' => 'Select country'], WC()->countries->get_countries()) - ], + 'default' => '10', + ), + 'fallback_country' => array( + 'title' => __( 'Default country', 'paytrail-for-woocommerce' ), + 'type' => 'select', + 'label' => __( 'Fallback country', 'paytrail-for-woocommerce' ), + 'default' => '', + 'description' => __( 'Select country to be used as fallback if no country specified in checkout.', 'paytrail-for-woocommerce' ), + 'options' => array_merge( array( '' => 'Select country' ), WC()->countries->get_countries() ), + ), // Whether debug mode is enabled - 'debug' => [ - 'title' => __('Debug log', 'paytrail-for-woocommerce'), + 'debug' => array( + 'title' => __( 'Debug log', 'paytrail-for-woocommerce' ), 'type' => 'checkbox', - 'label' => __('Enable logging', 'paytrail-for-woocommerce'), + 'label' => __( 'Enable logging', 'paytrail-for-woocommerce' ), 'default' => 'no', // translators: %s: URL - 'description' => sprintf(__('This enables logging all payment gateway events. The log will be written in %1$s. Recommended only for debugging purposes as this might save personal data. All logs can be viewed here: %2$s', 'paytrail-for-woocommerce'), '' . \WC_Log_Handler_File::get_log_file_path(Plugin::GATEWAY_ID) . '', 'Logs'), - ], + 'description' => sprintf( __( 'This enables logging all payment gateway events. The log will be written in %1$s. Recommended only for debugging purposes as this might save personal data. All logs can be viewed here: %2$s', 'paytrail-for-woocommerce' ), '' . \WC_Log_Handler_File::get_log_file_path( Plugin::GATEWAY_ID ) . '', 'Logs' ), + ), // Update tokens if enabled - 'tokenize' => [ - 'title' => __('Update tokens', 'paytrail-for-woocommerce'), + 'tokenize' => array( + 'title' => __( 'Update tokens', 'paytrail-for-woocommerce' ), 'type' => 'checkbox', - 'label' => __('Enable token update', 'paytrail-for-woocommerce'), + 'label' => __( 'Enable token update', 'paytrail-for-woocommerce' ), 'default' => 'no', // translators: %s: URL - 'description' => __('Choose this to update card information (tokens) from the old Checkout Finland for WooCommerce -plugin. The update is done upon saving settings. This will also update tokens for the current WooCommerce Subscriptions orders, if that module is in use.
CAUTION: This action cannot be reverted.', 'paytrail-for-woocommerce'), - ], - ]; + 'description' => __( 'Choose this to update card information (tokens) from the old Checkout Finland for WooCommerce -plugin. The update is done upon saving settings. This will also update tokens for the current WooCommerce Subscriptions orders, if that module is in use.
CAUTION: This action cannot be reverted.', 'paytrail-for-woocommerce' ), + ), + ); } /** @@ -446,16 +499,16 @@ public function process_admin_options() { $saved = parent::process_admin_options(); // Clear logs if debugging was disabled. - if ('yes' !== $this->get_option('debug', 'no')) { - if (empty($this->logger)) { + if ( 'yes' !== $this->get_option( 'debug', 'no' ) ) { + if ( empty( $this->logger ) ) { $this->logger = wc_get_logger(); } - $this->logger->clear(Plugin::GATEWAY_ID); + $this->logger->clear( Plugin::GATEWAY_ID ); } // Update tokens if checkbx was checked - if ('yes' === $this->get_option('tokenize', 'yes')) { + if ( 'yes' === $this->get_option( 'tokenize', 'yes' ) ) { $token_migration = new PaymentTokenMigration(); $token_migration->execute(); $subscription_migration = new PaymentSubscriptionMigration(); @@ -470,19 +523,19 @@ public function process_admin_options() { */ public function display_test_mode_notice() { // Check if test mode is enabled - $test_mode_enabled = $this->get_option('enable_test_mode', 'no') === 'yes'; + $test_mode_enabled = $this->get_option( 'enable_test_mode', 'no' ) === 'yes'; // Check if the notice should be displayed - if ($test_mode_enabled) { + if ( $test_mode_enabled ) { ?>

' . esc_html__('here', 'paytrail-for-woocommerce') . '' + esc_html__( 'If you have not registered yet, you can do so on our website %s to get your credentials!', 'paytrail-for-woocommerce' ), + '' . esc_html__( 'here', 'paytrail-for-woocommerce' ) . '' ); ?>

@@ -498,20 +551,21 @@ public function display_test_mode_notice() { */ public function display_currency_notice() { // Check the currently selected currency - $current_currency = get_woocommerce_currency(); - $currency_is_not_supported = !in_array($current_currency, self::SUPPORTED_CURRENCIES); + $current_currency = get_woocommerce_currency(); + $currency_is_not_supported = ! in_array( $current_currency, self::SUPPORTED_CURRENCIES ); // Check if the notice should be displayed - if ($currency_is_not_supported) { - $currency_settings_url = admin_url('admin.php?page=wc-settings&tab=general'); + if ( $currency_is_not_supported ) { + $currency_settings_url = admin_url( 'admin.php?page=wc-settings&tab=general' ); ?>

' . esc_html__('Please set the WooCommerce currency to Euro (€)', 'paytrail-for-woocommerce') . '', esc_url($currency_settings_url) - ); + '' . esc_html__( 'Please set the WooCommerce currency to Euro (€)', 'paytrail-for-woocommerce' ) . '', + esc_url( $currency_settings_url ) + ); ?>

@@ -531,9 +585,9 @@ public function admin_notices() { * Calculate bank reference */ private function calculate_reference( $base ) { - $base = sprintf( '%s%s', $this->settlement_prefix, $base ); - $base = trim( str_replace( ' ', '', $base ) ); - $base = str_split( $base ); + $base = sprintf( '%s%s', $this->settlement_prefix, $base ); + $base = trim( str_replace( ' ', '', $base ) ); + $base = str_split( $base ); $reversed_base = array_reverse( $base ); $weights = array( 7, 3, 1, 7, 3, 1, 7, 3, 1, 7, 3, 1, 7, 3, 1, 7, 3, 1, 7 ); @@ -541,7 +595,7 @@ private function calculate_reference( $base ) { $sum = 0; for ( $i = 0; $i < count( $reversed_base ); $i++ ) { $coefficient = array_shift( $weights ); - $sum += intval( $reversed_base[$i] ) * $coefficient; + $sum += intval( $reversed_base[ $i ] ) * $coefficient; } $checksum = ( 0 == ( $sum % 10 ) ) ? 0 : ( 10 - ( $sum % 10 ) ); @@ -557,11 +611,11 @@ private function calculate_reference( $base ) { * @return void */ public function receipt_page() { - $view = new View('CheckoutForm'); + $view = new View( 'CheckoutForm' ); - $provider = WC()->session->get('payment_provider'); + $provider = WC()->session->get( 'payment_provider' ); - $view->render($provider); + $view->render( $provider ); } /** @@ -569,8 +623,8 @@ public function receipt_page() { * * @return void */ - public function render_saved_payment_methods() { - $view = new View('SavedPaymentMethods'); + public static function render_saved_payment_methods() { + $view = new View( 'SavedPaymentMethods' ); $view->render(); } @@ -582,44 +636,44 @@ public function render_saved_payment_methods() { * @throws HmacException * @throws ValidationException */ - public function add_card_form( $context = Plugin::ADD_CARD_CONTEXT_CHECKOUT) { - $datetime = new \DateTime(); - $checkout_nonce = sha1(uniqid(true)); + public function add_card_form( $context = Plugin::ADD_CARD_CONTEXT_CHECKOUT ) { + $datetime = new \DateTime(); + $checkout_nonce = sha1( uniqid( true ) ); - if (Plugin::ADD_CARD_CONTEXT_MY_ACCOUNT === $context) { - $success_url = Router::get_url(Plugin::ADD_CARD_REDIRECT_SUCCESS_URL, Plugin::ADD_CARD_CONTEXT_MY_ACCOUNT); - $cancel_url = Router::get_url(Plugin::ADD_CARD_REDIRECT_CANCEL_URL, Plugin::ADD_CARD_CONTEXT_MY_ACCOUNT); - } elseif (Helper::getIsChangeSubscriptionPaymentMethod()) { + if ( Plugin::ADD_CARD_CONTEXT_MY_ACCOUNT === $context ) { + $success_url = Router::get_url( Plugin::ADD_CARD_REDIRECT_SUCCESS_URL, Plugin::ADD_CARD_CONTEXT_MY_ACCOUNT ); + $cancel_url = Router::get_url( Plugin::ADD_CARD_REDIRECT_CANCEL_URL, Plugin::ADD_CARD_CONTEXT_MY_ACCOUNT ); + } elseif ( Helper::getIsChangeSubscriptionPaymentMethod() ) { $success_url = Router::get_url( Plugin::ADD_CARD_REDIRECT_SUCCESS_URL, Plugin::ADD_CARD_CONTEXT_CHANGE_PAYMENT_METHOD ); - $cancel_url = Router::get_url( + $cancel_url = Router::get_url( Plugin::ADD_CARD_REDIRECT_CANCEL_URL, Plugin::ADD_CARD_CONTEXT_CHANGE_PAYMENT_METHOD ); } else { - $success_url = Router::get_url(Plugin::ADD_CARD_REDIRECT_SUCCESS_URL, Plugin::ADD_CARD_CONTEXT_CHECKOUT); - $cancel_url = Router::get_url(Plugin::ADD_CARD_REDIRECT_CANCEL_URL, Plugin::ADD_CARD_CONTEXT_CHECKOUT); + $success_url = Router::get_url( Plugin::ADD_CARD_REDIRECT_SUCCESS_URL, Plugin::ADD_CARD_CONTEXT_CHECKOUT ); + $cancel_url = Router::get_url( Plugin::ADD_CARD_REDIRECT_CANCEL_URL, Plugin::ADD_CARD_CONTEXT_CHECKOUT ); } - $this->log('Paytrail: try to add new card', 'debug'); + $this->log( 'Paytrail: try to add new card', 'debug' ); $add_card_form_request = new AddCardFormRequest(); - $add_card_form_request->setCheckoutAccount($this->merchant_id); - $add_card_form_request->setCheckoutAlgorithm('sha256'); - $add_card_form_request->setCheckoutMethod('POST'); - $add_card_form_request->setCheckoutTimestamp($datetime->format('Y-m-d\TH:i:s.u\Z')); - $add_card_form_request->setCheckoutNonce($checkout_nonce); - $add_card_form_request->setCheckoutRedirectSuccessUrl($success_url); - $add_card_form_request->setCheckoutRedirectCancelUrl($cancel_url); - $add_card_form_request->setLanguage(Helper::getLocale()); + $add_card_form_request->setCheckoutAccount( $this->merchant_id ); + $add_card_form_request->setCheckoutAlgorithm( 'sha256' ); + $add_card_form_request->setCheckoutMethod( 'POST' ); + $add_card_form_request->setCheckoutTimestamp( $datetime->format( 'Y-m-d\TH:i:s.u\Z' ) ); + $add_card_form_request->setCheckoutNonce( $checkout_nonce ); + $add_card_form_request->setCheckoutRedirectSuccessUrl( $success_url ); + $add_card_form_request->setCheckoutRedirectCancelUrl( $cancel_url ); + $add_card_form_request->setLanguage( Helper::getLocale() ); // Create a addCardFormRequest via Paytrail SDK // @var \GuzzleHttp\Psr7\Response $response - $response = $this->client->createAddCardFormRequest($add_card_form_request); + $response = $this->client->createAddCardFormRequest( $add_card_form_request ); - if ($response->getHeader('Location')) { - wp_redirect($response->getHeader('Location')[0]); + if ( $response->getHeader( 'Location' ) ) { + wp_redirect( $response->getHeader( 'Location' )[0] ); exit; } } @@ -633,12 +687,12 @@ public function add_card_form( $context = Plugin::ADD_CARD_CONTEXT_CHECKOUT) { */ public function process_card_token() { $getTokenRequest = new GetTokenRequest(); - $getTokenRequest->setCheckoutTokenizationId(filter_input(INPUT_GET, 'checkout-tokenization-id')); - $this->log('Paytrail: process_card_token', 'debug'); + $getTokenRequest->setCheckoutTokenizationId( filter_input( INPUT_GET, 'checkout-tokenization-id' ) ); + $this->log( 'Paytrail: process_card_token', 'debug' ); - $response = $this->client->createGetTokenRequest($getTokenRequest); + $response = $this->client->createGetTokenRequest( $getTokenRequest ); - return (bool) $this->save_card_token($response); + return (bool) $this->save_card_token( $response ); } /** @@ -646,18 +700,18 @@ public function process_card_token() { * * @param GetTokenResponse $card_token */ - private function save_card_token( GetTokenResponse $card_token) { - $this->log('Paytrail: save_card_token', 'debug'); + private function save_card_token( GetTokenResponse $card_token ) { + $this->log( 'Paytrail: save_card_token', 'debug' ); $token = new WC_Payment_Token_CC(); - $token->set_card_type($card_token->getCard()->getType()); - $token->set_expiry_month($card_token->getCard()->getExpireMonth()); - $token->set_expiry_year($card_token->getCard()->getExpireYear()); - $token->set_last4($card_token->getCard()->getPartialPan()); - $token->set_token($card_token->getToken()); - $token->set_user_id(get_current_user_id()); - $token->set_gateway_id(Plugin::GATEWAY_ID); - \WC_Payment_Tokens::set_users_default(get_current_user_id(), $token->get_id()); + $token->set_card_type( $card_token->getCard()->getType() ); + $token->set_expiry_month( $card_token->getCard()->getExpireMonth() ); + $token->set_expiry_year( $card_token->getCard()->getExpireYear() ); + $token->set_last4( $card_token->getCard()->getPartialPan() ); + $token->set_token( $card_token->getToken() ); + $token->set_user_id( get_current_user_id() ); + $token->set_gateway_id( Plugin::GATEWAY_ID ); + \WC_Payment_Tokens::set_users_default( get_current_user_id(), $token->get_id() ); return $token->save(); } @@ -670,11 +724,11 @@ private function save_card_token( GetTokenResponse $card_token) { * @throws ValidationException */ public function add_payment_method() { - $this->add_card_form(Plugin::ADD_CARD_CONTEXT_MY_ACCOUNT); + $this->add_card_form( Plugin::ADD_CARD_CONTEXT_MY_ACCOUNT ); return array( - 'result' => 'success', - 'redirect' => wc_get_endpoint_url('payment-methods'), + 'result' => 'success', + 'redirect' => wc_get_endpoint_url( 'payment-methods' ), ); } @@ -682,33 +736,33 @@ public function add_payment_method() { * Grab and display users saved card payment methods. */ public function saved_payment_methods() { - $html = '