mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 13:44:42 +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 Exception;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||||
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
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 ) {
|
// This check will either pass, or throw an exception.
|
||||||
throw new RuntimeException(
|
$this->verify_three_d_secure( $order );
|
||||||
__(
|
|
||||||
'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->session_handler->replace_order( $order );
|
$this->session_handler->replace_order( $order );
|
||||||
|
|
||||||
|
// Exit the request early.
|
||||||
wp_send_json_success();
|
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(
|
$message = sprintf(
|
||||||
// translators: %s is the id of the order.
|
// translators: %s is the id of the order.
|
||||||
__( 'Order %s is not ready for processing yet.', 'woocommerce-paypal-payments' ),
|
__( '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->set( 'blocks_final_review_enabled', ! $final_review_enabled_setting );
|
||||||
$this->settings->persist();
|
$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