mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-05 08:59:14 +08:00
pcp-37 / return to checkout after three times trying but returned with insufficient funds error
This commit is contained in:
parent
ae12409454
commit
00389dac84
6 changed files with 54 additions and 5 deletions
2
.github/workflows/php.yml
vendored
2
.github/workflows/php.yml
vendored
|
@ -29,4 +29,4 @@ jobs:
|
||||||
- name: Run test suite
|
- name: Run test suite
|
||||||
run: ./vendor/bin/phpunit
|
run: ./vendor/bin/phpunit
|
||||||
- name: Run Woocommerce coding standards
|
- name: Run Woocommerce coding standards
|
||||||
run: ./vendor/bin/phpcs src inc modules --extensions=php
|
run: ./vendor/bin/phpcs src modules --extensions=php
|
||||||
|
|
|
@ -32,6 +32,14 @@ class SessionHandler {
|
||||||
*/
|
*/
|
||||||
private $bn_code = '';
|
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.
|
* Returns the order.
|
||||||
*
|
*
|
||||||
|
@ -76,14 +84,35 @@ class SessionHandler {
|
||||||
return $this;
|
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.
|
* Destroys the session data.
|
||||||
*
|
*
|
||||||
* @return SessionHandler
|
* @return SessionHandler
|
||||||
*/
|
*/
|
||||||
public function destroy_session_data() : SessionHandler {
|
public function destroy_session_data() : SessionHandler {
|
||||||
$this->order = null;
|
$this->order = null;
|
||||||
$this->bn_code = '';
|
$this->bn_code = '';
|
||||||
|
$this->insufficient_funding_tries = 0;
|
||||||
$this->store_session();
|
$this->store_session();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,14 @@ class ReturnUrlEndpoint {
|
||||||
|
|
||||||
$success = $this->gateway->process_payment( $wc_order_id );
|
$success = $this->gateway->process_payment( $wc_order_id );
|
||||||
if ( isset( $success['result'] ) && 'success' === $success['result'] ) {
|
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'] );
|
wp_safe_redirect( $success['redirect'] );
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
*/
|
*/
|
||||||
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wc_order->has_status( 'processing' ) ) {
|
if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wc_order->has_status( 'processing' ) ) {
|
||||||
|
$this->session_handler->destroy_session_data();
|
||||||
return array(
|
return array(
|
||||||
'result' => 'success',
|
'result' => 'success',
|
||||||
'redirect' => $this->get_return_url( $wc_order ),
|
'redirect' => $this->get_return_url( $wc_order ),
|
||||||
|
@ -193,6 +194,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( $this->order_processor->process( $wc_order, $woocommerce ) ) {
|
if ( $this->order_processor->process( $wc_order, $woocommerce ) ) {
|
||||||
|
$this->session_handler->destroy_session_data();
|
||||||
return array(
|
return array(
|
||||||
'result' => 'success',
|
'result' => 'success',
|
||||||
'redirect' => $this->get_return_url( $wc_order ),
|
'redirect' => $this->get_return_url( $wc_order ),
|
||||||
|
@ -200,10 +202,18 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
}
|
}
|
||||||
} catch ( PayPalApiException $error ) {
|
} catch ( PayPalApiException $error ) {
|
||||||
if ( $error->has_detail( 'INSTRUMENT_DECLINED' ) ) {
|
if ( $error->has_detail( 'INSTRUMENT_DECLINED' ) ) {
|
||||||
|
$this->session_handler->increment_insufficient_funding_tries();
|
||||||
$host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ?
|
$host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ?
|
||||||
'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/';
|
'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/';
|
||||||
$url = $host . 'checkoutnow?token=' . $this->session_handler->order()->id();
|
$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(
|
return array(
|
||||||
'result' => 'success',
|
'result' => 'success',
|
||||||
'redirect' => $url,
|
'redirect' => $url,
|
||||||
|
|
|
@ -131,7 +131,7 @@ class OrderProcessor {
|
||||||
*/
|
*/
|
||||||
public function process( \WC_Order $wc_order, \WooCommerce $woocommerce ): bool {
|
public function process( \WC_Order $wc_order, \WooCommerce $woocommerce ): bool {
|
||||||
$order = $this->session_handler->order();
|
$order = $this->session_handler->order();
|
||||||
if (! $order) {
|
if ( ! $order ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
||||||
|
|
|
@ -37,6 +37,8 @@ class WcGatewayTest extends TestCase
|
||||||
$authorizedOrderActionNotice = Mockery::mock(AuthorizeOrderActionNotice::class);
|
$authorizedOrderActionNotice = Mockery::mock(AuthorizeOrderActionNotice::class);
|
||||||
$settings = Mockery::mock(Settings::class);
|
$settings = Mockery::mock(Settings::class);
|
||||||
$sessionHandler = Mockery::mock(SessionHandler::class);
|
$sessionHandler = Mockery::mock(SessionHandler::class);
|
||||||
|
$sessionHandler
|
||||||
|
->shouldReceive('destroy_session_data');
|
||||||
$settings
|
$settings
|
||||||
->shouldReceive('has')->andReturnFalse();
|
->shouldReceive('has')->andReturnFalse();
|
||||||
$testee = new PayPalGateway(
|
$testee = new PayPalGateway(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue