Add 3ds redirect handling

This commit is contained in:
Daniel Dudzic 2025-06-20 14:13:00 +02:00
parent fa047772c3
commit 30a933f2df
No known key found for this signature in database
GPG key ID: 31B40D33E3465483
8 changed files with 280 additions and 20 deletions

View file

@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Axo;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Authentication\SdkClientToken;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\Axo\Assets\AxoManager;
@ -19,6 +20,7 @@ use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\Settings\Data\SettingsModel;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExecutableModule;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExtendingModule;
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait;
@ -367,6 +369,43 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule {
}
);
// Trigger 3D Secure verification.
add_filter(
'ppcp_create_order_request_body_data',
function( array $data, string $payment_method ) use ( $c ): array {
if ( ! $c->get( 'axo.uk.enabled' ) ) {
return $data;
}
$logger = $c->get( 'woocommerce.logger.woocommerce' );
assert( $logger instanceof LoggerInterface );
if ( $payment_method !== AxoGateway::ID ) {
return $data;
}
$settings_model = $c->get( 'settings.data.settings' );
assert( $settings_model instanceof SettingsModel );
$three_d_secure = $settings_model->get_three_d_secure_enum();
if (
$three_d_secure === 'SCA_ALWAYS'
|| $three_d_secure === 'SCA_WHEN_REQUIRED'
) {
$data['payment_source']['card']->attributes = array(
'verification' => array(
'method' => $three_d_secure,
),
);
}
return $data;
},
10,
2
);
return true;
}

View file

@ -253,6 +253,49 @@ class AxoGateway extends WC_Payment_Gateway {
$order = $this->create_paypal_order( $wc_order, $token );
// Check if 3DS verification is required
$payer_action = '';
foreach ( $order->links() as $link ) {
if ( $link->rel === 'payer-action' ) {
$payer_action = $link->href;
}
}
$this->logger->debug(
'AXO order created',
array(
'result' => 'success',
'return_url' => $this->get_return_url( $wc_order ),
'payer_action' => $payer_action,
)
);
// If 3DS verification is required, append the redirect_uri and return the redirect URL
$this->logger->debug(
'AXO order created',
array(
'result' => 'success',
'return_url' => $this->get_return_url( $wc_order ),
'payer_action' => $payer_action,
)
);
// If 3DS verification is required, append the redirect_uri and return the redirect URL
if ( $payer_action ) {
$return_url = $this->get_return_url( $wc_order );
$redirect_url = add_query_arg(
'redirect_uri',
urlencode( $return_url ),
$payer_action
);
return array(
'result' => 'success',
'redirect' => $redirect_url,
);
}
/**
* This filter controls if the method 'process()' from OrderProcessor will be called.
* So you can implement your own for example on subscriptions
@ -286,6 +329,7 @@ class AxoGateway extends WC_Payment_Gateway {
* @return Order The PayPal order.
*/
protected function create_paypal_order( WC_Order $wc_order, string $payment_token ) : Order {
$purchase_unit = $this->purchase_unit_factory->from_wc_order( $wc_order );
$shipping_preference = $this->shipping_preference_factory->from_state(
@ -302,11 +346,20 @@ class AxoGateway extends WC_Payment_Gateway {
$payment_source_properties
);
$this->logger->debug(
'AXO full order endpoint data',
array(
'purchase_unit' => $purchase_unit,
'shipping_preference' => $shipping_preference,
'payment_source' => $payment_source,
)
);
return $this->order_endpoint->create(
array( $purchase_unit ),
$shipping_preference,
null,
'',
self::ID,
array(),
$payment_source
);