From 9a55140802d63ae8f3f287bf1f69f8ff28efa71a Mon Sep 17 00:00:00 2001 From: Narek Zakarian Date: Mon, 20 May 2024 15:29:56 +0400 Subject: [PATCH 1/8] Allow shipping callback with subscriptions --- modules/ppcp-blocks/extensions.php | 11 +---------- modules/ppcp-button/services.php | 2 -- .../src/Endpoint/ApproveOrderEndpoint.php | 12 +----------- modules/ppcp-wc-gateway/services.php | 1 - .../src/Settings/SettingsListener.php | 19 ------------------- 5 files changed, 2 insertions(+), 43 deletions(-) diff --git a/modules/ppcp-blocks/extensions.php b/modules/ppcp-blocks/extensions.php index c2b607780..b32f5bbc6 100644 --- a/modules/ppcp-blocks/extensions.php +++ b/modules/ppcp-blocks/extensions.php @@ -51,16 +51,7 @@ return array( ); } - $subscription_helper = $container->get( 'wc-subscriptions.helper' ); - - if ( $subscription_helper->plugin_is_active() ) { - $label .= __( - '

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

', - 'woocommerce-paypal-payments' - ); - } - - $should_disable_checkbox = $subscription_helper->plugin_is_active() || apply_filters( 'woocommerce_paypal_payments_toggle_final_review_checkbox', false ); + $should_disable_checkbox = apply_filters( 'woocommerce_paypal_payments_toggle_final_review_checkbox', false ); return $insert_after( $fields, diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index 3d14c9a74..7c564d1ef 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -239,7 +239,6 @@ return array( $final_review_enabled = $container->get( 'blocks.settings.final_review_enabled' ); $wc_order_creator = $container->get( 'button.helper.wc-order-creator' ); $gateway = $container->get( 'wcgateway.paypal-gateway' ); - $subscription_helper = $container->get( 'wc-subscriptions.helper' ); $logger = $container->get( 'woocommerce.logger.woocommerce' ); return new ApproveOrderEndpoint( $request_data, @@ -252,7 +251,6 @@ return array( $final_review_enabled, $gateway, $wc_order_creator, - $subscription_helper, $logger ); }, diff --git a/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php index 9e3d43c6f..775be302e 100644 --- a/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php @@ -105,13 +105,6 @@ class ApproveOrderEndpoint implements EndpointInterface { */ protected $wc_order_creator; - /** - * The Subscription Helper. - * - * @var SubscriptionHelper - */ - protected $subscription_helper; - /** * The logger. * @@ -132,7 +125,6 @@ class ApproveOrderEndpoint implements EndpointInterface { * @param bool $final_review_enabled Whether the final review is enabled. * @param PayPalGateway $gateway The WC gateway. * @param WooCommerceOrderCreator $wc_order_creator The WooCommerce order creator. - * @param SubscriptionHelper $subscription_helper The subscription helper. * @param LoggerInterface $logger The logger. */ public function __construct( @@ -146,7 +138,6 @@ class ApproveOrderEndpoint implements EndpointInterface { bool $final_review_enabled, PayPalGateway $gateway, WooCommerceOrderCreator $wc_order_creator, - SubscriptionHelper $subscription_helper, LoggerInterface $logger ) { @@ -160,7 +151,6 @@ class ApproveOrderEndpoint implements EndpointInterface { $this->final_review_enabled = $final_review_enabled; $this->gateway = $gateway; $this->wc_order_creator = $wc_order_creator; - $this->subscription_helper = $subscription_helper; $this->logger = $logger; } @@ -247,7 +237,7 @@ class ApproveOrderEndpoint implements EndpointInterface { $this->session_handler->replace_order( $order ); - if ( ! $this->subscription_helper->plugin_is_active() && apply_filters( 'woocommerce_paypal_payments_toggle_final_review_checkbox', false ) ) { + if ( apply_filters( 'woocommerce_paypal_payments_toggle_final_review_checkbox', false ) ) { $this->toggle_final_review_enabled_setting(); } diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 9ba0021b0..f2991d9ef 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -347,7 +347,6 @@ return array( $container->get( 'api.partner_merchant_id-production' ), $container->get( 'api.partner_merchant_id-sandbox' ), $container->get( 'api.endpoint.billing-agreements' ), - $container->get( 'wc-subscriptions.helper' ), $logger ); }, diff --git a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php index 6966f97c0..68c3572c2 100644 --- a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php +++ b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php @@ -10,8 +10,6 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\WcGateway\Settings; use Psr\Log\LoggerInterface; -use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message; -use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingAgreementsEndpoint; @@ -23,9 +21,7 @@ use WooCommerce\PayPalCommerce\Onboarding\Helper\OnboardingUrl; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus; use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceProductStatus; -use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar; -use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\WooCommerce\Logging\Logger\NullLogger; /** @@ -161,13 +157,6 @@ class SettingsListener { */ private $billing_agreements_endpoint; - /** - * The subscription helper - * - * @var SubscriptionHelper - */ - protected $subscription_helper; - /** * The logger. * @@ -193,7 +182,6 @@ class SettingsListener { * @param string $partner_merchant_id_production Partner merchant ID production. * @param string $partner_merchant_id_sandbox Partner merchant ID sandbox. * @param BillingAgreementsEndpoint $billing_agreements_endpoint Billing Agreements endpoint. - * @param SubscriptionHelper $subscription_helper The subscription helper. * @param ?LoggerInterface $logger The logger. */ public function __construct( @@ -212,7 +200,6 @@ class SettingsListener { string $partner_merchant_id_production, string $partner_merchant_id_sandbox, BillingAgreementsEndpoint $billing_agreements_endpoint, - SubscriptionHelper $subscription_helper, LoggerInterface $logger = null ) { @@ -231,7 +218,6 @@ class SettingsListener { $this->partner_merchant_id_production = $partner_merchant_id_production; $this->partner_merchant_id_sandbox = $partner_merchant_id_sandbox; $this->billing_agreements_endpoint = $billing_agreements_endpoint; - $this->subscription_helper = $subscription_helper; $this->logger = $logger ?: new NullLogger(); } @@ -403,11 +389,6 @@ class SettingsListener { $this->settings->persist(); } - if ( $this->subscription_helper->plugin_is_active() ) { - $this->settings->set( 'blocks_final_review_enabled', true ); - $this->settings->persist(); - } - if ( $subscription_mode === 'disable_paypal_subscriptions' && $vault_enabled === '1' ) { $this->settings->set( 'vault_enabled', false ); $this->settings->persist(); From 1de72ed0bfd4fc67e696de9990bf87d90611929b Mon Sep 17 00:00:00 2001 From: Narek Zakarian Date: Tue, 21 May 2024 18:41:27 +0400 Subject: [PATCH 2/8] allow skipping confirmation page for subscriptions --- .../ActionHandler/CartActionHandler.js | 7 ++- modules/ppcp-button/services.php | 11 +++- .../Endpoint/ApproveSubscriptionEndpoint.php | 58 ++++++++++++++++--- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js b/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js index 2b3066395..e5c0dbac1 100644 --- a/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js +++ b/modules/ppcp-button/resources/js/modules/ActionHandler/CartActionHandler.js @@ -23,7 +23,8 @@ class CartActionHandler { body: JSON.stringify({ nonce: this.config.ajax.approve_subscription.nonce, order_id: data.orderID, - subscription_id: data.subscriptionID + subscription_id: data.subscriptionID, + should_create_wc_order: !context.config.vaultingEnabled || data.paymentSource !== 'venmo' }) }).then((res)=>{ return res.json(); @@ -33,7 +34,9 @@ class CartActionHandler { throw Error(data.data.message); } - location.href = this.config.redirect; + let orderReceivedUrl = data.data?.order_received_url + + location.href = orderReceivedUrl ? orderReceivedUrl : context.config.redirect; }); }, onError: (err) => { diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index 7c564d1ef..aa518f13f 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -258,7 +258,10 @@ return array( return new ApproveSubscriptionEndpoint( $container->get( 'button.request-data' ), $container->get( 'api.endpoint.order' ), - $container->get( 'session.handler' ) + $container->get( 'session.handler' ), + $container->get( 'blocks.settings.final_review_enabled' ), + $container->get( 'button.helper.wc-order-creator' ), + $container->get( 'wcgateway.paypal-gateway' ) ); }, 'button.checkout-form-saver' => static function ( ContainerInterface $container ): CheckoutFormSaver { @@ -360,6 +363,10 @@ return array( }, 'button.helper.wc-order-creator' => static function ( ContainerInterface $container ): WooCommerceOrderCreator { - return new WooCommerceOrderCreator( $container->get( 'wcgateway.funding-source.renderer' ), $container->get( 'session.handler' ) ); + return new WooCommerceOrderCreator( + $container->get( 'wcgateway.funding-source.renderer' ), + $container->get( 'session.handler' ), + $container->get( 'wc-subscriptions.helper' ) + ); }, ); diff --git a/modules/ppcp-button/src/Endpoint/ApproveSubscriptionEndpoint.php b/modules/ppcp-button/src/Endpoint/ApproveSubscriptionEndpoint.php index d2ca73b83..d89a0a1af 100644 --- a/modules/ppcp-button/src/Endpoint/ApproveSubscriptionEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/ApproveSubscriptionEndpoint.php @@ -11,13 +11,18 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException; +use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait; +use WooCommerce\PayPalCommerce\Button\Helper\WooCommerceOrderCreator; use WooCommerce\PayPalCommerce\Session\SessionHandler; +use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; /** * Class ApproveSubscriptionEndpoint */ class ApproveSubscriptionEndpoint implements EndpointInterface { + use ContextTrait; + const ENDPOINT = 'ppc-approve-subscription'; /** @@ -41,21 +46,51 @@ class ApproveSubscriptionEndpoint implements EndpointInterface { */ private $session_handler; + /** + * Whether the final review is enabled. + * + * @var bool + */ + protected $final_review_enabled; + + /** + * The WooCommerce order creator. + * + * @var WooCommerceOrderCreator + */ + protected $wc_order_creator; + + /** + * The WC gateway. + * + * @var PayPalGateway + */ + protected $gateway; + /** * ApproveSubscriptionEndpoint constructor. * - * @param RequestData $request_data The request data helper. - * @param OrderEndpoint $order_endpoint The order endpoint. - * @param SessionHandler $session_handler The session handler. + * @param RequestData $request_data The request data helper. + * @param OrderEndpoint $order_endpoint The order endpoint. + * @param SessionHandler $session_handler The session handler. + * @param bool $final_review_enabled Whether the final review is enabled. + * @param WooCommerceOrderCreator $wc_order_creator The WooCommerce order creator. + * @param PayPalGateway $gateway The WC gateway. */ public function __construct( RequestData $request_data, OrderEndpoint $order_endpoint, - SessionHandler $session_handler + SessionHandler $session_handler, + bool $final_review_enabled, + WooCommerceOrderCreator $wc_order_creator, + PayPalGateway $gateway ) { - $this->request_data = $request_data; - $this->order_endpoint = $order_endpoint; - $this->session_handler = $session_handler; + $this->request_data = $request_data; + $this->order_endpoint = $order_endpoint; + $this->session_handler = $session_handler; + $this->final_review_enabled = $final_review_enabled; + $this->wc_order_creator = $wc_order_creator; + $this->gateway = $gateway; } /** @@ -88,6 +123,15 @@ class ApproveSubscriptionEndpoint implements EndpointInterface { WC()->session->set( 'ppcp_subscription_id', $data['subscription_id'] ); } + $should_create_wc_order = $data['should_create_wc_order'] ?? false; + if ( ! $this->final_review_enabled && ! $this->is_checkout() && $should_create_wc_order ) { + $wc_order = $this->wc_order_creator->create_from_paypal_order( $order, WC()->cart ); + $this->gateway->process_payment( $wc_order->get_id() ); + $order_received_url = $wc_order->get_checkout_order_received_url(); + + wp_send_json_success( array( 'order_received_url' => $order_received_url ) ); + } + wp_send_json_success(); return true; } From feab77ed03b25a5d6cf21d937b7f83789f628064 Mon Sep 17 00:00:00 2001 From: Narek Zakarian Date: Tue, 21 May 2024 18:42:03 +0400 Subject: [PATCH 3/8] Create subscription order --- .../src/Helper/WooCommerceOrderCreator.php | 101 ++++++++++++++++-- 1 file changed, 93 insertions(+), 8 deletions(-) diff --git a/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php b/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php index 92f07c0fd..6f26626e3 100644 --- a/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php +++ b/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php @@ -14,12 +14,14 @@ use WC_Cart; use WC_Order; use WC_Order_Item_Product; use WC_Order_Item_Shipping; +use WC_Subscriptions_Product; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer; use WooCommerce\PayPalCommerce\ApiClient\Entity\Shipping; use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; /** * Class WooCommerceOrderCreator @@ -40,18 +42,28 @@ class WooCommerceOrderCreator { */ protected $session_handler; + /** + * The subscription helper + * + * @var SubscriptionHelper + */ + protected $subscription_helper; + /** * WooCommerceOrderCreator constructor. * * @param FundingSourceRenderer $funding_source_renderer The funding source renderer. * @param SessionHandler $session_handler The session handler. + * @param SubscriptionHelper $subscription_helper The subscription helper. */ public function __construct( FundingSourceRenderer $funding_source_renderer, - SessionHandler $session_handler + SessionHandler $session_handler, + SubscriptionHelper $subscription_helper ) { $this->funding_source_renderer = $funding_source_renderer; $this->session_handler = $session_handler; + $this->subscription_helper = $subscription_helper; } /** @@ -69,10 +81,13 @@ class WooCommerceOrderCreator { throw new RuntimeException( 'Problem creating WC order.' ); } - $this->configure_line_items( $wc_order, $wc_cart ); - $this->configure_shipping( $wc_order, $order->payer(), $order->purchase_units()[0]->shipping() ); + $payer = $order->payer(); + $shipping = $order->purchase_units()[0]->shipping(); + $this->configure_payment_source( $wc_order ); $this->configure_customer( $wc_order ); + $this->configure_line_items( $wc_order, $wc_cart, $payer, $shipping ); + $this->configure_shipping( $wc_order, $payer, $shipping ); $this->configure_coupons( $wc_order, $wc_cart->get_applied_coupons() ); $wc_order->calculate_totals(); @@ -84,11 +99,13 @@ class WooCommerceOrderCreator { /** * Configures the line items. * - * @param WC_Order $wc_order The WC order. - * @param WC_Cart $wc_cart The Cart. + * @param WC_Order $wc_order The WC order. + * @param WC_Cart $wc_cart The Cart. + * @param Payer|null $payer The payer. + * @param Shipping|null $shipping The shipping. * @return void */ - protected function configure_line_items( WC_Order $wc_order, WC_Cart $wc_cart ): void { + protected function configure_line_items( WC_Order $wc_order, WC_Cart $wc_cart, ?Payer $payer, ?Shipping $shipping ): void { $cart_contents = $wc_cart->get_cart(); foreach ( $cart_contents as $cart_item ) { @@ -111,9 +128,37 @@ class WooCommerceOrderCreator { return; } + $total = $product->get_price() * $quantity; + $item->set_name( $product->get_name() ); - $item->set_subtotal( $product->get_price() * $quantity ); - $item->set_total( $product->get_price() * $quantity ); + $item->set_subtotal( $total ); + $item->set_total( $total ); + + $product_id = $product->get_id(); + + if ( $this->is_subscription( $product_id ) ) { + $subscription = $this->create_subscription( $wc_order, $product_id ); + $sign_up_fee = WC_Subscriptions_Product::get_sign_up_fee( $product ); + $subscription_total = $total + $sign_up_fee; + + $item->set_subtotal( $subscription_total ); + $item->set_total( $subscription_total ); + + $subscription->add_product( $product ); + $this->configure_shipping( $subscription, $payer, $shipping ); + $this->configure_payment_source( $subscription ); + $this->configure_coupons( $subscription, $wc_cart->get_applied_coupons() ); + + $dates = array( + 'trial_end' => WC_Subscriptions_Product::get_trial_expiration_date( $product_id ), + 'next_payment' => WC_Subscriptions_Product::get_first_renewal_payment_date( $product_id ), + 'end' => WC_Subscriptions_Product::get_expiration_date( $product_id ), + ); + + $subscription->update_dates( $dates ); + $subscription->calculate_totals(); + $subscription->payment_complete_for_order( $wc_order ); + } $wc_order->add_item( $item ); } @@ -179,6 +224,14 @@ class WooCommerceOrderCreator { $shipping->set_method_id( $shipping_options->id() ); $shipping->set_total( $shipping_options->amount()->value_str() ); + $items = $wc_order->get_items(); + $items_in_package = array(); + foreach ( $items as $item ) { + $items_in_package[] = $item->get_name() . ' × ' . $item->get_quantity(); + } + + $shipping->add_meta_data( __( 'Items', 'woocommerce-paypal-payments' ), implode( ', ', $items_in_package ) ); + $wc_order->add_item( $shipping ); } } @@ -225,4 +278,36 @@ class WooCommerceOrderCreator { } } + /** + * Checks if the product with given ID is WC subscription. + * + * @param int $product_id The product ID. + * @return bool true if the product is subscription, otherwise false. + */ + protected function is_subscription( int $product_id ): bool { + if ( ! $this->subscription_helper->plugin_is_active() ) { + return false; + } + + return WC_Subscriptions_Product::is_subscription( $product_id ); + } + + /** + * Creates WC subscription from given order and product ID. + * + * @param WC_Order $wc_order The WC order. + * @param int $product_id The product ID. + * @return WC_Order The subscription order + */ + protected function create_subscription( WC_Order $wc_order, int $product_id ): WC_Order { + return wcs_create_subscription( + array( + 'order_id' => $wc_order->get_id(), + 'status' => 'pending', + 'billing_period' => WC_Subscriptions_Product::get_period( $product_id ), + 'billing_interval' => WC_Subscriptions_Product::get_interval( $product_id ), + 'customer_id' => $wc_order->get_customer_id(), + ) + ); + } } From c011ce659f721edb57dad880d56bc16a8bdda013 Mon Sep 17 00:00:00 2001 From: Narek Zakarian Date: Thu, 23 May 2024 19:29:33 +0400 Subject: [PATCH 4/8] Fix more than 1 shipping option selected problem --- .../ppcp-api-client/src/Factory/ShippingOptionFactory.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/ppcp-api-client/src/Factory/ShippingOptionFactory.php b/modules/ppcp-api-client/src/Factory/ShippingOptionFactory.php index 08af8c79e..3c21d4161 100644 --- a/modules/ppcp-api-client/src/Factory/ShippingOptionFactory.php +++ b/modules/ppcp-api-client/src/Factory/ShippingOptionFactory.php @@ -50,9 +50,7 @@ class ShippingOptionFactory { $cart->calculate_shipping(); $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods', array() ); - if ( ! is_array( $chosen_shipping_methods ) ) { - $chosen_shipping_methods = array(); - } + $chosen_shipping_method = $chosen_shipping_methods[0] ?? false; $packages = WC()->shipping()->get_packages(); $options = array(); @@ -62,11 +60,10 @@ class ShippingOptionFactory { if ( ! $rate instanceof \WC_Shipping_Rate ) { continue; } - $options[] = new ShippingOption( $rate->get_id(), $rate->get_label(), - in_array( $rate->get_id(), $chosen_shipping_methods, true ), + $rate->get_id() === $chosen_shipping_method, new Money( (float) $rate->get_cost(), get_woocommerce_currency() From bd745cb7d4047266426196e25326e6d1175de73b Mon Sep 17 00:00:00 2001 From: Narek Zakarian Date: Fri, 24 May 2024 18:49:10 +0400 Subject: [PATCH 5/8] Do not update shipping when subscription --- .../js/modules/Helper/ShippingHandler.js | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js b/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js index 49f45ab2d..311b8a949 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js +++ b/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js @@ -39,19 +39,21 @@ export const handleShippingOptionsChange = async (data, actions, config) => { }) } - const res = await fetch(config.ajax.update_shipping.endpoint, { - method: 'POST', - credentials: 'same-origin', - body: JSON.stringify({ - nonce: config.ajax.update_shipping.nonce, - order_id: data.orderID, - }) - }); + if (!config.data_client_id.has_subscriptions) { + const res = await fetch(config.ajax.update_shipping.endpoint, { + method: 'POST', + credentials: 'same-origin', + body: JSON.stringify({ + nonce: config.ajax.update_shipping.nonce, + order_id: data.orderID, + }) + }); - const json = await res.json(); + const json = await res.json(); - if (!json.success) { - throw new Error(json.data.message); + if (!json.success) { + throw new Error(json.data.message); + } } } catch (e) { console.error(e); @@ -104,19 +106,21 @@ export const handleShippingAddressChange = async (data, actions, config) => { }) }) - const res = await fetch(config.ajax.update_shipping.endpoint, { - method: 'POST', - credentials: 'same-origin', - body: JSON.stringify({ - nonce: config.ajax.update_shipping.nonce, - order_id: data.orderID, - }) - }); + if (!config.data_client_id.has_subscriptions) { + const res = await fetch(config.ajax.update_shipping.endpoint, { + method: 'POST', + credentials: 'same-origin', + body: JSON.stringify({ + nonce: config.ajax.update_shipping.nonce, + order_id: data.orderID, + }) + }); - const json = await res.json(); + const json = await res.json(); - if (!json.success) { - throw new Error(json.data.message); + if (!json.success) { + throw new Error(json.data.message); + } } } catch (e) { console.error(e); From 11244fa055cdd8402f535e0800e5552ea2344429 Mon Sep 17 00:00:00 2001 From: Narek Zakarian Date: Fri, 24 May 2024 18:54:44 +0400 Subject: [PATCH 6/8] Fix the tests --- tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php b/tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php index 92d3f50d1..c34146f3e 100644 --- a/tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php +++ b/tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php @@ -60,7 +60,6 @@ class SettingsListenerTest extends ModularTestCase '', '', $billing_agreement_endpoint, - $subscription_helper, $logger ); From ac42b18592e1c94f9995ffeab30a46da8e6f9400 Mon Sep 17 00:00:00 2001 From: Narek Zakarian Date: Fri, 24 May 2024 19:08:44 +0400 Subject: [PATCH 7/8] Fix the Psalm errors --- .../src/Helper/WooCommerceOrderCreator.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php b/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php index 6f26626e3..313fb5e62 100644 --- a/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php +++ b/modules/ppcp-button/src/Helper/WooCommerceOrderCreator.php @@ -14,6 +14,7 @@ use WC_Cart; use WC_Order; use WC_Order_Item_Product; use WC_Order_Item_Shipping; +use WC_Subscription; use WC_Subscriptions_Product; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer; @@ -22,6 +23,7 @@ use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; +use WP_Error; /** * Class WooCommerceOrderCreator @@ -227,7 +229,7 @@ class WooCommerceOrderCreator { $items = $wc_order->get_items(); $items_in_package = array(); foreach ( $items as $item ) { - $items_in_package[] = $item->get_name() . ' × ' . $item->get_quantity(); + $items_in_package[] = $item->get_name() . ' × ' . (string) $item->get_quantity(); } $shipping->add_meta_data( __( 'Items', 'woocommerce-paypal-payments' ), implode( ', ', $items_in_package ) ); @@ -297,10 +299,11 @@ class WooCommerceOrderCreator { * * @param WC_Order $wc_order The WC order. * @param int $product_id The product ID. - * @return WC_Order The subscription order + * @return WC_Subscription The subscription order + * @throws RuntimeException If problem creating. */ - protected function create_subscription( WC_Order $wc_order, int $product_id ): WC_Order { - return wcs_create_subscription( + protected function create_subscription( WC_Order $wc_order, int $product_id ): WC_Subscription { + $subscription = wcs_create_subscription( array( 'order_id' => $wc_order->get_id(), 'status' => 'pending', @@ -309,5 +312,11 @@ class WooCommerceOrderCreator { 'customer_id' => $wc_order->get_customer_id(), ) ); + + if ( $subscription instanceof WP_Error ) { + throw new RuntimeException( $subscription->get_error_message() ); + } + + return $subscription; } } From 4967c472e7b48399de8e05d5309f917ee377f68e Mon Sep 17 00:00:00 2001 From: Narek Zakarian Date: Mon, 3 Jun 2024 15:27:01 +0400 Subject: [PATCH 8/8] Update the shipping option for subscriptions on address change --- .../ppcp-blocks/resources/js/checkout-block.js | 15 +++++++++++++++ .../js/modules/Helper/ShippingHandler.js | 2 -- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/modules/ppcp-blocks/resources/js/checkout-block.js b/modules/ppcp-blocks/resources/js/checkout-block.js index df003f494..9ac471352 100644 --- a/modules/ppcp-blocks/resources/js/checkout-block.js +++ b/modules/ppcp-blocks/resources/js/checkout-block.js @@ -391,6 +391,21 @@ const PayPalComponent = ({ await shippingData.setShippingAddress(address); + const res = await fetch(config.ajax.update_shipping.endpoint, { + method: 'POST', + credentials: 'same-origin', + body: JSON.stringify({ + nonce: config.ajax.update_shipping.nonce, + order_id: data.orderID, + }) + }); + + const json = await res.json(); + + if (!json.success) { + throw new Error(json.data.message); + } + } catch (e) { console.error(e); diff --git a/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js b/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js index 311b8a949..c67bee5bb 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js +++ b/modules/ppcp-button/resources/js/modules/Helper/ShippingHandler.js @@ -106,7 +106,6 @@ export const handleShippingAddressChange = async (data, actions, config) => { }) }) - if (!config.data_client_id.has_subscriptions) { const res = await fetch(config.ajax.update_shipping.endpoint, { method: 'POST', credentials: 'same-origin', @@ -121,7 +120,6 @@ export const handleShippingAddressChange = async (data, actions, config) => { if (!json.success) { throw new Error(json.data.message); } - } } catch (e) { console.error(e);