diff --git a/.ddev/commands/web/wp-cleanup b/.ddev/commands/web/wp-cleanup new file mode 100755 index 000000000..c6b3172d1 --- /dev/null +++ b/.ddev/commands/web/wp-cleanup @@ -0,0 +1,38 @@ +#!/bin/bash + +show-help() { + echo -e "\nDelete all posts -p [post type]" + echo -e "\tExample: ddev wp-cleanup -p shop_order,product" + echo -e "\nDelete all logs -l [wp-content path]" + echo -e "\tExample: ddev wp-cleanup -l uploads/wc-logs\n" +} + +delete-posts() { + for post in $(wp post list --post_type=$1 --format=ids --path=.ddev/wordpress); do + wp post delete $post --force --path=.ddev/wordpress + done +} + +delete-logs() { + rm .ddev/wordpress/wp-content/$1/*.log +} + +declare -i param_counter=0 + +while getopts "p:l:h" arg; do + case $arg in + p) + delete-posts $OPTARG + param_counter+=1 + ;; + l) + delete-logs $OPTARG + param_counter+=1 + ;; + h) show-help ;; + esac +done + +if [ $param_counter -eq 0 ]; then + show-help +fi diff --git a/.env.e2e.example b/.env.e2e.example index 079cdb856..c8023a9cb 100644 --- a/.env.e2e.example +++ b/.env.e2e.example @@ -2,6 +2,8 @@ PPCP_E2E_WP_DIR=${ROOT_DIR}/.ddev/wordpress BASEURL="https://woocommerce-paypal-payments.ddev.site" +PRODUCT_URL="/product/prod" + CUSTOMER_EMAIL="customer@example.com" CUSTOMER_PASSWORD="password" diff --git a/.psalm/stubs.php b/.psalm/stubs.php index bdf5e45c5..8b4990022 100644 --- a/.psalm/stubs.php +++ b/.psalm/stubs.php @@ -9,6 +9,10 @@ if (!defined('HOUR_IN_SECONDS')) { define('HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS); } +if (!defined('ABSPATH')) { + define('ABSPATH', ''); +} + /** * Cancel the next occurrence of a scheduled action. * diff --git a/README.md b/README.md index 676d60ffe..d640960c9 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,8 @@ Enable xdebug via `$ ddev xdebug`, and press `Start Listening for PHP Debug Conn After creating the server in the PHPStorm dialog, you need to set the local project path for the server plugin path. It should look [like this](https://i.imgur.com/ofsF1Mc.png). +See [tests/playwright](tests/playwright) for e2e (browser-based) tests. + ## Test account setup You will need a PayPal sandbox merchant and customer accounts to configure the plugin and make test purchases with it. diff --git a/api/order-functions.php b/api/order-functions.php new file mode 100644 index 000000000..f477651fd --- /dev/null +++ b/api/order-functions.php @@ -0,0 +1,109 @@ +get_meta( PayPalGateway::ORDER_ID_META_KEY ); + if ( ! $paypal_id_or_wc_order ) { + throw new InvalidArgumentException( 'PayPal order ID not found in meta.' ); + } + } + if ( ! is_string( $paypal_id_or_wc_order ) ) { + throw new InvalidArgumentException( 'Invalid PayPal order ID, string expected.' ); + } + + $order_endpoint = PPCP::container()->get( 'api.endpoint.order' ); + assert( $order_endpoint instanceof OrderEndpoint ); + + return $order_endpoint->order( $paypal_id_or_wc_order ); +} + +/** + * Captures the PayPal order. + * + * @param WC_Order $wc_order The WC order. + * @throws InvalidArgumentException When the order cannot be captured. + * @throws Exception When the operation fails. + */ +function ppcp_capture_order( WC_Order $wc_order ): void { + $intent = strtoupper( (string) $wc_order->get_meta( PayPalGateway::INTENT_META_KEY ) ); + + if ( $intent !== 'AUTHORIZE' ) { + throw new InvalidArgumentException( 'Only orders with "authorize" intent can be captured.' ); + } + $captured = wc_string_to_bool( $wc_order->get_meta( AuthorizedPaymentsProcessor::CAPTURED_META_KEY ) ); + if ( $captured ) { + throw new InvalidArgumentException( 'The order is already captured.' ); + } + + $authorized_payment_processor = PPCP::container()->get( 'wcgateway.processor.authorized-payments' ); + assert( $authorized_payment_processor instanceof AuthorizedPaymentsProcessor ); + + if ( ! $authorized_payment_processor->capture_authorized_payment( $wc_order ) ) { + throw new RuntimeException( 'Capture failed.' ); + } +} + +/** + * Refunds the PayPal order. + * Note that you can use wc_refund_payment() to trigger the refund in WC and PayPal. + * + * @param WC_Order $wc_order The WC order. + * @param float $amount The refund amount. + * @param string $reason The reason for the refund. + * @return string The PayPal refund ID. + * @throws InvalidArgumentException When the order cannot be refunded. + * @throws Exception When the operation fails. + */ +function ppcp_refund_order( WC_Order $wc_order, float $amount, string $reason = '' ): string { + $order = ppcp_get_paypal_order( $wc_order ); + + $refund_processor = PPCP::container()->get( 'wcgateway.processor.refunds' ); + assert( $refund_processor instanceof RefundProcessor ); + + return $refund_processor->refund( $order, $wc_order, $amount, $reason ); +} + +/** + * Voids the authorization. + * + * @param WC_Order $wc_order The WC order. + * @throws InvalidArgumentException When the order cannot be voided. + * @throws Exception When the operation fails. + */ +function ppcp_void_order( WC_Order $wc_order ): void { + $order = ppcp_get_paypal_order( $wc_order ); + + $refund_processor = PPCP::container()->get( 'wcgateway.processor.refunds' ); + assert( $refund_processor instanceof RefundProcessor ); + + $refund_processor->void( $order ); +} diff --git a/bootstrap.php b/bootstrap.php index 27c8f36a3..fe4552110 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -16,10 +16,18 @@ use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; return function ( string $root_dir, - ContainerInterface ...$additional_containers + array $additional_containers = array(), + array $additional_modules = array() ): ContainerInterface { + /** + * Skip path check. + * + * @psalm-suppress UnresolvableInclude + */ $modules = ( require "$root_dir/modules.php" )( $root_dir ); + $modules = array_merge( $modules, $additional_modules ); + /** * Use this filter to add custom module or remove some of existing ones. * Modules able to access container, add services and modify existing ones. @@ -38,7 +46,12 @@ return function ( // TODO: caching does not work currently, // may want to consider fixing it later (pass proxy as parent to DelegatingContainer) // for now not fixed since we were using this behavior for long time and fixing it now may break things. - $container = new DelegatingContainer( $provider ); + $container = new DelegatingContainer( $provider ); + /** + * Skip iterable vs array check. + * + * @psalm-suppress PossiblyInvalidArgument + */ $app_container = new CachingContainer( new CompositeContainer( array_merge( diff --git a/changelog.txt b/changelog.txt index b925f470b..d795329a8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,18 @@ *** Changelog *** -= 2.0.3 - TBD = += 2.0.4 - 2023-04-03 = +* Fix - Allow Pay Later in mini-cart #1221 +* Fix - Duplicated auth error when credentials become wrong #1229 +* Fix - Webhook issues when switching sandbox, and delete all webhooks when unsubscribing #1239 +* Fix - High volume of traffic from merchant-integrations endpoint #1273 +* Fix - Add content type json to all fetch ajax endpoints #1275 +* Enhancement - Remove shortcodes from description #1226 +* Enhancement - Handle price suffix with price for product button check #1234 +* Enhancement - Show funding source as payment method #1220 +* Enhancement - Change "Enabled" to "Available" in status text #1237 +* Enhancement - Programmatically capturing/voiding authorized payments #590 + += 2.0.3 - 2023-03-14 = * Fix - `DEVICE_DATA_NOT_AVAILABLE` error message when FraudNet is enabled #1177 * Fix - Redirect to connection tab after manual credentials input #1201 * Fix - Asking for address fields in checkout when not using them #1089 @@ -11,6 +23,7 @@ * Fix - PPEC compatibility layer does not take over subscriptions #1193 * Fix - Checkout conflict with "All products for subscriptions" plugin #629 * Fix - Pay Later on order pay page #1214 +* Fix - High volume of traffic from merchant-integrations endpoint #1241 * Enhancement - Save checkout form before free trial redirect #1135 * Enhancement - Add filter for controlling the ditching of items/breakdown #1146 * Enhancement - Add patch order data filter #1147 diff --git a/composer.json b/composer.json index e149ce2ed..4a94eb54b 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,10 @@ "psr-4": { "WooCommerce\\PayPalCommerce\\": "src", "WooCommerce\\PayPalCommerce\\Vendor\\": "lib/packages/" - } + }, + "files": [ + "api/order-functions.php" + ] }, "autoload-dev": { "psr-4": { diff --git a/composer.lock b/composer.lock index ce4259243..295f011ee 100644 --- a/composer.lock +++ b/composer.lock @@ -35,6 +35,10 @@ ], "description": "Promoting container interoperability through standard service providers", "homepage": "https://github.com/container-interop/service-provider", + "support": { + "issues": "https://github.com/container-interop/service-provider/issues", + "source": "https://github.com/container-interop/service-provider/tree/master" + }, "time": "2017-09-20T14:13:36+00:00" }, { @@ -86,6 +90,10 @@ } ], "description": "Interfaces for human readable string interoperation.", + "support": { + "issues": "https://github.com/Dhii/human-readable-interface/issues", + "source": "https://github.com/Dhii/human-readable-interface/tree/v0.2.0-alpha1" + }, "time": "2021-03-05T00:36:01+00:00" }, { @@ -134,6 +142,10 @@ } ], "description": "Interfaces for modules", + "support": { + "issues": "https://github.com/Dhii/module-interface/issues", + "source": "https://github.com/Dhii/module-interface/tree/v0.3.0-alpha2" + }, "time": "2021-08-23T08:23:01+00:00" }, { @@ -177,6 +189,10 @@ } ], "description": "Interfaces for package-related interop", + "support": { + "issues": "https://github.com/Dhii/package-interface/issues", + "source": "https://github.com/Dhii/package-interface/tree/v0.1.0-alpha4" + }, "time": "2021-12-08T15:57:36+00:00" }, { @@ -225,6 +241,10 @@ } ], "description": "A base interface for validators", + "support": { + "issues": "https://github.com/Dhii/validation-interface/issues", + "source": "https://github.com/Dhii/validation-interface/tree/v0.3.0-alpha3" + }, "time": "2021-01-14T16:19:20+00:00" }, { @@ -268,6 +288,10 @@ } ], "description": "Implementation for dealing with SemVer-compliant versions", + "support": { + "issues": "https://github.com/Dhii/versions/issues", + "source": "https://github.com/Dhii/versions/tree/v0.1.0-alpha3" + }, "time": "2021-12-08T16:54:50+00:00" }, { @@ -312,6 +336,10 @@ "container-interop", "psr" ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.1" + }, "time": "2021-03-05T17:36:06+00:00" }, { @@ -359,6 +387,9 @@ "psr", "psr-3" ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, "time": "2021-05-03T11:20:27+00:00" }, { @@ -399,6 +430,10 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { @@ -465,6 +500,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -528,6 +566,10 @@ } ], "description": "Composer plugin to merge multiple composer.json files", + "support": { + "issues": "https://github.com/wikimedia/composer-merge-plugin/issues", + "source": "https://github.com/wikimedia/composer-merge-plugin/tree/v2.0.1" + }, "time": "2021-02-24T05:28:06+00:00" }, { @@ -576,6 +618,10 @@ } ], "description": "Interfaces for interop within WordPress", + "support": { + "issues": "https://github.com/wp-oop/wordpress-interface/issues", + "source": "https://github.com/wp-oop/wordpress-interface/tree/v0.1.0-alpha2" + }, "time": "2021-04-30T09:37:37+00:00" } ], @@ -656,6 +702,11 @@ "non-blocking", "promise" ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v2.6.2" + }, "funding": [ { "url": "https://github.com/amphp", @@ -697,12 +748,12 @@ } }, "autoload": { - "psr-4": { - "Amp\\ByteStream\\": "lib" - }, "files": [ "lib/functions.php" - ] + ], + "psr-4": { + "Amp\\ByteStream\\": "lib" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -728,6 +779,11 @@ "non-blocking", "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" + }, "funding": [ { "url": "https://github.com/amphp", @@ -738,16 +794,16 @@ }, { "name": "antecedent/patchwork", - "version": "2.1.21", + "version": "2.1.25", "source": { "type": "git", "url": "https://github.com/antecedent/patchwork.git", - "reference": "25c1fa0cd9a6e6d0d13863d8df8f050b6733f16d" + "reference": "17314e042d45e0dacb0a494c2d1ef50e7621136a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/antecedent/patchwork/zipball/25c1fa0cd9a6e6d0d13863d8df8f050b6733f16d", - "reference": "25c1fa0cd9a6e6d0d13863d8df8f050b6733f16d", + "url": "https://api.github.com/repos/antecedent/patchwork/zipball/17314e042d45e0dacb0a494c2d1ef50e7621136a", + "reference": "17314e042d45e0dacb0a494c2d1ef50e7621136a", "shasum": "" }, "require": { @@ -778,7 +834,11 @@ "runkit", "testing" ], - "time": "2022-02-07T07:28:34+00:00" + "support": { + "issues": "https://github.com/antecedent/patchwork/issues", + "source": "https://github.com/antecedent/patchwork/tree/2.1.25" + }, + "time": "2023-02-19T12:51:24+00:00" }, { "name": "brain/monkey", @@ -844,6 +904,10 @@ "test", "testing" ], + "support": { + "issues": "https://github.com/Brain-WP/BrainMonkey/issues", + "source": "https://github.com/Brain-WP/BrainMonkey" + }, "time": "2021-11-11T15:53:55+00:00" }, { @@ -899,6 +963,10 @@ } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" + }, "funding": [ { "url": "https://packagist.com", @@ -966,6 +1034,10 @@ "regex", "regular expression" ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/2.1.0" + }, "funding": [ { "url": "https://packagist.com", @@ -1042,6 +1114,11 @@ "validation", "versioning" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, "funding": [ { "url": "https://packagist.com", @@ -1103,6 +1180,11 @@ "Xdebug", "performance" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, "funding": [ { "url": "https://packagist.com", @@ -1188,6 +1270,10 @@ "stylecheck", "tests" ], + "support": { + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + }, "time": "2022-02-04T12:51:07+00:00" }, { @@ -1239,6 +1325,10 @@ } ], "description": "A highly ISP-compliant collection of interfaces that represent maps and lists.", + "support": { + "issues": "https://github.com/Dhii/collections-interface/issues", + "source": "https://github.com/Dhii/collections-interface/tree/v0.3.0" + }, "time": "2021-10-06T10:56:09+00:00" }, { @@ -1295,6 +1385,10 @@ "PSR-11", "container" ], + "support": { + "issues": "https://github.com/Dhii/containers/issues", + "source": "https://github.com/Dhii/containers/tree/v0.1.4" + }, "time": "2021-10-06T11:13:51+00:00" }, { @@ -1328,6 +1422,10 @@ "MIT" ], "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, "time": "2019-12-04T15:06:13+00:00" }, { @@ -1380,6 +1478,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -1435,6 +1537,10 @@ } ], "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, "time": "2021-06-11T22:34:44+00:00" }, { @@ -1487,28 +1593,32 @@ "php", "server" ], + "support": { + "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", + "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2" + }, "time": "2022-03-02T22:36:06+00:00" }, { "name": "graham-campbell/result-type", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/a878d45c1914464426dc94da61c9e1d36ae262a8", - "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9" + "phpoption/phpoption": "^1.9.1" }, "require-dev": { - "phpunit/phpunit": "^8.5.28 || ^9.5.21" + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" }, "type": "library", "autoload": { @@ -1535,6 +1645,10 @@ "Result-Type", "result" ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -1545,7 +1659,7 @@ "type": "tidelift" } ], - "time": "2022-07-30T15:56:11+00:00" + "time": "2023-02-25T20:23:15+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -1592,6 +1706,10 @@ "keywords": [ "test" ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, "time": "2020-07-09T08:09:16+00:00" }, { @@ -1657,20 +1775,24 @@ "test double", "testing" ], + "support": { + "issues": "https://github.com/mockery/mockery/issues", + "source": "https://github.com/mockery/mockery/tree/1.3.6" + }, "time": "2022-09-07T15:05:49+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -1706,13 +1828,17 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "netresearch/jsonmapper", @@ -1758,20 +1884,25 @@ } ], "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v4.1.0" + }, "time": "2022-12-08T20:46:14+00:00" }, { "name": "nikic/php-parser", - "version": "v4.15.3", + "version": "v4.15.4", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039" + "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/570e980a201d8ed0236b0a62ddf2c9cbb2034039", - "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290", + "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290", "shasum": "" }, "require": { @@ -1810,7 +1941,11 @@ "parser", "php" ], - "time": "2023-01-16T22:05:37+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4" + }, + "time": "2023-03-05T19:49:14+00:00" }, { "name": "openlss/lib-array2xml", @@ -1859,6 +1994,10 @@ "xml", "xml conversion" ], + "support": { + "issues": "https://github.com/nullivex/lib-array2xml/issues", + "source": "https://github.com/nullivex/lib-array2xml/tree/master" + }, "time": "2019-03-29T20:06:56+00:00" }, { @@ -1915,6 +2054,10 @@ } ], "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" + }, "time": "2021-07-20T11:28:43+00:00" }, { @@ -1962,6 +2105,10 @@ } ], "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, "time": "2022-02-21T01:04:05+00:00" }, { @@ -2002,6 +2149,10 @@ "woocommerce", "wordpress" ], + "support": { + "issues": "https://github.com/php-stubs/woocommerce-stubs/issues", + "source": "https://github.com/php-stubs/woocommerce-stubs/tree/v5.9.1" + }, "time": "2022-04-30T06:35:48+00:00" }, { @@ -2045,6 +2196,10 @@ "static analysis", "wordpress" ], + "support": { + "issues": "https://github.com/php-stubs/wordpress-stubs/issues", + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v5.9.5" + }, "time": "2022-11-09T05:32:14+00:00" }, { @@ -2103,6 +2258,10 @@ "phpcs", "standards" ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibility" + }, "time": "2019-12-27T09:44:58+00:00" }, { @@ -2156,6 +2315,10 @@ "standards", "static analysis" ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" + }, "time": "2022-10-25T01:46:02+00:00" }, { @@ -2207,6 +2370,10 @@ "static analysis", "wordpress" ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP" + }, "time": "2022-10-24T09:00:36+00:00" }, { @@ -2256,6 +2423,10 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { @@ -2309,6 +2480,10 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, "time": "2021-10-19T17:43:47+00:00" }, { @@ -2355,28 +2530,32 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + }, "time": "2022-03-15T21:29:03+00:00" }, { "name": "phpoption/phpoption", - "version": "1.9.0", + "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab" + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", - "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e", + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8", - "phpunit/phpunit": "^8.5.28 || ^9.5.21" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" }, "type": "library", "extra": { @@ -2416,6 +2595,10 @@ "php", "type" ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.1" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -2426,7 +2609,7 @@ "type": "tidelift" } ], - "time": "2022-07-30T15:51:26+00:00" + "time": "2023-02-25T19:38:58+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2489,6 +2672,10 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.15" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2545,6 +2732,10 @@ "filesystem", "iterator" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2592,6 +2783,10 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, "time": "2015-06-21T13:50:34+00:00" }, { @@ -2641,6 +2836,16 @@ "keywords": [ "timer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-30T08:20:02+00:00" }, { @@ -2690,21 +2895,31 @@ "keywords": [ "tokenizer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "abandoned": true, "time": "2021-07-26T12:15:06+00:00" }, { "name": "phpunit/phpunit", - "version": "8.5.31", + "version": "8.5.33", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "33c126b09a42de5c99e5e8032b54e8221264a74e" + "reference": "7d1ff0e8c6b35db78ff13e3e05517d7cbf7aa32e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33c126b09a42de5c99e5e8032b54e8221264a74e", - "reference": "33c126b09a42de5c99e5e8032b54e8221264a74e", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7d1ff0e8c6b35db78ff13e3e05517d7cbf7aa32e", + "reference": "7d1ff0e8c6b35db78ff13e3e05517d7cbf7aa32e", "shasum": "" }, "require": { @@ -2770,6 +2985,10 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.33" + }, "funding": [ { "url": "https://phpunit.de/sponsors.html", @@ -2784,7 +3003,7 @@ "type": "tidelift" } ], - "time": "2022-10-28T05:57:37+00:00" + "time": "2023-02-27T13:04:50+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -2829,6 +3048,16 @@ ], "description": "Looks up which function or method a line of code belongs to", "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" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-30T08:15:22+00:00" }, { @@ -2893,6 +3122,10 @@ "compare", "equality" ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2955,6 +3188,16 @@ "unidiff", "unified diff" ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-30T07:59:04+00:00" }, { @@ -3008,6 +3251,16 @@ "environment", "hhvm" ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-30T07:53:42+00:00" }, { @@ -3075,6 +3328,10 @@ "export", "exporter" ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3135,6 +3392,10 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3188,6 +3449,16 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "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" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-30T07:40:27+00:00" }, { @@ -3233,6 +3504,16 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "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" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-30T07:37:18+00:00" }, { @@ -3286,6 +3567,16 @@ ], "description": "Provides functionality to recursively process PHP variables", "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" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-30T07:34:24+00:00" }, { @@ -3328,6 +3619,16 @@ ], "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" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], "time": "2020-11-30T07:30:19+00:00" }, { @@ -3374,6 +3675,10 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/1.1.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3423,20 +3728,24 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, "time": "2016-10-03T07:35:21+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.7.1", + "version": "3.7.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", "shasum": "" }, "require": { @@ -3472,22 +3781,28 @@ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", - "standards" + "standards", + "static analysis" ], - "time": "2022-06-18T07:21:10+00:00" + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2023-02-22T23:07:41+00:00" }, { "name": "symfony/console", - "version": "v5.4.17", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f" + "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f", - "reference": "58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f", + "url": "https://api.github.com/repos/symfony/console/zipball/c77433ddc6cdc689caf48065d9ea22ca0853fbd9", + "reference": "c77433ddc6cdc689caf48065d9ea22ca0853fbd9", "shasum": "" }, "require": { @@ -3556,6 +3871,9 @@ "console", "terminal" ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.21" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3570,7 +3888,7 @@ "type": "tidelift" } ], - "time": "2022-12-28T14:15:31+00:00" + "time": "2023-02-25T16:59:41+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3620,6 +3938,9 @@ ], "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" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3699,6 +4020,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3777,6 +4101,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3858,6 +4185,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3938,6 +4268,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4014,6 +4347,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4094,6 +4430,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4112,16 +4451,16 @@ }, { "name": "symfony/string", - "version": "v5.4.17", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "55733a8664b8853b003e70251c58bc8cb2d82a6b" + "reference": "edac10d167b78b1d90f46a80320d632de0bd9f2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/55733a8664b8853b003e70251c58bc8cb2d82a6b", - "reference": "55733a8664b8853b003e70251c58bc8cb2d82a6b", + "url": "https://api.github.com/repos/symfony/string/zipball/edac10d167b78b1d90f46a80320d632de0bd9f2f", + "reference": "edac10d167b78b1d90f46a80320d632de0bd9f2f", "shasum": "" }, "require": { @@ -4177,6 +4516,9 @@ "utf-8", "utf8" ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.4.21" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4191,7 +4533,7 @@ "type": "tidelift" } ], - "time": "2022-12-12T15:54:21+00:00" + "time": "2023-02-22T08:00:55+00:00" }, { "name": "theseer/tokenizer", @@ -4231,6 +4573,10 @@ } ], "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.1" + }, "funding": [ { "url": "https://github.com/theseer", @@ -4341,6 +4687,10 @@ "inspection", "php" ], + "support": { + "issues": "https://github.com/vimeo/psalm/issues", + "source": "https://github.com/vimeo/psalm/tree/4.30.0" + }, "time": "2022-11-06T20:37:08+00:00" }, { @@ -4411,6 +4761,10 @@ "env", "environment" ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -4475,6 +4829,10 @@ "check", "validate" ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, "time": "2022-06-03T18:03:27+00:00" }, { @@ -4521,6 +4879,10 @@ } ], "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "support": { + "issues": "https://github.com/webmozart/path-util/issues", + "source": "https://github.com/webmozart/path-util/tree/2.3.0" + }, "abandoned": "symfony/filesystem", "time": "2015-12-17T08:42:14+00:00" }, @@ -4562,6 +4924,10 @@ "woocommerce", "wordpress" ], + "support": { + "issues": "https://github.com/woocommerce/woocommerce-sniffs/issues", + "source": "https://github.com/woocommerce/woocommerce-sniffs/tree/0.1.3" + }, "time": "2022-02-17T15:34:51+00:00" }, { @@ -4608,6 +4974,11 @@ "standards", "wordpress" ], + "support": { + "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues", + "source": "https://github.com/WordPress/WordPress-Coding-Standards", + "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki" + }, "time": "2020-05-13T23:57:56+00:00" } ], @@ -4620,9 +4991,9 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0, ^7.2 | ^8.0", + "php": "^7.2 | ^8.0", "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.3.0" } diff --git a/modules/ppcp-api-client/services.php b/modules/ppcp-api-client/services.php index e2ad9c05d..1b1eb3da0 100644 --- a/modules/ppcp-api-client/services.php +++ b/modules/ppcp-api-client/services.php @@ -9,6 +9,7 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\ApiClient; +use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer; @@ -177,12 +178,13 @@ return array( $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' ); $logger = $container->get( 'woocommerce.logger.woocommerce' ); - /** - * The settings. - * - * @var Settings $settings - */ - $settings = $container->get( 'wcgateway.settings' ); + $session_handler = $container->get( 'session.handler' ); + assert( $session_handler instanceof SessionHandler ); + $bn_code = $session_handler->bn_code(); + + $settings = $container->get( 'wcgateway.settings' ); + assert( $settings instanceof Settings ); + $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE'; $application_context_repository = $container->get( 'api.repository.application-context' ); $subscription_helper = $container->get( 'subscription.helper' ); @@ -196,7 +198,8 @@ return array( $application_context_repository, $subscription_helper, $container->get( 'wcgateway.is-fraudnet-enabled' ), - $container->get( 'wcgateway.fraudnet' ) + $container->get( 'wcgateway.fraudnet' ), + $bn_code ); }, 'api.endpoint.billing-agreements' => static function ( ContainerInterface $container ): BillingAgreementsEndpoint { diff --git a/modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php b/modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php index a781dd8a8..a268d6ee9 100644 --- a/modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php +++ b/modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php @@ -197,6 +197,40 @@ class PaymentTokenEndpoint { return wp_remote_retrieve_response_code( $response ) === 204; } + /** + * Deletes payment token by the given id. + * + * @param string $token_id Token id. + * @return bool + * + * @throws RuntimeException If something goes wrong while deleting the token. + */ + public function delete_token_by_id( string $token_id ): bool { + $bearer = $this->bearer->bearer(); + + $url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/' . $token_id; + $args = array( + 'method' => 'DELETE', + 'headers' => array( + 'Authorization' => 'Bearer ' . $bearer->token(), + 'Content-Type' => 'application/json', + ), + ); + + $response = $this->request( $url, $args ); + + if ( is_wp_error( $response ) ) { + $error = new RuntimeException( + __( 'Could not delete payment token.', 'woocommerce-paypal-payments' ) + ); + $this->logger->warning( $error->getMessage() ); + + throw $error; + } + + return wp_remote_retrieve_response_code( $response ) === 204; + } + /** * Starts the process of PayPal account vaulting (without payment), returns the links for further actions. * diff --git a/modules/ppcp-api-client/src/Endpoint/WebhookEndpoint.php b/modules/ppcp-api-client/src/Endpoint/WebhookEndpoint.php index 252c1a294..d8cc06dca 100644 --- a/modules/ppcp-api-client/src/Endpoint/WebhookEndpoint.php +++ b/modules/ppcp-api-client/src/Endpoint/WebhookEndpoint.php @@ -175,12 +175,12 @@ class WebhookEndpoint { * * @param Webhook $hook The webhook to delete. * - * @return bool * @throws RuntimeException If the request fails. + * @throws PayPalApiException If the request fails. */ - public function delete( Webhook $hook ): bool { + public function delete( Webhook $hook ): void { if ( ! $hook->id() ) { - return false; + return; } $bearer = $this->bearer->bearer(); @@ -198,7 +198,18 @@ class WebhookEndpoint { __( 'Not able to delete the webhook.', 'woocommerce-paypal-payments' ) ); } - return wp_remote_retrieve_response_code( $response ) === 204; + + $status_code = (int) wp_remote_retrieve_response_code( $response ); + if ( 204 !== $status_code ) { + $json = null; + if ( is_array( $response ) ) { + $json = json_decode( $response['body'] ); + } + throw new PayPalApiException( + $json, + $status_code + ); + } } /** diff --git a/modules/ppcp-api-client/src/Factory/ItemFactory.php b/modules/ppcp-api-client/src/Factory/ItemFactory.php index c71e7ddfa..0c5e9b542 100644 --- a/modules/ppcp-api-client/src/Factory/ItemFactory.php +++ b/modules/ppcp-api-client/src/Factory/ItemFactory.php @@ -58,7 +58,7 @@ class ItemFactory { mb_substr( $product->get_name(), 0, 127 ), new Money( $price, $this->currency ), $quantity, - substr( wp_strip_all_tags( $product->get_description() ), 0, 127 ) ?: '', + $this->prepare_description( $product->get_description() ), null, $product->get_sku(), ( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS @@ -130,7 +130,7 @@ class ItemFactory { mb_substr( $item->get_name(), 0, 127 ), new Money( $price_without_tax_rounded, $currency ), $quantity, - substr( wp_strip_all_tags( $product instanceof WC_Product ? $product->get_description() : '' ), 0, 127 ) ?: '', + $product instanceof WC_Product ? $this->prepare_description( $product->get_description() ) : '', null, $product instanceof WC_Product ? $product->get_sku() : '', ( $product instanceof WC_Product && $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS @@ -198,4 +198,15 @@ class ItemFactory { $category ); } + + /** + * Cleanups the description and prepares it for sending to PayPal. + * + * @param string $description Item description. + * @return string + */ + protected function prepare_description( string $description ): string { + $description = strip_shortcodes( wp_strip_all_tags( $description ) ); + return substr( $description, 0, 127 ) ?: ''; + } } diff --git a/modules/ppcp-button/package.json b/modules/ppcp-button/package.json index 5fb4286e1..61e31d70f 100644 --- a/modules/ppcp-button/package.json +++ b/modules/ppcp-button/package.json @@ -23,7 +23,7 @@ "file-loader": "^6.2.0", "sass": "^1.42.1", "sass-loader": "^12.1.0", - "webpack": "^5.74", + "webpack": "^5.76", "webpack-cli": "^4.10" }, "scripts": { diff --git a/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js b/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js index dce4259c6..00966ec6c 100644 --- a/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js +++ b/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js @@ -16,6 +16,9 @@ class CartActionHandler { this.config.bn_codes[this.config.context] : ''; return fetch(this.config.ajax.create_order.endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: this.config.ajax.create_order.nonce, diff --git a/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js b/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js index 6f28e8a2f..b45b9f8b9 100644 --- a/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js +++ b/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js @@ -32,6 +32,9 @@ class CheckoutActionHandler { return fetch(this.config.ajax.create_order.endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: this.config.ajax.create_order.nonce, @@ -59,6 +62,11 @@ class CheckoutActionHandler { ); } else { errorHandler.clear(); + + if (data.data.refresh) { + jQuery( document.body ).trigger( 'update_checkout' ); + } + if (data.data.errors?.length > 0) { errorHandler.messages(data.data.errors); } else if (data.data.details?.length > 0) { diff --git a/modules/ppcp-button/resources/js/modules/ActionHandler/FreeTrialHandler.js b/modules/ppcp-button/resources/js/modules/ActionHandler/FreeTrialHandler.js index e24de3bee..878e20207 100644 --- a/modules/ppcp-button/resources/js/modules/ActionHandler/FreeTrialHandler.js +++ b/modules/ppcp-button/resources/js/modules/ActionHandler/FreeTrialHandler.js @@ -49,6 +49,9 @@ class FreeTrialHandler { const res = await fetch(this.config.ajax.vault_paypal.endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: this.config.ajax.vault_paypal.nonce, diff --git a/modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js b/modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js index 4296b1045..f1456a5b0 100644 --- a/modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js +++ b/modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js @@ -66,6 +66,9 @@ class SingleProductActionHandler { this.config.bn_codes[this.config.context] : ''; return fetch(this.config.ajax.create_order.endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: this.config.ajax.create_order.nonce, diff --git a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js index 6c0a03283..a36c1d408 100644 --- a/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js +++ b/modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js @@ -69,8 +69,13 @@ class SingleProductBootstap { () => { const priceEl = document.querySelector('.product .woocommerce-Price-amount'); // variable products show price like 10.00 - 20.00 here - if (priceEl && priceEl.parentElement.querySelectorAll('.woocommerce-Price-amount').length === 1) { - return priceEl.innerText; + // but the second price also can be the suffix with the price incl/excl tax + if (priceEl) { + const allPriceElements = Array.from(priceEl.parentElement.querySelectorAll('.woocommerce-Price-amount')) + .filter(el => !el.parentElement.classList.contains('woocommerce-price-suffix')); + if (allPriceElements.length === 1) { + return priceEl.innerText; + } } return null; }, diff --git a/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js b/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js index 16ddca85c..5f70d636b 100644 --- a/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js +++ b/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js @@ -27,6 +27,9 @@ const storeToken = (token) => { const dataClientIdAttributeHandler = (script, config) => { fetch(config.endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: config.nonce diff --git a/modules/ppcp-button/resources/js/modules/Helper/FormSaver.js b/modules/ppcp-button/resources/js/modules/Helper/FormSaver.js index 332c4a217..494aa354f 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/FormSaver.js +++ b/modules/ppcp-button/resources/js/modules/Helper/FormSaver.js @@ -10,6 +10,9 @@ export default class FormSaver { const res = await fetch(this.url, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: this.nonce, diff --git a/modules/ppcp-button/resources/js/modules/Helper/FormValidator.js b/modules/ppcp-button/resources/js/modules/Helper/FormValidator.js index af68be7dc..a1c738c8d 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/FormValidator.js +++ b/modules/ppcp-button/resources/js/modules/Helper/FormValidator.js @@ -10,6 +10,9 @@ export default class FormValidator { const res = await fetch(this.url, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: this.nonce, @@ -20,6 +23,10 @@ export default class FormValidator { const data = await res.json(); if (!data.success) { + if (data.data.refresh) { + jQuery( document.body ).trigger( 'update_checkout' ); + } + if (data.data.errors) { return data.data.errors; } diff --git a/modules/ppcp-button/resources/js/modules/Helper/UpdateCart.js b/modules/ppcp-button/resources/js/modules/Helper/UpdateCart.js index 43a95ee83..4c5b08355 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/UpdateCart.js +++ b/modules/ppcp-button/resources/js/modules/Helper/UpdateCart.js @@ -20,6 +20,9 @@ class UpdateCart { this.endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: this.nonce, diff --git a/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js b/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js index 12260fe9f..2068563a7 100644 --- a/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js +++ b/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForContinue.js @@ -2,6 +2,9 @@ const onApprove = (context, errorHandler) => { return (data, actions) => { return fetch(context.config.ajax.approve_order.endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: context.config.ajax.approve_order.nonce, diff --git a/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForPayNow.js b/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForPayNow.js index 4e1000bfa..e8fcbde09 100644 --- a/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForPayNow.js +++ b/modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForPayNow.js @@ -5,6 +5,9 @@ const onApprove = (context, errorHandler, spinner) => { return fetch(context.config.ajax.approve_order.endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: context.config.ajax.approve_order.nonce, diff --git a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php index 205505c5c..86c280be1 100644 --- a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php @@ -288,12 +288,15 @@ class CreateOrderEndpoint implements EndpointInterface { return true; } catch ( ValidationException $error ) { - wp_send_json_error( - array( - 'message' => $error->getMessage(), - 'errors' => $error->errors(), - ) + $response = array( + 'message' => $error->getMessage(), + 'errors' => $error->errors(), + 'refresh' => isset( WC()->session->refresh_totals ), ); + + unset( WC()->session->refresh_totals ); + + wp_send_json_error( $response ); } catch ( \RuntimeException $error ) { $this->logger->error( 'Order creation failed: ' . $error->getMessage() ); diff --git a/modules/ppcp-button/src/Endpoint/ValidateCheckoutEndpoint.php b/modules/ppcp-button/src/Endpoint/ValidateCheckoutEndpoint.php index 7c99bb063..934c82cd4 100644 --- a/modules/ppcp-button/src/Endpoint/ValidateCheckoutEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/ValidateCheckoutEndpoint.php @@ -86,12 +86,15 @@ class ValidateCheckoutEndpoint implements EndpointInterface { return true; } catch ( ValidationException $exception ) { - wp_send_json_error( - array( - 'message' => $exception->getMessage(), - 'errors' => $exception->errors(), - ) + $response = array( + 'message' => $exception->getMessage(), + 'errors' => $exception->errors(), + 'refresh' => isset( WC()->session->refresh_totals ), ); + + unset( WC()->session->refresh_totals ); + + wp_send_json_error( $response ); return false; } catch ( Throwable $error ) { $this->logger->error( "Form validation execution failed. {$error->getMessage()} {$error->getFile()}:{$error->getLine()}" ); diff --git a/modules/ppcp-button/yarn.lock b/modules/ppcp-button/yarn.lock index 5d7c6fab8..e76c992e1 100644 --- a/modules/ppcp-button/yarn.lock +++ b/modules/ppcp-button/yarn.lock @@ -1703,9 +1703,9 @@ json-schema-traverse@^0.4.1: integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json5@^2.1.2, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== kind-of@^6.0.2: version "6.0.3" @@ -1723,9 +1723,9 @@ loader-runner@^4.2.0: integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" - integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -2191,10 +2191,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.74: - version "5.74.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== +webpack@^5.76: + version "5.76.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" diff --git a/modules/ppcp-compat/package.json b/modules/ppcp-compat/package.json index 75351485e..d200ad7d4 100644 --- a/modules/ppcp-compat/package.json +++ b/modules/ppcp-compat/package.json @@ -21,7 +21,7 @@ "file-loader": "^6.2.0", "sass": "^1.42.1", "sass-loader": "^12.1.0", - "webpack": "^5.74", + "webpack": "^5.76", "webpack-cli": "^4.10" }, "scripts": { diff --git a/modules/ppcp-compat/src/CompatModule.php b/modules/ppcp-compat/src/CompatModule.php index 84906580b..059425be7 100644 --- a/modules/ppcp-compat/src/CompatModule.php +++ b/modules/ppcp-compat/src/CompatModule.php @@ -21,6 +21,7 @@ use WooCommerce\PayPalCommerce\Compat\Assets\CompatAssets; use WooCommerce\PayPalCommerce\OrderTracking\Endpoint\OrderTrackingEndpoint; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; +use WP_Theme; /** * Class CompatModule @@ -57,6 +58,8 @@ class CompatModule implements ModuleInterface { $this->migrate_pay_later_settings( $c ); $this->migrate_smart_button_settings( $c ); + + $this->fix_page_builders(); } /** @@ -320,4 +323,49 @@ class CompatModule implements ModuleInterface { } ); } + + /** + * Changes the button rendering place for page builders + * that do not work well with our default places. + * + * @return void + */ + protected function fix_page_builders(): void { + if ( $this->is_elementor_pro_active() || $this->is_divi_theme_active() ) { + add_filter( + 'woocommerce_paypal_payments_single_product_renderer_hook', + function(): string { + return 'woocommerce_after_add_to_cart_form'; + }, + 5 + ); + + add_filter( + 'woocommerce_paypal_payments_checkout_button_renderer_hook', + function(): string { + return 'woocommerce_review_order_after_submit'; + }, + 5 + ); + } + } + + /** + * Checks whether the Elementor Pro plugins (allowing integrations with WC) is active. + * + * @return bool + */ + protected function is_elementor_pro_active(): bool { + return is_plugin_active( 'elementor-pro/elementor-pro.php' ); + } + + /** + * Checks whether the Divi theme is currently used. + * + * @return bool + */ + protected function is_divi_theme_active(): bool { + $theme = wp_get_theme(); + return $theme->get( 'Name' ) === 'Divi'; + } } diff --git a/modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php b/modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php index 523909d77..c61d036e3 100644 --- a/modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php +++ b/modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php @@ -184,14 +184,14 @@ class SubscriptionsHandler { } // Are we on the WC > Subscriptions screen? - // phpcs:ignore WordPress.Security.NonceVerification.Missing + // phpcs:ignore WordPress.Security.NonceVerification $post_type = wc_clean( wp_unslash( $_GET['post_type'] ?? $_POST['post_type'] ?? '' ) ); if ( $post_type === 'shop_subscription' ) { return true; } // Are we editing an order or subscription tied to PPEC? - // phpcs:ignore WordPress.Security.NonceVerification.Missing + // phpcs:ignore WordPress.Security.NonceVerification $order_id = wc_clean( wp_unslash( $_GET['post'] ?? $_POST['post_ID'] ?? '' ) ); if ( $order_id ) { $order = wc_get_order( $order_id ); diff --git a/modules/ppcp-compat/yarn.lock b/modules/ppcp-compat/yarn.lock index c790c4b52..22ce5854e 100644 --- a/modules/ppcp-compat/yarn.lock +++ b/modules/ppcp-compat/yarn.lock @@ -1682,9 +1682,9 @@ json-schema-traverse@^0.4.1: integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json5@^2.1.2, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== kind-of@^6.0.2: version "6.0.3" @@ -1702,9 +1702,9 @@ loader-runner@^4.2.0: integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" - integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -2155,10 +2155,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.74: - version "5.74.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== +webpack@^5.76: + version "5.76.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" diff --git a/modules/ppcp-onboarding/package.json b/modules/ppcp-onboarding/package.json index 7746a726e..3dd9aa04e 100644 --- a/modules/ppcp-onboarding/package.json +++ b/modules/ppcp-onboarding/package.json @@ -21,7 +21,7 @@ "file-loader": "^6.2.0", "sass": "^1.42.1", "sass-loader": "^12.1.0", - "webpack": "^5.74", + "webpack": "^5.76", "webpack-cli": "^4.10" }, "scripts": { diff --git a/modules/ppcp-onboarding/resources/js/onboarding.js b/modules/ppcp-onboarding/resources/js/onboarding.js index 630dcb811..46c962e81 100644 --- a/modules/ppcp-onboarding/resources/js/onboarding.js +++ b/modules/ppcp-onboarding/resources/js/onboarding.js @@ -84,6 +84,9 @@ const ppcp_onboarding = { fetch(PayPalCommerceGatewayOnboarding.pui_endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: PayPalCommerceGatewayOnboarding.pui_nonce, diff --git a/modules/ppcp-onboarding/src/OnboardingRESTController.php b/modules/ppcp-onboarding/src/OnboardingRESTController.php index 4eac5ba72..283cf64be 100644 --- a/modules/ppcp-onboarding/src/OnboardingRESTController.php +++ b/modules/ppcp-onboarding/src/OnboardingRESTController.php @@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\Onboarding; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; +use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar; /** * Exposes and handles REST routes related to onboarding. @@ -249,7 +250,7 @@ class OnboardingRESTController { } $webhook_registrar = $this->container->get( 'webhook.registrar' ); - $webhook_registrar->unregister(); + assert( $webhook_registrar instanceof WebhookRegistrar ); $webhook_registrar->register(); return array(); diff --git a/modules/ppcp-onboarding/yarn.lock b/modules/ppcp-onboarding/yarn.lock index 84a6766b7..fdcec8c07 100644 --- a/modules/ppcp-onboarding/yarn.lock +++ b/modules/ppcp-onboarding/yarn.lock @@ -1682,9 +1682,9 @@ json-schema-traverse@^0.4.1: integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json5@^2.1.2, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== kind-of@^6.0.2: version "6.0.3" @@ -1702,9 +1702,9 @@ loader-runner@^4.2.0: integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" - integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -2155,10 +2155,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.74: - version "5.74.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== +webpack@^5.76: + version "5.76.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" diff --git a/modules/ppcp-order-tracking/package.json b/modules/ppcp-order-tracking/package.json index 69607cfd9..080003865 100644 --- a/modules/ppcp-order-tracking/package.json +++ b/modules/ppcp-order-tracking/package.json @@ -21,7 +21,7 @@ "file-loader": "^6.2.0", "sass": "^1.42.1", "sass-loader": "^12.1.0", - "webpack": "^5.74", + "webpack": "^5.76", "webpack-cli": "^4.10" }, "scripts": { diff --git a/modules/ppcp-order-tracking/resources/js/order-edit-page.js b/modules/ppcp-order-tracking/resources/js/order-edit-page.js index af86bf53e..a49717d8c 100644 --- a/modules/ppcp-order-tracking/resources/js/order-edit-page.js +++ b/modules/ppcp-order-tracking/resources/js/order-edit-page.js @@ -18,6 +18,9 @@ document.addEventListener( submitButton.setAttribute('disabled', 'disabled'); fetch(config.ajax.tracking_info.endpoint, { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, credentials: 'same-origin', body: JSON.stringify({ nonce: config.ajax.tracking_info.nonce, diff --git a/modules/ppcp-order-tracking/yarn.lock b/modules/ppcp-order-tracking/yarn.lock index 54ef909ff..565a1b6b8 100644 --- a/modules/ppcp-order-tracking/yarn.lock +++ b/modules/ppcp-order-tracking/yarn.lock @@ -1242,12 +1242,7 @@ acorn-import-assertions@^1.7.6: resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== -acorn@^8.5.0: - version "8.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" - integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== - -acorn@^8.7.1: +acorn@^8.5.0, acorn@^8.7.1: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== @@ -1785,9 +1780,9 @@ json-schema-traverse@^0.4.1: integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json5@^2.1.2, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== kind-of@^6.0.2: version "6.0.3" @@ -1805,9 +1800,9 @@ loader-runner@^4.2.0: integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" - integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -2263,10 +2258,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.74: - version "5.74.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== +webpack@^5.76: + version "5.76.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" diff --git a/modules/ppcp-status-report/src/StatusReportModule.php b/modules/ppcp-status-report/src/StatusReportModule.php index 3e380b069..abf84b83b 100644 --- a/modules/ppcp-status-report/src/StatusReportModule.php +++ b/modules/ppcp-status-report/src/StatusReportModule.php @@ -20,7 +20,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies; use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply; use WooCommerce\PayPalCommerce\Compat\PPEC\PPECHelper; use WooCommerce\PayPalCommerce\Onboarding\State; -use WooCommerce\PayPalCommerce\Webhooks\WebhookInfoStorage; +use WooCommerce\PayPalCommerce\Webhooks\WebhookEventStorage; /** * Class StatusReportModule @@ -62,7 +62,7 @@ class StatusReportModule implements ModuleInterface { $messages_apply = $c->get( 'button.helper.messages-apply' ); $last_webhook_storage = $c->get( 'webhook.last-webhook-storage' ); - assert( $last_webhook_storage instanceof WebhookInfoStorage ); + assert( $last_webhook_storage instanceof WebhookEventStorage ); $billing_agreements_endpoint = $c->get( 'api.endpoint.billing-agreements' ); assert( $billing_agreements_endpoint instanceof BillingAgreementsEndpoint ); diff --git a/modules/ppcp-uninstall/package.json b/modules/ppcp-uninstall/package.json index b7038cf3a..40bb2f18f 100644 --- a/modules/ppcp-uninstall/package.json +++ b/modules/ppcp-uninstall/package.json @@ -21,7 +21,7 @@ "file-loader": "^6.2.0", "sass": "^1.42.1", "sass-loader": "^12.1.0", - "webpack": "^5.74", + "webpack": "^5.76", "webpack-cli": "^4.10" }, "scripts": { diff --git a/modules/ppcp-uninstall/yarn.lock b/modules/ppcp-uninstall/yarn.lock index 54ef909ff..565a1b6b8 100644 --- a/modules/ppcp-uninstall/yarn.lock +++ b/modules/ppcp-uninstall/yarn.lock @@ -1242,12 +1242,7 @@ acorn-import-assertions@^1.7.6: resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== -acorn@^8.5.0: - version "8.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" - integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== - -acorn@^8.7.1: +acorn@^8.5.0, acorn@^8.7.1: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== @@ -1785,9 +1780,9 @@ json-schema-traverse@^0.4.1: integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json5@^2.1.2, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== kind-of@^6.0.2: version "6.0.3" @@ -1805,9 +1800,9 @@ loader-runner@^4.2.0: integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" - integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -2263,10 +2258,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.74: - version "5.74.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== +webpack@^5.76: + version "5.76.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" diff --git a/modules/ppcp-vaulting/.babelrc b/modules/ppcp-vaulting/.babelrc deleted file mode 100644 index 9e972c8b9..000000000 --- a/modules/ppcp-vaulting/.babelrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "usage", - "corejs": "3.25.0" - } - ] - ] -} diff --git a/modules/ppcp-vaulting/.gitignore b/modules/ppcp-vaulting/.gitignore deleted file mode 100644 index f69a89f4b..000000000 --- a/modules/ppcp-vaulting/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -/assets diff --git a/modules/ppcp-vaulting/assets/js/myaccount-payments.js b/modules/ppcp-vaulting/assets/js/myaccount-payments.js new file mode 100644 index 000000000..f03455c7b --- /dev/null +++ b/modules/ppcp-vaulting/assets/js/myaccount-payments.js @@ -0,0 +1,3 @@ +/*! For license information please see myaccount-payments.js.LICENSE.txt */ +(()=>{var t={9662:(t,r,e)=>{var n=e(614),o=e(6330),i=TypeError;t.exports=function(t){if(n(t))return t;throw i(o(t)+" is not a function")}},9483:(t,r,e)=>{var n=e(4411),o=e(6330),i=TypeError;t.exports=function(t){if(n(t))return t;throw i(o(t)+" is not a constructor")}},6077:(t,r,e)=>{var n=e(614),o=String,i=TypeError;t.exports=function(t){if("object"==typeof t||n(t))return t;throw i("Can't set "+o(t)+" as a prototype")}},1223:(t,r,e)=>{var n=e(5112),o=e(30),i=e(3070).f,a=n("unscopables"),c=Array.prototype;null==c[a]&&i(c,a,{configurable:!0,value:o(null)}),t.exports=function(t){c[a][t]=!0}},5787:(t,r,e)=>{var n=e(7976),o=TypeError;t.exports=function(t,r){if(n(r,t))return t;throw o("Incorrect invocation")}},9670:(t,r,e)=>{var n=e(111),o=String,i=TypeError;t.exports=function(t){if(n(t))return t;throw i(o(t)+" is not an object")}},8533:(t,r,e)=>{"use strict";var n=e(2092).forEach,o=e(2133)("forEach");t.exports=o?[].forEach:function(t){return n(this,t,arguments.length>1?arguments[1]:void 0)}},1318:(t,r,e)=>{var n=e(5656),o=e(1400),i=e(6244),a=function(t){return function(r,e,a){var c,u=n(r),s=i(u),f=o(a,s);if(t&&e!=e){for(;s>f;)if((c=u[f++])!=c)return!0}else for(;s>f;f++)if((t||f in u)&&u[f]===e)return t||f||0;return!t&&-1}};t.exports={includes:a(!0),indexOf:a(!1)}},2092:(t,r,e)=>{var n=e(9974),o=e(1702),i=e(8361),a=e(7908),c=e(6244),u=e(5417),s=o([].push),f=function(t){var r=1==t,e=2==t,o=3==t,f=4==t,p=6==t,l=7==t,v=5==t||p;return function(h,y,d,g){for(var m,b,x=a(h),w=i(x),S=n(y,d),O=c(w),j=0,E=g||u,P=r?E(h,O):e||l?E(h,0):void 0;O>j;j++)if((v||j in w)&&(b=S(m=w[j],j,x),t))if(r)P[j]=b;else if(b)switch(t){case 3:return!0;case 5:return m;case 6:return j;case 2:s(P,m)}else switch(t){case 4:return!1;case 7:s(P,m)}return p?-1:o||f?f:P}};t.exports={forEach:f(0),map:f(1),filter:f(2),some:f(3),every:f(4),find:f(5),findIndex:f(6),filterReject:f(7)}},1194:(t,r,e)=>{var n=e(7293),o=e(5112),i=e(7392),a=o("species");t.exports=function(t){return i>=51||!n((function(){var r=[];return(r.constructor={})[a]=function(){return{foo:1}},1!==r[t](Boolean).foo}))}},2133:(t,r,e)=>{"use strict";var n=e(7293);t.exports=function(t,r){var e=[][t];return!!e&&n((function(){e.call(null,r||function(){return 1},1)}))}},1589:(t,r,e)=>{var n=e(1400),o=e(6244),i=e(6135),a=Array,c=Math.max;t.exports=function(t,r,e){for(var u=o(t),s=n(r,u),f=n(void 0===e?u:e,u),p=a(c(f-s,0)),l=0;s{var n=e(1702);t.exports=n([].slice)},7475:(t,r,e)=>{var n=e(3157),o=e(4411),i=e(111),a=e(5112)("species"),c=Array;t.exports=function(t){var r;return n(t)&&(r=t.constructor,(o(r)&&(r===c||n(r.prototype))||i(r)&&null===(r=r[a]))&&(r=void 0)),void 0===r?c:r}},5417:(t,r,e)=>{var n=e(7475);t.exports=function(t,r){return new(n(t))(0===r?0:r)}},7072:(t,r,e)=>{var n=e(5112)("iterator"),o=!1;try{var i=0,a={next:function(){return{done:!!i++}},return:function(){o=!0}};a[n]=function(){return this},Array.from(a,(function(){throw 2}))}catch(t){}t.exports=function(t,r){if(!r&&!o)return!1;var e=!1;try{var i={};i[n]=function(){return{next:function(){return{done:e=!0}}}},t(i)}catch(t){}return e}},4326:(t,r,e)=>{var n=e(1702),o=n({}.toString),i=n("".slice);t.exports=function(t){return i(o(t),8,-1)}},648:(t,r,e)=>{var n=e(1694),o=e(614),i=e(4326),a=e(5112)("toStringTag"),c=Object,u="Arguments"==i(function(){return arguments}());t.exports=n?i:function(t){var r,e,n;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(e=function(t,r){try{return t[r]}catch(t){}}(r=c(t),a))?e:u?i(r):"Object"==(n=i(r))&&o(r.callee)?"Arguments":n}},9920:(t,r,e)=>{var n=e(2597),o=e(3887),i=e(1236),a=e(3070);t.exports=function(t,r,e){for(var c=o(r),u=a.f,s=i.f,f=0;f{var n=e(7293);t.exports=!n((function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype}))},6178:t=>{t.exports=function(t,r){return{value:t,done:r}}},8880:(t,r,e)=>{var n=e(9781),o=e(3070),i=e(9114);t.exports=n?function(t,r,e){return o.f(t,r,i(1,e))}:function(t,r,e){return t[r]=e,t}},9114:t=>{t.exports=function(t,r){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:r}}},6135:(t,r,e)=>{"use strict";var n=e(4948),o=e(3070),i=e(9114);t.exports=function(t,r,e){var a=n(r);a in t?o.f(t,a,i(0,e)):t[a]=e}},8052:(t,r,e)=>{var n=e(614),o=e(3070),i=e(6339),a=e(3072);t.exports=function(t,r,e,c){c||(c={});var u=c.enumerable,s=void 0!==c.name?c.name:r;if(n(e)&&i(e,s,c),c.global)u?t[r]=e:a(r,e);else{try{c.unsafe?t[r]&&(u=!0):delete t[r]}catch(t){}u?t[r]=e:o.f(t,r,{value:e,enumerable:!1,configurable:!c.nonConfigurable,writable:!c.nonWritable})}return t}},3072:(t,r,e)=>{var n=e(7854),o=Object.defineProperty;t.exports=function(t,r){try{o(n,t,{value:r,configurable:!0,writable:!0})}catch(e){n[t]=r}return r}},9781:(t,r,e)=>{var n=e(7293);t.exports=!n((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},317:(t,r,e)=>{var n=e(7854),o=e(111),i=n.document,a=o(i)&&o(i.createElement);t.exports=function(t){return a?i.createElement(t):{}}},8324:t=>{t.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},8509:(t,r,e)=>{var n=e(317)("span").classList,o=n&&n.constructor&&n.constructor.prototype;t.exports=o===Object.prototype?void 0:o},7871:(t,r,e)=>{var n=e(3823),o=e(5268);t.exports=!n&&!o&&"object"==typeof window&&"object"==typeof document},3823:t=>{t.exports="object"==typeof Deno&&Deno&&"object"==typeof Deno.version},1528:(t,r,e)=>{var n=e(8113),o=e(7854);t.exports=/ipad|iphone|ipod/i.test(n)&&void 0!==o.Pebble},6833:(t,r,e)=>{var n=e(8113);t.exports=/(?:ipad|iphone|ipod).*applewebkit/i.test(n)},5268:(t,r,e)=>{var n=e(4326),o=e(7854);t.exports="process"==n(o.process)},1036:(t,r,e)=>{var n=e(8113);t.exports=/web0s(?!.*chrome)/i.test(n)},8113:(t,r,e)=>{var n=e(5005);t.exports=n("navigator","userAgent")||""},7392:(t,r,e)=>{var n,o,i=e(7854),a=e(8113),c=i.process,u=i.Deno,s=c&&c.versions||u&&u.version,f=s&&s.v8;f&&(o=(n=f.split("."))[0]>0&&n[0]<4?1:+(n[0]+n[1])),!o&&a&&(!(n=a.match(/Edge\/(\d+)/))||n[1]>=74)&&(n=a.match(/Chrome\/(\d+)/))&&(o=+n[1]),t.exports=o},748:t=>{t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},1060:(t,r,e)=>{var n=e(1702),o=Error,i=n("".replace),a=String(o("zxcasd").stack),c=/\n\s*at [^:]*:[^\n]*/,u=c.test(a);t.exports=function(t,r){if(u&&"string"==typeof t&&!o.prepareStackTrace)for(;r--;)t=i(t,c,"");return t}},2914:(t,r,e)=>{var n=e(7293),o=e(9114);t.exports=!n((function(){var t=Error("a");return!("stack"in t)||(Object.defineProperty(t,"stack",o(1,7)),7!==t.stack)}))},2109:(t,r,e)=>{var n=e(7854),o=e(1236).f,i=e(8880),a=e(8052),c=e(3072),u=e(9920),s=e(4705);t.exports=function(t,r){var e,f,p,l,v,h=t.target,y=t.global,d=t.stat;if(e=y?n:d?n[h]||c(h,{}):(n[h]||{}).prototype)for(f in r){if(l=r[f],p=t.dontCallGetSet?(v=o(e,f))&&v.value:e[f],!s(y?f:h+(d?".":"#")+f,t.forced)&&void 0!==p){if(typeof l==typeof p)continue;u(l,p)}(t.sham||p&&p.sham)&&i(l,"sham",!0),a(e,f,l,t)}}},7293:t=>{t.exports=function(t){try{return!!t()}catch(t){return!0}}},2104:(t,r,e)=>{var n=e(4374),o=Function.prototype,i=o.apply,a=o.call;t.exports="object"==typeof Reflect&&Reflect.apply||(n?a.bind(i):function(){return a.apply(i,arguments)})},9974:(t,r,e)=>{var n=e(1702),o=e(9662),i=e(4374),a=n(n.bind);t.exports=function(t,r){return o(t),void 0===r?t:i?a(t,r):function(){return t.apply(r,arguments)}}},4374:(t,r,e)=>{var n=e(7293);t.exports=!n((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},6916:(t,r,e)=>{var n=e(4374),o=Function.prototype.call;t.exports=n?o.bind(o):function(){return o.apply(o,arguments)}},6530:(t,r,e)=>{var n=e(9781),o=e(2597),i=Function.prototype,a=n&&Object.getOwnPropertyDescriptor,c=o(i,"name"),u=c&&"something"===function(){}.name,s=c&&(!n||n&&a(i,"name").configurable);t.exports={EXISTS:c,PROPER:u,CONFIGURABLE:s}},1702:(t,r,e)=>{var n=e(4374),o=Function.prototype,i=o.bind,a=o.call,c=n&&i.bind(a,a);t.exports=n?function(t){return t&&c(t)}:function(t){return t&&function(){return a.apply(t,arguments)}}},5005:(t,r,e)=>{var n=e(7854),o=e(614),i=function(t){return o(t)?t:void 0};t.exports=function(t,r){return arguments.length<2?i(n[t]):n[t]&&n[t][r]}},1246:(t,r,e)=>{var n=e(648),o=e(8173),i=e(8554),a=e(7497),c=e(5112)("iterator");t.exports=function(t){if(!i(t))return o(t,c)||o(t,"@@iterator")||a[n(t)]}},4121:(t,r,e)=>{var n=e(6916),o=e(9662),i=e(9670),a=e(6330),c=e(1246),u=TypeError;t.exports=function(t,r){var e=arguments.length<2?c(t):r;if(o(e))return i(n(e,t));throw u(a(t)+" is not iterable")}},8173:(t,r,e)=>{var n=e(9662),o=e(8554);t.exports=function(t,r){var e=t[r];return o(e)?void 0:n(e)}},7854:(t,r,e)=>{var n=function(t){return t&&t.Math==Math&&t};t.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof e.g&&e.g)||function(){return this}()||Function("return this")()},2597:(t,r,e)=>{var n=e(1702),o=e(7908),i=n({}.hasOwnProperty);t.exports=Object.hasOwn||function(t,r){return i(o(t),r)}},3501:t=>{t.exports={}},842:(t,r,e)=>{var n=e(7854);t.exports=function(t,r){var e=n.console;e&&e.error&&(1==arguments.length?e.error(t):e.error(t,r))}},490:(t,r,e)=>{var n=e(5005);t.exports=n("document","documentElement")},4664:(t,r,e)=>{var n=e(9781),o=e(7293),i=e(317);t.exports=!n&&!o((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},8361:(t,r,e)=>{var n=e(1702),o=e(7293),i=e(4326),a=Object,c=n("".split);t.exports=o((function(){return!a("z").propertyIsEnumerable(0)}))?function(t){return"String"==i(t)?c(t,""):a(t)}:a},9587:(t,r,e)=>{var n=e(614),o=e(111),i=e(7674);t.exports=function(t,r,e){var a,c;return i&&n(a=r.constructor)&&a!==e&&o(c=a.prototype)&&c!==e.prototype&&i(t,c),t}},2788:(t,r,e)=>{var n=e(1702),o=e(614),i=e(5465),a=n(Function.toString);o(i.inspectSource)||(i.inspectSource=function(t){return a(t)}),t.exports=i.inspectSource},8340:(t,r,e)=>{var n=e(111),o=e(8880);t.exports=function(t,r){n(r)&&"cause"in r&&o(t,"cause",r.cause)}},9909:(t,r,e)=>{var n,o,i,a=e(4811),c=e(7854),u=e(1702),s=e(111),f=e(8880),p=e(2597),l=e(5465),v=e(6200),h=e(3501),y="Object already initialized",d=c.TypeError,g=c.WeakMap;if(a||l.state){var m=l.state||(l.state=new g),b=u(m.get),x=u(m.has),w=u(m.set);n=function(t,r){if(x(m,t))throw d(y);return r.facade=t,w(m,t,r),r},o=function(t){return b(m,t)||{}},i=function(t){return x(m,t)}}else{var S=v("state");h[S]=!0,n=function(t,r){if(p(t,S))throw d(y);return r.facade=t,f(t,S,r),r},o=function(t){return p(t,S)?t[S]:{}},i=function(t){return p(t,S)}}t.exports={set:n,get:o,has:i,enforce:function(t){return i(t)?o(t):n(t,{})},getterFor:function(t){return function(r){var e;if(!s(r)||(e=o(r)).type!==t)throw d("Incompatible receiver, "+t+" required");return e}}}},7659:(t,r,e)=>{var n=e(5112),o=e(7497),i=n("iterator"),a=Array.prototype;t.exports=function(t){return void 0!==t&&(o.Array===t||a[i]===t)}},3157:(t,r,e)=>{var n=e(4326);t.exports=Array.isArray||function(t){return"Array"==n(t)}},614:t=>{t.exports=function(t){return"function"==typeof t}},4411:(t,r,e)=>{var n=e(1702),o=e(7293),i=e(614),a=e(648),c=e(5005),u=e(2788),s=function(){},f=[],p=c("Reflect","construct"),l=/^\s*(?:class|function)\b/,v=n(l.exec),h=!l.exec(s),y=function(t){if(!i(t))return!1;try{return p(s,f,t),!0}catch(t){return!1}},d=function(t){if(!i(t))return!1;switch(a(t)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return h||!!v(l,u(t))}catch(t){return!0}};d.sham=!0,t.exports=!p||o((function(){var t;return y(y.call)||!y(Object)||!y((function(){t=!0}))||t}))?d:y},4705:(t,r,e)=>{var n=e(7293),o=e(614),i=/#|\.prototype\./,a=function(t,r){var e=u[c(t)];return e==f||e!=s&&(o(r)?n(r):!!r)},c=a.normalize=function(t){return String(t).replace(i,".").toLowerCase()},u=a.data={},s=a.NATIVE="N",f=a.POLYFILL="P";t.exports=a},8554:t=>{t.exports=function(t){return null==t}},111:(t,r,e)=>{var n=e(614),o="object"==typeof document&&document.all,i=void 0===o&&void 0!==o;t.exports=i?function(t){return"object"==typeof t?null!==t:n(t)||t===o}:function(t){return"object"==typeof t?null!==t:n(t)}},1913:t=>{t.exports=!1},2190:(t,r,e)=>{var n=e(5005),o=e(614),i=e(7976),a=e(3307),c=Object;t.exports=a?function(t){return"symbol"==typeof t}:function(t){var r=n("Symbol");return o(r)&&i(r.prototype,c(t))}},408:(t,r,e)=>{var n=e(9974),o=e(6916),i=e(9670),a=e(6330),c=e(7659),u=e(6244),s=e(7976),f=e(4121),p=e(1246),l=e(9212),v=TypeError,h=function(t,r){this.stopped=t,this.result=r},y=h.prototype;t.exports=function(t,r,e){var d,g,m,b,x,w,S,O=e&&e.that,j=!(!e||!e.AS_ENTRIES),E=!(!e||!e.IS_RECORD),P=!(!e||!e.IS_ITERATOR),T=!(!e||!e.INTERRUPTED),L=n(r,O),A=function(t){return d&&l(d,"normal",t),new h(!0,t)},k=function(t){return j?(i(t),T?L(t[0],t[1],A):L(t[0],t[1])):T?L(t,A):L(t)};if(E)d=t.iterator;else if(P)d=t;else{if(!(g=p(t)))throw v(a(t)+" is not iterable");if(c(g)){for(m=0,b=u(t);b>m;m++)if((x=k(t[m]))&&s(y,x))return x;return new h(!1)}d=f(t,g)}for(w=E?t.next:d.next;!(S=o(w,d)).done;){try{x=k(S.value)}catch(t){l(d,"throw",t)}if("object"==typeof x&&x&&s(y,x))return x}return new h(!1)}},9212:(t,r,e)=>{var n=e(6916),o=e(9670),i=e(8173);t.exports=function(t,r,e){var a,c;o(t);try{if(!(a=i(t,"return"))){if("throw"===r)throw e;return e}a=n(a,t)}catch(t){c=!0,a=t}if("throw"===r)throw e;if(c)throw a;return o(a),e}},3061:(t,r,e)=>{"use strict";var n=e(3383).IteratorPrototype,o=e(30),i=e(9114),a=e(8003),c=e(7497),u=function(){return this};t.exports=function(t,r,e,s){var f=r+" Iterator";return t.prototype=o(n,{next:i(+!s,e)}),a(t,f,!1,!0),c[f]=u,t}},1656:(t,r,e)=>{"use strict";var n=e(2109),o=e(6916),i=e(1913),a=e(6530),c=e(614),u=e(3061),s=e(9518),f=e(7674),p=e(8003),l=e(8880),v=e(8052),h=e(5112),y=e(7497),d=e(3383),g=a.PROPER,m=a.CONFIGURABLE,b=d.IteratorPrototype,x=d.BUGGY_SAFARI_ITERATORS,w=h("iterator"),S="keys",O="values",j="entries",E=function(){return this};t.exports=function(t,r,e,a,h,d,P){u(e,r,a);var T,L,A,k=function(t){if(t===h&&N)return N;if(!x&&t in _)return _[t];switch(t){case S:case O:case j:return function(){return new e(this,t)}}return function(){return new e(this)}},R=r+" Iterator",C=!1,_=t.prototype,I=_[w]||_["@@iterator"]||h&&_[h],N=!x&&I||k(h),F="Array"==r&&_.entries||I;if(F&&(T=s(F.call(new t)))!==Object.prototype&&T.next&&(i||s(T)===b||(f?f(T,b):c(T[w])||v(T,w,E)),p(T,R,!0,!0),i&&(y[R]=E)),g&&h==O&&I&&I.name!==O&&(!i&&m?l(_,"name",O):(C=!0,N=function(){return o(I,this)})),h)if(L={values:k(O),keys:d?N:k(S),entries:k(j)},P)for(A in L)(x||C||!(A in _))&&v(_,A,L[A]);else n({target:r,proto:!0,forced:x||C},L);return i&&!P||_[w]===N||v(_,w,N,{name:h}),y[r]=N,L}},3383:(t,r,e)=>{"use strict";var n,o,i,a=e(7293),c=e(614),u=e(111),s=e(30),f=e(9518),p=e(8052),l=e(5112),v=e(1913),h=l("iterator"),y=!1;[].keys&&("next"in(i=[].keys())?(o=f(f(i)))!==Object.prototype&&(n=o):y=!0),!u(n)||a((function(){var t={};return n[h].call(t)!==t}))?n={}:v&&(n=s(n)),c(n[h])||p(n,h,(function(){return this})),t.exports={IteratorPrototype:n,BUGGY_SAFARI_ITERATORS:y}},7497:t=>{t.exports={}},6244:(t,r,e)=>{var n=e(7466);t.exports=function(t){return n(t.length)}},6339:(t,r,e)=>{var n=e(7293),o=e(614),i=e(2597),a=e(9781),c=e(6530).CONFIGURABLE,u=e(2788),s=e(9909),f=s.enforce,p=s.get,l=Object.defineProperty,v=a&&!n((function(){return 8!==l((function(){}),"length",{value:8}).length})),h=String(String).split("String"),y=t.exports=function(t,r,e){"Symbol("===String(r).slice(0,7)&&(r="["+String(r).replace(/^Symbol\(([^)]*)\)/,"$1")+"]"),e&&e.getter&&(r="get "+r),e&&e.setter&&(r="set "+r),(!i(t,"name")||c&&t.name!==r)&&(a?l(t,"name",{value:r,configurable:!0}):t.name=r),v&&e&&i(e,"arity")&&t.length!==e.arity&&l(t,"length",{value:e.arity});try{e&&i(e,"constructor")&&e.constructor?a&&l(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var n=f(t);return i(n,"source")||(n.source=h.join("string"==typeof r?r:"")),t};Function.prototype.toString=y((function(){return o(this)&&p(this).source||u(this)}),"toString")},4758:t=>{var r=Math.ceil,e=Math.floor;t.exports=Math.trunc||function(t){var n=+t;return(n>0?e:r)(n)}},5948:(t,r,e)=>{var n,o,i,a,c,u,s,f,p=e(7854),l=e(9974),v=e(1236).f,h=e(261).set,y=e(6833),d=e(1528),g=e(1036),m=e(5268),b=p.MutationObserver||p.WebKitMutationObserver,x=p.document,w=p.process,S=p.Promise,O=v(p,"queueMicrotask"),j=O&&O.value;j||(n=function(){var t,r;for(m&&(t=w.domain)&&t.exit();o;){r=o.fn,o=o.next;try{r()}catch(t){throw o?a():i=void 0,t}}i=void 0,t&&t.enter()},y||m||g||!b||!x?!d&&S&&S.resolve?((s=S.resolve(void 0)).constructor=S,f=l(s.then,s),a=function(){f(n)}):m?a=function(){w.nextTick(n)}:(h=l(h,p),a=function(){h(n)}):(c=!0,u=x.createTextNode(""),new b(n).observe(u,{characterData:!0}),a=function(){u.data=c=!c})),t.exports=j||function(t){var r={fn:t,next:void 0};i&&(i.next=r),o||(o=r,a()),i=r}},8523:(t,r,e)=>{"use strict";var n=e(9662),o=TypeError,i=function(t){var r,e;this.promise=new t((function(t,n){if(void 0!==r||void 0!==e)throw o("Bad Promise constructor");r=t,e=n})),this.resolve=n(r),this.reject=n(e)};t.exports.f=function(t){return new i(t)}},6277:(t,r,e)=>{var n=e(1340);t.exports=function(t,r){return void 0===t?arguments.length<2?"":r:n(t)}},30:(t,r,e)=>{var n,o=e(9670),i=e(6048),a=e(748),c=e(3501),u=e(490),s=e(317),f=e(6200)("IE_PROTO"),p=function(){},l=function(t){return"