mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 10:55:00 +08:00
♻️ Extract the 3DS check into a new method
This commit is contained in:
parent
8153026e22
commit
4f420a2f8a
1 changed files with 82 additions and 18 deletions
|
@ -13,6 +13,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
|
|||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
|
@ -199,29 +200,23 @@ class ApproveOrderEndpoint implements EndpointInterface {
|
|||
);
|
||||
}
|
||||
}
|
||||
$proceed = $this->threed_secure->proceed_with_order( $order );
|
||||
if ( ThreeDSecure::RETRY === $proceed ) {
|
||||
throw new RuntimeException(
|
||||
__(
|
||||
'Something went wrong. Please try again.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
}
|
||||
if ( ThreeDSecure::REJECT === $proceed ) {
|
||||
throw new RuntimeException(
|
||||
__(
|
||||
'Unfortunately, we can\'t accept your card. Please choose a different payment method.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// This check will either pass, or throw an exception.
|
||||
$this->verify_three_d_secure( $order );
|
||||
|
||||
$this->session_handler->replace_order( $order );
|
||||
|
||||
// Exit the request early.
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
if ( $this->order_helper->contains_physical_goods( $order ) && ! $order->status()->is( OrderStatus::APPROVED ) && ! $order->status()->is( OrderStatus::CREATED ) ) {
|
||||
// Verify 3DS details. Throws an error when security check fails.
|
||||
$this->verify_three_d_secure( $order );
|
||||
|
||||
$is_ready = $order->status()->is( OrderStatus::APPROVED )
|
||||
|| $order->status()->is( OrderStatus::CREATED );
|
||||
|
||||
if ( ! $is_ready && $this->order_helper->contains_physical_goods( $order ) ) {
|
||||
$message = sprintf(
|
||||
// translators: %s is the id of the order.
|
||||
__( 'Order %s is not ready for processing yet.', 'woocommerce-paypal-payments' ),
|
||||
|
@ -279,4 +274,73 @@ class ApproveOrderEndpoint implements EndpointInterface {
|
|||
$this->settings->set( 'blocks_final_review_enabled', ! $final_review_enabled_setting );
|
||||
$this->settings->persist();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a 3DS check to verify the payment is not rejected from PayPal side.
|
||||
*
|
||||
* This method only checks, if the payment was rejected:
|
||||
*
|
||||
* - No 3DS details are present: The payment can proceed.
|
||||
* - 3DS details present but no rejected: Payment can proceed.
|
||||
* - 3DS details with a clear rejected: Payment fails.
|
||||
*
|
||||
* @param Order $order The PayPal order to inspect.
|
||||
* @throws RuntimeException When the 3DS check was rejected.
|
||||
*/
|
||||
protected function verify_three_d_secure( Order $order ) : void {
|
||||
$payment_source = $order->payment_source();
|
||||
|
||||
if ( ! $payment_source ) {
|
||||
// Missing 3DS details.
|
||||
return;
|
||||
}
|
||||
|
||||
$proceed = ThreeDSecure::NO_DECISION;
|
||||
$order_status = $order->status();
|
||||
$source_name = $payment_source->name();
|
||||
|
||||
/**
|
||||
* For GooglePay (and possibly other payment sources) we check the order
|
||||
* status, as it will clearly indicate if verification is needed.
|
||||
*
|
||||
* Note: PayPal is currently investigating this case.
|
||||
* Maybe the order status is wrong and should be ACCEPTED, in that case,
|
||||
* we could drop the condition and always run proceed_with_order().
|
||||
*/
|
||||
if ( $order_status->is( OrderStatus::PAYER_ACTION_REQUIRED ) ) {
|
||||
$proceed = $this->threed_secure->proceed_with_order( $order );
|
||||
} elseif ( 'card' === $source_name ) {
|
||||
// For credit cards, we also check the 3DS response.
|
||||
$proceed = $this->threed_secure->proceed_with_order( $order );
|
||||
}
|
||||
|
||||
// Handle the verification result based on the proceed value.
|
||||
switch ( $proceed ) {
|
||||
case ThreeDSecure::PROCCEED:
|
||||
// Check was successful.
|
||||
return;
|
||||
|
||||
case ThreeDSecure::NO_DECISION:
|
||||
// No rejection. Let's proceed with the payment.
|
||||
return;
|
||||
|
||||
case ThreeDSecure::RETRY:
|
||||
// Rejection case 1, verification can be retried.
|
||||
throw new RuntimeException(
|
||||
__(
|
||||
'Something went wrong. Please try again.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
|
||||
case ThreeDSecure::REJECT:
|
||||
// Rejection case 2, payment was rejected.
|
||||
throw new RuntimeException(
|
||||
__(
|
||||
'Unfortunately, we can\'t accept your card. Please choose a different payment method.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue