mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 18:16:38 +08:00
Use continuation mode when APM does not redirect back
This commit is contained in:
parent
8a6437b558
commit
e29ef9c7d6
7 changed files with 105 additions and 16 deletions
|
@ -125,6 +125,7 @@ return array(
|
||||||
$container->get( 'button.basic-checkout-validation-enabled' ),
|
$container->get( 'button.basic-checkout-validation-enabled' ),
|
||||||
$container->get( 'button.early-wc-checkout-validation-enabled' ),
|
$container->get( 'button.early-wc-checkout-validation-enabled' ),
|
||||||
$container->get( 'button.pay-now-contexts' ),
|
$container->get( 'button.pay-now-contexts' ),
|
||||||
|
$container->get( 'wcgateway.funding-sources-without-redirect' ),
|
||||||
$container->get( 'woocommerce.logger.woocommerce' )
|
$container->get( 'woocommerce.logger.woocommerce' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -176,6 +177,7 @@ return array(
|
||||||
$container->get( 'button.early-wc-checkout-validation-enabled' ),
|
$container->get( 'button.early-wc-checkout-validation-enabled' ),
|
||||||
$container->get( 'button.pay-now-contexts' ),
|
$container->get( 'button.pay-now-contexts' ),
|
||||||
$container->get( 'button.handle-shipping-in-paypal' ),
|
$container->get( 'button.handle-shipping-in-paypal' ),
|
||||||
|
$container->get( 'wcgateway.funding-sources-without-redirect' ),
|
||||||
$logger
|
$logger
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -152,6 +152,13 @@ class CreateOrderEndpoint implements EndpointInterface {
|
||||||
*/
|
*/
|
||||||
private $handle_shipping_in_paypal;
|
private $handle_shipping_in_paypal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
private $funding_sources_without_redirect;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger.
|
* The logger.
|
||||||
*
|
*
|
||||||
|
@ -175,6 +182,7 @@ class CreateOrderEndpoint implements EndpointInterface {
|
||||||
* @param bool $early_validation_enabled Whether to execute WC validation of the checkout form.
|
* @param bool $early_validation_enabled Whether to execute WC validation of the checkout form.
|
||||||
* @param string[] $pay_now_contexts The contexts that should have the Pay Now button.
|
* @param string[] $pay_now_contexts The contexts that should have the Pay Now button.
|
||||||
* @param bool $handle_shipping_in_paypal If true, the shipping methods are sent to PayPal allowing the customer to select it inside the popup.
|
* @param bool $handle_shipping_in_paypal If true, the shipping methods are sent to PayPal allowing the customer to select it inside the popup.
|
||||||
|
* @param string[] $funding_sources_without_redirect The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back.
|
||||||
* @param LoggerInterface $logger The logger.
|
* @param LoggerInterface $logger The logger.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
@ -191,23 +199,25 @@ class CreateOrderEndpoint implements EndpointInterface {
|
||||||
bool $early_validation_enabled,
|
bool $early_validation_enabled,
|
||||||
array $pay_now_contexts,
|
array $pay_now_contexts,
|
||||||
bool $handle_shipping_in_paypal,
|
bool $handle_shipping_in_paypal,
|
||||||
|
array $funding_sources_without_redirect,
|
||||||
LoggerInterface $logger
|
LoggerInterface $logger
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$this->request_data = $request_data;
|
$this->request_data = $request_data;
|
||||||
$this->purchase_unit_factory = $purchase_unit_factory;
|
$this->purchase_unit_factory = $purchase_unit_factory;
|
||||||
$this->shipping_preference_factory = $shipping_preference_factory;
|
$this->shipping_preference_factory = $shipping_preference_factory;
|
||||||
$this->api_endpoint = $order_endpoint;
|
$this->api_endpoint = $order_endpoint;
|
||||||
$this->payer_factory = $payer_factory;
|
$this->payer_factory = $payer_factory;
|
||||||
$this->session_handler = $session_handler;
|
$this->session_handler = $session_handler;
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->early_order_handler = $early_order_handler;
|
$this->early_order_handler = $early_order_handler;
|
||||||
$this->registration_needed = $registration_needed;
|
$this->registration_needed = $registration_needed;
|
||||||
$this->card_billing_data_mode = $card_billing_data_mode;
|
$this->card_billing_data_mode = $card_billing_data_mode;
|
||||||
$this->early_validation_enabled = $early_validation_enabled;
|
$this->early_validation_enabled = $early_validation_enabled;
|
||||||
$this->pay_now_contexts = $pay_now_contexts;
|
$this->pay_now_contexts = $pay_now_contexts;
|
||||||
$this->handle_shipping_in_paypal = $handle_shipping_in_paypal;
|
$this->handle_shipping_in_paypal = $handle_shipping_in_paypal;
|
||||||
$this->logger = $logger;
|
$this->funding_sources_without_redirect = $funding_sources_without_redirect;
|
||||||
|
$this->logger = $logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -288,6 +298,11 @@ class CreateOrderEndpoint implements EndpointInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'checkout' === $data['context'] ) {
|
if ( 'checkout' === $data['context'] ) {
|
||||||
|
if ( ! in_array( $funding_source, $this->funding_sources_without_redirect, true ) ) {
|
||||||
|
$this->session_handler->replace_order( $order );
|
||||||
|
$this->session_handler->replace_funding_source( $funding_source );
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
! $this->early_order_handler->should_create_early_order()
|
! $this->early_order_handler->should_create_early_order()
|
||||||
|| $this->registration_needed
|
|| $this->registration_needed
|
||||||
|
|
|
@ -9,6 +9,8 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace WooCommerce\PayPalCommerce\Button\Helper;
|
namespace WooCommerce\PayPalCommerce\Button\Helper;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||||
|
|
||||||
trait ContextTrait {
|
trait ContextTrait {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,6 +58,12 @@ trait ContextTrait {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! $order->status()->is( OrderStatus::APPROVED )
|
||||||
|
&& ! $order->status()->is( OrderStatus::COMPLETED )
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$source = $order->payment_source();
|
$source = $order->payment_source();
|
||||||
if ( $source && $source->card() ) {
|
if ( $source && $source->card() ) {
|
||||||
return false; // Ignore for DCC.
|
return false; // Ignore for DCC.
|
||||||
|
|
|
@ -55,6 +55,8 @@ class SessionHandler {
|
||||||
public function order() {
|
public function order() {
|
||||||
$this->load_session();
|
$this->load_session();
|
||||||
|
|
||||||
|
do_action( 'ppcp_session_get_order', $this->order, $this );
|
||||||
|
|
||||||
return $this->order;
|
return $this->order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,11 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace WooCommerce\PayPalCommerce\Session;
|
namespace WooCommerce\PayPalCommerce\Session;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Throwable;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||||
use WooCommerce\PayPalCommerce\Session\Cancellation\CancelController;
|
use WooCommerce\PayPalCommerce\Session\Cancellation\CancelController;
|
||||||
|
@ -19,6 +24,12 @@ use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
* Class SessionModule
|
* Class SessionModule
|
||||||
*/
|
*/
|
||||||
class SessionModule implements ModuleInterface {
|
class SessionModule implements ModuleInterface {
|
||||||
|
/**
|
||||||
|
* A flag to avoid multiple requests to reload order.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $reloaded_order = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
|
@ -46,6 +57,45 @@ class SessionModule implements ModuleInterface {
|
||||||
$controller->run();
|
$controller->run();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_action(
|
||||||
|
'ppcp_session_get_order',
|
||||||
|
function ( ?Order $order, SessionHandler $session_handler ) use ( $c ): void {
|
||||||
|
if ( ! isset( WC()->session ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->reloaded_order ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $order ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $order->status()->is( OrderStatus::APPROVED )
|
||||||
|
|| $order->status()->is( OrderStatus::COMPLETED )
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$order_endpoint = $c->get( 'api.endpoint.order' );
|
||||||
|
assert( $order_endpoint instanceof OrderEndpoint );
|
||||||
|
|
||||||
|
$this->reloaded_order = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$session_handler->replace_order( $order_endpoint->order( $order->id() ) );
|
||||||
|
} catch ( Throwable $exception ) {
|
||||||
|
$logger = $c->get( 'woocommerce.logger.woocommerce' );
|
||||||
|
assert( $logger instanceof LoggerInterface );
|
||||||
|
|
||||||
|
$logger->warning( 'Failed to reload PayPal order in the session: ' . $exception->getMessage() );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
10,
|
||||||
|
2
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -903,6 +903,12 @@ return array(
|
||||||
'paylater' => _x( 'Pay Later', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
'paylater' => _x( 'Pay Later', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back.
|
||||||
|
*/
|
||||||
|
'wcgateway.funding-sources-without-redirect' => static function( ContainerInterface $container ): array {
|
||||||
|
return array( 'paypal', 'paylater', 'venmo', 'card' );
|
||||||
|
},
|
||||||
'wcgateway.settings.funding-sources' => static function( ContainerInterface $container ): array {
|
'wcgateway.settings.funding-sources' => static function( ContainerInterface $container ): array {
|
||||||
return array_diff_key(
|
return array_diff_key(
|
||||||
$container->get( 'wcgateway.all-funding-sources' ),
|
$container->get( 'wcgateway.all-funding-sources' ),
|
||||||
|
|
|
@ -13,6 +13,7 @@ use Exception;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use WC_Order;
|
use WC_Order;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||||
|
@ -253,8 +254,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
|
|
||||||
$funding_source = $this->session_handler->funding_source();
|
$funding_source = $this->session_handler->funding_source();
|
||||||
if ( $funding_source ) {
|
if ( $funding_source ) {
|
||||||
$this->title = $this->funding_source_renderer->render_name( $funding_source );
|
$order = $this->session_handler->order();
|
||||||
$this->description = $this->funding_source_renderer->render_description( $funding_source );
|
if ( $order &&
|
||||||
|
( $order->status()->is( OrderStatus::APPROVED ) || $order->status()->is( OrderStatus::COMPLETED ) )
|
||||||
|
) {
|
||||||
|
$this->title = $this->funding_source_renderer->render_name( $funding_source );
|
||||||
|
$this->description = $this->funding_source_renderer->render_description( $funding_source );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->init_form_fields();
|
$this->init_form_fields();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue