pcp-37 / return to checkout after three times trying but returned with insufficient funds error

This commit is contained in:
David Remer 2020-09-02 08:43:41 +03:00
parent ae12409454
commit 00389dac84
6 changed files with 54 additions and 5 deletions

View file

@ -32,6 +32,14 @@ class SessionHandler {
*/
private $bn_code = '';
/**
* If PayPal respondes with INSTRUMENT_DECLINED, we only
* want to go max. three times through the process of trying again.
*
* @var int
*/
private $insufficient_funding_tries = 0;
/**
* Returns the order.
*
@ -76,14 +84,35 @@ class SessionHandler {
return $this;
}
/**
* Returns how many times the customer tried to use the PayPal Gateway in this session.
*
* @return int
*/
public function insufficient_funding_tries() : int {
return $this->insufficient_funding_tries;
}
/**
* Increments the number of tries, the customer has done in this session.
*
* @return SessionHandler
*/
public function increment_insufficient_funding_tries() : SessionHandler {
$this->insufficient_funding_tries++;
$this->store_session();
return $this;
}
/**
* Destroys the session data.
*
* @return SessionHandler
*/
public function destroy_session_data() : SessionHandler {
$this->order = null;
$this->bn_code = '';
$this->order = null;
$this->bn_code = '';
$this->insufficient_funding_tries = 0;
$this->store_session();
return $this;
}

View file

@ -77,6 +77,14 @@ class ReturnUrlEndpoint {
$success = $this->gateway->process_payment( $wc_order_id );
if ( isset( $success['result'] ) && 'success' === $success['result'] ) {
add_filter(
'allowed_redirect_hosts',
function( $allowed_hosts ) : array {
$allowed_hosts[] = 'www.paypal.com';
$allowed_hosts[] = 'www.sandbox.paypal.com';
return (array) $allowed_hosts;
}
);
wp_safe_redirect( $success['redirect'] );
exit();
}

View file

@ -184,6 +184,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
*/
//phpcs:disable WordPress.Security.NonceVerification.Recommended
if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wc_order->has_status( 'processing' ) ) {
$this->session_handler->destroy_session_data();
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $wc_order ),
@ -193,6 +194,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
try {
if ( $this->order_processor->process( $wc_order, $woocommerce ) ) {
$this->session_handler->destroy_session_data();
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $wc_order ),
@ -200,10 +202,18 @@ class PayPalGateway extends \WC_Payment_Gateway {
}
} catch ( PayPalApiException $error ) {
if ( $error->has_detail( 'INSTRUMENT_DECLINED' ) ) {
$this->session_handler->increment_insufficient_funding_tries();
$host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ?
'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/';
$url = $host . 'checkoutnow?token=' . $this->session_handler->order()->id();
if ( $this->session_handler->insufficient_funding_tries() >= 3 ) {
$this->session_handler->destroy_session_data();
wc_add_notice(
__( 'Please use a different payment method.', 'paypal-for-woocommerce' ),
'error'
);
return null;
}
return array(
'result' => 'success',
'redirect' => $url,

View file

@ -131,7 +131,7 @@ class OrderProcessor {
*/
public function process( \WC_Order $wc_order, \WooCommerce $woocommerce ): bool {
$order = $this->session_handler->order();
if (! $order) {
if ( ! $order ) {
return false;
}
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );