diff --git a/changelog.txt b/changelog.txt index 2332be339..1b680e746 100644 --- a/changelog.txt +++ b/changelog.txt @@ -6,6 +6,10 @@ * Fix - Allow PUI Gateway for refund processor #2192 * Fix - Notice on newly created block cart checkout #2211 * Fix - Apple Pay button in the editor #2177 +* Fix - Allow shipping callback and skipping confirmation page from any express button #2236 +* Fix - Pay Later messaging configurator sometimes displays old settings after saving #2249 +* Fix - Update the apple-developer-merchantid-domain-association validation strings for Apple Pay #2251 +* Enhancement - Use admin theme color #1602 = 2.7.0 - 2024-04-30 = * Fix - Zero sum subscriptions cause CANNOT_BE_ZERO_OR_NEGATIVE when using Vault v3 #2152 diff --git a/composer.json b/composer.json index bb2ccbf7c..e378de009 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0", "brain/monkey": "^2.4", "php-stubs/wordpress-stubs": "^5.0@stable", - "php-stubs/woocommerce-stubs": "^5.0@stable", + "php-stubs/woocommerce-stubs": "^8.0@stable", "vimeo/psalm": "^4.0", "vlucas/phpdotenv": "^5" }, diff --git a/composer.lock b/composer.lock index 9bd08ba42..528b9224e 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": "97559eb2b9d8b6f1529d44abd2604f99", + "content-hash": "8d6d274f3742efb3f1278eee713257b4", "packages": [ { "name": "container-interop/service-provider", @@ -628,16 +628,16 @@ "packages-dev": [ { "name": "amphp/amp", - "version": "v2.6.2", + "version": "v2.6.4", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb" + "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", + "url": "https://api.github.com/repos/amphp/amp/zipball/ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", + "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", "shasum": "" }, "require": { @@ -649,8 +649,8 @@ "ext-json": "*", "jetbrains/phpstorm-stubs": "^2019.3", "phpunit/phpunit": "^7 | ^8 | ^9", - "psalm/phar": "^3.11@dev", - "react/promise": "^2" + "react/promise": "^2", + "vimeo/psalm": "^3.12" }, "type": "library", "extra": { @@ -705,7 +705,7 @@ "support": { "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.2" + "source": "https://github.com/amphp/amp/tree/v2.6.4" }, "funding": [ { @@ -713,20 +713,20 @@ "type": "github" } ], - "time": "2022-02-20T17:52:18+00:00" + "time": "2024-03-21T18:52:26+00:00" }, { "name": "amphp/byte-stream", - "version": "v1.8.1", + "version": "v1.8.2", "source": { "type": "git", "url": "https://github.com/amphp/byte-stream.git", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd" + "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/4f0e968ba3798a423730f567b1b50d3441c16ddc", + "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc", "shasum": "" }, "require": { @@ -742,11 +742,6 @@ "psalm/phar": "^3.11.4" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, "autoload": { "files": [ "lib/functions.php" @@ -770,7 +765,7 @@ } ], "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "http://amphp.org/byte-stream", + "homepage": "https://amphp.org/byte-stream", "keywords": [ "amp", "amphp", @@ -780,9 +775,8 @@ "stream" ], "support": { - "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v1.8.1" + "source": "https://github.com/amphp/byte-stream/tree/v1.8.2" }, "funding": [ { @@ -790,7 +784,7 @@ "type": "github" } ], - "time": "2021-03-30T17:13:30+00:00" + "time": "2024-04-13T18:00:56+00:00" }, { "name": "antecedent/patchwork", @@ -985,16 +979,16 @@ }, { "name": "composer/pcre", - "version": "2.1.1", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "b439557066cd445732fa57cbc8d905394b4db8a0" + "reference": "540af382c97b83c628227d5f87cf56466d476191" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/b439557066cd445732fa57cbc8d905394b4db8a0", - "reference": "b439557066cd445732fa57cbc8d905394b4db8a0", + "url": "https://api.github.com/repos/composer/pcre/zipball/540af382c97b83c628227d5f87cf56466d476191", + "reference": "540af382c97b83c628227d5f87cf56466d476191", "shasum": "" }, "require": { @@ -1036,7 +1030,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/2.1.1" + "source": "https://github.com/composer/pcre/tree/2.1.3" }, "funding": [ { @@ -1052,7 +1046,7 @@ "type": "tidelift" } ], - "time": "2023-10-11T07:10:55+00:00" + "time": "2024-03-19T09:03:05+00:00" }, { "name": "composer/semver", @@ -1137,16 +1131,16 @@ }, { "name": "composer/xdebug-handler", - "version": "3.0.3", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { @@ -1157,7 +1151,7 @@ "require-dev": { "phpstan/phpstan": "^1.0", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, "type": "library", "autoload": { @@ -1181,9 +1175,9 @@ "performance" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" }, "funding": [ { @@ -1199,7 +1193,7 @@ "type": "tidelift" } ], - "time": "2022-02-25T21:32:43+00:00" + "time": "2024-05-06T16:37:16+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", @@ -1893,21 +1887,21 @@ }, { "name": "nikic/php-parser", - "version": "v4.18.0", + "version": "v4.19.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b", + "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.1" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", @@ -1943,9 +1937,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1" }, - "time": "2023-12-10T21:03:43+00:00" + "time": "2024-03-17T08:10:35+00:00" }, { "name": "openlss/lib-array2xml", @@ -2002,20 +1996,21 @@ }, { "name": "phar-io/manifest", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", @@ -2056,9 +2051,15 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2021-07-20T11:28:43+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", @@ -2113,23 +2114,23 @@ }, { "name": "php-stubs/woocommerce-stubs", - "version": "v5.9.1", + "version": "v8.9.0", "source": { "type": "git", "url": "https://github.com/php-stubs/woocommerce-stubs.git", - "reference": "486ccff117badfab94c404065d37a77d632d7db5" + "reference": "2c0bb50a76a703206151fac3123faec6ba7d5879" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/woocommerce-stubs/zipball/486ccff117badfab94c404065d37a77d632d7db5", - "reference": "486ccff117badfab94c404065d37a77d632d7db5", + "url": "https://api.github.com/repos/php-stubs/woocommerce-stubs/zipball/2c0bb50a76a703206151fac3123faec6ba7d5879", + "reference": "2c0bb50a76a703206151fac3123faec6ba7d5879", "shasum": "" }, "require": { - "php-stubs/wordpress-stubs": "^5.3.0" + "php-stubs/wordpress-stubs": "^5.3 || ^6.0" }, "require-dev": { - "php": "~7.1", + "php": "~7.1 || ~8.0", "php-stubs/generator": "^0.8.0" }, "suggest": { @@ -2151,35 +2152,37 @@ ], "support": { "issues": "https://github.com/php-stubs/woocommerce-stubs/issues", - "source": "https://github.com/php-stubs/woocommerce-stubs/tree/v5.9.1" + "source": "https://github.com/php-stubs/woocommerce-stubs/tree/v8.9.0" }, - "time": "2022-04-30T06:35:48+00:00" + "time": "2024-05-14T16:07:36+00:00" }, { "name": "php-stubs/wordpress-stubs", - "version": "v5.9.6", + "version": "v5.9.9", "source": { "type": "git", "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "6a18d938d0aef39d091505a4a35b025fb6c10098" + "reference": "06c51c4863659ea9e9f4c2a23293728a677cb059" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/6a18d938d0aef39d091505a4a35b025fb6c10098", - "reference": "6a18d938d0aef39d091505a4a35b025fb6c10098", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/06c51c4863659ea9e9f4c2a23293728a677cb059", + "reference": "06c51c4863659ea9e9f4c2a23293728a677cb059", "shasum": "" }, "require-dev": { - "nikic/php-parser": "< 4.12.0", - "php": "~7.3 || ~8.0", + "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" + "phpdocumentor/reflection-docblock": "5.3", + "phpstan/phpstan": "^1.10.49", + "phpunit/phpunit": "^9.5", + "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^0.11" }, "suggest": { "paragonie/sodium_compat": "Pure PHP implementation of libsodium", - "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "symfony/polyfill-php80": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" }, "type": "library", @@ -2196,9 +2199,9 @@ ], "support": { "issues": "https://github.com/php-stubs/wordpress-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-stubs/tree/v5.9.6" + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v5.9.9" }, - "time": "2023-05-18T04:34:27+00:00" + "time": "2024-04-14T17:16:00+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -2264,28 +2267,28 @@ }, { "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.3.2", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26" + "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", - "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/293975b465e0e709b571cbf0c957c6c0a7b9a2ac", + "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac", "shasum": "" }, "require": { "phpcompatibility/php-compatibility": "^9.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "paragonie/random_compat": "dev-master", "paragonie/sodium_compat": "dev-master" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." }, "type": "phpcodesniffer-standard", @@ -2315,22 +2318,37 @@ ], "support": { "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", + "security": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/security/policy", "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" }, - "time": "2022-10-25T01:46:02+00:00" + "funding": [ + { + "url": "https://github.com/PHPCompatibility", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-04-24T21:30:46+00:00" }, { "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.4", + "version": "2.1.5", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "b6c1e3ee1c35de6c41a511d5eb9bd03e447480a5" + "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/b6c1e3ee1c35de6c41a511d5eb9bd03e447480a5", - "reference": "b6c1e3ee1c35de6c41a511d5eb9bd03e447480a5", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/01c1ff2704a58e46f0cb1ca9d06aee07b3589082", + "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082", "shasum": "" }, "require": { @@ -2338,10 +2356,10 @@ "phpcompatibility/phpcompatibility-paragonie": "^1.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7" + "dealerdirect/phpcodesniffer-composer-installer": "^1.0" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." }, "type": "phpcodesniffer-standard", @@ -2370,9 +2388,24 @@ ], "support": { "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues", + "security": "https://github.com/PHPCompatibility/PHPCompatibilityWP/security/policy", "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP" }, - "time": "2022-10-24T09:00:36+00:00" + "funding": [ + { + "url": "https://github.com/PHPCompatibility", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-04-24T21:37:59+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -2611,16 +2644,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "7.0.15", + "version": "7.0.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "819f92bba8b001d4363065928088de22f25a3a48" + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/819f92bba8b001d4363065928088de22f25a3a48", - "reference": "819f92bba8b001d4363065928088de22f25a3a48", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", "shasum": "" }, "require": { @@ -2672,7 +2705,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.17" }, "funding": [ { @@ -2680,20 +2713,20 @@ "type": "github" } ], - "time": "2021-07-26T12:20:09+00:00" + "time": "2024-03-02T06:09:37+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.5", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5" + "reference": "69deeb8664f611f156a924154985fbd4911eb36b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/69deeb8664f611f156a924154985fbd4911eb36b", + "reference": "69deeb8664f611f156a924154985fbd4911eb36b", "shasum": "" }, "require": { @@ -2732,7 +2765,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.6" }, "funding": [ { @@ -2740,7 +2773,7 @@ "type": "github" } ], - "time": "2021-12-02T12:42:26+00:00" + "time": "2024-03-01T13:39:50+00:00" }, { "name": "phpunit/php-text-template", @@ -2789,16 +2822,16 @@ }, { "name": "phpunit/php-timer", - "version": "2.1.3", + "version": "2.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a691211e94ff39a34811abd521c31bd5b305b0bb", + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb", "shasum": "" }, "require": { @@ -2836,7 +2869,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.4" }, "funding": [ { @@ -2844,7 +2877,7 @@ "type": "github" } ], - "time": "2020-11-30T08:20:02+00:00" + "time": "2024-03-01T13:42:41+00:00" }, { "name": "phpunit/php-token-stream", @@ -2908,16 +2941,16 @@ }, { "name": "phpunit/phpunit", - "version": "8.5.36", + "version": "8.5.38", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "9652df58e06a681429d8cfdaec3c43d6de581d5a" + "reference": "1ecad678646c817a29e55a32c930f3601c3f5a8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9652df58e06a681429d8cfdaec3c43d6de581d5a", - "reference": "9652df58e06a681429d8cfdaec3c43d6de581d5a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1ecad678646c817a29e55a32c930f3601c3f5a8c", + "reference": "1ecad678646c817a29e55a32c930f3601c3f5a8c", "shasum": "" }, "require": { @@ -2986,7 +3019,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.36" + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.38" }, "funding": [ { @@ -3002,20 +3035,20 @@ "type": "tidelift" } ], - "time": "2023-12-01T16:52:15+00:00" + "time": "2024-04-05T04:31:23+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", "shasum": "" }, "require": { @@ -3049,7 +3082,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.3" }, "funding": [ { @@ -3057,7 +3090,7 @@ "type": "github" } ], - "time": "2020-11-30T08:15:22+00:00" + "time": "2024-03-01T13:45:45+00:00" }, { "name": "sebastian/comparator", @@ -3135,16 +3168,16 @@ }, { "name": "sebastian/diff", - "version": "3.0.4", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae" + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/6296a0c086dd0117c1b78b059374d7fcbe7545ae", - "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/98ff311ca519c3aa73ccd3de053bdb377171d7b6", + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6", "shasum": "" }, "require": { @@ -3189,7 +3222,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/3.0.4" + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.6" }, "funding": [ { @@ -3197,20 +3230,20 @@ "type": "github" } ], - "time": "2023-05-07T05:30:20+00:00" + "time": "2024-03-02T06:16:36+00:00" }, { "name": "sebastian/environment", - "version": "4.2.4", + "version": "4.2.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" + "reference": "56932f6049a0482853056ffd617c91ffcc754205" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/56932f6049a0482853056ffd617c91ffcc754205", + "reference": "56932f6049a0482853056ffd617c91ffcc754205", "shasum": "" }, "require": { @@ -3252,7 +3285,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.5" }, "funding": [ { @@ -3260,24 +3293,24 @@ "type": "github" } ], - "time": "2020-11-30T07:53:42+00:00" + "time": "2024-03-01T13:49:59+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.5", + "version": "3.1.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6" + "reference": "1939bc8fd1d39adcfa88c5b35335910869214c56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6", - "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1939bc8fd1d39adcfa88c5b35335910869214c56", + "reference": "1939bc8fd1d39adcfa88c5b35335910869214c56", "shasum": "" }, "require": { - "php": ">=7.0", + "php": ">=7.2", "sebastian/recursion-context": "^3.0" }, "require-dev": { @@ -3329,7 +3362,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5" + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.6" }, "funding": [ { @@ -3337,20 +3370,20 @@ "type": "github" } ], - "time": "2022-09-14T06:00:17+00:00" + "time": "2024-03-02T06:21:38+00:00" }, { "name": "sebastian/global-state", - "version": "3.0.3", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "66783ce213de415b451b904bfef9dda0cf9aeae0" + "reference": "91c7c47047a971f02de57ed6f040087ef110c5d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/66783ce213de415b451b904bfef9dda0cf9aeae0", - "reference": "66783ce213de415b451b904bfef9dda0cf9aeae0", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/91c7c47047a971f02de57ed6f040087ef110c5d9", + "reference": "91c7c47047a971f02de57ed6f040087ef110c5d9", "shasum": "" }, "require": { @@ -3393,7 +3426,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.5" }, "funding": [ { @@ -3401,20 +3434,20 @@ "type": "github" } ], - "time": "2023-08-02T09:23:32+00:00" + "time": "2024-03-02T06:13:16+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.4", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" + "reference": "ac5b293dba925751b808e02923399fb44ff0d541" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/ac5b293dba925751b808e02923399fb44ff0d541", + "reference": "ac5b293dba925751b808e02923399fb44ff0d541", "shasum": "" }, "require": { @@ -3450,7 +3483,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.5" }, "funding": [ { @@ -3458,20 +3491,20 @@ "type": "github" } ], - "time": "2020-11-30T07:40:27+00:00" + "time": "2024-03-01T13:54:02+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/1d439c229e61f244ff1f211e5c99737f90c67def", + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def", "shasum": "" }, "require": { @@ -3505,7 +3538,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.3" }, "funding": [ { @@ -3513,20 +3546,20 @@ "type": "github" } ], - "time": "2020-11-30T07:37:18+00:00" + "time": "2024-03-01T13:56:04+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" + "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/9bfd3c6f1f08c026f542032dfb42813544f7d64c", + "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c", "shasum": "" }, "require": { @@ -3568,7 +3601,7 @@ "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.2" }, "funding": [ { @@ -3576,20 +3609,20 @@ "type": "github" } ], - "time": "2020-11-30T07:34:24+00:00" + "time": "2024-03-01T14:07:30+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/72a7f7674d053d548003b16ff5a106e7e0e06eee", + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee", "shasum": "" }, "require": { @@ -3619,8 +3652,7 @@ "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.3" }, "funding": [ { @@ -3628,20 +3660,20 @@ "type": "github" } ], - "time": "2020-11-30T07:30:19+00:00" + "time": "2024-03-01T13:59:09+00:00" }, { "name": "sebastian/type", - "version": "1.1.4", + "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4" + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4", - "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/18f071c3a29892b037d35e6b20ddf3ea39b42874", + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874", "shasum": "" }, "require": { @@ -3676,7 +3708,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/1.1.4" + "source": "https://github.com/sebastianbergmann/type/tree/1.1.5" }, "funding": [ { @@ -3684,7 +3716,7 @@ "type": "github" } ], - "time": "2020-11-30T07:25:11+00:00" + "time": "2024-03-01T14:04:07+00:00" }, { "name": "sebastian/version", @@ -3735,16 +3767,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.8.1", + "version": "3.9.2", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "14f5fff1e64118595db5408e946f3a22c75807f7" + "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/14f5fff1e64118595db5408e946f3a22c75807f7", - "reference": "14f5fff1e64118595db5408e946f3a22c75807f7", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/aac1f6f347a5c5ac6bc98ad395007df00990f480", + "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480", "shasum": "" }, "require": { @@ -3811,20 +3843,20 @@ "type": "open_collective" } ], - "time": "2024-01-11T20:47:48+00:00" + "time": "2024-04-23T20:25:34+00:00" }, { "name": "symfony/console", - "version": "v5.4.35", + "version": "v5.4.39", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "dbdf6adcb88d5f83790e1efb57ef4074309d3931" + "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/dbdf6adcb88d5f83790e1efb57ef4074309d3931", - "reference": "dbdf6adcb88d5f83790e1efb57ef4074309d3931", + "url": "https://api.github.com/repos/symfony/console/zipball/f3e591c48688a0cfa1a3296205926c05e84b22b1", + "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1", "shasum": "" }, "require": { @@ -3894,7 +3926,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.35" + "source": "https://github.com/symfony/console/tree/v5.4.39" }, "funding": [ { @@ -3910,20 +3942,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:28:09+00:00" + "time": "2024-04-18T08:26:06+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.2", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + "reference": "80d075412b557d41002320b96a096ca65aa2c98d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/80d075412b557d41002320b96a096ca65aa2c98d", + "reference": "80d075412b557d41002320b96a096ca65aa2c98d", "shasum": "" }, "require": { @@ -3961,7 +3993,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.3" }, "funding": [ { @@ -3977,7 +4009,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2023-01-24T14:02:46+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4375,16 +4407,16 @@ }, { "name": "symfony/service-contracts", - "version": "v2.5.2", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a2329596ddc8fd568900e3fc76cba42489ecc7f3", + "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3", "shasum": "" }, "require": { @@ -4438,7 +4470,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.3" }, "funding": [ { @@ -4454,20 +4486,20 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:17:29+00:00" + "time": "2023-04-21T15:04:16+00:00" }, { "name": "symfony/string", - "version": "v5.4.35", + "version": "v5.4.39", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "c209c4d0559acce1c9a2067612cfb5d35756edc2" + "reference": "495e71bae5862308051b9e63cc3e34078eed83ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/c209c4d0559acce1c9a2067612cfb5d35756edc2", - "reference": "c209c4d0559acce1c9a2067612cfb5d35756edc2", + "url": "https://api.github.com/repos/symfony/string/zipball/495e71bae5862308051b9e63cc3e34078eed83ef", + "reference": "495e71bae5862308051b9e63cc3e34078eed83ef", "shasum": "" }, "require": { @@ -4524,7 +4556,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.35" + "source": "https://github.com/symfony/string/tree/v5.4.39" }, "funding": [ { @@ -4540,20 +4572,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T13:51:25+00:00" + "time": "2024-04-18T08:26:06+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.2", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -4582,7 +4614,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.2" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -4590,7 +4622,7 @@ "type": "github" } ], - "time": "2023-11-20T00:12:19+00:00" + "time": "2024-03-03T12:36:25+00:00" }, { "name": "vimeo/psalm", diff --git a/modules/ppcp-applepay/src/ApplepayModule.php b/modules/ppcp-applepay/src/ApplepayModule.php index d9d93d6e6..5ac6a62cb 100644 --- a/modules/ppcp-applepay/src/ApplepayModule.php +++ b/modules/ppcp-applepay/src/ApplepayModule.php @@ -320,7 +320,7 @@ class ApplepayModule implements ModuleInterface { private function sandbox_validation_string(): string { return apply_filters( 'woocommerce_paypal_payments_applepay_sandbox_validation_string', - '7B227073704964223A2241443631324543383841333039314132314539434132433035304439454130353741414535444341304542413237424243333838463239344231353534434233222C2276657273696F6E223A312C22637265617465644F6E223A313632343438393037393630362C227369676E6174757265223A2233303830303630393261383634383836663730643031303730326130383033303830303230313031333130663330306430363039363038363438303136353033303430323031303530303330383030363039326138363438383666373064303130373031303030306130383033303832303365343330383230333862613030333032303130323032303835396438613162636161663465336364333030613036303832613836343863653364303430333032333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303165313730643332333133303334333233303331333933333337333033303561313730643332333633303334333133393331333933333336333533393561333036323331323833303236303630333535303430333063316636353633363332643733366437303264363237323666366236353732326437333639363736653566353534333334326435333431346534343432346635383331313433303132303630333535303430623063306236393466353332303533373937333734363536643733333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303539333031333036303732613836343863653364303230313036303832613836343863653364303330313037303334323030303438323330666461626333396366373565323032633530643939623435313265363337653261393031646436636233653062316364346235323637393866386366346562646538316132356138633231653463333364646365386532613936633266366166613139333033343563346538376134343236636539353162313239356133383230323131333038323032306433303063303630333535316431333031303166663034303233303030333031663036303335353164323330343138333031363830313432336632343963343466393365346566323765366334663632383663336661326262666432653462333034353036303832623036303130353035303730313031303433393330333733303335303630383262303630313035303530373330303138363239363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363536313639363336313333333033323330383230313164303630333535316432303034383230313134333038323031313033303832303130633036303932613836343838366637363336343035303133303831666533303831633330363038326230363031303530353037303230323330383162363063383162333532363536633639363136653633363532303666366532303734363836393733323036333635373237343639363636393633363137343635323036323739323036313665373932303730363137323734373932303631373337333735366436353733323036313633363336353730373436313665363336353230366636363230373436383635323037343638363536653230363137303730366336393633363136323663363532303733373436313665363436313732363432303734363537323664373332303631366536343230363336663665363436393734363936663665373332303666363632303735373336353263323036333635373237343639363636393633363137343635323037303666366336393633373932303631366536343230363336353732373436393636363936333631373436393666366532303730373236313633373436393633363532303733373436313734363536643635366537343733326533303336303630383262303630313035303530373032303131363261363837343734373033613266326637373737373732653631373037303663363532653633366636643266363336353732373436393636363936333631373436353631373537343638366637323639373437393266333033343036303335353164316630343264333032623330323961303237613032353836323336383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635363136393633363133333265363337323663333031643036303335353164306530343136303431343032323433303062396165656564343633313937613461363561323939653432373138323163343533303065303630333535316430663031303166663034303430333032303738303330306630363039326138363438383666373633363430363164303430323035303033303061303630383261383634386365336430343033303230333437303033303434303232303734613162333234646234323439343330646433323734633530373463343830386439613166343830653361383563356331333632353636333235666263613330323230363933363930353361626635306235613532663966363030346463353861616436633530613764363038363833373930653061373361643031653461643938313330383230326565333038323032373561303033303230313032303230383439366432666266336139386461393733303061303630383261383634386365336430343033303233303637333131623330313930363033353530343033306331323431373037303663363532303532366636663734323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303165313730643331333433303335333033363332333333343336333333303561313730643332333933303335333033363332333333343336333333303561333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303539333031333036303732613836343863653364303230313036303832613836343863653364303330313037303334323030303466303137313138343139643736343835643531613565323538313037373665383830613265666465376261653464653038646663346239336531333335366435363635623335616532326430393737363064323234653762626130386664373631376365383863623736626236363730626563386538323938346666353434356133383166373330383166343330343630363038326230363031303530353037303130313034336133303338333033363036303832623036303130353035303733303031383632613638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635373236663666373436333631363733333330316430363033353531643065303431363034313432336632343963343466393365346566323765366334663632383663336661326262666432653462333030663036303335353164313330313031666630343035333030333031303166663330316630363033353531643233303431383330313638303134626262306465613135383333383839616134386139396465626562646562616664616362323461623330333730363033353531643166303433303330326533303263613032616130323838363236363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353732366636663734363336313637333332653633373236633330306530363033353531643066303130316666303430343033303230313036333031303036306132613836343838366637363336343036303230653034303230353030333030613036303832613836343863653364303430333032303336373030333036343032333033616366373238333531313639396231383666623335633335366361363262666634313765646439306637353464613238656265663139633831356534326237383966383938663739623539396639386435343130643866396465396332666530323330333232646435343432316230613330353737366335646633333833623930363766643137376332633231366439363466633637323639383231323666353466383761376431623939636239623039383932313631303639393066303939323164303030303331383230313863333038323031383830323031303133303831383633303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333032303835396438613162636161663465336364333030643036303936303836343830313635303330343032303130353030613038313935333031383036303932613836343838366637306430313039303333313062303630393261383634383836663730643031303730313330316330363039326138363438383666373064303130393035333130663137306433323331333033363332333333323332333533373335333935613330326130363039326138363438383666373064303130393334333131643330316233303064303630393630383634383031363530333034303230313035303061313061303630383261383634386365336430343033303233303266303630393261383634383836663730643031303930343331323230343230343239323932333766306638303764346538373932333134643438393635623165626262633038636265386333333432643365643261333939623963336538353330306130363038326138363438636533643034303330323034343733303435303232313030643430333138326637626530396663386265393738316463646461613434623332663362353634386566353666323664323933363738343237393933616530383032323037646663306563316361306461343531653464663031386236376538326231366330313065313930373431363762666632363839356230336563336430396134303030303030303030303030227D' + '7B227073704964223A2241443631324543383841333039314132314539434132433035304439454130353741414535444341304542413237424243333838463239344231353534434233222C2276657273696F6E223A312C22637265617465644F6E223A313731353237313630333931352C227369676E6174757265223A223330383030363039326138363438383666373064303130373032613038303330383030323031303133313064333030623036303936303836343830313635303330343032303133303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038313636333463386230653330353731373330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433323334333033343332333933313337333433373332333735613137306433323339333033343332333833313337333433373332333635613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306336663032336362323631346262333033383838613136323938336531613933663130353666353066613738636462396261346361323431636331346532356530323231303062653363643064666431363234376636343934343735333830653964343463323238613130383930613361316463373234623862346362383838393831386263333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031383833303832303138343032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383136363334633862306533303537313733303062303630393630383634383031363530333034303230316130383139333330313830363039326138363438383666373064303130393033333130623036303932613836343838366637306430313037303133303163303630393261383634383836663730643031303930353331306631373064333233343330333533303339333133363332333033303333356133303238303630393261383634383836663730643031303933343331316233303139333030623036303936303836343830313635303330343032303161313061303630383261383634386365336430343033303233303266303630393261383634383836663730643031303930343331323230343230633364366466616634636131326539643331666630363161636563303536613232653131386261333262633934346664323166336231373838363634646634363330306130363038326138363438636533643034303330323034343733303435303232313030633961346263306665316537366332356636343136303264306238313462363666643264376534623263636537343138633132343532313866356230353963363032323036623632373361383536363830633738313064303131333538666463383563633764303730656531393736333234316537356336636237353732326164303930303030303030303030303030227D' ); } @@ -332,7 +332,7 @@ class ApplepayModule implements ModuleInterface { private function live_validation_string(): string { return apply_filters( 'woocommerce_paypal_payments_applepay_live_validation_string', - '7B227073704964223A2246354246304143324336314131413238313043373531453439333444414433384346393037313041303935303844314133453241383436314141363232414145222C2276657273696F6E223A312C22637265617465644F6E223A313633343737323736393531342C227369676E6174757265223A223330383030363039326138363438383666373064303130373032613038303330383030323031303133313066333030643036303936303836343830313635303330343032303130353030333038303036303932613836343838366637306430313037303130303030613038303330383230336533333038323033383861303033303230313032303230383463333034313439353139643534333633303061303630383261383634386365336430343033303233303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133393330333533313338333033313333333233353337356131373064333233343330333533313336333033313333333233353337356133303566333132353330323330363033353530343033306331633635363336333264373336643730326436323732366636623635373232643733363936373665356635353433333432643530353234663434333131343330313230363033353530343062306330623639346635333230353337393733373436353664373333313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346332313537376564656264366337623232313866363864643730393061313231386463376230626436663263323833643834363039356439346166346135343131623833343230656438313166333430376538333333316631633534633366376562333232306436626164356434656666343932383938393365376330663133613338323032313133303832303230643330306330363033353531643133303130316666303430323330303033303166303630333535316432333034313833303136383031343233663234396334346639336534656632376536633466363238366333666132626266643265346233303435303630383262303630313035303530373031303130343339333033373330333530363038326230363031303530353037333030313836323936383734373437303361326632663666363337333730326536313730373036633635326536333666366432663666363337333730333033343264363137303730366336353631363936333631333333303332333038323031316430363033353531643230303438323031313433303832303131303330383230313063303630393261383634383836663736333634303530313330383166653330383163333036303832623036303130353035303730323032333038316236306338316233353236353663363936313665363336353230366636653230373436383639373332303633363537323734363936363639363336313734363532303632373932303631366537393230373036313732373437393230363137333733373536643635373332303631363336333635373037343631366536333635323036663636323037343638363532303734363836353665323036313730373036633639363336313632366336353230373337343631366536343631373236343230373436353732366437333230363136653634323036333666366536343639373436393666366537333230366636363230373537333635326332303633363537323734363936363639363336313734363532303730366636633639363337393230363136653634323036333635373237343639363636393633363137343639366636653230373037323631363337343639363336353230373337343631373436353664363536653734373332653330333630363038326230363031303530353037303230313136326136383734373437303361326632663737373737373265363137303730366336353265363336663664326636333635373237343639363636393633363137343635363137353734363836663732363937343739326633303334303630333535316431663034326433303262333032396130323761303235383632333638373437343730336132663266363337323663326536313730373036633635326536333666366432663631373037303663363536313639363336313333326536333732366333303164303630333535316430653034313630343134393435376462366664353734383138363839383937363266376535373835303765373962353832343330306530363033353531643066303130316666303430343033303230373830333030663036303932613836343838366637363336343036316430343032303530303330306130363038326138363438636533643034303330323033343930303330343630323231303062653039353731666537316531653733356235356535616661636234633732666562343435663330313835323232633732353130303262363165626436663535303232313030643138623335306135646436646436656231373436303335623131656232636538376366613365366166366362643833383038393064633832636464616136333330383230326565333038323032373561303033303230313032303230383439366432666266336139386461393733303061303630383261383634386365336430343033303233303637333131623330313930363033353530343033306331323431373037303663363532303532366636663734323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303165313730643331333433303335333033363332333333343336333333303561313730643332333933303335333033363332333333343336333333303561333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303539333031333036303732613836343863653364303230313036303832613836343863653364303330313037303334323030303466303137313138343139643736343835643531613565323538313037373665383830613265666465376261653464653038646663346239336531333335366435363635623335616532326430393737363064323234653762626130386664373631376365383863623736626236363730626563386538323938346666353434356133383166373330383166343330343630363038326230363031303530353037303130313034336133303338333033363036303832623036303130353035303733303031383632613638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635373236663666373436333631363733333330316430363033353531643065303431363034313432336632343963343466393365346566323765366334663632383663336661326262666432653462333030663036303335353164313330313031666630343035333030333031303166663330316630363033353531643233303431383330313638303134626262306465613135383333383839616134386139396465626562646562616664616362323461623330333730363033353531643166303433303330326533303263613032616130323838363236363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353732366636663734363336313637333332653633373236633330306530363033353531643066303130316666303430343033303230313036333031303036306132613836343838366637363336343036303230653034303230353030333030613036303832613836343863653364303430333032303336373030333036343032333033616366373238333531313639396231383666623335633335366361363262666634313765646439306637353464613238656265663139633831356534326237383966383938663739623539396639386435343130643866396465396332666530323330333232646435343432316230613330353737366335646633333833623930363766643137376332633231366439363466633637323639383231323666353466383761376431623939636239623039383932313631303639393066303939323164303030303331383230313863333038323031383830323031303133303831383633303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333032303834633330343134393531396435343336333030643036303936303836343830313635303330343032303130353030613038313935333031383036303932613836343838366637306430313039303333313062303630393261383634383836663730643031303730313330316330363039326138363438383666373064303130393035333130663137306433323331333133303332333033323333333333323334333935613330326130363039326138363438383666373064303130393334333131643330316233303064303630393630383634383031363530333034303230313035303061313061303630383261383634386365336430343033303233303266303630393261383634383836663730643031303930343331323230343230623935666665303261316539316665656565396330623239616361656661643465333031396331666237626238313665366631623762343233346666306533353330306130363038326138363438636533643034303330323034343733303435303232303665356233363937366364383733653632623339326330353136633134326362356639303938663330323535656435343938633436393039356133636462346430323231303038396261626335356162626635653037393163633139373562306535383630633937336532336661313266643338343533303930353938343061326363363337303030303030303030303030227D' + '7B227073704964223A2246354246304143324336314131413238313043373531453439333444414433384346393037313041303935303844314133453241383436314141363232414145222C2276657273696F6E223A312C22637265617465644F6E223A313731353230343037313232362C227369676E6174757265223A223330383030363039326138363438383666373064303130373032613038303330383030323031303133313064333030623036303936303836343830313635303330343032303133303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038313636333463386230653330353731373330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433323334333033343332333933313337333433373332333735613137306433323339333033343332333833313337333433373332333635613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306336663032336362323631346262333033383838613136323938336531613933663130353666353066613738636462396261346361323431636331346532356530323231303062653363643064666431363234376636343934343735333830653964343463323238613130383930613361316463373234623862346362383838393831386263333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031383833303832303138343032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383136363334633862306533303537313733303062303630393630383634383031363530333034303230316130383139333330313830363039326138363438383666373064303130393033333130623036303932613836343838366637306430313037303133303163303630393261383634383836663730643031303930353331306631373064333233343330333533303338333233313333333433333331356133303238303630393261383634383836663730643031303933343331316233303139333030623036303936303836343830313635303330343032303161313061303630383261383634386365336430343033303233303266303630393261383634383836663730643031303930343331323230343230353936643939343335373738303366313137346361653066633761343164383634653964366266336535363638646164356563393334303937313439633762623330306130363038326138363438636533643034303330323034343733303435303232313030383565623363643837343731346466343461333830373838643439626537656630303630643765313236633966653638663261333336386363623233373363643032323035366535336363363330376433393561643465663532376234333531323462616636653761383537363030616463376135343561333862613039376139643734303030303030303030303030227D' ); } } diff --git a/modules/ppcp-applepay/src/Assets/ApplePayButton.php b/modules/ppcp-applepay/src/Assets/ApplePayButton.php index 517f76cf0..926fc5ce2 100644 --- a/modules/ppcp-applepay/src/Assets/ApplePayButton.php +++ b/modules/ppcp-applepay/src/Assets/ApplePayButton.php @@ -620,13 +620,18 @@ class ApplePayButton implements ButtonInterface { ): array { $shipping_methods_array = array(); - $shipping_methods = WC()->shipping->calculate_shipping( + /** + * The argument is defined only in docblock. + * + * @psalm-suppress InvalidScalarArgument + */ + $shipping_methods = WC()->shipping->calculate_shipping( $this->getShippingPackages( $customer_address, $cart->get_total( 'edit' ) ) ); - $done = false; + $done = false; foreach ( $shipping_methods[0]['rates'] as $rate ) { $shipping_methods_array[] = array( 'label' => $rate->get_label(), diff --git a/modules/ppcp-blocks/extensions.php b/modules/ppcp-blocks/extensions.php index a75957eec..c2b607780 100644 --- a/modules/ppcp-blocks/extensions.php +++ b/modules/ppcp-blocks/extensions.php @@ -37,6 +37,31 @@ return array( return array_merge( array_slice( $array, 0, $pos ), $new, array_slice( $array, $pos ) ); }; + $label = __( + 'Enable this option to require customers to manually confirm express payments on the checkout page. +

