From 279a3452c8927b16ff46a5841e75c83c3cc88b08 Mon Sep 17 00:00:00 2001 From: "Alex P." Date: Thu, 29 May 2025 16:34:25 +0300 Subject: [PATCH] Use ExperienceContext for PayPal buttons --- .../src/Endpoint/OrderEndpoint.php | 6 ++-- .../src/Factory/ExperienceContextBuilder.php | 26 +++++++++++++++++ modules/ppcp-button/services.php | 1 + .../src/Endpoint/CreateOrderEndpoint.php | 28 +++++++++++++++++-- .../Endpoint/CreateOrderEndpointTest.php | 3 ++ 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php b/modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php index 4bf9fe9ca..97d7dc7b9 100644 --- a/modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php +++ b/modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php @@ -196,8 +196,8 @@ class OrderEndpoint { ): Order { $bearer = $this->bearer->bearer(); $data = array( - 'intent' => apply_filters( 'woocommerce_paypal_payments_order_intent', $this->intent ), - 'purchase_units' => array_map( + 'intent' => apply_filters( 'woocommerce_paypal_payments_order_intent', $this->intent ), + 'purchase_units' => array_map( static function ( PurchaseUnit $item ) use ( $shipping_preference ): array { $data = $item->to_array(); @@ -210,8 +210,6 @@ class OrderEndpoint { }, $items ), - 'application_context' => $this->application_context_repository - ->current_context( $shipping_preference, $user_action )->to_array(), ); if ( $payer && ! empty( $payer->email_address() ) ) { $data['payer'] = $payer->to_array(); diff --git a/modules/ppcp-api-client/src/Factory/ExperienceContextBuilder.php b/modules/ppcp-api-client/src/Factory/ExperienceContextBuilder.php index 1cd229896..200f7c35c 100644 --- a/modules/ppcp-api-client/src/Factory/ExperienceContextBuilder.php +++ b/modules/ppcp-api-client/src/Factory/ExperienceContextBuilder.php @@ -41,6 +41,32 @@ class ExperienceContextBuilder { $this->settings = $settings; } + /** + * Uses the default config for the PayPal buttons. + * + * @param string $shipping_preference One of the ExperienceContext::SHIPPING_PREFERENCE_* values. + * @param string $user_action One of the ExperienceContext::USER_ACTION_* values. + */ + public function with_default_paypal_config( + string $shipping_preference = ExperienceContext::SHIPPING_PREFERENCE_NO_SHIPPING, + string $user_action = ExperienceContext::USER_ACTION_CONTINUE + ): ExperienceContextBuilder { + $builder = clone $this; + + $builder = $builder + ->with_current_locale() + ->with_current_brand_name() + ->with_current_landing_page() + ->with_current_payment_method_preference() + ->with_endpoint_return_urls(); + + $builder->experience_context = $builder->experience_context + ->with_shipping_preference( $shipping_preference ) + ->with_user_action( $user_action ); + + return $builder; + } + /** * Uses the ReturnUrlEndpoint return URL. */ diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index 18d9e27e4..5c6efa35e 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -227,6 +227,7 @@ return array( $request_data, $purchase_unit_factory, $container->get( 'api.factory.shipping-preference' ), + $container->get( 'wcgateway.builder.experience-context' ), $order_endpoint, $payer_factory, $session_handler, diff --git a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php index 99abdb614..430440543 100644 --- a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php @@ -19,9 +19,11 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext; use WooCommerce\PayPalCommerce\ApiClient\Entity\Money; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer; +use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource; use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; +use WooCommerce\PayPalCommerce\ApiClient\Factory\ExperienceContextBuilder; use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory; @@ -66,6 +68,11 @@ class CreateOrderEndpoint implements EndpointInterface { */ private $shipping_preference_factory; + /** + * The ExperienceContextBuilder. + */ + private ExperienceContextBuilder $experience_context_builder; + /** * The order endpoint. * @@ -177,6 +184,7 @@ class CreateOrderEndpoint implements EndpointInterface { * @param RequestData $request_data The RequestData object. * @param PurchaseUnitFactory $purchase_unit_factory The PurchaseUnit factory. * @param ShippingPreferenceFactory $shipping_preference_factory The shipping_preference factory. + * @param ExperienceContextBuilder $experience_context_builder The ExperienceContextBuilder. * @param OrderEndpoint $order_endpoint The OrderEndpoint object. * @param PayerFactory $payer_factory The PayerFactory object. * @param SessionHandler $session_handler The SessionHandler object. @@ -194,6 +202,7 @@ class CreateOrderEndpoint implements EndpointInterface { RequestData $request_data, PurchaseUnitFactory $purchase_unit_factory, ShippingPreferenceFactory $shipping_preference_factory, + ExperienceContextBuilder $experience_context_builder, OrderEndpoint $order_endpoint, PayerFactory $payer_factory, SessionHandler $session_handler, @@ -211,6 +220,7 @@ class CreateOrderEndpoint implements EndpointInterface { $this->request_data = $request_data; $this->purchase_unit_factory = $purchase_unit_factory; $this->shipping_preference_factory = $shipping_preference_factory; + $this->experience_context_builder = $experience_context_builder; $this->api_endpoint = $order_endpoint; $this->payer_factory = $payer_factory; $this->session_handler = $session_handler; @@ -475,6 +485,15 @@ class CreateOrderEndpoint implements EndpointInterface { } } + $payment_source = new PaymentSource( + 'paypal', + (object) array( + 'experience_context' => $this->experience_context_builder + ->with_default_paypal_config( $shipping_preference, $action ) + ->build()->to_array(), + ) + ); + try { return $this->api_endpoint->create( array( $this->purchase_unit ), @@ -482,7 +501,8 @@ class CreateOrderEndpoint implements EndpointInterface { $payer, $action, $payment_method, - $data + $data, + $payment_source ); } catch ( PayPalApiException $exception ) { // Looks like currently there is no proper way to validate the shipping address for PayPal, @@ -502,7 +522,11 @@ class CreateOrderEndpoint implements EndpointInterface { return $this->api_endpoint->create( array( $this->purchase_unit ), $shipping_preference, - $payer + $payer, + $action, + $payment_method, + $data, + $payment_source ); } diff --git a/tests/PHPUnit/Button/Endpoint/CreateOrderEndpointTest.php b/tests/PHPUnit/Button/Endpoint/CreateOrderEndpointTest.php index 79f80de3f..22df8c5c5 100644 --- a/tests/PHPUnit/Button/Endpoint/CreateOrderEndpointTest.php +++ b/tests/PHPUnit/Button/Endpoint/CreateOrderEndpointTest.php @@ -8,6 +8,7 @@ use Mockery; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; use ReflectionClass; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; +use WooCommerce\PayPalCommerce\ApiClient\Factory\ExperienceContextBuilder; use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory; @@ -147,6 +148,7 @@ class CreateOrderEndpointTest extends TestCase { $request_data = Mockery::mock(RequestData::class); $shippingPreferenceFactory = Mockery::mock(ShippingPreferenceFactory::class); + $experienceContextBuilder = Mockery::mock(ExperienceContextBuilder::class); $purchase_unit_factory = Mockery::mock(PurchaseUnitFactory::class); $order_endpoint = Mockery::mock(OrderEndpoint::class); $payer_factory = Mockery::mock(PayerFactory::class); @@ -159,6 +161,7 @@ class CreateOrderEndpointTest extends TestCase $request_data, $purchase_unit_factory, $shippingPreferenceFactory, + $experienceContextBuilder, $order_endpoint, $payer_factory, $session_handler,