diff --git a/modules/ppcp-button/resources/js/button.js b/modules/ppcp-button/resources/js/button.js index 40997d15a..9bc2e4b49 100644 --- a/modules/ppcp-button/resources/js/button.js +++ b/modules/ppcp-button/resources/js/button.js @@ -40,11 +40,6 @@ const bootstrap = () => { ); const spinner = new Spinner(); - let creditCardRenderer = new HostedFieldsRenderer(PayPalCommerceGateway, errorHandler, spinner); - if (typeof paypal.CardFields !== 'undefined') { - creditCardRenderer = new CardFieldsRenderer(PayPalCommerceGateway, errorHandler, spinner); - } - const formSaver = new FormSaver( PayPalCommerceGateway.ajax.save_checkout_form.endpoint, PayPalCommerceGateway.ajax.save_checkout_form.nonce, @@ -73,13 +68,7 @@ const bootstrap = () => { && document.querySelector(PayPalCommerceGateway.messages.wrapper); } - const onSmartButtonClick = async (data, actions) => { - window.ppcpFundingSource = data.fundingSource; - const requiredFields = jQuery('form.woocommerce-checkout .validate-required:visible :input'); - requiredFields.each((i, input) => { - jQuery(input).trigger('validate'); - }); - + const doBasicCheckoutValidation = () => { if (PayPalCommerceGateway.basic_checkout_validation_enabled) { // A quick fix to get the errors about empty form fields before attempting PayPal order, // it should solve #513 for most of the users, but it is not a proper solution. @@ -117,9 +106,26 @@ const bootstrap = () => { errorHandler.message(PayPalCommerceGateway.labels.error.required.generic); } - return actions.reject(); + return false; } } + return true; + }; + + const onCardFieldsBeforeSubmit = () => { + return doBasicCheckoutValidation(); + }; + + const onSmartButtonClick = async (data, actions) => { + window.ppcpFundingSource = data.fundingSource; + const requiredFields = jQuery('form.woocommerce-checkout .validate-required:visible :input'); + requiredFields.each((i, input) => { + jQuery(input).trigger('validate'); + }); + + if (!doBasicCheckoutValidation()) { + return actions.reject(); + } const form = document.querySelector(checkoutFormSelector); if (form) { @@ -149,6 +155,12 @@ const bootstrap = () => { jQuery(document).trigger('ppcp-smart-buttons-init', this); buttonsSpinner.unblock(); }; + + let creditCardRenderer = new HostedFieldsRenderer(PayPalCommerceGateway, errorHandler, spinner); + if (typeof paypal.CardFields !== 'undefined') { + creditCardRenderer = new CardFieldsRenderer(PayPalCommerceGateway, errorHandler, spinner, onCardFieldsBeforeSubmit); + } + const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick, onSmartButtonsInit); const messageRenderer = new MessageRenderer(PayPalCommerceGateway.messages); diff --git a/modules/ppcp-button/resources/js/modules/Renderer/CardFieldsRenderer.js b/modules/ppcp-button/resources/js/modules/Renderer/CardFieldsRenderer.js index 377568fcb..13f37cda0 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/CardFieldsRenderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/CardFieldsRenderer.js @@ -3,7 +3,7 @@ import {cardFieldStyles} from "../Helper/CardFieldsHelper"; class CardFieldsRenderer { - constructor(defaultConfig, errorHandler, spinner) { + constructor(defaultConfig, errorHandler, spinner, onCardFieldsBeforeSubmit) { this.defaultConfig = defaultConfig; this.errorHandler = errorHandler; this.spinner = spinner; @@ -11,6 +11,7 @@ class CardFieldsRenderer { this.formValid = false; this.emptyFields = new Set(['number', 'cvv', 'expirationDate']); this.currentHostedFieldsInstance = null; + this.onCardFieldsBeforeSubmit = onCardFieldsBeforeSubmit; } render(wrapper, contextConfig) { @@ -110,6 +111,11 @@ class CardFieldsRenderer { return; } + if (typeof this.onCardFieldsBeforeSubmit === 'function' && !this.onCardFieldsBeforeSubmit()) { + this.spinner.unblock(); + return; + } + cardField.submit() .catch((error) => { this.spinner.unblock(); diff --git a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php index 2150b931f..ca34e59fb 100644 --- a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php @@ -294,7 +294,7 @@ class CreateOrderEndpoint implements EndpointInterface { if ( $this->early_validation_enabled && $this->form && 'checkout' === $data['context'] - && in_array( $payment_method, array( PayPalGateway::ID, CardButtonGateway::ID ), true ) + && in_array( $payment_method, array( PayPalGateway::ID, CardButtonGateway::ID, CreditCardGateway::ID ), true ) ) { $this->validate_form( $this->form ); }