Use ExperienceContext for PayPal buttons

This commit is contained in:
Alex P. 2025-05-29 16:34:25 +03:00
parent c19b89ed5b
commit 279a3452c8
No known key found for this signature in database
GPG key ID: 54487A734A204D71
5 changed files with 58 additions and 6 deletions

View file

@ -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();

View file

@ -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.
*/

View file

@ -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,

View file

@ -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
);
}

View file

@ -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,