diff --git a/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js b/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js index 522880333..b45b9f8b9 100644 --- a/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js +++ b/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js @@ -62,6 +62,11 @@ class CheckoutActionHandler { ); } else { errorHandler.clear(); + + if (data.data.refresh) { + jQuery( document.body ).trigger( 'update_checkout' ); + } + if (data.data.errors?.length > 0) { errorHandler.messages(data.data.errors); } else if (data.data.details?.length > 0) { diff --git a/modules/ppcp-button/resources/js/modules/Helper/FormValidator.js b/modules/ppcp-button/resources/js/modules/Helper/FormValidator.js index 61220d27b..a1c738c8d 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/FormValidator.js +++ b/modules/ppcp-button/resources/js/modules/Helper/FormValidator.js @@ -23,6 +23,10 @@ export default class FormValidator { const data = await res.json(); if (!data.success) { + if (data.data.refresh) { + jQuery( document.body ).trigger( 'update_checkout' ); + } + if (data.data.errors) { return data.data.errors; } diff --git a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php index 205505c5c..86c280be1 100644 --- a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php @@ -288,12 +288,15 @@ class CreateOrderEndpoint implements EndpointInterface { return true; } catch ( ValidationException $error ) { - wp_send_json_error( - array( - 'message' => $error->getMessage(), - 'errors' => $error->errors(), - ) + $response = array( + 'message' => $error->getMessage(), + 'errors' => $error->errors(), + 'refresh' => isset( WC()->session->refresh_totals ), ); + + unset( WC()->session->refresh_totals ); + + wp_send_json_error( $response ); } catch ( \RuntimeException $error ) { $this->logger->error( 'Order creation failed: ' . $error->getMessage() ); diff --git a/modules/ppcp-button/src/Endpoint/ValidateCheckoutEndpoint.php b/modules/ppcp-button/src/Endpoint/ValidateCheckoutEndpoint.php index 7c99bb063..934c82cd4 100644 --- a/modules/ppcp-button/src/Endpoint/ValidateCheckoutEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/ValidateCheckoutEndpoint.php @@ -86,12 +86,15 @@ class ValidateCheckoutEndpoint implements EndpointInterface { return true; } catch ( ValidationException $exception ) { - wp_send_json_error( - array( - 'message' => $exception->getMessage(), - 'errors' => $exception->errors(), - ) + $response = array( + 'message' => $exception->getMessage(), + 'errors' => $exception->errors(), + 'refresh' => isset( WC()->session->refresh_totals ), ); + + unset( WC()->session->refresh_totals ); + + wp_send_json_error( $response ); return false; } catch ( Throwable $error ) { $this->logger->error( "Form validation execution failed. {$error->getMessage()} {$error->getFile()}:{$error->getLine()}" ); diff --git a/tests/PHPUnit/Button/Endpoint/ValidateCheckoutEndpointTest.php b/tests/PHPUnit/Button/Endpoint/ValidateCheckoutEndpointTest.php index 8d8a7dabc..9a99cf924 100644 --- a/tests/PHPUnit/Button/Endpoint/ValidateCheckoutEndpointTest.php +++ b/tests/PHPUnit/Button/Endpoint/ValidateCheckoutEndpointTest.php @@ -11,6 +11,7 @@ use WooCommerce\PayPalCommerce\Button\Exception\ValidationException; use WooCommerce\PayPalCommerce\Button\Validation\CheckoutFormValidator; use WooCommerce\PayPalCommerce\TestCase; use function Brain\Monkey\Functions\expect; +use function Brain\Monkey\Functions\when; class ValidateCheckoutEndpointTest extends TestCase { @@ -21,6 +22,8 @@ class ValidateCheckoutEndpointTest extends TestCase private $logger; private $sut; + private $session = []; + public function setUp(): void { parent::setUp(); @@ -36,6 +39,10 @@ class ValidateCheckoutEndpointTest extends TestCase ); $this->requestData->expects('read_request')->andReturn(['form' => ['field1' => 'value']]); + + when('WC')->alias(function () { + return (object) ['session' => (object) $this->session]; + }); } public function testValid() @@ -54,7 +61,21 @@ class ValidateCheckoutEndpointTest extends TestCase ->andThrow($exception); expect('wp_send_json_error')->once() - ->with(['message' => $exception->getMessage(), 'errors' => ['Invalid value']]); + ->with(['message' => $exception->getMessage(), 'errors' => ['Invalid value'], 'refresh' => false]); + + $this->sut->handle_request(); + } + + public function testInvalidAndRefresh() + { + $exception = new ValidationException(['Invalid value']); + $this->formValidator->expects('validate')->once() + ->andThrow($exception); + + $this->session['refresh_totals'] = true; + + expect('wp_send_json_error')->once() + ->with(['message' => $exception->getMessage(), 'errors' => ['Invalid value'], 'refresh' => true]); $this->sut->handle_request(); }