This ensures they can review the order, update shipping options, and fill in eventual custom fields necessary for the transaction.

+

If this is disabled, the system will automatically synchronize shipping options with PayPal and bypass the final checkout confirmation. This expedites the checkout process but prevents buyers from filling in eventual custom fields and reviewing final details before finalizing the payment.

', + 'woocommerce-paypal-payments' + ); + + if ( wc_terms_and_conditions_page_id() > 0 ) { + $label .= __( + '

Important: Your store has a Terms and Conditions page configured. Buyers who use a PayPal express payment method will not be able to consent to the terms on the Classic Checkout, as the final checkout confirmation will be skipped.

', + 'woocommerce-paypal-payments' + ); + } + + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); + + if ( $subscription_helper->plugin_is_active() ) { + $label .= __( + '

Important: Cannot be deactivated while the WooCommerce Subscriptions plugin is active.

', + 'woocommerce-paypal-payments' + ); + } + + $should_disable_checkbox = $subscription_helper->plugin_is_active() || apply_filters( 'woocommerce_paypal_payments_toggle_final_review_checkbox', false ); + return $insert_after( $fields, 'smart_button_locations', @@ -44,16 +69,13 @@ return array( 'blocks_final_review_enabled' => array( 'title' => __( 'Require final confirmation on checkout', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', - 'label' => __( - 'Require customers to confirm express payments from the Cart and Express Checkout on the checkout page. -

If this setting is not enabled, payment confirmation on the checkout will be skipped. -Skipping the final confirmation on the checkout page may impact the buyer experience during the PayPal payment process.

', - 'woocommerce-paypal-payments' - ), - 'default' => true, + 'label' => $label, + 'default' => false, 'screens' => array( State::STATE_START, State::STATE_ONBOARDED ), 'requirements' => array(), 'gateway' => 'paypal', + 'class' => array( 'ppcp-grayed-out-text' ), + 'input_class' => $should_disable_checkbox ? array( 'ppcp-disabled-checkbox' ) : array(), ), ) ); diff --git a/modules/ppcp-blocks/resources/js/Helper/Address.js b/modules/ppcp-blocks/resources/js/Helper/Address.js index 19ca36fdd..6f24d700a 100644 --- a/modules/ppcp-blocks/resources/js/Helper/Address.js +++ b/modules/ppcp-blocks/resources/js/Helper/Address.js @@ -139,7 +139,17 @@ export const paypalOrderToWcAddresses = (order) => { billingAddress = paypalPayerToWc(order.payer); // no billing address, such as if billing address retrieval is not allowed in the merchant account if (!billingAddress.address_line_1) { - billingAddress = {...shippingAddress, ...paypalPayerToWc(order.payer)}; + // use only non empty values from payer address, otherwise it will override shipping address + let payerAddress = Object.fromEntries( + Object.entries(billingAddress).filter( + ([key, value]) => value !== '' && key !== 'country' + ) + ); + + billingAddress = { + ...shippingAddress, + ...payerAddress + }; } } diff --git a/modules/ppcp-blocks/resources/js/checkout-block.js b/modules/ppcp-blocks/resources/js/checkout-block.js index e5e492b7c..df003f494 100644 --- a/modules/ppcp-blocks/resources/js/checkout-block.js +++ b/modules/ppcp-blocks/resources/js/checkout-block.js @@ -82,7 +82,7 @@ const PayPalComponent = ({ window.ppcpContinuationFilled = true; }, []) - const createOrder = async () => { + const createOrder = async (data, actions) => { try { const res = await fetch(config.scriptData.ajax.create_order.endpoint, { method: 'POST', @@ -93,7 +93,8 @@ const PayPalComponent = ({ context: config.scriptData.context, payment_method: 'ppcp-gateway', funding_source: window.ppcpFundingSource ?? 'paypal', - createaccount: false + createaccount: false, + payment_source: data.paymentSource }), }); @@ -296,10 +297,15 @@ const PayPalComponent = ({ onClick(); }; + const isVenmoAndVaultingEnabled = () => { + return window.ppcpFundingSource === 'venmo' && config.scriptData.vaultingEnabled; + } + let handleShippingOptionsChange = null; let handleShippingAddressChange = null; let handleSubscriptionShippingOptionsChange = null; let handleSubscriptionShippingAddressChange = null; + if (shippingData.needsShipping && !config.finalReviewEnabled) { handleShippingOptionsChange = async (data, actions) => { try { diff --git a/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js b/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js index 0400c8013..2b3066395 100644 --- a/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js +++ b/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js @@ -60,7 +60,8 @@ class CartActionHandler { funding_source: window.ppcpFundingSource, bn_code:bnCode, payer, - context:this.config.context + context:this.config.context, + payment_source: data.paymentSource }), }).then(function(res) { return res.json(); diff --git a/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js b/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js new file mode 100644 index 000000000..49f45ab2d --- /dev/null +++ b/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js @@ -0,0 +1,126 @@ +import {paypalAddressToWc} from "../../../../../ppcp-blocks/resources/js/Helper/Address.js"; +import {convertKeysToSnakeCase} from "../../../../../ppcp-blocks/resources/js/Helper/Helper.js"; + +/** + * Handles the shipping option change in PayPal. + * + * @param data + * @param actions + * @param config + * @returns {Promise} + */ +export const handleShippingOptionsChange = async (data, actions, config) => { + try { + const shippingOptionId = data.selectedShippingOption?.id; + + if (shippingOptionId) { + await fetch(config.ajax.update_customer_shipping.shipping_options.endpoint, { + method: 'POST', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + 'X-WC-Store-API-Nonce': config.ajax.update_customer_shipping.wp_rest_nonce, + }, + body: JSON.stringify({ + rate_id: shippingOptionId, + }) + }) + .then(response => { + return response.json(); + }) + .then(cardData => { + const shippingMethods = document.querySelectorAll('.shipping_method'); + + shippingMethods.forEach(function(method) { + if (method.value === shippingOptionId) { + method.checked = true; + } + }); + }) + } + + const res = await fetch(config.ajax.update_shipping.endpoint, { + method: 'POST', + credentials: 'same-origin', + body: JSON.stringify({ + nonce: config.ajax.update_shipping.nonce, + order_id: data.orderID, + }) + }); + + const json = await res.json(); + + if (!json.success) { + throw new Error(json.data.message); + } + } catch (e) { + console.error(e); + + actions.reject(); + } +}; + +/** + * Handles the shipping address change in PayPal. + * + * @param data + * @param actions + * @param config + * @returns {Promise} + */ +export const handleShippingAddressChange = async (data, actions, config) => { + try { + const address = paypalAddressToWc(convertKeysToSnakeCase(data.shippingAddress)); + + // Retrieve current cart contents + await fetch(config.ajax.update_customer_shipping.shipping_address.cart_endpoint) + .then(response => { + return response.json(); + }) + .then(cartData => { + // Update shipping address in the cart data + cartData.shipping_address.address_1 = address.address_1; + cartData.shipping_address.address_2 = address.address_2; + cartData.shipping_address.city = address.city; + cartData.shipping_address.state = address.state; + cartData.shipping_address.postcode = address.postcode; + cartData.shipping_address.country = address.country; + + // Send update request + return fetch(config.ajax.update_customer_shipping.shipping_address.update_customer_endpoint, { + method: 'POST', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + 'X-WC-Store-API-Nonce': config.ajax.update_customer_shipping.wp_rest_nonce, + }, + body: JSON.stringify({ + shipping_address: cartData.shipping_address, + }) + }).then(function (res) { + return res.json(); + }).then(function (customerData) { + jQuery(".cart_totals .shop_table").load(location.href + " " + ".cart_totals .shop_table" + ">*", ""); + }) + }) + + const res = await fetch(config.ajax.update_shipping.endpoint, { + method: 'POST', + credentials: 'same-origin', + body: JSON.stringify({ + nonce: config.ajax.update_shipping.nonce, + order_id: data.orderID, + }) + }); + + const json = await res.json(); + + if (!json.success) { + throw new Error(json.data.message); + } + } catch (e) { + console.error(e); + + actions.reject(); + } +}; diff --git a/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js b/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js index 2068563a7..b983689ce 100644 --- a/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js +++ b/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js @@ -10,6 +10,7 @@ const onApprove = (context, errorHandler) => { nonce: context.config.ajax.approve_order.nonce, order_id:data.orderID, funding_source: window.ppcpFundingSource, + should_create_wc_order: !context.config.vaultingEnabled || data.paymentSource !== 'venmo' }) }).then((res)=>{ return res.json(); @@ -20,7 +21,11 @@ const onApprove = (context, errorHandler) => { errorHandler.genericError(); }); } - location.href = context.config.redirect; + + let orderReceivedUrl = data.data?.order_received_url + + location.href = orderReceivedUrl ? orderReceivedUrl : context.config.redirect; + }); } diff --git a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js index f01219467..d7de31ec8 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js @@ -3,6 +3,10 @@ import {loadScript} from "@paypal/paypal-js"; import {keysToCamelCase} from "../Helper/Utils"; import widgetBuilder from "./WidgetBuilder"; import {normalizeStyleForFundingSource} from "../Helper/Style"; +import { + handleShippingOptionsChange, + handleShippingAddressChange, +} from "../Helper/ShippingHandler.js"; class Renderer { constructor(creditCardRenderer, defaultSettings, onSmartButtonClick, onSmartButtonsInit) { @@ -64,6 +68,14 @@ class Renderer { } } + shouldHandleShippingInPaypal = (venmoButtonClicked) => { + if (!this.defaultSettings.should_handle_shipping_in_paypal) { + return false; + } + + return !venmoButtonClicked || !this.defaultSettings.vaultingEnabled; + } + renderButtons(wrapper, style, contextConfig, hasEnabledSeparateGateways, fundingSource = null) { if (! document.querySelector(wrapper) || this.isAlreadyRendered(wrapper, fundingSource, hasEnabledSeparateGateways) ) { // Try to render registered buttons again in case they were removed from the DOM by an external source. @@ -75,8 +87,10 @@ class Renderer { contextConfig.fundingSource = fundingSource; } + let venmoButtonClicked = false; + const buttonsOptions = () => { - return { + const options = { style, ...contextConfig, onClick: this.onSmartButtonClick, @@ -86,8 +100,16 @@ class Renderer { } this.handleOnButtonsInit(wrapper, data, actions); }, + }; + + // Check the condition and add the onShippingOptionsChange handler if needed + if (this.shouldHandleShippingInPaypal(venmoButtonClicked)) { + options.onShippingOptionsChange = (data, actions) => null; + options.onShippingAddressChange = (data, actions) => null; } - } + + return options; + }; jQuery(document) .off(this.reloadEventName, wrapper) diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index 6f781911b..3d14c9a74 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -16,6 +16,7 @@ use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper; use WooCommerce\PayPalCommerce\Button\Helper\CheckoutFormSaver; use WooCommerce\PayPalCommerce\Button\Endpoint\SaveCheckoutFormEndpoint; use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait; +use WooCommerce\PayPalCommerce\Button\Helper\WooCommerceOrderCreator; use WooCommerce\PayPalCommerce\Button\Validation\CheckoutFormValidator; use WooCommerce\PayPalCommerce\Button\Endpoint\ValidateCheckoutEndpoint; use WooCommerce\PayPalCommerce\Session\SessionHandler; @@ -147,7 +148,8 @@ return array( $container->get( 'wcgateway.funding-sources-without-redirect' ), $container->get( 'vaulting.vault-v3-enabled' ), $container->get( 'api.endpoint.payment-tokens' ), - $container->get( 'woocommerce.logger.woocommerce' ) + $container->get( 'woocommerce.logger.woocommerce' ), + $container->get( 'button.handle-shipping-in-paypal' ) ); }, 'button.url' => static function ( ContainerInterface $container ): string { @@ -157,7 +159,13 @@ return array( ); }, 'button.pay-now-contexts' => static function ( ContainerInterface $container ): array { - return array( 'checkout', 'pay-now' ); + $defaults = array( 'checkout', 'pay-now' ); + + if ( $container->get( 'button.handle-shipping-in-paypal' ) ) { + return array_merge( $defaults, array( 'cart', 'product', 'mini-cart' ) ); + } + + return $defaults; }, 'button.request-data' => static function ( ContainerInterface $container ): RequestData { return new RequestData(); @@ -221,14 +229,18 @@ return array( return new EarlyOrderHandler( $state, $order_processor, $session_handler ); }, 'button.endpoint.approve-order' => static function ( ContainerInterface $container ): ApproveOrderEndpoint { - $request_data = $container->get( 'button.request-data' ); - $order_endpoint = $container->get( 'api.endpoint.order' ); - $session_handler = $container->get( 'session.handler' ); - $three_d_secure = $container->get( 'button.helper.three-d-secure' ); - $settings = $container->get( 'wcgateway.settings' ); - $dcc_applies = $container->get( 'api.helpers.dccapplies' ); - $order_helper = $container->get( 'api.order-helper' ); - $logger = $container->get( 'woocommerce.logger.woocommerce' ); + $request_data = $container->get( 'button.request-data' ); + $order_endpoint = $container->get( 'api.endpoint.order' ); + $session_handler = $container->get( 'session.handler' ); + $three_d_secure = $container->get( 'button.helper.three-d-secure' ); + $settings = $container->get( 'wcgateway.settings' ); + $dcc_applies = $container->get( 'api.helpers.dccapplies' ); + $order_helper = $container->get( 'api.order-helper' ); + $final_review_enabled = $container->get( 'blocks.settings.final_review_enabled' ); + $wc_order_creator = $container->get( 'button.helper.wc-order-creator' ); + $gateway = $container->get( 'wcgateway.paypal-gateway' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); + $logger = $container->get( 'woocommerce.logger.woocommerce' ); return new ApproveOrderEndpoint( $request_data, $order_endpoint, @@ -237,6 +249,10 @@ return array( $settings, $dcc_applies, $order_helper, + $final_review_enabled, + $gateway, + $wc_order_creator, + $subscription_helper, $logger ); }, @@ -342,6 +358,10 @@ return array( * May result in slower popup performance, additional loading. */ 'button.handle-shipping-in-paypal' => static function ( ContainerInterface $container ): bool { - return false; + return ! $container->get( 'blocks.settings.final_review_enabled' ); + }, + + 'button.helper.wc-order-creator' => static function ( ContainerInterface $container ): WooCommerceOrderCreator { + return new WooCommerceOrderCreator( $container->get( 'wcgateway.funding-source.renderer' ), $container->get( 'session.handler' ) ); }, ); diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index a4d1a63c8..7d6909c2e 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -19,6 +19,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Money; use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken; use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies; +use WooCommerce\PayPalCommerce\Blocks\Endpoint\UpdateShippingEndpoint; use WooCommerce\PayPalCommerce\Button\Endpoint\ApproveOrderEndpoint; use WooCommerce\PayPalCommerce\Button\Endpoint\ApproveSubscriptionEndpoint; use WooCommerce\PayPalCommerce\Button\Endpoint\CartScriptParamsEndpoint; @@ -217,6 +218,13 @@ class SmartButton implements SmartButtonInterface { */ private $logger; + /** + * Whether the shipping should be handled in PayPal. + * + * @var bool + */ + private $should_handle_shipping_in_paypal; + /** * SmartButton constructor. * @@ -242,6 +250,7 @@ class SmartButton implements SmartButtonInterface { * @param bool $vault_v3_enabled Whether Vault v3 module is enabled. * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. * @param LoggerInterface $logger The logger. + * @param bool $should_handle_shipping_in_paypal Whether the shipping should be handled in PayPal. */ public function __construct( string $module_url, @@ -265,7 +274,8 @@ class SmartButton implements SmartButtonInterface { array $funding_sources_without_redirect, bool $vault_v3_enabled, PaymentTokensEndpoint $payment_tokens_endpoint, - LoggerInterface $logger + LoggerInterface $logger, + bool $should_handle_shipping_in_paypal ) { $this->module_url = $module_url; @@ -290,6 +300,7 @@ class SmartButton implements SmartButtonInterface { $this->vault_v3_enabled = $vault_v3_enabled; $this->logger = $logger; $this->payment_tokens_endpoint = $payment_tokens_endpoint; + $this->should_handle_shipping_in_paypal = $should_handle_shipping_in_paypal; } /** @@ -1133,6 +1144,21 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages 'endpoint' => \WC_AJAX::get_endpoint( CreatePaymentTokenForGuest::ENDPOINT ), 'nonce' => wp_create_nonce( CreatePaymentTokenForGuest::nonce() ), ), + 'update_shipping' => array( + 'endpoint' => \WC_AJAX::get_endpoint( UpdateShippingEndpoint::ENDPOINT ), + 'nonce' => wp_create_nonce( UpdateShippingEndpoint::nonce() ), + ), + 'update_customer_shipping' => array( + 'shipping_options' => array( + 'endpoint' => '/wp-json/wc/store/cart/select-shipping-rate', + ), + 'shipping_address' => array( + 'cart_endpoint' => '/wp-json/wc/store/cart/', + 'update_customer_endpoint' => '/wp-json/wc/store/v1/cart/update-customer/', + ), + 'wp_rest_nonce' => wp_create_nonce( 'wc_store_api' ), + 'update_shipping_method' => \WC_AJAX::get_endpoint( 'update_shipping_method' ), + ), ), 'cart_contains_subscription' => $this->subscription_helper->cart_contains_subscription(), 'subscription_plan_id' => $this->subscription_helper->paypal_subscription_id(), @@ -1253,6 +1279,8 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages 'user' => array( 'is_logged' => is_user_logged_in(), ), + 'should_handle_shipping_in_paypal' => $this->should_handle_shipping_in_paypal && ! $this->is_checkout(), + 'vaultingEnabled' => $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ), ); if ( 'pay-now' === $this->context() ) { diff --git a/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php index e33ab3b69..9e3d43c6f 100644 --- a/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php @@ -14,20 +14,25 @@ use Exception; use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; -use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies; use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderHelper; use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException; +use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait; use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure; +use WooCommerce\PayPalCommerce\Button\Helper\WooCommerceOrderCreator; use WooCommerce\PayPalCommerce\Session\SessionHandler; +use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; /** * Class ApproveOrderEndpoint */ class ApproveOrderEndpoint implements EndpointInterface { + use ContextTrait; + const ENDPOINT = 'ppc-approve-order'; /** @@ -79,6 +84,34 @@ class ApproveOrderEndpoint implements EndpointInterface { */ protected $order_helper; + /** + * Whether the final review is enabled. + * + * @var bool + */ + protected $final_review_enabled; + + /** + * The WC gateway. + * + * @var PayPalGateway + */ + protected $gateway; + + /** + * The WooCommerce order creator. + * + * @var WooCommerceOrderCreator + */ + protected $wc_order_creator; + + /** + * The Subscription Helper. + * + * @var SubscriptionHelper + */ + protected $subscription_helper; + /** * The logger. * @@ -89,14 +122,18 @@ class ApproveOrderEndpoint implements EndpointInterface { /** * ApproveOrderEndpoint constructor. * - * @param RequestData $request_data The request data helper. - * @param OrderEndpoint $order_endpoint The order endpoint. - * @param SessionHandler $session_handler The session handler. - * @param ThreeDSecure $three_d_secure The 3d secure helper object. - * @param Settings $settings The settings. - * @param DccApplies $dcc_applies The DCC applies object. - * @param OrderHelper $order_helper The order helper. - * @param LoggerInterface $logger The logger. + * @param RequestData $request_data The request data helper. + * @param OrderEndpoint $order_endpoint The order endpoint. + * @param SessionHandler $session_handler The session handler. + * @param ThreeDSecure $three_d_secure The 3d secure helper object. + * @param Settings $settings The settings. + * @param DccApplies $dcc_applies The DCC applies object. + * @param OrderHelper $order_helper The order helper. + * @param bool $final_review_enabled Whether the final review is enabled. + * @param PayPalGateway $gateway The WC gateway. + * @param WooCommerceOrderCreator $wc_order_creator The WooCommerce order creator. + * @param SubscriptionHelper $subscription_helper The subscription helper. + * @param LoggerInterface $logger The logger. */ public function __construct( RequestData $request_data, @@ -106,17 +143,25 @@ class ApproveOrderEndpoint implements EndpointInterface { Settings $settings, DccApplies $dcc_applies, OrderHelper $order_helper, + bool $final_review_enabled, + PayPalGateway $gateway, + WooCommerceOrderCreator $wc_order_creator, + SubscriptionHelper $subscription_helper, LoggerInterface $logger ) { - $this->request_data = $request_data; - $this->api_endpoint = $order_endpoint; - $this->session_handler = $session_handler; - $this->threed_secure = $three_d_secure; - $this->settings = $settings; - $this->dcc_applies = $dcc_applies; - $this->order_helper = $order_helper; - $this->logger = $logger; + $this->request_data = $request_data; + $this->api_endpoint = $order_endpoint; + $this->session_handler = $session_handler; + $this->threed_secure = $three_d_secure; + $this->settings = $settings; + $this->dcc_applies = $dcc_applies; + $this->order_helper = $order_helper; + $this->final_review_enabled = $final_review_enabled; + $this->gateway = $gateway; + $this->wc_order_creator = $wc_order_creator; + $this->subscription_helper = $subscription_helper; + $this->logger = $logger; } /** @@ -182,6 +227,7 @@ class ApproveOrderEndpoint implements EndpointInterface { ); } $this->session_handler->replace_order( $order ); + wp_send_json_success(); } @@ -200,6 +246,19 @@ class ApproveOrderEndpoint implements EndpointInterface { $this->session_handler->replace_funding_source( $funding_source ); $this->session_handler->replace_order( $order ); + + if ( ! $this->subscription_helper->plugin_is_active() && apply_filters( 'woocommerce_paypal_payments_toggle_final_review_checkbox', false ) ) { + $this->toggle_final_review_enabled_setting(); + } + + $should_create_wc_order = $data['should_create_wc_order'] ?? false; + if ( ! $this->final_review_enabled && ! $this->is_checkout() && $should_create_wc_order ) { + $wc_order = $this->wc_order_creator->create_from_paypal_order( $order, WC()->cart ); + $this->gateway->process_payment( $wc_order->get_id() ); + $order_received_url = $wc_order->get_checkout_order_received_url(); + + wp_send_json_success( array( 'order_received_url' => $order_received_url ) ); + } wp_send_json_success(); return true; } catch ( Exception $error ) { @@ -216,4 +275,15 @@ class ApproveOrderEndpoint implements EndpointInterface { return false; } } + + /** + * Will toggle the "final confirmation" checkbox. + * + * @return void + */ + protected function toggle_final_review_enabled_setting(): void { + $final_review_enabled_setting = $this->settings->has( 'blocks_final_review_enabled' ) && $this->settings->get( 'blocks_final_review_enabled' ); + $final_review_enabled_setting ? $this->settings->set( 'blocks_final_review_enabled', false ) : $this->settings->set( 'blocks_final_review_enabled', true ); + $this->settings->persist(); + } } diff --git a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php index 1ef06c3be..fbfb22309 100644 --- a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php @@ -246,6 +246,7 @@ class CreateOrderEndpoint implements EndpointInterface { $this->parsed_request_data = $data; $payment_method = $data['payment_method'] ?? ''; $funding_source = $data['funding_source'] ?? ''; + $payment_source = $data['payment_source'] ?? ''; $wc_order = null; if ( 'pay-now' === $data['context'] ) { $wc_order = wc_get_order( (int) $data['order_id'] ); @@ -261,7 +262,7 @@ class CreateOrderEndpoint implements EndpointInterface { } $this->purchase_unit = $this->purchase_unit_factory->from_wc_order( $wc_order ); } else { - $this->purchase_unit = $this->purchase_unit_factory->from_wc_cart( null, $this->handle_shipping_in_paypal ); + $this->purchase_unit = $this->purchase_unit_factory->from_wc_cart( null, $this->should_handle_shipping_in_paypal( $payment_source ) ); // Do not allow completion by webhooks when started via non-checkout buttons, // it is needed only for some APMs in checkout. @@ -610,4 +611,20 @@ class CreateOrderEndpoint implements EndpointInterface { 'custom_id' => $order->purchase_units()[0]->custom_id(), ); } + + /** + * Checks if the shipping should be handled in PayPal popup. + * + * @param string $payment_source The payment source. + * @return bool true if the shipping should be handled in PayPal popup, otherwise false. + */ + protected function should_handle_shipping_in_paypal( string $payment_source ): bool { + $is_vaulting_enabled = $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ); + + if ( ! $this->handle_shipping_in_paypal ) { + return false; + } + + return ! $is_vaulting_enabled || $payment_source !== 'venmo'; + } } diff --git a/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php b/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php new file mode 100644 index 000000000..92f07c0fd --- /dev/null +++ b/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php @@ -0,0 +1,228 @@ +funding_source_renderer = $funding_source_renderer; + $this->session_handler = $session_handler; + } + + /** + * Creates WC order based on given PayPal order. + * + * @param Order $order The PayPal order. + * @param WC_Cart $wc_cart The Cart. + * @return WC_Order The WC order. + * @throws RuntimeException If problem creating. + */ + public function create_from_paypal_order( Order $order, WC_Cart $wc_cart ): WC_Order { + $wc_order = wc_create_order(); + + if ( ! $wc_order instanceof WC_Order ) { + throw new RuntimeException( 'Problem creating WC order.' ); + } + + $this->configure_line_items( $wc_order, $wc_cart ); + $this->configure_shipping( $wc_order, $order->payer(), $order->purchase_units()[0]->shipping() ); + $this->configure_payment_source( $wc_order ); + $this->configure_customer( $wc_order ); + $this->configure_coupons( $wc_order, $wc_cart->get_applied_coupons() ); + + $wc_order->calculate_totals(); + $wc_order->save(); + + return $wc_order; + } + + /** + * Configures the line items. + * + * @param WC_Order $wc_order The WC order. + * @param WC_Cart $wc_cart The Cart. + * @return void + */ + protected function configure_line_items( WC_Order $wc_order, WC_Cart $wc_cart ): void { + $cart_contents = $wc_cart->get_cart(); + + foreach ( $cart_contents as $cart_item ) { + $product_id = $cart_item['product_id'] ?? 0; + $variation_id = $cart_item['variation_id'] ?? 0; + $quantity = $cart_item['quantity'] ?? 0; + $variation_attributes = $cart_item['variation']; + + $item = new WC_Order_Item_Product(); + $item->set_product_id( $product_id ); + $item->set_quantity( $quantity ); + + if ( $variation_id ) { + $item->set_variation_id( $variation_id ); + $item->set_variation( $variation_attributes ); + } + + $product = wc_get_product( $variation_id ?: $product_id ); + if ( ! $product ) { + return; + } + + $item->set_name( $product->get_name() ); + $item->set_subtotal( $product->get_price() * $quantity ); + $item->set_total( $product->get_price() * $quantity ); + + $wc_order->add_item( $item ); + } + } + + /** + * Configures the shipping & billing addresses for WC order from given payer. + * + * @param WC_Order $wc_order The WC order. + * @param Payer|null $payer The payer. + * @param Shipping|null $shipping The shipping. + * @return void + */ + protected function configure_shipping( WC_Order $wc_order, ?Payer $payer, ?Shipping $shipping ): void { + $shipping_address = null; + $billing_address = null; + $shipping_options = null; + + if ( $payer ) { + $address = $payer->address(); + $payer_name = $payer->name(); + + $billing_address = array( + 'first_name' => $payer_name ? $payer_name->given_name() : '', + 'last_name' => $payer_name ? $payer_name->surname() : '', + 'address_1' => $address ? $address->address_line_1() : '', + 'address_2' => $address ? $address->address_line_2() : '', + 'city' => $address ? $address->admin_area_2() : '', + 'state' => $address ? $address->admin_area_1() : '', + 'postcode' => $address ? $address->postal_code() : '', + 'country' => $address ? $address->country_code() : '', + ); + } + + if ( $shipping ) { + $address = $shipping->address(); + + $shipping_address = array( + 'first_name' => $shipping->name(), + 'last_name' => '', + 'address_1' => $address->address_line_1(), + 'address_2' => $address->address_line_2(), + 'city' => $address->admin_area_2(), + 'state' => $address->admin_area_1(), + 'postcode' => $address->postal_code(), + 'country' => $address->country_code(), + ); + + $shipping_options = $shipping->options()[0] ?? ''; + } + + if ( $shipping_address ) { + $wc_order->set_shipping_address( $shipping_address ); + } + + if ( $billing_address || $shipping_address ) { + $wc_order->set_billing_address( $billing_address ?: $shipping_address ); + } + + if ( $shipping_options ) { + $shipping = new WC_Order_Item_Shipping(); + $shipping->set_method_title( $shipping_options->label() ); + $shipping->set_method_id( $shipping_options->id() ); + $shipping->set_total( $shipping_options->amount()->value_str() ); + + $wc_order->add_item( $shipping ); + } + } + + /** + * Configures the payment source. + * + * @param WC_Order $wc_order The WC order. + * @return void + */ + protected function configure_payment_source( WC_Order $wc_order ): void { + $funding_source = $this->session_handler->funding_source(); + $wc_order->set_payment_method( PayPalGateway::ID ); + + if ( $funding_source ) { + $wc_order->set_payment_method_title( $this->funding_source_renderer->render_name( $funding_source ) ); + } + } + + /** + * Configures the customer ID. + * + * @param WC_Order $wc_order The WC order. + * @return void + */ + protected function configure_customer( WC_Order $wc_order ): void { + $current_user = wp_get_current_user(); + + if ( $current_user->ID !== 0 ) { + $wc_order->set_customer_id( $current_user->ID ); + } + } + + /** + * Configures the applied coupons. + * + * @param WC_Order $wc_order The WC order. + * @param string[] $coupons The list of applied coupons. + * @return void + */ + protected function configure_coupons( WC_Order $wc_order, array $coupons ): void { + foreach ( $coupons as $coupon_code ) { + $wc_order->apply_coupon( $coupon_code ); + } + } + +} diff --git a/modules/ppcp-compat/src/PPEC/DeactivateNote.php b/modules/ppcp-compat/src/PPEC/DeactivateNote.php index 07e0dbe1b..5fb3aad8f 100644 --- a/modules/ppcp-compat/src/PPEC/DeactivateNote.php +++ b/modules/ppcp-compat/src/PPEC/DeactivateNote.php @@ -28,13 +28,18 @@ class DeactivateNote { /** * Note initialization. */ - public static function init() { + public static function init(): void { if ( ! PPECHelper::is_plugin_active() ) { self::maybe_mark_note_as_actioned(); return; } try { + /** + * The method exists in the NoteTraits trait. + * + * @psalm-suppress UndefinedMethod + */ self::possibly_add_note(); } catch ( \Exception $e ) { return; @@ -44,7 +49,7 @@ class DeactivateNote { /** * Get the note. * - * @return Automatic\WooCommerce\Admin\Notes\Note + * @return Note */ public static function get_note() { if ( PPECHelper::site_has_ppec_subscriptions() ) { @@ -87,7 +92,7 @@ class DeactivateNote { /** * Marks the inbox note as actioned so that it doesn't re-appear. */ - private static function maybe_mark_note_as_actioned() { + private static function maybe_mark_note_as_actioned(): void { try { $data_store = \WC_Data_Store::load( 'admin-note' ); } catch ( \Exception $e ) { @@ -106,7 +111,7 @@ class DeactivateNote { $note = Notes::get_note( $note_ids[0] ); - if ( Note::E_WC_ADMIN_NOTE_ACTIONED !== $note->get_status() ) { + if ( $note instanceof Note && Note::E_WC_ADMIN_NOTE_ACTIONED !== $note->get_status() ) { $note->set_status( Note::E_WC_ADMIN_NOTE_ACTIONED ); $note->save(); } diff --git a/modules/ppcp-paylater-configurator/resources/css/paylater-configurator.scss b/modules/ppcp-paylater-configurator/resources/css/paylater-configurator.scss index 6b61e8a2c..ccb65f0ef 100644 --- a/modules/ppcp-paylater-configurator/resources/css/paylater-configurator.scss +++ b/modules/ppcp-paylater-configurator/resources/css/paylater-configurator.scss @@ -48,6 +48,45 @@ margin-right: 16px; border-top-color: #B1B7BD; } + + .css-168cq4n-checkbox_input:checked + label > span > span:first-of-type { + background-color: var(--wp-admin-theme-color); + border-color: var(--wp-admin-theme-color); + } + + .css-168cq4n-checkbox_input:focus + label > span > span:first-of-type { + outline: var(--wp-admin-theme-color); + } + + span[class*="-svg-size_sm-SelectedMain-selected_icon"], + span[class*="-svg-size_xs-selected_icon"] { + color: var(--wp-admin-theme-color); + } + + button[class*="-dropdown_menu_button-text_field_value_sm-active-active"] { + outline: var(--wp-admin-theme-color) solid 0.125rem; + } + + button[class*="-dropdown_menu_button-text_field_value_sm-active"] { + &:focus { + outline: var(--wp-admin-theme-color) solid 0.125rem; + } + } + + .css-gzgyp8-control:checked ~ label { + background-color: var(--wp-admin-theme-color); + border: var(--wp-admin-theme-color); + outline: var(--wp-admin-theme-color) solid 0.125rem; + } + + .css-gzgyp8-control:focus ~ label { + outline: var(--wp-admin-theme-color) solid 0.125rem; + } + + .css-gzgyp8-control:checked ~ span { + border: 0.0625rem solid var(--wp-admin-theme-color); + } + } #field-pay_later_messaging_heading h3{ diff --git a/modules/ppcp-paylater-configurator/resources/js/paylater-configurator.js b/modules/ppcp-paylater-configurator/resources/js/paylater-configurator.js index 9549ef2af..5aa4df772 100644 --- a/modules/ppcp-paylater-configurator/resources/js/paylater-configurator.js +++ b/modules/ppcp-paylater-configurator/resources/js/paylater-configurator.js @@ -1,4 +1,4 @@ -document.addEventListener( 'DOMContentLoaded', () => { +document.addEventListener('DOMContentLoaded', () => { const form = document.querySelector('#mainform'); const table = form.querySelector('.form-table'); const headingRow = table.querySelector('#field-pay_later_messaging_heading'); @@ -14,7 +14,6 @@ document.addEventListener( 'DOMContentLoaded', () => { // Insert the new row after the headingRow headingRow.parentNode.insertBefore(newRow, headingRow.nextSibling); - let isSaving = false; // Flag variable to track whether saving is in progress saveChangesButton.addEventListener('click', () => { @@ -24,39 +23,63 @@ document.addEventListener( 'DOMContentLoaded', () => { // Trigger the click event on the publish button form.querySelector('.' + publishButtonClassName).click(); - - // Trigger click event on saveChangesButton after a short delay - setTimeout(() => { - saveChangesButton.click(); // Trigger click event on saveChangesButton - isSaving = false; // Reset flag when saving is complete - }, 1000); // Adjust the delay as needed + saveChangesButton.click(); // Trigger click event on saveChangesButton + isSaving = false; // Reset flag when saving is complete } }); - merchantConfigurators.Messaging({ - config: PcpPayLaterConfigurator.config, - merchantClientId: PcpPayLaterConfigurator.merchantClientId, - partnerClientId: PcpPayLaterConfigurator.partnerClientId, - partnerName: 'WooCommerce', - bnCode: 'Woo_PPCP', - placements: ['cart', 'checkout', 'product', 'shop', 'home', 'custom_placement'], - styleOverrides: { - button: publishButtonClassName, - header: PcpPayLaterConfigurator.headerClassName, - subheader: PcpPayLaterConfigurator.subheaderClassName + // Fetch the configuration settings + fetch(PcpPayLaterConfigurator.ajax.get_config.endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' }, - onSave: data => { - fetch(PcpPayLaterConfigurator.ajax.save_config.endpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - credentials: 'same-origin', - body: JSON.stringify({ - nonce: PcpPayLaterConfigurator.ajax.save_config.nonce, - config: data, - }), - }); - } + body: JSON.stringify({ + action: 'ppc-get-message-config', + nonce: PcpPayLaterConfigurator.ajax.get_config.nonce + }), }) -} ); + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + return response.json(); + }) + .then(data => { + if (data.success) { + const config = data.data; + + merchantConfigurators.Messaging({ + config: config, + merchantClientId: PcpPayLaterConfigurator.merchantClientId, + partnerClientId: PcpPayLaterConfigurator.partnerClientId, + partnerName: 'WooCommerce', + bnCode: 'Woo_PPCP', + placements: ['cart', 'checkout', 'product', 'shop', 'home', 'custom_placement'], + styleOverrides: { + button: publishButtonClassName, + header: PcpPayLaterConfigurator.headerClassName, + subheader: PcpPayLaterConfigurator.subheaderClassName + }, + onSave: data => { + fetch(PcpPayLaterConfigurator.ajax.save_config.endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + credentials: 'same-origin', + body: JSON.stringify({ + nonce: PcpPayLaterConfigurator.ajax.save_config.nonce, + config: data, + }), + }); + } + }); + } else { + console.error('Failed to fetch configuration:', data); + } + }) + .catch(error => { + console.error('Error fetching configuration:', error); + }); +}); diff --git a/modules/ppcp-paylater-configurator/services.php b/modules/ppcp-paylater-configurator/services.php index 7b668aba7..de282b4c1 100644 --- a/modules/ppcp-paylater-configurator/services.php +++ b/modules/ppcp-paylater-configurator/services.php @@ -10,6 +10,7 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\PayLaterConfigurator; use WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint\SaveConfig; +use WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint\GetConfig; use WooCommerce\PayPalCommerce\PayLaterConfigurator\Factory\ConfigFactory; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; @@ -35,4 +36,10 @@ return array( $container->get( 'woocommerce.logger.woocommerce' ) ); }, + 'paylater-configurator.endpoint.get-config' => static function ( ContainerInterface $container ): GetConfig { + return new GetConfig( + $container->get( 'wcgateway.settings' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, ); diff --git a/modules/ppcp-paylater-configurator/src/Endpoint/GetConfig.php b/modules/ppcp-paylater-configurator/src/Endpoint/GetConfig.php new file mode 100644 index 000000000..d12d1e856 --- /dev/null +++ b/modules/ppcp-paylater-configurator/src/Endpoint/GetConfig.php @@ -0,0 +1,99 @@ +settings = $settings; + $this->logger = $logger; + } + + /** + * Returns the nonce. + */ + public static function nonce(): string { + return self::ENDPOINT; + } + + /** + * Handles the request. + */ + public function handle_request(): bool { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + $this->logger->error( 'User does not have permission: manage_woocommerce' ); + wp_send_json_error( 'Not admin.', 403 ); + return false; + } + + try { + $input = file_get_contents( 'php://input' ); + + if ( false === $input ) { + $this->logger->error( 'Failed to get input data.' ); + wp_send_json_error( 'Failed to get input data.', 400 ); + return false; + } + + $data = json_decode( $input, true ); + + if ( json_last_error() !== JSON_ERROR_NONE ) { + $this->logger->error( 'Failed to decode JSON: ' . json_last_error_msg() ); + wp_send_json_error( 'Failed to decode JSON.', 400 ); + return false; + } + + if ( ! isset( $data['nonce'] ) || ! wp_verify_nonce( $data['nonce'], self::ENDPOINT ) ) { + $this->logger->error( 'Invalid nonce' ); + wp_send_json_error( 'Invalid nonce.', 403 ); + return false; + } + + $config_factory = new ConfigFactory(); + $config = $config_factory->from_settings( $this->settings ); + wp_send_json_success( $config ); + return true; + } catch ( Throwable $error ) { + $this->logger->error( "GetConfig execution failed. {$error->getMessage()} {$error->getFile()}:{$error->getLine()}" ); + + wp_send_json_error( 'An error occurred while fetching the configuration.' ); + return false; + } + } +} diff --git a/modules/ppcp-paylater-configurator/src/PayLaterConfiguratorModule.php b/modules/ppcp-paylater-configurator/src/PayLaterConfiguratorModule.php index fd5d4c6d5..3588f393a 100644 --- a/modules/ppcp-paylater-configurator/src/PayLaterConfiguratorModule.php +++ b/modules/ppcp-paylater-configurator/src/PayLaterConfiguratorModule.php @@ -10,6 +10,7 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\PayLaterConfigurator; use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply; +use WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint\GetConfig; use WooCommerce\PayPalCommerce\PayLaterConfigurator\Endpoint\SaveConfig; use WooCommerce\PayPalCommerce\PayLaterConfigurator\Factory\ConfigFactory; use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider; @@ -27,7 +28,7 @@ class PayLaterConfiguratorModule implements ModuleInterface { */ public static function is_enabled(): bool { return apply_filters( - // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores 'woocommerce.feature-flags.woocommerce_paypal_payments.paylater_configurator_enabled', getenv( 'PCP_PAYLATER_CONFIGURATOR' ) !== '0' ); @@ -68,6 +69,15 @@ class PayLaterConfiguratorModule implements ModuleInterface { } ); + add_action( + 'wc_ajax_' . GetConfig::ENDPOINT, + static function () use ( $c ) { + $endpoint = $c->get( 'paylater-configurator.endpoint.get-config' ); + assert( $endpoint instanceof GetConfig ); + $endpoint->handle_request(); + } + ); + $current_page_id = $c->get( 'wcgateway.current-ppcp-settings-page-id' ); if ( $current_page_id !== Settings::PAY_LATER_TAB_ID ) { @@ -112,6 +122,10 @@ class PayLaterConfiguratorModule implements ModuleInterface { 'endpoint' => \WC_AJAX::get_endpoint( SaveConfig::ENDPOINT ), 'nonce' => wp_create_nonce( SaveConfig::nonce() ), ), + 'get_config' => array( + 'endpoint' => \WC_AJAX::get_endpoint( GetConfig::ENDPOINT ), + 'nonce' => wp_create_nonce( GetConfig::nonce() ), + ), ), 'config' => $config_factory->from_settings( $settings ), 'merchantClientId' => $settings->get( 'client_id' ), diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index dcbc43333..9ba0021b0 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -347,6 +347,7 @@ return array( $container->get( 'api.partner_merchant_id-production' ), $container->get( 'api.partner_merchant_id-sandbox' ), $container->get( 'api.endpoint.billing-agreements' ), + $container->get( 'wc-subscriptions.helper' ), $logger ); }, @@ -1461,7 +1462,7 @@ return array( $button_text = $enabled ? esc_html__( 'Settings', 'woocommerce-paypal-payments' ) - : esc_html__( 'Enable Advanced PayPal Wallet', 'woocommerce-paypal-payments' ); + : esc_html__( 'Enable saving PayPal & Venmo', 'woocommerce-paypal-payments' ); $enable_url = $environment->current_environment_is( Environment::PRODUCTION ) ? $container->get( 'wcgateway.enable-reference-transactions-url-live' ) diff --git a/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php b/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php index 0abe5d0c8..50f453d9e 100644 --- a/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php +++ b/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php @@ -263,7 +263,7 @@ class SettingsPageAssets { 'reference_transaction_enabled' => $this->billing_agreements_endpoint->reference_transaction_enabled(), 'vaulting_must_enable_advanced_wallet_message' => sprintf( // translators: %1$s and %2$s are the opening and closing of HTML tag. - esc_html__( 'Your PayPal account must be enabled for the %1$sAdvanced PayPal Wallet%2$s to use PayPal Vaulting.', 'woocommerce-paypal-payments' ), + esc_html__( 'Your PayPal account must be eligible to %1$ssave PayPal and Venmo payment methods%2$s to enable PayPal Vaulting.', 'woocommerce-paypal-payments' ), '', '' ), diff --git a/modules/ppcp-wc-gateway/src/Settings/Fields/connection-tab-fields.php b/modules/ppcp-wc-gateway/src/Settings/Fields/connection-tab-fields.php index 73a17081b..7d29dd08b 100644 --- a/modules/ppcp-wc-gateway/src/Settings/Fields/connection-tab-fields.php +++ b/modules/ppcp-wc-gateway/src/Settings/Fields/connection-tab-fields.php @@ -411,7 +411,7 @@ return function ( ContainerInterface $container, array $fields ): array { 'gateway' => Settings::CONNECTION_TAB_ID, ), 'ppcp_reference_transactions_status' => array( - 'title' => __( 'Advanced PayPal Wallet', 'woocommerce-paypal-payments' ), + 'title' => __( 'Save PayPal & Venmo payment methods', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-text', 'text' => $container->get( 'wcgateway.settings.connection.reference-transactions-status-text' ), 'screens' => array( diff --git a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php index c6d7e7231..e726377d3 100644 --- a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php +++ b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php @@ -23,6 +23,7 @@ use WooCommerce\PayPalCommerce\Onboarding\Helper\OnboardingUrl; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus; use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceProductStatus; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\WooCommerce\Logging\Logger\NullLogger; @@ -160,6 +161,13 @@ class SettingsListener { */ private $billing_agreements_endpoint; + /** + * The subscription helper + * + * @var SubscriptionHelper + */ + protected $subscription_helper; + /** * The logger. * @@ -185,6 +193,7 @@ class SettingsListener { * @param string $partner_merchant_id_production Partner merchant ID production. * @param string $partner_merchant_id_sandbox Partner merchant ID sandbox. * @param BillingAgreementsEndpoint $billing_agreements_endpoint Billing Agreements endpoint. + * @param SubscriptionHelper $subscription_helper The subscription helper. * @param ?LoggerInterface $logger The logger. */ public function __construct( @@ -203,6 +212,7 @@ class SettingsListener { string $partner_merchant_id_production, string $partner_merchant_id_sandbox, BillingAgreementsEndpoint $billing_agreements_endpoint, + SubscriptionHelper $subscription_helper, LoggerInterface $logger = null ) { @@ -221,6 +231,7 @@ class SettingsListener { $this->partner_merchant_id_production = $partner_merchant_id_production; $this->partner_merchant_id_sandbox = $partner_merchant_id_sandbox; $this->billing_agreements_endpoint = $billing_agreements_endpoint; + $this->subscription_helper = $subscription_helper; $this->logger = $logger ?: new NullLogger(); } @@ -392,6 +403,11 @@ class SettingsListener { $this->settings->persist(); } + if ( $this->subscription_helper->plugin_is_active() ) { + $this->settings->set( 'blocks_final_review_enabled', true ); + $this->settings->persist(); + } + if ( $subscription_mode === 'disable_paypal_subscriptions' && $vault_enabled === '1' ) { $this->settings->set( 'vault_enabled', false ); $this->settings->persist(); diff --git a/readme.txt b/readme.txt index 42840c062..ff494fa80 100644 --- a/readme.txt +++ b/readme.txt @@ -185,6 +185,10 @@ If you encounter issues with the PayPal buttons not appearing after an update, p * Fix - Allow PUI Gateway for refund processor #2192 * Fix - Notice on newly created block cart checkout #2211 * Fix - Apple Pay button in the editor #2177 +* Fix - Allow shipping callback and skipping confirmation page from any express button #2236 +* Fix - Pay Later messaging configurator sometimes displays old settings after saving #2249 +* Fix - Update the apple-developer-merchantid-domain-association validation strings for Apple Pay #2251 +* Enhancement - Use admin theme color #1602 = 2.7.0 - 2024-04-30 = * Fix - Zero sum subscriptions cause CANNOT_BE_ZERO_OR_NEGATIVE when using Vault v3 #2152 diff --git a/tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php b/tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php index 7b23ca67d..92d3f50d1 100644 --- a/tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php +++ b/tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php @@ -3,16 +3,15 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Settings; use Psr\Log\LoggerInterface; -use Requests_Utility_CaseInsensitiveDictionary; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingAgreementsEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache; use WooCommerce\PayPalCommerce\Helper\RedirectorStub; -use WooCommerce\PayPalCommerce\Helper\StubRedirectionException; use WooCommerce\PayPalCommerce\ModularTestCase; use WooCommerce\PayPalCommerce\Onboarding\State; use Mockery; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar; use function Brain\Monkey\Functions\when; @@ -42,6 +41,7 @@ class SettingsListenerTest extends ModularTestCase $pui_status_cache = Mockery::mock(Cache::class); $dcc_status_cache = Mockery::mock(Cache::class); $billing_agreement_endpoint = Mockery::mock(BillingAgreementsEndpoint::class); + $subscription_helper = Mockery::mock(SubscriptionHelper::class); $logger = Mockery::mock(LoggerInterface::class); $testee = new SettingsListener( @@ -60,6 +60,7 @@ class SettingsListenerTest extends ModularTestCase '', '', $billing_agreement_endpoint, + $subscription_helper, $logger );