Validate form before Stripe pop up/payment modal appears

I’m trying to validate my form before the stripe payment modal appears, but the modal appears before the form can be validated. I’m using jquery validation plugin for my validation. I’ve tried adding the Stripe integration code in the submitHandler function, but still no luck. Below is what I currently have for my code:

HTML

<!-- google & apple pay btn -->
<div id="payment-request-button" class="btn__link btn__link--fullwidth-mob btn__link--paypal-flex btn__link--marginLeft-0">
   <%--A Stripe Element will be inserted here--%>
</div>

<!--  google & apple validation btn -->
<input id="paymentRequestButtonValidation" class="btn__link btn__link--fullwidth-mob btn__link--secondary btn__submit" type="submit" value="G Pay Validation">

JS

    var btnSubmitId = '';

    //-- get the id of the btn submit
    $('.btn__submit').click(function(event) {
        btnSubmitId = event.target.id;
    });

    // ----------------------------- STRIPE INTEGRATION  ----------------------------- //
    let searchParams = new URLSearchParams(window.location.search);
    var urlAmount = searchParams.get('Amount');
    var urlAmountNum = parseFloat(urlAmount);
    var donationAmount = urlAmountNum * 100;
    var clientSecret = "<%= clientSecret %>";
    var stripe = Stripe(stripeCredentials);
    var paymentRequest = stripe.paymentRequest({
        country: 'GB',
        currency: 'gbp',
        total: {
            label: 'Test payment',
            amount: donationAmount
        },
        requestPayerName: true,
        requestPayerEmail: true,
    });
    var elements = stripe.elements();
    var prButton = elements.create('paymentRequestButton', {
        paymentRequest: paymentRequest,
    });
    
    // Check the availability of the Payment Request API first.
    paymentRequest.canMakePayment().then(function(result) {
        if (result) {
            // if available mount/create the button
            prButton.mount('#payment-request-button');
        } else {
            // if NOT available hide the button and console log it
            document.getElementById('payment-request-button').style.display = 'none';
            console.log('ERROR - btn not available & can't be mounted');
        }
    });

    paymentRequest.on('paymentmethod', function(ev) {
        // Confirm the PaymentIntent without handling potential next actions (yet).
        stripe.confirmCardPayment(
            clientSecret,
            {payment_method: ev.paymentMethod.id},
            {handleActions: false}

        ).then(function(confirmResult) {
            if (confirmResult.error) {
                // Report to the browser that the payment failed, prompting it to
                // re-show the payment interface, or show an error message and close
                // the payment interface.
                ev.complete('fail');
            } else {
                // Report to the browser that the confirmation was successful, prompting
                // it to close the browser payment method collection interface.
                ev.complete('success');
                // Check if the PaymentIntent requires any actions and if so let Stripe.js
                // handle the flow. If using an API version older than "2019-02-11"
                // instead check for: `paymentIntent.status === "requires_source_action"`.
                if (confirmResult.paymentIntent.status === "requires_action") {
                    // Let Stripe.js handle the rest of the payment flow.
                    stripe.confirmCardPayment(clientSecret).then(function(result) {
                        if (result.error) {
                            // The payment failed -- ask your customer for a new payment method.
                        } else {
                            // The payment has succeeded.
                        }
                    });
                } else {
                    // The payment has succeeded.
                }
            }
        });

        prButton.on('click', function(ev) {

            // get the current amount from the #donationValue inout field
            paymentRequest.update({
                total: {
                    label: 'Test payment',
                    amount: $("#donationValue").val()*100,
                },
            });
        })
    });

    // -- single form validation
    $('#singleForm').validate({
        rules: {
            donationValue: {
                required: true,
                number: true,
                twoDecimal: true
            },

            donationtype: {
                required: true
            },

            firstname: {
                required: true
            },

            lastname: {
                required: true
            },

            email: {
                required: true
            },

            addressSearch: {
                required: true
            },

            address1: {
                required: true
            },

            postcode: {
                required: function(e) {
                    return $(e).closest('form').find('#country').val() == 'United Kingdom';
                }
            },

            town: {
                required: true
            },

            country: {
                required: true
            },

            mobile: {
                required: '#receiveSMS:checked' 
            }
        },

        messages: {
            donationValue: {
                required: 'Please enter your donation amount.',
                number: 'Please enter a valid donation amount.'
            },
            donationtype: 'Please select one of the options for Gift Aid.',
            firstname: 'Please enter a valid first name.',
            lastname: 'Please enter a valid last name.',
            email: 'Please enter a valid email address.',
            addressSearch: 'Please enter a valid postcode, street name or address.',
            address1: 'Please enter a valid address.',
            postcode: 'Please enter a valid postcode.',
            town: 'Please enter a valid town/city.',
            country: 'Please select a valid country.',
            mobile: 'Please enter your mobile phone number above'
        },

        highlight: function(element) {
            $(element).parent().find('span').addClass('error__text--icon');
            $(element).parent().find('input').addClass('form__input--error');
            $(element).parent().find('select').addClass('form__input--error');

            if ( element.id == 'dtOwnDonation' ) {
                $(element).parent().find('span').removeClass('error__text--icon');
            }
        },

        unhighlight: function(element) {
            $(element).parent().find('span').removeClass('error__text--icon');
            $(element).parent().find('input').removeClass('form__input--error');
            $(element).parent().find('select').removeClass('form__input--error');
        },

        submitHandler: function() {
            if ( btnSubmitId == 'singleBtnValidation' ) {

                $('#singleBtn').click();
                console.log('debit/credit card form - validation successful');

            } else if ( btnSubmitId == 'paymentRequestButtonValidation' ) {

                console.log('paymentRequestButtonValidation - validation successful');

                
            }
        }  
    });

Thanks in advance!