From 94f7d956343348c284a37e7b00a0a92e34f2178b Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 6 Nov 2023 17:58:55 +0100 Subject: [PATCH 01/39] Update composer packages --- composer.json | 4 ++-- composer.lock | 64 ++++++++++++++++++++++++--------------------------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/composer.json b/composer.json index c5516f8..a963450 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "require": { - "krokedil/wp-api": "^1.0", - "krokedil/woocommerce": "dev-develop-free-trial-shipping as 1.3.1" + "krokedil/wp-api": "dev-develop", + "krokedil/woocommerce": "^1.0" }, "require-dev": { "wp-coding-standards/wpcs": "^2.3", diff --git a/composer.lock b/composer.lock index ffab292..4d6dca3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c672af86d1723c5c57933963ab295f42", + "content-hash": "0355fdd2715a587727b4139f996923b6", "packages": [ { "name": "krokedil/woocommerce", - "version": "dev-develop-free-trial-shipping", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/krokedil/woocommerce.git", - "reference": "abc47fcc65bd2c04d1d96e0a71245e98600f6dc5" + "reference": "5ea0b2af42359562c6d47cedd84038cdf0dc5823" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/krokedil/woocommerce/zipball/abc47fcc65bd2c04d1d96e0a71245e98600f6dc5", - "reference": "abc47fcc65bd2c04d1d96e0a71245e98600f6dc5", + "url": "https://api.github.com/repos/krokedil/woocommerce/zipball/5ea0b2af42359562c6d47cedd84038cdf0dc5823", + "reference": "5ea0b2af42359562c6d47cedd84038cdf0dc5823", "shasum": "" }, "require-dev": { @@ -42,23 +42,23 @@ ], "description": "A library package for Krokedils plugins that contains helper methods when working with WooCommerce.", "support": { - "source": "https://github.com/krokedil/woocommerce/tree/develop-free-trial-shipping", + "source": "https://github.com/krokedil/woocommerce/tree/1.3.0", "issues": "https://github.com/krokedil/woocommerce/issues" }, - "time": "2023-10-06T00:07:50+00:00" + "time": "2023-10-03T06:34:40+00:00" }, { "name": "krokedil/wp-api", - "version": "1.0.1", + "version": "dev-develop", "source": { "type": "git", "url": "https://github.com/krokedil/wp-api.git", - "reference": "5da83b450809821a80e2d1891da3bbb90c42d111" + "reference": "1fdc43ff3a0205e9af63d5d8a66c1d9a8223b64b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/krokedil/wp-api/zipball/5da83b450809821a80e2d1891da3bbb90c42d111", - "reference": "5da83b450809821a80e2d1891da3bbb90c42d111", + "url": "https://api.github.com/repos/krokedil/wp-api/zipball/1fdc43ff3a0205e9af63d5d8a66c1d9a8223b64b", + "reference": "1fdc43ff3a0205e9af63d5d8a66c1d9a8223b64b", "shasum": "" }, "require-dev": { @@ -83,10 +83,10 @@ ], "description": "A composer library for Krokedil WordPress plugins that contains classes for working with wp_remote_request to setup request classes. Also uses the WooCommerce logger to log request reponses.", "support": { - "source": "https://github.com/krokedil/wp-api/tree/1.0.1", + "source": "https://github.com/krokedil/wp-api/tree/develop", "issues": "https://github.com/krokedil/wp-api/issues" }, - "time": "2023-02-27T07:45:30+00:00" + "time": "2023-05-23T13:35:17+00:00" } ], "packages-dev": [ @@ -136,28 +136,31 @@ }, { "name": "php-stubs/wordpress-stubs", - "version": "v6.3.0", + "version": "6.4.x-dev", "source": { "type": "git", "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "adda7609e71d5f4dc7b87c74f8ec9e3437d2e92c" + "reference": "7b48cdb201f30ac92b0da3c0ad661e315ddad8fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/adda7609e71d5f4dc7b87c74f8ec9e3437d2e92c", - "reference": "adda7609e71d5f4dc7b87c74f8ec9e3437d2e92c", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/7b48cdb201f30ac92b0da3c0ad661e315ddad8fd", + "reference": "7b48cdb201f30ac92b0da3c0ad661e315ddad8fd", "shasum": "" }, "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "nikic/php-parser": "^4.13", "php": "^7.4 || ~8.0.0", "php-stubs/generator": "^0.8.3", "phpdocumentor/reflection-docblock": "^5.3", "phpstan/phpstan": "^1.10.12", - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^9.5", + "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^0.8" }, "suggest": { "paragonie/sodium_compat": "Pure PHP implementation of libsodium", + "symfony/polyfill-php80": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" }, "type": "library", @@ -174,9 +177,9 @@ ], "support": { "issues": "https://github.com/php-stubs/wordpress-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.3.0" + "source": "https://github.com/php-stubs/wordpress-stubs/tree/6.4" }, - "time": "2023-08-10T16:34:11+00:00" + "time": "2023-11-01T17:56:43+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -184,12 +187,12 @@ "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "7566b4d89de1d08d2a8ad85910507d6633a35d28" + "reference": "7763e2e1f773cb0615ed8afa133189fc804f583d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/7566b4d89de1d08d2a8ad85910507d6633a35d28", - "reference": "7566b4d89de1d08d2a8ad85910507d6633a35d28", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/7763e2e1f773cb0615ed8afa133189fc804f583d", + "reference": "7763e2e1f773cb0615ed8afa133189fc804f583d", "shasum": "" }, "require": { @@ -234,7 +237,7 @@ "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, - "time": "2023-09-11T11:08:03+00:00" + "time": "2023-11-02T00:47:31+00:00" }, { "name": "wp-coding-standards/wpcs", @@ -288,21 +291,14 @@ "time": "2020-05-13T23:57:56+00:00" } ], - "aliases": [ - { - "package": "krokedil/woocommerce", - "version": "dev-develop-free-trial-shipping", - "alias": "1.3.1", - "alias_normalized": "1.3.1.0" - } - ], + "aliases": [], "minimum-stability": "dev", "stability-flags": { - "krokedil/woocommerce": 20 + "krokedil/wp-api": 20 }, "prefer-stable": false, "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } From 8aced1cd2f48890724b42e51f09d83009c46b080 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 6 Nov 2023 17:59:08 +0100 Subject: [PATCH 02/39] Fix spelling issues --- classes/requests/helpers/class-kp-order-data.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/requests/helpers/class-kp-order-data.php b/classes/requests/helpers/class-kp-order-data.php index a4a37c5..92ffd38 100644 --- a/classes/requests/helpers/class-kp-order-data.php +++ b/classes/requests/helpers/class-kp-order-data.php @@ -91,7 +91,7 @@ public function get_order_data() { } /** - * Returns a formated Klarna order object. + * Returns a formatted Klarna order object. * * @param KP_IFrame $iframe_options The options to use for the Klarna Payments iframes. * @return array @@ -172,7 +172,7 @@ public function get_klarna_order_lines_array() { } /** - * Returns a formated Klarna order line object. + * Returns a formatted Klarna order line object. * * @param \Krokedil\WooCommerce\OrderLineData $order_line The order line data. * @return array @@ -228,7 +228,7 @@ public function get_klarna_order_line_object( $order_line ) { } /** - * Returns a formated Klarna customer object. + * Returns a formatted Klarna customer object. * * @param string|null $customer_type The customer type to use for generating the data. If empty it will use the class property instead. * @return array From b85573d81fbb375225f1ac8166b2fd62b17184f5 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 6 Nov 2023 17:59:19 +0100 Subject: [PATCH 03/39] Add request to get order from OM endpoint --- classes/requests/get/class-kp-get-order.php | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 classes/requests/get/class-kp-get-order.php diff --git a/classes/requests/get/class-kp-get-order.php b/classes/requests/get/class-kp-get-order.php new file mode 100644 index 0000000..a6c588a --- /dev/null +++ b/classes/requests/get/class-kp-get-order.php @@ -0,0 +1,27 @@ +log_title = 'Get Klarna order'; + $this->request_filter = 'wc_klarna_payments_get_order_args'; + $klarna_order_id = $this->arguments['klarna_order_id']; + $this->endpoint = "ordermanagement/v1/orders/{$klarna_order_id}"; + } +} From 1b58013ab3c43aae12094523efa50efd56cc7f0b Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 6 Nov 2023 17:59:31 +0100 Subject: [PATCH 04/39] Add request to upsell an order --- .../requests/patch/class-kp-upsell-order.php | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 classes/requests/patch/class-kp-upsell-order.php diff --git a/classes/requests/patch/class-kp-upsell-order.php b/classes/requests/patch/class-kp-upsell-order.php new file mode 100644 index 0000000..86a1f49 --- /dev/null +++ b/classes/requests/patch/class-kp-upsell-order.php @@ -0,0 +1,50 @@ +log_title = 'Upsell order'; + $this->request_filter = 'wc_klarna_payments_upsell_order_args'; + $this->endpoint = "/ordermanagement/v1/orders/{$klarna_order_id}/authorization"; + } + + /** + * Returns a formatted Klarna order object. + * + * @return array + */ + public function get_body() { + $order_id = $this->arguments['order_id']; + $order_data = new KP_Order_Data( '', $order_id ); + + $order_lines = $order_data->get_klarna_order_lines_array(); + $order_total = $order_data->order_data->get_total(); + + return array( + 'order_lines' => empty( $order_lines ) ? null : $order_lines, // Null the values if they are empty force an error. + 'order_amount' => 0 === $order_total ? null : $order_total, // Null the values if they are empty force an error. + 'description' => __( 'Upsell from thankyou page', 'klarna-upsell-for-woocommerce' ), + ); + } +} From bf2aa4a684722ff345f72c631ed48e8280e2a23b Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 6 Nov 2023 17:59:33 +0100 Subject: [PATCH 05/39] Create class-kp-requests-get.php --- classes/requests/class-kp-requests-get.php | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 classes/requests/class-kp-requests-get.php diff --git a/classes/requests/class-kp-requests-get.php b/classes/requests/class-kp-requests-get.php new file mode 100644 index 0000000..9329378 --- /dev/null +++ b/classes/requests/class-kp-requests-get.php @@ -0,0 +1,41 @@ +method = 'GET'; + } + + /** + * Build and return proper request arguments for this request type. + * + * @return array Request arguments + */ + protected function get_request_args() { + return apply_filters( + $this->request_filter, + array( + 'headers' => $this->get_request_headers(), + 'user-agent' => $this->get_user_agent(), + 'method' => $this->method, + 'timeout' => apply_filters( 'wc_kp_request_timeout', 10 ), + ) + ); + } +} From babb70c826e90fe77be6eccc6ea3d978a7341e9e Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 6 Nov 2023 17:59:50 +0100 Subject: [PATCH 06/39] Add API calls for getting orders and upselling orders --- classes/class-kp-api.php | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/classes/class-kp-api.php b/classes/class-kp-api.php index 7a9c803..ed722a0 100644 --- a/classes/class-kp-api.php +++ b/classes/class-kp-api.php @@ -166,6 +166,48 @@ public function cancel_recurring_order( $country, $recurring_token ) { return self::check_for_api_error( $response ); } + /** + * Get the Klarna order from the order management API. + * + * @param string $country The Klarna country to use. + * @param string $klarna_order_id The Klarna order id. + * + * @return array|WP_Error The response from Klarna. + */ + public function get_klarna_om_order( $country, $klarna_order_id ) { + $request = new KP_Get_Order( + array( + 'country' => $country, + 'klarna_order_id' => $klarna_order_id, + ) + ); + $response = $request->request(); + + return self::check_for_api_error( $response ); + } + + /** + * Upsell the klarna order. + * + * @param string $country The Klarna country to use. + * @param string $klarna_order_id The Klarna order id. + * @param int $order_id The WooCommerce order id. + * + * @return array|WP_Error The response from Klarna. + */ + public function upsell_klarna_order( $country, $klarna_order_id, $order_id ) { + $request = new KP_Upsell_Order( + array( + 'country' => $country, + 'klarna_order_id' => $klarna_order_id, + 'order_id' => $order_id, + ) + ); + $response = $request->request(); + + return self::check_for_api_error( $response ); + } + /** * Checks for WP Errors and returns either the response or a WP Error.. * From b9ff558df5fc1985ff8555c8f91aba43e1a665ba Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 6 Nov 2023 18:00:07 +0100 Subject: [PATCH 07/39] Add support for post purchase upsell in the gateway class --- classes/class-wc-gateway-klarna-payments.php | 71 ++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/classes/class-wc-gateway-klarna-payments.php b/classes/class-wc-gateway-klarna-payments.php index 1036f73..6ccbfb7 100644 --- a/classes/class-wc-gateway-klarna-payments.php +++ b/classes/class-wc-gateway-klarna-payments.php @@ -79,6 +79,7 @@ public function __construct() { 'subscription_payment_method_change_customer', 'subscription_payment_method_change_admin', 'multiple_subscriptions', + 'upsell' ) ); // Make this filterable. @@ -456,6 +457,76 @@ public function set_payment_method_title( $order, $klarna_place_order_response ) $order->set_payment_method_title( $new_title ); } } + + /** + * Check if upsell should be available for the Klarna order or not. + * + * @param int $order_id The WooCommerce order id. + * @return bool + */ + public function upsell_available( $order_id ) { + $order = wc_get_order( $order_id ); + $country = $order->get_meta( '_wc_klarna_country', true ); + $klarna_order_id = $order->get_meta( '_wc_klarna_order_id', true ); + + if ( empty( $klarna_order_id ) ) { + return false; + } + + $klarna_order = KP_WC()->api->get_klarna_om_order( $country, $klarna_order_id ); + + if ( is_wp_error( $klarna_order ) ) { + return false; + } + + // If the needed keys are not set, return false. + if ( ! isset( $klarna_order['initial_payment_method'] ) || ! isset( $klarna_order['initial_payment_method']['type'] ) ) { + return false; + } + + // Set allowed payment methods for upsell based on country. https://developers.klarna.com/documentation/order-management/integration-guide/pre-delivery/#update-order-amount. + $allowed_payment_methods = array( 'INVOICE', 'B2B_INVOICE', 'BASE_ACCOUNT', 'DIRECT_DEBIT' ); + switch ( $klarna_order['billing_address']['country'] ) { + case 'AT': + case 'DE': + case 'DK': + case 'FI': + case 'FR': + case 'NL': + case 'NO': + case 'SE': + $allowed_payment_methods[] = 'FIXED_AMOUNT'; + break; + case 'CH': + $allowed_payment_methods = array(); + break; + } + + return in_array( $klarna_order['initial_payment_method']['type'], $allowed_payment_methods, true ); + } + + /** + * Make an upsell request to Klarna. + * + * @param int $order_id The WooCommerce order id. + * @param string $upsell_uuid The unique id for the upsell request. + * + * @return bool|WP_Error + */ + public function upsell( $order_id, $upsell_uuid ) { + $order = wc_get_order( $order_id ); + $country = $order->get_meta( '_wc_klarna_country', true ); + $klarna_order_id = $order->get_meta( '_wc_klarna_order_id', true ); + + $klarna_upsell_order = KP_WC()->api->upsell_klarna_order( $country, $klarna_order_id, $order_id ); + + if ( is_wp_error( $klarna_upsell_order ) ) { + $error = new WP_Error( '401', __( 'Klarna did not accept the new order amount, the order has not been updated' ) ); + return $error; + } + + return true; + } } /** From e3a7827070ee7e316bd4adc43fba7861e01f66a9 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 6 Nov 2023 18:03:35 +0100 Subject: [PATCH 08/39] Require new files --- klarna-payments-for-woocommerce.php | 30 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/klarna-payments-for-woocommerce.php b/klarna-payments-for-woocommerce.php index 81f8acf..bc22827 100644 --- a/klarna-payments-for-woocommerce.php +++ b/klarna-payments-for-woocommerce.php @@ -197,9 +197,10 @@ public function order_management_check() { $current_screen = get_current_screen(); if ( 'shop_order' === $current_screen->id || 'plugins' === $current_screen->id || 'woocommerce_page_wc-settings' === $current_screen->id ) { ?> -
-

-
+
+

+

+

- +

- "> + + + ' . sprintf( @@ -301,7 +304,7 @@ public function check_permalinks() { */ public function include_files() { // Classes. - include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/admin/class-kp-form-fields.php'; // This is loaded very early becasue we'll need these settings right away. + include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/admin/class-kp-form-fields.php'; // This is loaded very early because we'll need these settings right away. include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/class-wc-gateway-klarna-payments.php'; include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/class-kp-gdpr.php'; include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/class-kp-ajax.php'; @@ -318,9 +321,12 @@ public function include_files() { // Requests. include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/class-kp-requests.php'; + include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/class-kp-requests-get.php'; include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/class-kp-requests-post.php'; include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/class-kp-requests-patch.php'; + include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/get/class-kp-get-order.php'; include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/patch/class-kp-cancel-recurring.php'; + include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/patch/class-kp-upsell-order.php'; include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/post/class-kp-create-session.php'; include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/post/class-kp-update-session.php'; include_once WC_KLARNA_PAYMENTS_PLUGIN_PATH . '/classes/requests/post/class-kp-place-order.php'; @@ -368,11 +374,11 @@ protected static function missing_autoloader() { 'admin_notices', function () { ?> -
-

- -

-
+
+

+ +

+
Date: Thu, 7 Dec 2023 13:30:33 +0100 Subject: [PATCH 09/39] Updated WP/WC version Updated Tested up to WP/WC version --- klarna-payments-for-woocommerce.php | 2 +- readme.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/klarna-payments-for-woocommerce.php b/klarna-payments-for-woocommerce.php index 3a5d31d..42d96d8 100644 --- a/klarna-payments-for-woocommerce.php +++ b/klarna-payments-for-woocommerce.php @@ -10,7 +10,7 @@ * Domain Path: /languages * * WC requires at least: 5.6.0 - * WC tested up to: 8.2.1 + * WC tested up to: 8.3.1 * * Copyright (c) 2017-2023 Krokedil * diff --git a/readme.txt b/readme.txt index e8fb7cf..f8f10cf 100644 --- a/readme.txt +++ b/readme.txt @@ -3,10 +3,10 @@ Contributors: klarna, krokedil, automattic Tags: woocommerce, klarna, ecommerce, e-commerce Donate link: https://klarna.com Requires at least: 5.0 -Tested up to: 6.3.2 +Tested up to: 6.4.1 Requires PHP: 7.4 WC requires at least: 5.6.0 -WC tested up to: 8.2.1 +WC tested up to: 8.3.1 Stable tag: 3.2.4 License: GPLv3 or later License URI: http://www.gnu.org/licenses/gpl-3.0.html From b24b7491cf60e2b6f2015656a53556a460831947 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:52:47 +0100 Subject: [PATCH 10/39] Add function to get a klarna session --- classes/class-kp-api.php | 24 ++++++++++- classes/requests/class-kp-requests-get.php | 42 +++++++++++++++++++ classes/requests/get/class-kp-get-session.php | 28 +++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 classes/requests/class-kp-requests-get.php create mode 100644 classes/requests/get/class-kp-get-session.php diff --git a/classes/class-kp-api.php b/classes/class-kp-api.php index 7a9c803..607a176 100644 --- a/classes/class-kp-api.php +++ b/classes/class-kp-api.php @@ -166,6 +166,29 @@ public function cancel_recurring_order( $country, $recurring_token ) { return self::check_for_api_error( $response ); } + /** + * Return the session from Klarna Payments. + * + * @param string $session_id The Klarna session id. + * @param string $country The Klarna country to use. + * @return array|WP_Error The response from Klarna. + */ + public function get_session( $session_id, $country = null ) { + if ( ! $country ) { + $country = kp_get_klarna_country(); + } + + $request = new KP_Get_Session( + array( + 'session_id' => $session_id, + 'country' => $country, + ) + ); + $response = $request->request(); + + return self::check_for_api_error( $response ); + } + /** * Checks for WP Errors and returns either the response or a WP Error.. * @@ -182,5 +205,4 @@ private static function check_for_api_error( $response ) { } return $response; } - } diff --git a/classes/requests/class-kp-requests-get.php b/classes/requests/class-kp-requests-get.php new file mode 100644 index 0000000..bc27b09 --- /dev/null +++ b/classes/requests/class-kp-requests-get.php @@ -0,0 +1,42 @@ +method = 'GET'; + } + + /** + * Build and return proper request arguments for this request type. + * + * @return array Request arguments + */ + protected function get_request_args() { + + return apply_filters( + $this->request_filter, + array( + 'headers' => $this->get_request_headers(), + 'user-agent' => $this->get_user_agent(), + 'method' => $this->method, + 'timeout' => apply_filters( 'wc_kp_request_timeout', 10 ), + ) + ); + } +} diff --git a/classes/requests/get/class-kp-get-session.php b/classes/requests/get/class-kp-get-session.php new file mode 100644 index 0000000..84f9264 --- /dev/null +++ b/classes/requests/get/class-kp-get-session.php @@ -0,0 +1,28 @@ +log_title = 'Get session'; + $this->request_filter = 'wc_klarna_payments_get_session_args'; + $this->endpoint = "payments/v1/sessions/$session_id"; + } +} From 9c6afdd24d41f447b66e98fae6a4d9a646750d96 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:52:55 +0100 Subject: [PATCH 11/39] Create class-kp-klarna-express-checkout.php --- classes/class-kp-klarna-express-checkout.php | 97 ++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 classes/class-kp-klarna-express-checkout.php diff --git a/classes/class-kp-klarna-express-checkout.php b/classes/class-kp-klarna-express-checkout.php new file mode 100644 index 0000000..864a084 --- /dev/null +++ b/classes/class-kp-klarna-express-checkout.php @@ -0,0 +1,97 @@ +klarna_express_checkout = new KlarnaExpressCheckout(); + + $this->klarna_express_checkout->ajax()->set_get_payload( array( $this, 'get_payload' ) ); + } + + /** + * Get order data for the cart. + * + * @return KP_Order_Data + */ + public function get_order_data_helper() { + $settings = get_option( 'woocommerce_klarna_payments_settings', array() ); + $customer_type = $settings['customer_type'] ?? 'b2c'; + $order_data_helper = new KP_Order_Data( $customer_type ); // Should always use the cart. + + return $order_data_helper; + } + + /** + * Get the payload for the Klarna Express Checkout. + * + * @return array + */ + public function get_payload() { + $order_data_helper = $this->get_order_data_helper(); + + $payload = array( + 'purchase_country' => kp_get_klarna_country(), + 'purchase_currency' => get_woocommerce_currency(), + 'locale' => kp_get_locale(), + 'order_amount' => $order_data_helper->order_data->get_total(), + 'order_tax_amount' => $order_data_helper->order_data->get_total_tax(), + 'order_lines' => $order_data_helper->get_klarna_order_lines_array(), + ); + + return $payload; + } + + /** + * Set session data from KEC auth response. + * + * @param string $session_id The session ID. + * @param string $client_token The client token. + * + * @return void + */ + public static function set_session_data( $session_id, $client_token ) { + // Get the Klarna session. + $country = kp_get_klarna_country(); + $klarna_session = KP_WC()->api->get_session( $session_id, $country ); + + // Verify the response. + if ( is_wp_error( $klarna_session ) ) { + return; + } + + KP_WC()->session->klarna_session = array( + 'session_id' => $session_id, + 'client_token' => $client_token, + 'payment_method_categories' => $klarna_session['payment_method_categories'] ?? array(), + ); + + KP_WC()->session->session_country = $country; + + KP_WC()->session->is_kec = true; + + WC()->session->set( 'kp_session_data', wp_json_encode( KP_WC()->session ) ); + } +} From 844551b80fb0af95043d85b6e9cb6bdcbc282d7b Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:53:07 +0100 Subject: [PATCH 12/39] Add KEC session value to KP session data --- classes/class-kp-session.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/classes/class-kp-session.php b/classes/class-kp-session.php index 029d516..ad9138c 100644 --- a/classes/class-kp-session.php +++ b/classes/class-kp-session.php @@ -50,6 +50,13 @@ class KP_Session { */ public $session_country = null; + /** + * If KEC is used or not. + * + * @var bool + */ + public $is_kec = false; + /** * Class constructor. */ @@ -84,6 +91,7 @@ public function get_session( $order = null ) { $this->klarna_session = null; $this->session_hash = null; $this->session_country = null; + $this->is_kec = false; } // If we already have a Klarna session and session does not need an update, return the Klarna session. @@ -139,6 +147,7 @@ public function set_session_data( $order = null ) { $this->klarna_session = $session_data['klarna_session']; $this->session_hash = $session_data['session_hash']; $this->session_country = $session_data['session_country']; + $this->is_kec = $session_data['is_kec'] ?? false; } /** @@ -256,7 +265,7 @@ private function get_session_cart_hash() { // The `get_totals` method can return non-numeric items which should be removed before using `array_sum`. $cart_totals = array_filter( WC()->cart->get_totals(), - function( $total ) { + function ( $total ) { return is_numeric( $total ); } ); From e5464280513e3e962c9d4b743c815c9caa3dbc57 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:53:24 +0100 Subject: [PATCH 13/39] Dont initialize KP_Checkout in class file --- classes/class-kp-checkout.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/class-kp-checkout.php b/classes/class-kp-checkout.php index 0f88dbd..39023b7 100644 --- a/classes/class-kp-checkout.php +++ b/classes/class-kp-checkout.php @@ -57,4 +57,4 @@ public function html_client_token( $session_token = false ) { Date: Tue, 12 Dec 2023 13:53:37 +0100 Subject: [PATCH 14/39] Update assets to include if KEC is enabled or not --- classes/class-kp-assets.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/class-kp-assets.php b/classes/class-kp-assets.php index e2e5f2c..150f61a 100644 --- a/classes/class-kp-assets.php +++ b/classes/class-kp-assets.php @@ -78,6 +78,8 @@ private function get_checkout_params( $settings ) { $order_data = new KP_Order_Data( $customer_type, $order_id ); $customer = $order_data->get_klarna_customer_object(); + KP_WC()->session->set_session_data(); + // Create the params array. $klarna_payments_params = array( // Ajax URLS. @@ -96,6 +98,7 @@ private function get_checkout_params( $settings ) { 'customer_type' => $customer_type, 'remove_postcode_spaces' => ( apply_filters( 'wc_kp_remove_postcode_spaces', false ) ) ? 'yes' : 'no', 'client_token' => KP_WC()->session->get_klarna_client_token(), + 'kec_enabled' => KP_WC()->session->is_kec ? 'yes' : 'no', 'order_pay_page' => $pay_for_order, 'pay_for_order' => $pay_for_order, 'order_id' => $order_id, @@ -159,7 +162,6 @@ public function enqueue_express_button() { $this->enqueue_express_button_scripts(); $this->enqueue_express_button_styles(); - } /** @@ -318,9 +320,7 @@ private function enqueue_express_button_styles() { ); wp_enqueue_style( 'klarna_express_button_styles' ); - } - } new KP_Assets(); From 63e655e794066479c5f1bc97f541d9668cb26297 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:54:22 +0100 Subject: [PATCH 15/39] Make iframe_options optional for getting order data for KP requests --- classes/requests/helpers/class-kp-order-data.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/requests/helpers/class-kp-order-data.php b/classes/requests/helpers/class-kp-order-data.php index a4a37c5..1cb7b77 100644 --- a/classes/requests/helpers/class-kp-order-data.php +++ b/classes/requests/helpers/class-kp-order-data.php @@ -91,12 +91,12 @@ public function get_order_data() { } /** - * Returns a formated Klarna order object. + * Returns a formatted Klarna order object. * * @param KP_IFrame $iframe_options The options to use for the Klarna Payments iframes. * @return array */ - public function get_klarna_order_object( $iframe_options ) { + public function get_klarna_order_object( $iframe_options = null ) { $customer = $this->get_klarna_customer_object(); return array( @@ -109,7 +109,7 @@ public function get_klarna_order_object( $iframe_options ) { 'customer' => get_klarna_customer( $this->customer_type ), 'billing_address' => $customer['billing'], 'shipping_address' => $customer['shipping'], - 'options' => $iframe_options->get_kp_color_options(), + 'options' => $iframe_options ? $iframe_options->get_kp_color_options() : array(), 'merchant_urls' => array( 'authorization' => home_url( '/wc-api/KP_WC_AUTHORIZATION' ), ), From 4e4a8aadba7cd93930f1158c4fa05f9bd1107c5b Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:54:26 +0100 Subject: [PATCH 16/39] Update class-kp-place-order.php --- classes/requests/post/class-kp-place-order.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/requests/post/class-kp-place-order.php b/classes/requests/post/class-kp-place-order.php index 8d67770..dc8fa9b 100644 --- a/classes/requests/post/class-kp-place-order.php +++ b/classes/requests/post/class-kp-place-order.php @@ -34,8 +34,8 @@ public function get_body() { $body = parent::get_body(); $order = wc_get_order( $this->arguments['order_id'] ); - $body['merchant_reference1'] = $order->get_order_number(); - $body['merchant_reference2'] = $order->get_id(); + $body['merchant_reference1'] = $order->get_order_number(); + $body['merchant_reference2'] = $order->get_id(); $body['merchant_urls']['confirmation'] = $order->get_checkout_order_received_url(); return $body; From ee8eb11e93567e439e388c2eb88ad2aa4af379f8 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:54:38 +0100 Subject: [PATCH 17/39] Add kec package --- composer.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c5516f8..11766c4 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,8 @@ { "require": { "krokedil/wp-api": "^1.0", - "krokedil/woocommerce": "dev-develop-free-trial-shipping as 1.3.1" + "krokedil/woocommerce": "^1.3", + "krokedil/klarna-express-checkout": "^1.0.0" }, "require-dev": { "wp-coding-standards/wpcs": "^2.3", @@ -16,6 +17,10 @@ { "type": "vcs", "url": "git@github.com:krokedil/woocommerce.git" + }, + { + "type": "vcs", + "url": "git@github.com:krokedil/klarna-express-checkout.git" } ], "minimum-stability": "dev" From 7026d065c8eb076e097d99fdb0d0d6cb0226b5e6 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:55:07 +0100 Subject: [PATCH 18/39] Update main plugin file to include new files and initialize KEC and checkout classes --- klarna-payments-for-woocommerce.php | 42 ++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/klarna-payments-for-woocommerce.php b/klarna-payments-for-woocommerce.php index f8220a5..3ef74df 100644 --- a/klarna-payments-for-woocommerce.php +++ b/klarna-payments-for-woocommerce.php @@ -5,7 +5,7 @@ * Description: Provides Klarna Payments as payment method to WooCommerce. * Author: krokedil, klarna, automattic * Author URI: https://krokedil.com/ - * Version: 3.2.3 + * Version: 3.2.3-kec * Text Domain: klarna-payments-for-woocommerce * Domain Path: /languages * @@ -110,6 +110,13 @@ public function __wakeup() { */ public $session = null; + /** + * KP Checkout class. Handles the checkout process. + * + * @var KP_Checkout|null + */ + public $checkout = null; + /** * KP Subscription class. Handles the integration with WooCommerce Subscription @@ -118,6 +125,13 @@ public function __wakeup() { */ public $subscription = null; + /** + * KP Klarna Express Checkout class. Handles the integration with Klarna Express Checkout + * + * @var KP_Klarna_Express_Checkout|null + */ + public $klarna_express_checkout = null; + /** * Protected constructor to prevent creating a new instance of the * *Singleton* via the `new` operator from outside of this class. @@ -131,7 +145,7 @@ protected function __construct() { add_filter( 'woocommerce_checkout_posted_data', array( $this, 'filter_payment_method_id' ) ); // Load text domain. - load_plugin_textdomain( 'klarna-payments-for-woocommerce', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' ); + load_plugin_textdomain( 'klarna-payments-for-woocommerce', false, plugin_basename( __DIR__ ) . '/languages' ); } /** @@ -157,6 +171,9 @@ public function init() { $this->subscription = new KP_Subscription(); } + $this->checkout = new KP_Checkout(); + $this->klarna_express_checkout = new KP_Klarna_Express_Checkout(); + $this->register_payment_block(); add_action( 'before_woocommerce_init', array( $this, 'declare_wc_compatibility' ) ); @@ -197,9 +214,9 @@ public function order_management_check() { $current_screen = get_current_screen(); if ( 'shop_order' === $current_screen->id || 'plugins' === $current_screen->id || 'woocommerce_page_wc-settings' === $current_screen->id ) { ?> -
-

-
+
+

+
Date: Tue, 12 Dec 2023 13:55:31 +0100 Subject: [PATCH 19/39] Update phpcs.ruleset.xml --- phpcs.ruleset.xml | 56 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/phpcs.ruleset.xml b/phpcs.ruleset.xml index 719491b..ca06f2d 100644 --- a/phpcs.ruleset.xml +++ b/phpcs.ruleset.xml @@ -1,9 +1,53 @@ - - Generally-applicable sniffs for WordPress plugins - - + + WooCommerce dev PHP_CodeSniffer ruleset. - */node_modules/* - */vendor/* + + */node_modules/* + */vendor/* + + + tests/* + + + + + + + + + + + + + + + + + + + + + src/ + + + + + src/ + + + + + src/ + + + + + src/ + + + + + src/ + From 37fffec401fd78f64ef64be04449e4007fa36c0d Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:57:14 +0100 Subject: [PATCH 20/39] Add KEC data to return for place order and register pay button support --- classes/class-wc-gateway-klarna-payments.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/classes/class-wc-gateway-klarna-payments.php b/classes/class-wc-gateway-klarna-payments.php index 1036f73..fbb975c 100644 --- a/classes/class-wc-gateway-klarna-payments.php +++ b/classes/class-wc-gateway-klarna-payments.php @@ -69,6 +69,7 @@ public function __construct() { 'wc_klarna_payments_supports', array( 'products', + 'pay_button', 'subscriptions', 'subscription_cancellation', 'subscription_suspension', @@ -101,6 +102,8 @@ public function __construct() { $this->hide_what_is_klarna = 'yes' === $this->get_option( 'hide_what_is_klarna' ); $this->float_what_is_klarna = 'yes' === $this->get_option( 'float_what_is_klarna' ); + $this->pay_button_id = \Krokedil\KlarnaExpressCheckout\KlarnaExpressCheckout::get_payment_button_id(); + // Hooks. add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); add_action( 'woocommerce_api_wc_gateway_klarna_payments', array( $this, 'notification_listener' ) ); @@ -331,7 +334,7 @@ private function process_checkout_order( $order ) { $customer = $order_data->get_klarna_customer_object(); // Return success without redirect URL since our script handles the return instead of WooCommerce. - return array( + $return = array( 'result' => 'success', 'order_id' => $order_id, 'addresses' => array( @@ -339,6 +342,13 @@ private function process_checkout_order( $order ) { 'shipping' => $customer['shipping'], ), ); + + // If KEC is enabled, we should pass the payload with the result. + if ( KP_WC()->session->is_kec ) { + $return['payload'] = KP_WC()->klarna_express_checkout->get_payload(); + } + + return $return; } /** From 3db23df63c0916b57555d64a11f06ebeaa6fc31c Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:57:31 +0100 Subject: [PATCH 21/39] Add support for KEC flow in the script, and clean up some formatting --- assets/js/klarna-payments.js | 641 +++++++++++++++++++++-------------- 1 file changed, 385 insertions(+), 256 deletions(-) diff --git a/assets/js/klarna-payments.js b/assets/js/klarna-payments.js index c940396..48a6e9e 100644 --- a/assets/js/klarna-payments.js +++ b/assets/js/klarna-payments.js @@ -6,26 +6,29 @@ jQuery( function($) { authorization_response: {}, iframe_loaded: false, show_form: false, - klarna_container_selector: '#klarna_container_2', + klarna_container_selector: "#klarna_container_2", checkout_values: {}, addresses: {}, - check_changes: function() { - $('.woocommerce-billing-fields input, .woocommerce-billing-fields select, .woocommerce-shipping-fields input, .woocommerce-shipping-fields select').each(function() { - var fieldName = $(this).attr('name'); + check_changes: function () { + $( + ".woocommerce-billing-fields input, .woocommerce-billing-fields select, .woocommerce-shipping-fields input, .woocommerce-shipping-fields select" + ).each(function () { + var fieldName = $(this).attr("name"); var fieldValue = $(this).val(); - if ( klarna_payments.checkout_values[ fieldName ] !== fieldValue ) { - klarna_payments.checkout_values[ fieldName ] = fieldValue; - $(this).trigger('change'); + if (klarna_payments.checkout_values[fieldName] !== fieldValue) { + klarna_payments.checkout_values[fieldName] = fieldValue; + $(this).trigger("change"); } }); }, - debounce_changes: function(func, wait, immediate) { + debounce_changes: function (func, wait, immediate) { var timeout; - return function() { - var context = this, args = arguments; - var later = function() { + return function () { + var context = this, + args = arguments; + var later = function () { timeout = null; if (!immediate) func.apply(context, args); }; @@ -36,14 +39,16 @@ jQuery( function($) { }; }, - start: function() { + start: function () { // Store all billing and shipping values. - $(document).ready(function() { - $('#customer_details input, #customer_details select').each(function() { - var fieldName = $(this).attr('name'); - var fieldValue = $(this).val(); - klarna_payments.checkout_values[ fieldName ] = fieldValue; - }); + $(document).ready(function () { + $("#customer_details input, #customer_details select").each( + function () { + var fieldName = $(this).attr("name"); + var fieldValue = $(this).val(); + klarna_payments.checkout_values[fieldName] = fieldValue; + } + ); if (klarna_payments.isKlarnaPaymentsSelected()) { klarna_payments.initKlarnaCredit(); klarna_payments.load().then(klarna_payments.loadHandler); @@ -54,11 +59,14 @@ jQuery( function($) { * When WooCommerce updates checkout * Happens on initial page load, country, state and postal code changes */ - $('body').on('updated_checkout', function() { + $("body").on("updated_checkout", function () { // Unblock the payments element if blocked - var blocked_el = $('.woocommerce-checkout-payment'); + var blocked_el = $(".woocommerce-checkout-payment"); var blocked_el_data = blocked_el.data(); - if (blocked_el.length && 1 === blocked_el_data['blockUI.isBlocked']) { + if ( + blocked_el.length && + 1 === blocked_el_data["blockUI.isBlocked"] + ) { blocked_el.unblock(); } @@ -74,50 +82,68 @@ jQuery( function($) { /** * Clear auth token if there's checkout error. */ - $( document.body ).on( 'checkout_error', function() { + $(document.body).on("checkout_error", function () { $('input[name="klarna_payments_authorization_token"]').remove(); }); /** * Phone field changes. Has to be 5 characters or longer for KP to work. */ - $('form.checkout').on('keyup', '#billing_phone', klarna_payments.debounce_changes(function() { - if (klarna_payments.isKlarnaPaymentsSelected()) { - //$('#place_order').attr('disabled', true); - if ($(this).val().length > 4) { - klarna_payments.initKlarnaCredit(); - klarna_payments.load().then(klarna_payments.loadHandler); + $("form.checkout").on( + "keyup", + "#billing_phone", + klarna_payments.debounce_changes(function () { + if (klarna_payments.isKlarnaPaymentsSelected()) { + //$('#place_order').attr('disabled', true); + if ($(this).val().length > 4) { + klarna_payments.initKlarnaCredit(); + klarna_payments + .load() + .then(klarna_payments.loadHandler); + } } - } - }, 750)); + }, 750) + ); /** * Email field changes, check if WooCommerce says field is valid. */ - $('form.checkout').on('keyup', '#billing_email', klarna_payments.debounce_changes(function() { - if (klarna_payments.isKlarnaPaymentsSelected()) { - //$('#place_order').attr('disabled', true); - if (!$(this).parent().hasClass('woocommerce-invalid')) { - klarna_payments.initKlarnaCredit(); - klarna_payments.load().then(klarna_payments.loadHandler); + $("form.checkout").on( + "keyup", + "#billing_email", + klarna_payments.debounce_changes(function () { + if (klarna_payments.isKlarnaPaymentsSelected()) { + //$('#place_order').attr('disabled', true); + if (!$(this).parent().hasClass("woocommerce-invalid")) { + klarna_payments.initKlarnaCredit(); + klarna_payments + .load() + .then(klarna_payments.loadHandler); + } } - } - }, 750)); + }, 750) + ); /** * Billing company field changes. */ - $('form.checkout').on('keyup', '#billing_company', klarna_payments.debounce_changes(function() { - if (klarna_payments.isKlarnaPaymentsSelected()) { - klarna_payments.initKlarnaCredit(); - klarna_payments.load().then(klarna_payments.loadHandler); - } - }, 750)); + $("form.checkout").on( + "keyup", + "#billing_company", + klarna_payments.debounce_changes(function () { + if (klarna_payments.isKlarnaPaymentsSelected()) { + klarna_payments.initKlarnaCredit(); + klarna_payments + .load() + .then(klarna_payments.loadHandler); + } + }, 750) + ); /** * When changing payment method. - */ - $('body').on('change', 'input[name="payment_method"]', function() { + */ + $("body").on("change", 'input[name="payment_method"]', function () { // If Klarna Payments is selected and iframe is not loaded yet, disable the form. Also collapse any unselected Klarna Payments gateways. if (klarna_payments.isKlarnaPaymentsSelected()) { klarna_payments.initKlarnaCredit(); @@ -127,28 +153,27 @@ jQuery( function($) { // Enable the form if any other payment method is selected. if (!klarna_payments.isKlarnaPaymentsSelected()) { - $('#place_order').attr('disabled', false); + $("#place_order").attr("disabled", false); } // Check if we need to hide the shipping fields klarna_payments.maybeHideShippingAddress(); }); - }, - load: function() { + load: function () { var $defer = $.Deferred(); // Dont run load during checkout completion. - if( $('form.checkout').hasClass('processing') ) { + if ($("form.checkout").hasClass("processing")) { return $defer.reject(); } - var klarna_payments_container_selector_id = '#' + klarna_payments.getSelectorContainerID(); + var klarna_payments_container_selector_id = + "#" + klarna_payments.getSelectorContainerID(); console.log(klarna_payments_container_selector_id); if (klarna_payments_container_selector_id) { - var klarnaLoadedInterval = setInterval(function () { var Klarna = false; @@ -164,11 +189,16 @@ jQuery( function($) { var options = { container: klarna_payments_container_selector_id, - payment_method_category: klarna_payments.getSelectedPaymentCategory() === "klarna_payments" ? "" : klarna_payments.getSelectedPaymentCategory() + payment_method_category: + klarna_payments.getSelectedPaymentCategory() === + "klarna_payments" + ? "" + : klarna_payments.getSelectedPaymentCategory(), }; - if ( 'US' === $('#billing_country').val() ) { - var address = klarna_payments.get_address_from_checkout_form(); + if ("US" === $("#billing_country").val()) { + var address = + klarna_payments.get_address_from_checkout_form(); Klarna.Payments.load( options, @@ -178,12 +208,9 @@ jQuery( function($) { } ); } else { - Klarna.Payments.load( - options, - function (response) { - $defer.resolve(response); - } - ); + Klarna.Payments.load(options, function (response) { + $defer.resolve(response); + }); } } }, 100); @@ -197,7 +224,7 @@ jQuery( function($) { } }, - loadHandler: function(response) { + loadHandler: function (response) { klarna_payments.iframe_loaded = true; if (response.show_form) { @@ -207,44 +234,55 @@ jQuery( function($) { isKlarnaPaymentsSelected: function () { if ($('input[name="payment_method"]:checked').length) { - var selected_value = $('input[name="payment_method"]:checked').val(); - return selected_value.indexOf('klarna_payments') !== -1; + var selected_value = $( + 'input[name="payment_method"]:checked' + ).val(); + return selected_value.indexOf("klarna_payments") !== -1; } return false; }, setRadioButtonValues: function () { - $('input[name="payment_method"]').each( function( ) { - if( $(this).val().indexOf( 'klarna_payments' ) !== -1 ) { - $(this).val( 'klarna_payments' ); + $('input[name="payment_method"]').each(function () { + if ($(this).val().indexOf("klarna_payments") !== -1) { + $(this).val("klarna_payments"); } }); - }, - getSelectorContainerID: function() { - var containerID = $('input[name="payment_method"]:checked').attr('id').replace('payment_method_', ''); + getSelectorContainerID: function () { + var containerID = $('input[name="payment_method"]:checked') + .attr("id") + .replace("payment_method_", ""); - return containerID + '_container'; + return containerID + "_container"; }, - getSelectedPaymentCategory: function() { - var selected_category = $('input[name="payment_method"]:checked').attr('id').replace('payment_method_', ''); - console.log( selected_category ); - return selected_category.replace('klarna_payments_', ''); + getSelectedPaymentCategory: function () { + var selected_category = $('input[name="payment_method"]:checked') + .attr("id") + .replace("payment_method_", ""); + console.log(selected_category); + return selected_category.replace("klarna_payments_", ""); }, - authorize: function() { + authorize: function () { var $defer = $.Deferred(); var address = klarna_payments.get_address(); - + console.log(address); klarna_payments.authorization_response = {}; try { Klarna.Payments.authorize( address, - {payment_method_category: klarna_payments.getSelectedPaymentCategory() === "klarna_payments" ? "" : klarna_payments.getSelectedPaymentCategory()}, + { + payment_method_category: + klarna_payments.getSelectedPaymentCategory() === + "klarna_payments" + ? "" + : klarna_payments.getSelectedPaymentCategory(), + }, function (response) { klarna_payments.authorization_response = response; $defer.resolve(response); @@ -257,77 +295,107 @@ jQuery( function($) { return $defer.promise(); }, - get_address: function() { + get_address: function () { var address = { billing_address: { - given_name : klarna_payments.addresses.billing.given_name, - family_name : klarna_payments.addresses.billing.family_name, - email : klarna_payments.addresses.billing.email, - phone : klarna_payments.addresses.billing.phone, - country : klarna_payments.addresses.billing.country, - region : klarna_payments.addresses.billing.region, - postal_code : klarna_payments.addresses.billing.postal_code, - city : klarna_payments.addresses.billing.city, - street_address : klarna_payments.addresses.billing.street_address, - street_address2 : klarna_payments.addresses.billing.street_address2, - organization_name : ( 'b2b' === klarna_payments_params.customer_type ) ? klarna_payments.addresses.billing.organization_name : '', + given_name: klarna_payments.addresses.billing.given_name, + family_name: klarna_payments.addresses.billing.family_name, + email: klarna_payments.addresses.billing.email, + phone: klarna_payments.addresses.billing.phone, + country: klarna_payments.addresses.billing.country, + region: klarna_payments.addresses.billing.region, + postal_code: klarna_payments.addresses.billing.postal_code, + city: klarna_payments.addresses.billing.city, + street_address: + klarna_payments.addresses.billing.street_address, + street_address2: + klarna_payments.addresses.billing.street_address2, + organization_name: + "b2b" === klarna_payments_params.customer_type + ? klarna_payments.addresses.billing + .organization_name + : "", }, - shipping_address: {} + shipping_address: {}, }; address.shipping_address = $.extend({}, address.billing_address); - if ( $( '#ship-to-different-address' ).find( 'input' ).is( ':checked' ) ) { - address.shipping_address.given_name = klarna_payments.addresses.shipping.given_name; - address.shipping_address.family_name = klarna_payments.addresses.shipping.family_name; - address.shipping_address.country = klarna_payments.addresses.shipping.country; - address.shipping_address.region = klarna_payments.addresses.shipping.region; - address.shipping_address.postal_code = klarna_payments.addresses.shipping.postal_code; - address.shipping_address.city = klarna_payments.addresses.shipping.city; - address.shipping_address.street_address = klarna_payments.addresses.shipping.street_address; - address.shipping_address.street_address2 = klarna_payments.addresses.shipping.street_address2; + if ($("#ship-to-different-address").find("input").is(":checked")) { + address.shipping_address.given_name = + klarna_payments.addresses.shipping.given_name; + address.shipping_address.family_name = + klarna_payments.addresses.shipping.family_name; + address.shipping_address.country = + klarna_payments.addresses.shipping.country; + address.shipping_address.region = + klarna_payments.addresses.shipping.region; + address.shipping_address.postal_code = + klarna_payments.addresses.shipping.postal_code; + address.shipping_address.city = + klarna_payments.addresses.shipping.city; + address.shipping_address.street_address = + klarna_payments.addresses.shipping.street_address; + address.shipping_address.street_address2 = + klarna_payments.addresses.shipping.street_address2; } return address; }, - get_address_from_checkout_form: function() { + get_address_from_checkout_form: function () { var address = { billing_address: { - given_name : klarna_payments.checkout_values.billing_first_name, - family_name : klarna_payments.checkout_values.billing_last_name, - email : klarna_payments.checkout_values.billing_email, - phone : klarna_payments.checkout_values.billing_phone, - country : klarna_payments.checkout_values.billing_country, - region : klarna_payments.checkout_values.billing_state, - postal_code : klarna_payments.checkout_values.billing_postcode, - city : klarna_payments.checkout_values.billing_city, - street_address : klarna_payments.checkout_values.billing_address_1, - street_address2 : klarna_payments.checkout_values.billing_address_2, - organization_name : ( 'b2b' === klarna_payments_params.customer_type ) ? klarna_payments.checkout_values.billing_company : '', + given_name: + klarna_payments.checkout_values.billing_first_name, + family_name: + klarna_payments.checkout_values.billing_last_name, + email: klarna_payments.checkout_values.billing_email, + phone: klarna_payments.checkout_values.billing_phone, + country: klarna_payments.checkout_values.billing_country, + region: klarna_payments.checkout_values.billing_state, + postal_code: + klarna_payments.checkout_values.billing_postcode, + city: klarna_payments.checkout_values.billing_city, + street_address: + klarna_payments.checkout_values.billing_address_1, + street_address2: + klarna_payments.checkout_values.billing_address_2, + organization_name: + "b2b" === klarna_payments_params.customer_type + ? klarna_payments.checkout_values.billing_company + : "", }, - shipping_address: {} + shipping_address: {}, }; address.shipping_address = $.extend({}, address.billing_address); - if ( $( '#ship-to-different-address' ).find( 'input' ).is( ':checked' ) ) { - address.shipping_address.given_name = klarna_payments.checkout_values.shipping_first_name; - address.shipping_address.family_name = klarna_payments.checkout_values.shipping_last_name; - address.shipping_address.country = klarna_payments.checkout_values.shipping_country; - address.shipping_address.region = klarna_payments.checkout_values.shipping_state; - address.shipping_address.postal_code = klarna_payments.checkout_values.shipping_postcode; - address.shipping_address.city = klarna_payments.checkout_values.shipping_city; - address.shipping_address.street_address = klarna_payments.checkout_values.shipping_address_1; - address.shipping_address.street_address2 = klarna_payments.checkout_values.shipping_address_2; + if ($("#ship-to-different-address").find("input").is(":checked")) { + address.shipping_address.given_name = + klarna_payments.checkout_values.shipping_first_name; + address.shipping_address.family_name = + klarna_payments.checkout_values.shipping_last_name; + address.shipping_address.country = + klarna_payments.checkout_values.shipping_country; + address.shipping_address.region = + klarna_payments.checkout_values.shipping_state; + address.shipping_address.postal_code = + klarna_payments.checkout_values.shipping_postcode; + address.shipping_address.city = + klarna_payments.checkout_values.shipping_city; + address.shipping_address.street_address = + klarna_payments.checkout_values.shipping_address_1; + address.shipping_address.street_address2 = + klarna_payments.checkout_values.shipping_address_2; } return address; }, - collapseGateways: function() { - $('input[name="payment_method"]').each( function() { - if ( $(this).is( ':checked' ) ){ + collapseGateways: function () { + $('input[name="payment_method"]').each(function () { + if ($(this).is(":checked")) { $(this).siblings("div.payment_box").show(); } else { $(this).siblings("div.payment_box").hide(); @@ -335,200 +403,261 @@ jQuery( function($) { }); }, - maybeHideShippingAddress: function() { - if( false !== klarna_payments.isKlarnaPaymentsSelected() ) { - if( 'b2b' === klarna_payments_params.customer_type ) { - jQuery('#customer_details .col-2').hide(); + maybeHideShippingAddress: function () { + if (false !== klarna_payments.isKlarnaPaymentsSelected()) { + if ("b2b" === klarna_payments_params.customer_type) { + jQuery("#customer_details .col-2").hide(); } } else { - jQuery('#customer_details .col-2').show(); + jQuery("#customer_details .col-2").show(); } }, - initKlarnaCredit: function ( client_token ) { + initKlarnaCredit: function (client_token) { var client_token = klarna_payments.getClientToken(); - window.klarnaInitData = {client_token: client_token}; + window.klarnaInitData = { client_token: client_token }; Klarna.Payments.init(klarnaInitData); }, - printErrorMessage: function( message ) { - $('#klarna-payments-error-notice').remove(); - $('form.checkout').prepend( '
' ); - $.scroll_to_notices( $('form.checkout') ); + printErrorMessage: function (message) { + $("#klarna-payments-error-notice").remove(); + $("form.checkout").prepend( + '
" + ); + $.scroll_to_notices($("form.checkout")); }, - authorizeKlarnaOrder: function( order_id ) { - klarna_payments.authorize().done( function( response ) { - if ('authorization_token' in response) { - $('body').trigger( 'kp_auth_success' ); - $.ajax( - klarna_payments_params.place_order_url, - { - type: "POST", - dataType: "json", - async: true, - data: { - order_id: order_id, - auth_token: klarna_payments.authorization_response.authorization_token, - nonce: klarna_payments_params.place_order_nonce, - }, - success: function (response) { - // Log the success. - console.log('kp_place_order success'); - console.log(response); - }, - error: function (response) { - // Log the error. - console.log('kp_place_order error'); - console.log(response); - }, - complete: function (response) { - if( response.responseJSON.success === true ) { - window.location.href = response.responseJSON.data; - } else { - $('form.checkout').removeClass('processing').unblock(); - $('form.checkout').find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur(); - $('form.checkout').trigger('update_checkout'); - } - } - } + onSuccessfulAuthorization: function (order_id) { + $("body").trigger("kp_auth_success"); + $.ajax(klarna_payments_params.place_order_url, { + type: "POST", + dataType: "json", + async: true, + data: { + order_id: order_id, + auth_token: + klarna_payments.authorization_response + .authorization_token, + nonce: klarna_payments_params.place_order_nonce, + }, + success: function (response) { + // Log the success. + console.log("kp_place_order success"); + console.log(response); + }, + error: function (response) { + // Log the error. + console.log("kp_place_order error"); + console.log(response); + }, + complete: function (response) { + if (response.responseJSON.success === true) { + window.location.href = response.responseJSON.data; + } else { + $("form.checkout").removeClass("processing").unblock(); + $("form.checkout") + .find(".input-text, select, input:checkbox") + .trigger("validate") + .blur(); + $("form.checkout").trigger("update_checkout"); + } + }, + }); + }, + + onFailedAuthorization: function (order_id, response) { + $("body").trigger("kp_auth_failed"); + + // Re-enable the form. + $("body").trigger("updated_checkout"); + $("form.checkout").removeClass("processing"); + $("form.checkout").unblock(); + $(".woocommerce-checkout-review-order-table").unblock(); + + console.log("No authorization_token in response"); + $("form.woocommerce-checkout").removeClass("processing").unblock(); + $.ajax(klarna_payments_params.auth_failed_url, { + type: "POST", + dataType: "json", + async: true, + data: { + show_form: response.show_form, + order_id: json.order_id, + nonce: klarna_payments_params.auth_failed_nonce, + }, + }); + }, + + authorizeKlarnaOrder: async function (order_id, payload) { + if ("yes" === klarna_payments_params.kec_enabled) { + await Klarna.Payments.finalize({}, payload, function (result) { + klarna_payments.authorization_response = result; + if (result.approved) { + klarna_payments.onSuccessfulAuthorization( + order_id, + result + ); + } else { + klarna_payments.onFailedAuthorization(order_id, result); + } + }); + + return; + } + + await klarna_payments.authorize().done(function (response) { + if ("authorization_token" in response) { + klarna_payments.onSuccessfulAuthorization( + order_id, + response ); } else { - $('body').trigger( 'kp_auth_failed' ); - - // Re-enable the form. - $( 'body' ).trigger( 'updated_checkout' ); - $( 'form.checkout' ).removeClass( 'processing' ); - $( 'form.checkout' ).unblock(); - $( '.woocommerce-checkout-review-order-table' ).unblock(); - - console.log('No authorization_token in response'); - $('form.woocommerce-checkout').removeClass( 'processing' ).unblock(); - $.ajax( - klarna_payments_params.auth_failed_url, - { - type: "POST", - dataType: "json", - async: true, - data: { - show_form: response.show_form, - order_id: json.order_id, - nonce: klarna_payments_params.auth_failed_nonce - }, - } - ); + klarna_payments.onFailedAuthorization(order_id, response); } }); }, - klarnaPayForOrder: function( event ) { - if( klarna_payments.isKlarnaPaymentsSelected() ) { + klarnaPayForOrder: function (event) { + if (klarna_payments.isKlarnaPaymentsSelected()) { event.preventDefault(); klarna_payments.addresses = klarna_payments_params.addresses; - klarna_payments.authorizeKlarnaOrder( klarna_payments_params.order_id ); + klarna_payments.authorizeKlarnaOrder( + klarna_payments_params.order_id + ); } }, - getClientToken: function() { - if( $('#kp_client_token').length > 0 ) { - return $('#kp_client_token').val(); + getClientToken: function () { + if ($("#kp_client_token").length > 0) { + return $("#kp_client_token").val(); } else { return klarna_payments_params.client_token; } }, - orderSubmit: function( event ) { - if( klarna_payments.isKlarnaPaymentsSelected() ) { + orderSubmit: function (event) { + if (klarna_payments.isKlarnaPaymentsSelected()) { event.preventDefault(); - if( $('form.checkout').is('.processing') ) { + if ($("form.checkout").is(".processing")) { return false; } - $('form.checkout').addClass('processing'); - $( '.woocommerce-checkout-review-order-table' ).block({ + $("form.checkout").addClass("processing"); + $(".woocommerce-checkout-review-order-table").block({ message: null, overlayCSS: { - background: '#fff', - opacity: 0.6 - } + background: "#fff", + opacity: 0.6, + }, }); $.ajax({ - type: 'POST', + type: "POST", url: klarna_payments_params.submit_order, - data: $('form.checkout').serialize(), - dataType: 'json', - success: function( data ) { + data: $("form.checkout").serialize(), + dataType: "json", + success: function (data) { try { - if ( 'success' === data.result ) { - klarna_payments.logToFile( 'Successfully placed order. Starting authorization with Klarna' ); - klarna_payments.addresses = data.addresses - klarna_payments.authorizeKlarnaOrder( data.order_id ); + if ("success" === data.result) { + klarna_payments.logToFile( + "Successfully placed order. Starting authorization with Klarna" + ); + klarna_payments.addresses = data.addresses; + klarna_payments.authorizeKlarnaOrder( + data.order_id, + data.payload || null + ); } else { - throw 'Result failed'; + throw "Result failed"; } - } catch ( err ) { - if ( data.messages ) { - klarna_payments.logToFile( 'Checkout error | ' + data.messages ); - klarna_payments.failOrder( 'submission', data.messages ); + } catch (err) { + if (data.messages) { + klarna_payments.logToFile( + "Checkout error | " + data.messages + ); + klarna_payments.failOrder( + "submission", + data.messages + ); } else { - klarna_payments.logToFile( 'Checkout error | ' + err ); - klarna_payments.failOrder( 'submission', '
' + 'Checkout error' + '
' ); + klarna_payments.logToFile( + "Checkout error | " + err + ); + klarna_payments.failOrder( + "submission", + '
' + + "Checkout error" + + "
" + ); } } }, - error: function( data ) { + error: function (data) { try { - klarna_payments.logToFile( 'AJAX error | ' + JSON.stringify(data) ); - } catch( e ) { - klarna_payments.logToFile( 'AJAX error | Failed to parse error message.' ); + klarna_payments.logToFile( + "AJAX error | " + JSON.stringify(data) + ); + } catch (e) { + klarna_payments.logToFile( + "AJAX error | Failed to parse error message." + ); } - klarna_payments.failOrder( 'ajax-error', '
Internal Server Error
' ); - } + klarna_payments.failOrder( + "ajax-error", + '
Internal Server Error
' + ); + }, }); } }, /** * Fails the order with Klarna on a checkout error and timeout. - * @param {string} event + * @param {string} event */ - failOrder: function( event, error_message ) { - + failOrder: function (event, error_message) { // Re-enable the form. - $( 'body' ).trigger( 'updated_checkout' ); - $( 'form.checkout' ).removeClass( 'processing' ); - $( 'form.checkout' ).unblock(); - $( '.woocommerce-checkout-review-order-table' ).unblock(); + $("body").trigger("updated_checkout"); + $("form.checkout").removeClass("processing"); + $("form.checkout").unblock(); + $(".woocommerce-checkout-review-order-table").unblock(); // Print error messages, and trigger checkout_error, and scroll to notices. - $( '.woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message' ).remove(); - $( 'form.checkout' ).prepend( '
' + error_message + '
' ); // eslint-disable-line max-len - $( 'form.checkout' ).removeClass( 'processing' ).unblock(); - $( 'form.checkout' ).find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur(); - $( document.body ).trigger( 'checkout_error' , [ error_message ] ); - $.scroll_to_notices( $('form.checkout') ); + $( + ".woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message" + ).remove(); + $("form.checkout").prepend( + '
' + + error_message + + "
" + ); // eslint-disable-line max-len + $("form.checkout").removeClass("processing").unblock(); + $("form.checkout") + .find(".input-text, select, input:checkbox") + .trigger("validate") + .blur(); + $(document.body).trigger("checkout_error", [error_message]); + $.scroll_to_notices($("form.checkout")); }, /** * Logs the message to the klarna payments log in WooCommerce. - * @param {string} message + * @param {string} message */ - logToFile: function( message ) { - $.ajax( - { - url: klarna_payments_params.log_to_file_url, - type: 'POST', - dataType: 'json', - data: { - message: message, - nonce: klarna_payments_params.log_to_file_nonce - } - } - ); + logToFile: function (message) { + $.ajax({ + url: klarna_payments_params.log_to_file_url, + type: "POST", + dataType: "json", + data: { + message: message, + nonce: klarna_payments_params.log_to_file_nonce, + }, + }); }, - }; klarna_payments.start(); $('body').ready( function() { From 44ca189e1c2758768c1cacad570864530f02acbc Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 13:59:09 +0100 Subject: [PATCH 22/39] Update composer.lock --- composer.lock | 223 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 186 insertions(+), 37 deletions(-) diff --git a/composer.lock b/composer.lock index 66915d2..ac8a3b1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,155 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c672af86d1723c5c57933963ab295f42", + "content-hash": "d8f40ecac2761b509181bd214bfb8769", "packages": [ + { + "name": "firebase/php-jwt", + "version": "v6.10.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", + "shasum": "" + }, + "require": { + "php": "^7.4||^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.5||^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^1.0||^2.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" + }, + "time": "2023-12-01T16:26:39+00:00" + }, + { + "name": "krokedil/klarna-express-checkout", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/krokedil/klarna-express-checkout.git", + "reference": "cea60145ba5204028807601198be659511ebeb35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/krokedil/klarna-express-checkout/zipball/cea60145ba5204028807601198be659511ebeb35", + "reference": "cea60145ba5204028807601198be659511ebeb35", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "^6.10", + "php": "~7.4 || ~8.0" + }, + "require-dev": { + "10up/wp_mock": "^1.0", + "php-stubs/woocommerce-stubs": "^8.3", + "wp-coding-standards/wpcs": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Krokedil\\KlarnaExpressCheckout\\": "src/" + } + }, + "archive": { + "exclude": [ + "tests/*", + "phpunit.xml", + "composer-lock.json", + ".github/*", + ".gitignore", + ".gitattributes" + ] + }, + "scripts": { + "phpcs": [ + "phpcs --standard=phpcs.xml --extensions=php --ignore=vendor/,tests/" + ], + "phpcbf": [ + "phpcbf --standard=phpcs.xml --extensions=php --ignore=vendor/,tests/" + ], + "test": [ + "phpunit --configuration phpunit.xml" + ], + "test-coverage-html": [ + "phpunit --configuration phpunit.xml --coverage-html coverage" + ], + "test-coverage-clover": [ + "phpunit --configuration phpunit.xml --coverage-clover coverage.xml" + ] + }, + "license": [ + "GPL-v3" + ], + "authors": [ + { + "name": "Krokedil AB", + "email": "info@krokedil.se" + } + ], + "description": "A Klarna Express Checkout solution for WooCommerce", + "support": { + "source": "https://github.com/krokedil/klarna-express-checkout/tree/1.0.0", + "issues": "https://github.com/krokedil/klarna-express-checkout/issues" + }, + "time": "2023-12-12T12:49:30+00:00" + }, { "name": "krokedil/woocommerce", - "version": "dev-develop-free-trial-shipping", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/krokedil/woocommerce.git", - "reference": "abc47fcc65bd2c04d1d96e0a71245e98600f6dc5" + "reference": "8b83ebc73f169a8a3aebc943e527a47d40233015" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/krokedil/woocommerce/zipball/abc47fcc65bd2c04d1d96e0a71245e98600f6dc5", - "reference": "abc47fcc65bd2c04d1d96e0a71245e98600f6dc5", + "url": "https://api.github.com/repos/krokedil/woocommerce/zipball/8b83ebc73f169a8a3aebc943e527a47d40233015", + "reference": "8b83ebc73f169a8a3aebc943e527a47d40233015", "shasum": "" }, "require-dev": { @@ -42,23 +177,23 @@ ], "description": "A library package for Krokedils plugins that contains helper methods when working with WooCommerce.", "support": { - "source": "https://github.com/krokedil/woocommerce/tree/develop-free-trial-shipping", + "source": "https://github.com/krokedil/woocommerce/tree/1.3.1", "issues": "https://github.com/krokedil/woocommerce/issues" }, - "time": "2023-10-06T00:07:50+00:00" + "time": "2023-12-04T12:07:37+00:00" }, { "name": "krokedil/wp-api", - "version": "1.0.1", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/krokedil/wp-api.git", - "reference": "5da83b450809821a80e2d1891da3bbb90c42d111" + "reference": "494eb9a7d08e722f66ea059e87eb1bee7e73f7d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/krokedil/wp-api/zipball/5da83b450809821a80e2d1891da3bbb90c42d111", - "reference": "5da83b450809821a80e2d1891da3bbb90c42d111", + "url": "https://api.github.com/repos/krokedil/wp-api/zipball/494eb9a7d08e722f66ea059e87eb1bee7e73f7d0", + "reference": "494eb9a7d08e722f66ea059e87eb1bee7e73f7d0", "shasum": "" }, "require-dev": { @@ -83,10 +218,10 @@ ], "description": "A composer library for Krokedil WordPress plugins that contains classes for working with wp_remote_request to setup request classes. Also uses the WooCommerce logger to log request reponses.", "support": { - "source": "https://github.com/krokedil/wp-api/tree/1.0.1", + "source": "https://github.com/krokedil/wp-api/tree/1.1.0", "issues": "https://github.com/krokedil/wp-api/issues" }, - "time": "2023-02-27T07:45:30+00:00" + "time": "2023-12-04T12:15:24+00:00" } ], "packages-dev": [ @@ -186,13 +321,13 @@ "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "7763e2e1f773cb0615ed8afa133189fc804f583d" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "040f675a5020a62ddc9c46344d9cf26658e2b04e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/7763e2e1f773cb0615ed8afa133189fc804f583d", - "reference": "7763e2e1f773cb0615ed8afa133189fc804f583d", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/040f675a5020a62ddc9c46344d9cf26658e2b04e", + "reference": "040f675a5020a62ddc9c46344d9cf26658e2b04e", "shasum": "" }, "require": { @@ -202,12 +337,12 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "default-branch": true, "bin": [ - "bin/phpcs", - "bin/phpcbf" + "bin/phpcbf", + "bin/phpcs" ], "type": "library", "extra": { @@ -222,22 +357,45 @@ "authors": [ { "name": "Greg Sherwood", - "role": "lead" + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ "phpcs", "standards", "static analysis" ], "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, - "time": "2023-11-02T00:47:31+00:00" + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2023-12-11T21:00:05+00:00" }, { "name": "wp-coding-standards/wpcs", @@ -291,18 +449,9 @@ "time": "2020-05-13T23:57:56+00:00" } ], - "aliases": [ - { - "package": "krokedil/woocommerce", - "version": "dev-develop-free-trial-shipping", - "alias": "1.3.1", - "alias_normalized": "1.3.1.0" - } - ], + "aliases": [], "minimum-stability": "dev", - "stability-flags": { - "krokedil/woocommerce": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": [], From c2991c6244a0634bc8406556e7a031944bfd76bf Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Tue, 12 Dec 2023 14:20:11 +0100 Subject: [PATCH 23/39] Fix issues from merge conflicts --- assets/js/klarna-payments.js | 16 +++++++++----- classes/class-kp-api.php | 42 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/assets/js/klarna-payments.js b/assets/js/klarna-payments.js index 9c64a9a..5fa7271 100644 --- a/assets/js/klarna-payments.js +++ b/assets/js/klarna-payments.js @@ -429,7 +429,7 @@ jQuery( function($) { $.scroll_to_notices($("form.checkout")); }, - onSuccessfulAuthorization: function (order_id) { + onSuccessfulAuthorization: function (order_id, order_key) { $("body").trigger("kp_auth_success"); $.ajax(klarna_payments_params.place_order_url, { type: "POST", @@ -437,6 +437,7 @@ jQuery( function($) { async: true, data: { order_id: order_id, + order_key: order_key, auth_token: klarna_payments.authorization_response .authorization_token, @@ -467,7 +468,7 @@ jQuery( function($) { }); }, - onFailedAuthorization: function (order_id, response) { + onFailedAuthorization: function (order_id, order_key, response) { $("body").trigger("kp_auth_failed"); // Re-enable the form. @@ -484,7 +485,8 @@ jQuery( function($) { async: true, data: { show_form: response.show_form, - order_id: json.order_id, + order_id: order_id, + order_key: order_key, nonce: klarna_payments_params.auth_failed_nonce, }, }); @@ -501,7 +503,7 @@ jQuery( function($) { result ); } else { - klarna_payments.onFailedAuthorization(order_id, result); + klarna_payments.onFailedAuthorization(order_id, order_key, result); } }); @@ -516,7 +518,11 @@ jQuery( function($) { response ); } else { - klarna_payments.onFailedAuthorization(order_id, response); + klarna_payments.onFailedAuthorization( + order_id, + order_key, + response + ); } }); }, diff --git a/classes/class-kp-api.php b/classes/class-kp-api.php index 607a176..3912c20 100644 --- a/classes/class-kp-api.php +++ b/classes/class-kp-api.php @@ -166,6 +166,48 @@ public function cancel_recurring_order( $country, $recurring_token ) { return self::check_for_api_error( $response ); } + /** + * Get the Klarna order from the order management API. + * + * @param string $country The Klarna country to use. + * @param string $klarna_order_id The Klarna order id. + * + * @return array|WP_Error The response from Klarna. + */ + public function get_klarna_om_order( $country, $klarna_order_id ) { + $request = new KP_Get_Order( + array( + 'country' => $country, + 'klarna_order_id' => $klarna_order_id, + ) + ); + $response = $request->request(); + + return self::check_for_api_error( $response ); + } + + /** + * Upsell the klarna order. + * + * @param string $country The Klarna country to use. + * @param string $klarna_order_id The Klarna order id. + * @param int $order_id The WooCommerce order id. + * + * @return array|WP_Error The response from Klarna. + */ + public function upsell_klarna_order( $country, $klarna_order_id, $order_id ) { + $request = new KP_Upsell_Order( + array( + 'country' => $country, + 'klarna_order_id' => $klarna_order_id, + 'order_id' => $order_id, + ) + ); + $response = $request->request(); + + return self::check_for_api_error( $response ); + } + /** * Return the session from Klarna Payments. * From 9929cd3cb18afdc38e1b5c1773552a3eb95f3a7a Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Fri, 15 Dec 2023 08:36:26 +0100 Subject: [PATCH 24/39] Revert "Update assets to include if KEC is enabled or not" This reverts commit 1a6bce520c0983cb9371779a45c96ae4175af98a. --- classes/class-kp-assets.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/class-kp-assets.php b/classes/class-kp-assets.php index cdc5722..3a9fe82 100644 --- a/classes/class-kp-assets.php +++ b/classes/class-kp-assets.php @@ -82,8 +82,6 @@ private function get_checkout_params( $settings ) { $order_data = new KP_Order_Data( $customer_type, $order_id ); $customer = $order_data->get_klarna_customer_object(); - KP_WC()->session->set_session_data(); - // Create the params array. $klarna_payments_params = array( // Ajax URLS. @@ -102,7 +100,6 @@ private function get_checkout_params( $settings ) { 'customer_type' => $customer_type, 'remove_postcode_spaces' => ( apply_filters( 'wc_kp_remove_postcode_spaces', false ) ) ? 'yes' : 'no', 'client_token' => KP_WC()->session->get_klarna_client_token(), - 'kec_enabled' => KP_WC()->session->is_kec ? 'yes' : 'no', 'order_pay_page' => $pay_for_order, 'pay_for_order' => $pay_for_order, 'order_id' => $order_id, @@ -167,6 +164,7 @@ public function enqueue_express_button() { $this->enqueue_express_button_scripts(); $this->enqueue_express_button_styles(); + } /** @@ -325,7 +323,9 @@ private function enqueue_express_button_styles() { ); wp_enqueue_style( 'klarna_express_button_styles' ); + } + } new KP_Assets(); From 15e5fa0f64d5d7e90a68d68bea59da6af154fe22 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Fri, 15 Dec 2023 08:37:13 +0100 Subject: [PATCH 25/39] Revert "Add KEC session value to KP session data" This reverts commit 844551b80fb0af95043d85b6e9cb6bdcbc282d7b. --- classes/class-kp-session.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/classes/class-kp-session.php b/classes/class-kp-session.php index ad9138c..029d516 100644 --- a/classes/class-kp-session.php +++ b/classes/class-kp-session.php @@ -50,13 +50,6 @@ class KP_Session { */ public $session_country = null; - /** - * If KEC is used or not. - * - * @var bool - */ - public $is_kec = false; - /** * Class constructor. */ @@ -91,7 +84,6 @@ public function get_session( $order = null ) { $this->klarna_session = null; $this->session_hash = null; $this->session_country = null; - $this->is_kec = false; } // If we already have a Klarna session and session does not need an update, return the Klarna session. @@ -147,7 +139,6 @@ public function set_session_data( $order = null ) { $this->klarna_session = $session_data['klarna_session']; $this->session_hash = $session_data['session_hash']; $this->session_country = $session_data['session_country']; - $this->is_kec = $session_data['is_kec'] ?? false; } /** @@ -265,7 +256,7 @@ private function get_session_cart_hash() { // The `get_totals` method can return non-numeric items which should be removed before using `array_sum`. $cart_totals = array_filter( WC()->cart->get_totals(), - function ( $total ) { + function( $total ) { return is_numeric( $total ); } ); From 585c37c2c3007517df1422c7728ac686dd9ecd27 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Fri, 15 Dec 2023 08:39:03 +0100 Subject: [PATCH 26/39] Restore changes in JS file for KEC since its no longer needed --- assets/js/klarna-payments.js | 187 +++++++++++++++-------------------- 1 file changed, 81 insertions(+), 106 deletions(-) diff --git a/assets/js/klarna-payments.js b/assets/js/klarna-payments.js index 5fa7271..d9b7b2b 100644 --- a/assets/js/klarna-payments.js +++ b/assets/js/klarna-payments.js @@ -1,6 +1,6 @@ /* global console, Klarna */ -jQuery( function($) { - 'use strict'; +jQuery(function ($) { + "use strict"; var klarna_payments = { authorization_response: {}, @@ -270,7 +270,7 @@ jQuery( function($) { authorize: function () { var $defer = $.Deferred(); var address = klarna_payments.get_address(); - console.log(address); + klarna_payments.authorization_response = {}; try { @@ -429,100 +429,72 @@ jQuery( function($) { $.scroll_to_notices($("form.checkout")); }, - onSuccessfulAuthorization: function (order_id, order_key) { - $("body").trigger("kp_auth_success"); - $.ajax(klarna_payments_params.place_order_url, { - type: "POST", - dataType: "json", - async: true, - data: { - order_id: order_id, - order_key: order_key, - auth_token: - klarna_payments.authorization_response - .authorization_token, - nonce: klarna_payments_params.place_order_nonce, - }, - success: function (response) { - // Log the success. - console.log("kp_place_order success"); - console.log(response); - }, - error: function (response) { - // Log the error. - console.log("kp_place_order error"); - console.log(response); - }, - complete: function (response) { - if (response.responseJSON.success === true) { - window.location.href = response.responseJSON.data; - } else { - $("form.checkout").removeClass("processing").unblock(); - $("form.checkout") - .find(".input-text, select, input:checkbox") - .trigger("validate") - .blur(); - $("form.checkout").trigger("update_checkout"); - } - }, - }); - }, - - onFailedAuthorization: function (order_id, order_key, response) { - $("body").trigger("kp_auth_failed"); - - // Re-enable the form. - $("body").trigger("updated_checkout"); - $("form.checkout").removeClass("processing"); - $("form.checkout").unblock(); - $(".woocommerce-checkout-review-order-table").unblock(); - - console.log("No authorization_token in response"); - $("form.woocommerce-checkout").removeClass("processing").unblock(); - $.ajax(klarna_payments_params.auth_failed_url, { - type: "POST", - dataType: "json", - async: true, - data: { - show_form: response.show_form, - order_id: order_id, - order_key: order_key, - nonce: klarna_payments_params.auth_failed_nonce, - }, - }); - }, - - authorizeKlarnaOrder: async function (order_id, order_key, payload) { - if ("yes" === klarna_payments_params.kec_enabled) { - await Klarna.Payments.finalize({}, payload, function (result) { - klarna_payments.authorization_response = result; - if (result.approved) { - klarna_payments.onSuccessfulAuthorization( - order_id, - order_key, - result - ); - } else { - klarna_payments.onFailedAuthorization(order_id, order_key, result); - } - }); - - return; - } - - await klarna_payments.authorize().done(function (response) { + authorizeKlarnaOrder: function (order_id, order_key) { + klarna_payments.authorize().done(function (response) { if ("authorization_token" in response) { - klarna_payments.onSuccessfulAuthorization( - order_id, - order_key, - response - ); + $("body").trigger("kp_auth_success"); + $.ajax(klarna_payments_params.place_order_url, { + type: "POST", + dataType: "json", + async: true, + data: { + order_key: order_key, + order_id: order_id, + auth_token: + klarna_payments.authorization_response + .authorization_token, + nonce: klarna_payments_params.place_order_nonce, + }, + success: function (response) { + // Log the success. + console.log("kp_place_order success"); + console.log(response); + }, + error: function (response) { + // Log the error. + console.log("kp_place_order error"); + console.log(response); + }, + complete: function (response) { + if (response.responseJSON.success === true) { + window.location.href = + response.responseJSON.data; + } else { + $("form.checkout") + .removeClass("processing") + .unblock(); + $("form.checkout") + .find(".input-text, select, input:checkbox") + .trigger("validate") + .blur(); + $("form.checkout").trigger("update_checkout"); + } + }, + }); } else { - klarna_payments.onFailedAuthorization( - order_id, - order_key, - response - ); + $("body").trigger("kp_auth_failed"); + + // Re-enable the form. + $("body").trigger("updated_checkout"); + $("form.checkout").removeClass("processing"); + $("form.checkout").unblock(); + $(".woocommerce-checkout-review-order-table").unblock(); + + console.log("No authorization_token in response"); + $("form.woocommerce-checkout") + .removeClass("processing") + .unblock(); + $.ajax(klarna_payments_params.auth_failed_url, { + type: "POST", + dataType: "json", + async: true, + data: { + show_form: response.show_form, + order_key: order_key, + order_id: order_id, + nonce: klarna_payments_params.auth_failed_nonce, + }, + }); } }); }, @@ -577,8 +549,7 @@ jQuery( function($) { klarna_payments.addresses = data.addresses; klarna_payments.authorizeKlarnaOrder( data.order_id, - data.order_key, - data.payload || null + data.order_key ); } else { throw "Result failed"; @@ -670,20 +641,24 @@ jQuery( function($) { }, }; klarna_payments.start(); - $('body').ready( function() { + $("body").ready(function () { klarna_payments.setRadioButtonValues(); }); - $('body').ajaxComplete( function() { + $("body").ajaxComplete(function () { klarna_payments.setRadioButtonValues(); }); - $('body').on('click', 'input#place_order, button#place_order', function (e) { - // No strict comparison: wp_localize_script() converts booleans to strings "1", respectively, "0". - if( true == klarna_payments_params.pay_for_order ) { - klarna_payments.klarnaPayForOrder( e ); - } else { - klarna_payments.orderSubmit( e ); + $("body").on( + "click", + "input#place_order, button#place_order", + function (e) { + // No strict comparison: wp_localize_script() converts booleans to strings "1", respectively, "0". + if (true == klarna_payments_params.pay_for_order) { + klarna_payments.klarnaPayForOrder(e); + } else { + klarna_payments.orderSubmit(e); + } } - }); + ); }); From 1202b951544f8812f257e973a084c0836e3bc7f8 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Fri, 15 Dec 2023 08:39:09 +0100 Subject: [PATCH 27/39] Update class-kp-klarna-express-checkout.php --- classes/class-kp-klarna-express-checkout.php | 46 ++++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/classes/class-kp-klarna-express-checkout.php b/classes/class-kp-klarna-express-checkout.php index 864a084..876daa4 100644 --- a/classes/class-kp-klarna-express-checkout.php +++ b/classes/class-kp-klarna-express-checkout.php @@ -29,6 +29,7 @@ public function __construct() { $this->klarna_express_checkout = new KlarnaExpressCheckout(); $this->klarna_express_checkout->ajax()->set_get_payload( array( $this, 'get_payload' ) ); + $this->klarna_express_checkout->ajax()->set_finalize_callback( array( $this, 'finalize_callback' ) ); } /** @@ -65,33 +66,40 @@ public function get_payload() { } /** - * Set session data from KEC auth response. + * Finalize order callback handler. * - * @param string $session_id The session ID. - * @param string $client_token The client token. + * @param string $auth_token The auth token from Klarna. + * @param string $order_id The order ID. + * @param string $order_key The order key. * - * @return void + * @throws Exception If the order is invalid. + * @return array */ - public static function set_session_data( $session_id, $client_token ) { - // Get the Klarna session. - $country = kp_get_klarna_country(); - $klarna_session = KP_WC()->api->get_session( $session_id, $country ); + public function finalize_callback( $auth_token, $order_id, $order_key ) { + // Get the order from the order ID. + $order = wc_get_order( $order_id ); - // Verify the response. - if ( is_wp_error( $klarna_session ) ) { - return; + // Verify the order. + if ( ! $order ) { + throw new Exception( __( 'Invalid order.', 'klarna-payments-for-woocommerce' ) ); // phpcs:ignore } - KP_WC()->session->klarna_session = array( - 'session_id' => $session_id, - 'client_token' => $client_token, - 'payment_method_categories' => $klarna_session['payment_method_categories'] ?? array(), - ); + // Verify the order key. + if ( $order->get_order_key() !== $order_key ) { + throw new Exception( __( 'Invalid order key.', 'klarna-payments-for-woocommerce' ) ); // phpcs:ignore + } - KP_WC()->session->session_country = $country; + // Make a place order call to Klarna. + $place_order_response = KP_WC()->api->place_order( kp_get_klarna_country(), $auth_token, $order_id ); - KP_WC()->session->is_kec = true; + // Verify the response. + if ( is_wp_error( $place_order_response ) ) { + throw new Exception( $place_order_response->get_error_message() ); // phpcs:ignore + } - WC()->session->set( 'kp_session_data', wp_json_encode( KP_WC()->session ) ); + return array( + 'result' => 'success', + 'redirect' => $order->get_checkout_order_received_url(), + ); } } From 8eed2cbf1bd425ffd8af7aac312577d8e8770d71 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Fri, 15 Dec 2023 08:39:14 +0100 Subject: [PATCH 28/39] Update class-wc-gateway-klarna-payments.php --- classes/class-wc-gateway-klarna-payments.php | 40 +++++++++++--------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/classes/class-wc-gateway-klarna-payments.php b/classes/class-wc-gateway-klarna-payments.php index 86aa0fd..7422de4 100644 --- a/classes/class-wc-gateway-klarna-payments.php +++ b/classes/class-wc-gateway-klarna-payments.php @@ -80,7 +80,7 @@ public function __construct() { 'subscription_payment_method_change_customer', 'subscription_payment_method_change_admin', 'multiple_subscriptions', - 'upsell' + 'upsell', ) ); // Make this filterable. @@ -306,21 +306,27 @@ private function process_subscription( $order ) { * @return array */ private function process_checkout_order( $order ) { - // Load any session data that we might have. Pass null instead of order identifier to load session from WC()->session. - KP_WC()->session->set_session_data( null ); - - $order_key = $order->get_order_key(); - $order_id = $order->get_id(); - $klarna_country = KP_WC()->session->get_klarna_session_country( $order ); - $klarna_session_id = KP_WC()->session->get_klarna_session_id(); - - if ( empty( $klarna_country ) || empty( $klarna_session_id ) ) { - return array( - 'result' => 'error', - 'messages' => array( - __( 'Failed to get required data from the Klarna session. Please try again.', 'klarna-payments-for-woocommerce' ), - ), - ); + $kec_client_token = \Krokedil\KlarnaExpressCheckout\KlarnaExpressCheckout::get_client_token(); + $order_key = $order->get_order_key(); + $order_id = $order->get_id(); + + if ( empty( $kec_client_token ) ) { + // Load any session data that we might have. Pass null instead of order identifier to load session from WC()->session. + KP_WC()->session->set_session_data( null ); + $klarna_country = KP_WC()->session->get_klarna_session_country( $order ); + $klarna_session_id = KP_WC()->session->get_klarna_session_id(); + + if ( empty( $klarna_country ) || empty( $klarna_session_id ) ) { + return array( + 'result' => 'error', + 'messages' => array( + __( 'Failed to get required data from the Klarna session. Please try again.', 'klarna-payments-for-woocommerce' ), + ), + ); + } + } else { + $klarna_country = kp_get_klarna_country( $order ); + $klarna_session_id = $kec_client_token; } // Set the order meta data. @@ -347,7 +353,7 @@ private function process_checkout_order( $order ) { ); // If KEC is enabled, we should pass the payload with the result. - if ( KP_WC()->session->is_kec ) { + if ( ! empty( $kec_client_token ) ) { $return['payload'] = KP_WC()->klarna_express_checkout->get_payload(); } From 6a7afab54225f7f08f065244b5934f4ea9d76492 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Fri, 15 Dec 2023 09:32:02 +0100 Subject: [PATCH 29/39] Update composer --- composer.json | 2 +- composer.lock | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index 11766c4..80cc442 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "require": { "krokedil/wp-api": "^1.0", "krokedil/woocommerce": "^1.3", - "krokedil/klarna-express-checkout": "^1.0.0" + "krokedil/klarna-express-checkout": "^1.1.0" }, "require-dev": { "wp-coding-standards/wpcs": "^2.3", diff --git a/composer.lock b/composer.lock index ac8a3b1..9edfb8c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d8f40ecac2761b509181bd214bfb8769", + "content-hash": "b42d57c4c09b2598c6d49caa9e6d9547", "packages": [ { "name": "firebase/php-jwt", @@ -71,16 +71,16 @@ }, { "name": "krokedil/klarna-express-checkout", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/krokedil/klarna-express-checkout.git", - "reference": "cea60145ba5204028807601198be659511ebeb35" + "reference": "32fd2c8b252b8016fbab2f424ecefef94e9b344c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/krokedil/klarna-express-checkout/zipball/cea60145ba5204028807601198be659511ebeb35", - "reference": "cea60145ba5204028807601198be659511ebeb35", + "url": "https://api.github.com/repos/krokedil/klarna-express-checkout/zipball/32fd2c8b252b8016fbab2f424ecefef94e9b344c", + "reference": "32fd2c8b252b8016fbab2f424ecefef94e9b344c", "shasum": "" }, "require": { @@ -136,10 +136,10 @@ ], "description": "A Klarna Express Checkout solution for WooCommerce", "support": { - "source": "https://github.com/krokedil/klarna-express-checkout/tree/1.0.0", + "source": "https://github.com/krokedil/klarna-express-checkout/tree/1.1.0", "issues": "https://github.com/krokedil/klarna-express-checkout/issues" }, - "time": "2023-12-12T12:49:30+00:00" + "time": "2023-12-15T08:22:22+00:00" }, { "name": "krokedil/woocommerce", @@ -322,12 +322,12 @@ "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "040f675a5020a62ddc9c46344d9cf26658e2b04e" + "reference": "88d3cec355a252c8fb6a338c420960bf1b0d5679" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/040f675a5020a62ddc9c46344d9cf26658e2b04e", - "reference": "040f675a5020a62ddc9c46344d9cf26658e2b04e", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/88d3cec355a252c8fb6a338c420960bf1b0d5679", + "reference": "88d3cec355a252c8fb6a338c420960bf1b0d5679", "shasum": "" }, "require": { @@ -395,7 +395,7 @@ "type": "open_collective" } ], - "time": "2023-12-11T21:00:05+00:00" + "time": "2023-12-14T14:17:01+00:00" }, { "name": "wp-coding-standards/wpcs", From 0529a3ee95a2ab3f218c68c402323e85d0b0d345 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Thu, 21 Dec 2023 09:38:45 +0100 Subject: [PATCH 30/39] Remove nopriv access to hide_klarna_kp_banner, and add nonce check --- classes/class-kp-banners.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/class-kp-banners.php b/classes/class-kp-banners.php index 43dbf6d..9819da5 100644 --- a/classes/class-kp-banners.php +++ b/classes/class-kp-banners.php @@ -21,7 +21,6 @@ public function __construct() { add_action( 'in_admin_header', array( $this, 'klarna_banner' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'load_admin_css' ) ); add_action( 'wp_ajax_hide_klarna_kp_banner', array( $this, 'hide_klarna_kp_banner' ) ); - add_action( 'wp_ajax_nopriv_hide_klarna_kp_banner', array( $this, 'hide_klarna_kp_banner' ) ); } /** @@ -196,6 +195,7 @@ public static function settings_sidebar( $parent_options ) { * Hide Klarna banner in admin pages for. */ public function hide_klarna_kp_banner() { + check_ajax_referer( 'hide-klarna-banner', '_wpnonce' ); $permanent = ( array_key_exists( 'permanent', $_POST ) && 'true' === $_POST['permanent'] ); //phpcs:ignore WordPress.Security.NonceVerification.Missing -- It is my understanding that WP checks the nonce before triggering the action? if ( $permanent ) { set_transient( 'klarna_kp_hide_banner', '1' ); From 69843adaa6b5505064ba905e738791b10b825c3b Mon Sep 17 00:00:00 2001 From: Martin Lindahl <84283336+krokedilmartin@users.noreply.github.com> Date: Sat, 30 Dec 2023 19:14:24 +0100 Subject: [PATCH 31/39] change author and author URI and Use the __DIR__ constant instead of calling dirname(__FILE__) --- klarna-payments-for-woocommerce.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/klarna-payments-for-woocommerce.php b/klarna-payments-for-woocommerce.php index 42d96d8..4cd3796 100644 --- a/klarna-payments-for-woocommerce.php +++ b/klarna-payments-for-woocommerce.php @@ -3,8 +3,8 @@ * Plugin Name: Klarna Payments for WooCommerce * Plugin URI: https://krokedil.com/klarna-payments/ * Description: Provides Klarna Payments as payment method to WooCommerce. - * Author: krokedil, klarna, automattic - * Author URI: https://krokedil.com/ + * Author: klarna + * Author URI: https://www.klarna.com/ * Version: 3.2.4 * Text Domain: klarna-payments-for-woocommerce * Domain Path: /languages @@ -131,7 +131,7 @@ protected function __construct() { add_filter( 'woocommerce_checkout_posted_data', array( $this, 'filter_payment_method_id' ) ); // Load text domain. - load_plugin_textdomain( 'klarna-payments-for-woocommerce', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' ); + load_plugin_textdomain( 'klarna-payments-for-woocommerce', false, plugin_basename( __DIR__ ) . '/languages' ); } /** @@ -290,7 +290,7 @@ public function check_permalinks() { ) ) ); - ?> + ?>
Date: Fri, 5 Jan 2024 10:46:16 +0100 Subject: [PATCH 32/39] Process the payment after KEC order has been placed --- classes/class-kp-klarna-express-checkout.php | 34 +++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/classes/class-kp-klarna-express-checkout.php b/classes/class-kp-klarna-express-checkout.php index 876daa4..fa73d02 100644 --- a/classes/class-kp-klarna-express-checkout.php +++ b/classes/class-kp-klarna-express-checkout.php @@ -97,9 +97,35 @@ public function finalize_callback( $auth_token, $order_id, $order_key ) { throw new Exception( $place_order_response->get_error_message() ); // phpcs:ignore } - return array( - 'result' => 'success', - 'redirect' => $order->get_checkout_order_received_url(), - ); + $fraud_status = $place_order_response['fraud_status']; + switch ( $fraud_status ) { + case 'ACCEPTED': + kp_process_accepted( $order, $place_order_response ); + kp_unset_session_values(); + return array( + 'result' => 'success', + 'redirect' => $place_order_response['redirect_url'], + ); + case 'PENDING': + kp_process_pending( $order, $place_order_response ); + kp_unset_session_values(); + return array( + 'result' => 'success', + 'redirect' => $place_order_response['redirect_url'], + ); + case 'REJECTED': + kp_process_rejected( $order, $place_order_response ); + kp_unset_session_values(); + return array( + 'result' => 'error', + 'redirect' => $order->get_cancel_order_url_raw(), + ); + default: + kp_unset_session_values(); + return array( + 'result' => 'error', + 'redirect' => $order->get_cancel_order_url_raw(), + ); + } } } From 4389f5673bf218f078cb3b1e51ab17db0b1bd510 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Fri, 5 Jan 2024 13:20:40 +0100 Subject: [PATCH 33/39] Change class for getting the client token --- classes/class-wc-gateway-klarna-payments.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/class-wc-gateway-klarna-payments.php b/classes/class-wc-gateway-klarna-payments.php index 7422de4..1de4a7f 100644 --- a/classes/class-wc-gateway-klarna-payments.php +++ b/classes/class-wc-gateway-klarna-payments.php @@ -306,7 +306,7 @@ private function process_subscription( $order ) { * @return array */ private function process_checkout_order( $order ) { - $kec_client_token = \Krokedil\KlarnaExpressCheckout\KlarnaExpressCheckout::get_client_token(); + $kec_client_token = \Krokedil\KlarnaExpressCheckout\Session::get_client_token(); $order_key = $order->get_order_key(); $order_id = $order->get_id(); From ff77969499774a4838e3aa4bb1b1641e9d9539ba Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 8 Jan 2024 09:10:24 +0100 Subject: [PATCH 34/39] Update composer packages Updates the krokedil/woocommerce package to version 1.4.0 to include the support for AvaTax --- composer.lock | 61 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/composer.lock b/composer.lock index be77986..5a89b1f 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "krokedil/woocommerce", - "version": "1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/krokedil/woocommerce.git", - "reference": "8b83ebc73f169a8a3aebc943e527a47d40233015" + "reference": "11a6ac25cdab496a169a1ea1fc6c17594579634c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/krokedil/woocommerce/zipball/8b83ebc73f169a8a3aebc943e527a47d40233015", - "reference": "8b83ebc73f169a8a3aebc943e527a47d40233015", + "url": "https://api.github.com/repos/krokedil/woocommerce/zipball/11a6ac25cdab496a169a1ea1fc6c17594579634c", + "reference": "11a6ac25cdab496a169a1ea1fc6c17594579634c", "shasum": "" }, "require-dev": { @@ -42,10 +42,10 @@ ], "description": "A library package for Krokedils plugins that contains helper methods when working with WooCommerce.", "support": { - "source": "https://github.com/krokedil/woocommerce/tree/1.3.1", + "source": "https://github.com/krokedil/woocommerce/tree/1.4.0", "issues": "https://github.com/krokedil/woocommerce/issues" }, - "time": "2023-12-04T12:07:37+00:00" + "time": "2024-01-08T08:08:25+00:00" }, { "name": "krokedil/wp-api", @@ -186,13 +186,13 @@ "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "7763e2e1f773cb0615ed8afa133189fc804f583d" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "2ab648b9a420f9f573b73a7c847ff3517fa2a82f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/7763e2e1f773cb0615ed8afa133189fc804f583d", - "reference": "7763e2e1f773cb0615ed8afa133189fc804f583d", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/2ab648b9a420f9f573b73a7c847ff3517fa2a82f", + "reference": "2ab648b9a420f9f573b73a7c847ff3517fa2a82f", "shasum": "" }, "require": { @@ -202,12 +202,12 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "default-branch": true, "bin": [ - "bin/phpcs", - "bin/phpcbf" + "bin/phpcbf", + "bin/phpcs" ], "type": "library", "extra": { @@ -222,22 +222,45 @@ "authors": [ { "name": "Greg Sherwood", - "role": "lead" + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ "phpcs", "standards", "static analysis" ], "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, - "time": "2023-11-02T00:47:31+00:00" + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-01-06T09:21:55+00:00" }, { "name": "wp-coding-standards/wpcs", From 528fd8bd0aa241574ee59ef739207dd31f816b5c Mon Sep 17 00:00:00 2001 From: Montazar <26507935+mntzrr@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:07:04 +0100 Subject: [PATCH 35/39] Resolve undefined index --- classes/class-kp-assets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/class-kp-assets.php b/classes/class-kp-assets.php index 3a9fe82..a4164bb 100644 --- a/classes/class-kp-assets.php +++ b/classes/class-kp-assets.php @@ -41,7 +41,7 @@ public function enqueue_checkout_script() { } $settings = get_option( 'woocommerce_klarna_payments_settings', array() ); - if ( 'yes' !== $settings['enabled'] ?? 'no' ) { + if ( 'yes' !== ( $settings['enabled'] ?? 'no' ) ) { return; } From db96da8bf5b401baeddbf5836beaba5ba10377aa Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Fri, 12 Jan 2024 11:29:54 +0100 Subject: [PATCH 36/39] Add KEC and version number to useragent when placing a KEC order --- classes/class-kp-klarna-express-checkout.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/classes/class-kp-klarna-express-checkout.php b/classes/class-kp-klarna-express-checkout.php index fa73d02..8cdbd0c 100644 --- a/classes/class-kp-klarna-express-checkout.php +++ b/classes/class-kp-klarna-express-checkout.php @@ -89,6 +89,8 @@ public function finalize_callback( $auth_token, $order_id, $order_key ) { throw new Exception( __( 'Invalid order key.', 'klarna-payments-for-woocommerce' ) ); // phpcs:ignore } + add_filter( 'http_headers_useragent', array( $this, 'add_to_useragent' ) ); + // Make a place order call to Klarna. $place_order_response = KP_WC()->api->place_order( kp_get_klarna_country(), $auth_token, $order_id ); @@ -128,4 +130,20 @@ public function finalize_callback( $auth_token, $order_id, $order_key ) { ); } } + + /** + * Add to user agent. + * + * @param string $user_agent The user agent. + * + * @return string + */ + public function add_to_useragent( $user_agent ) { + // Only if the useragent contains KP. + if ( strpos( $user_agent, 'KP' ) !== false ) { + $user_agent .= ' KEC: ' . KlarnaExpressCheckout::VERSION; + } + + return $user_agent; + } } From 6f4e396a0eecb99718a6aff079a2b6c81a401e7a Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Fri, 12 Jan 2024 11:53:18 +0100 Subject: [PATCH 37/39] Update composer and lock file --- composer.json | 2 +- composer.lock | 147 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 142 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 80cc442..1373b69 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "require": { "krokedil/wp-api": "^1.0", "krokedil/woocommerce": "^1.3", - "krokedil/klarna-express-checkout": "^1.1.0" + "krokedil/klarna-express-checkout": "^1.2.0" }, "require-dev": { "wp-coding-standards/wpcs": "^2.3", diff --git a/composer.lock b/composer.lock index 5a89b1f..0f020d2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,143 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c987eb11f7e3e90d32e80bb14f539e32", + "content-hash": "978a7f69a01f9c4fcbbf8dc44f854acd", "packages": [ + { + "name": "firebase/php-jwt", + "version": "v6.10.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", + "shasum": "" + }, + "require": { + "php": "^7.4||^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.5||^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^1.0||^2.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" + }, + "time": "2023-12-01T16:26:39+00:00" + }, + { + "name": "krokedil/klarna-express-checkout", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/krokedil/klarna-express-checkout.git", + "reference": "ecb80460ebf7570337c2b01afe138302b1645bc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/krokedil/klarna-express-checkout/zipball/ecb80460ebf7570337c2b01afe138302b1645bc4", + "reference": "ecb80460ebf7570337c2b01afe138302b1645bc4", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "^6.10", + "php": "~7.4 || ~8.0" + }, + "require-dev": { + "10up/wp_mock": "^1.0", + "php-stubs/woocommerce-stubs": "^8.3", + "wp-coding-standards/wpcs": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Krokedil\\KlarnaExpressCheckout\\": "src/" + } + }, + "archive": { + "exclude": [ + "tests/*", + "phpunit.xml", + "composer-lock.json", + ".github/*", + ".gitignore", + ".gitattributes" + ] + }, + "scripts": { + "phpcs": [ + "phpcs --standard=phpcs.xml --extensions=php --ignore=vendor/,tests/" + ], + "phpcbf": [ + "phpcbf --standard=phpcs.xml --extensions=php --ignore=vendor/,tests/" + ], + "test": [ + "@php ./vendor/bin/phpunit --configuration phpunit.xml" + ], + "test-coverage-html": [ + "@php ./vendor/bin/phpunit --configuration phpunit.xml --coverage-html coverage" + ], + "test-coverage-clover": [ + "@php ./vendor/bin/phpunit --configuration phpunit.xml --coverage-clover coverage.xml" + ] + }, + "license": [ + "GPL-v3" + ], + "authors": [ + { + "name": "Krokedil AB", + "email": "info@krokedil.se" + } + ], + "description": "A Klarna Express Checkout solution for WooCommerce", + "support": { + "source": "https://github.com/krokedil/klarna-express-checkout/tree/1.2.0", + "issues": "https://github.com/krokedil/klarna-express-checkout/issues" + }, + "time": "2024-01-12T10:49:27+00:00" + }, { "name": "krokedil/woocommerce", "version": "1.4.0", @@ -187,12 +322,12 @@ "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "2ab648b9a420f9f573b73a7c847ff3517fa2a82f" + "reference": "1703a6bd5a80f2bfef7cd2166cc86b915617b8bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/2ab648b9a420f9f573b73a7c847ff3517fa2a82f", - "reference": "2ab648b9a420f9f573b73a7c847ff3517fa2a82f", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/1703a6bd5a80f2bfef7cd2166cc86b915617b8bb", + "reference": "1703a6bd5a80f2bfef7cd2166cc86b915617b8bb", "shasum": "" }, "require": { @@ -202,7 +337,7 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, "default-branch": true, "bin": [ @@ -260,7 +395,7 @@ "type": "open_collective" } ], - "time": "2024-01-06T09:21:55+00:00" + "time": "2024-01-11T23:26:22+00:00" }, { "name": "wp-coding-standards/wpcs", From 12a4f75f9d360ec1e22a57fc3171aa8843f64811 Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 15 Jan 2024 08:34:05 +0100 Subject: [PATCH 38/39] Remove KEC version flag --- klarna-payments-for-woocommerce.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/klarna-payments-for-woocommerce.php b/klarna-payments-for-woocommerce.php index 8e3bc35..d2a5bb8 100644 --- a/klarna-payments-for-woocommerce.php +++ b/klarna-payments-for-woocommerce.php @@ -5,7 +5,7 @@ * Description: Provides Klarna Payments as payment method to WooCommerce. * Author: krokedil, klarna, automattic * Author URI: https://krokedil.com/ - * Version: 3.2.4-kec + * Version: 3.2.4 * Text Domain: klarna-payments-for-woocommerce * Domain Path: /languages * From f9beb88d011dae1f69599f7ffdaa2163d64f30cf Mon Sep 17 00:00:00 2001 From: MichaelBengtsson Date: Mon, 15 Jan 2024 13:48:39 +0100 Subject: [PATCH 39/39] Version 3.3.0 --- klarna-payments-for-woocommerce.php | 4 ++-- readme.txt | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/klarna-payments-for-woocommerce.php b/klarna-payments-for-woocommerce.php index 28fb0a8..5ace64c 100644 --- a/klarna-payments-for-woocommerce.php +++ b/klarna-payments-for-woocommerce.php @@ -5,7 +5,7 @@ * Description: Provides Klarna Payments as payment method to WooCommerce. * Author: klarna * Author URI: https://www.klarna.com/ - * Version: 3.2.4 + * Version: 3.3.0 * Text Domain: klarna-payments-for-woocommerce * Domain Path: /languages * @@ -39,7 +39,7 @@ /** * Required minimums and constants */ -define( 'WC_KLARNA_PAYMENTS_VERSION', '3.2.4' ); +define( 'WC_KLARNA_PAYMENTS_VERSION', '3.3.0' ); define( 'WC_KLARNA_PAYMENTS_MIN_PHP_VER', '7.4.0' ); define( 'WC_KLARNA_PAYMENTS_MIN_WC_VER', '5.6.0' ); define( 'WC_KLARNA_PAYMENTS_MAIN_FILE', __FILE__ ); diff --git a/readme.txt b/readme.txt index f8f10cf..d6e0ec1 100644 --- a/readme.txt +++ b/readme.txt @@ -3,11 +3,11 @@ Contributors: klarna, krokedil, automattic Tags: woocommerce, klarna, ecommerce, e-commerce Donate link: https://klarna.com Requires at least: 5.0 -Tested up to: 6.4.1 +Tested up to: 6.4.2 Requires PHP: 7.4 WC requires at least: 5.6.0 -WC tested up to: 8.3.1 -Stable tag: 3.2.4 +WC tested up to: 8.5.0 +Stable tag: 3.3.0 License: GPLv3 or later License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -51,6 +51,12 @@ For help setting up and configuring Klarna Payments for WooCommerce please refer == Changelog == += 2024.01.15 - version 3.3.0 = +* Feature - Added support for Klarna Express Checkout. +* Feature - Added support for Post Purchase Upsell. +* Fix - Fixed an issue with a undefined index when reading the enabled setting before it has been saved. +* Tweak - Changed author and author uri for the plugin. + = 2023.12.06 - version 3.2.4 = * Fix – Added a check to ensure that a Klarna order is always, at most, processed once. This should prevent accidental order re-processing. * Fix - Fixed PHP 8 deprecation warnings.