diff --git a/assets/js/stripe-payment-request.js b/assets/js/stripe-payment-request.js index 6684f5116..a95eafe27 100644 --- a/assets/js/stripe-payment-request.js +++ b/assets/js/stripe-payment-request.js @@ -139,6 +139,40 @@ jQuery( function( $ ) { data.shipping_postcode = shipping.postalCode; } + data = wc_stripe_payment_request.getRequiredFieldDataFromCheckoutForm( data ); + + return data; + }, + + /** + * Get required field values from the checkout form if they are filled and add to the order data. + * + * @param {Object} data Order data. + * + * @return {Object} + */ + getRequiredFieldDataFromCheckoutForm: function( data ) { + const requiredfields = $( 'form.checkout' ).find( '.validate-required' ); + + if ( requiredfields.length ) { + requiredfields.each( function() { + const field = $( this ).find( ':input' ); + const value = field.val(); + const name = field.attr( 'name' ); + if ( value && ! data[ name ] ) { + data[ name ] = value; + } + // if shipping same as billing is selected, copy the billing field to shipping field. + const shipToDiffAddress = $( '#ship-to-different-address' ).find( 'input' ).is( ':checked' ); + if ( ! shipToDiffAddress ) { + var shippingFieldName = name.replace( 'billing_', 'shipping_' ); + if ( ! data[ shippingFieldName ] && data[ name ] ) { + data[ shippingFieldName ] = data[ name ]; + } + } + }); + } + return data; }, diff --git a/client/api/blocks.js b/client/api/blocks.js index 3d3286f86..409d64a3f 100644 --- a/client/api/blocks.js +++ b/client/api/blocks.js @@ -66,7 +66,8 @@ export const updateShippingDetails = ( shippingOption ) => { }; export const createOrder = ( sourceEvent, paymentRequestType ) => { - const data = normalizeOrderData( sourceEvent, paymentRequestType ); + let data = normalizeOrderData( sourceEvent, paymentRequestType ); + data = getRequiredFieldDataFromCheckoutForm( data ); return $.ajax( { type: 'POST', @@ -75,3 +76,31 @@ export const createOrder = ( sourceEvent, paymentRequestType ) => { url: getAjaxUrl( 'create_order' ), } ); }; + +const getRequiredFieldDataFromCheckoutForm = ( data ) => { + const checkoutForm = document.querySelector( '.wc-block-checkout' ); + const requiredFields = checkoutForm.querySelectorAll( '[required]' ); + + if ( requiredFields.length ) { + requiredFields.forEach( ( field ) => { + const value = field.value; + const id = field.id?.replace( '-', '_' ); + if ( value && ! data[ id ] ) { + data[ id ] = value; + } + + // if billing same as shipping is selected, copy the shipping field to billing field. + const useSameBillingAddress = checkoutForm + .querySelector( '.wc-block-checkout__use-address-for-billing' ) + ?.querySelector( 'input' )?.checked; + if ( useSameBillingAddress ) { + const billingFieldName = id.replace( 'shipping_', 'billing_' ); + if ( ! data[ billingFieldName ] && data[ id ] ) { + data[ billingFieldName ] = data[ id ]; + } + } + } ); + } + + return data; +}; diff --git a/includes/payment-methods/class-wc-stripe-payment-request.php b/includes/payment-methods/class-wc-stripe-payment-request.php index 3b04f24e3..f245463ef 100644 --- a/includes/payment-methods/class-wc-stripe-payment-request.php +++ b/includes/payment-methods/class-wc-stripe-payment-request.php @@ -974,6 +974,11 @@ public function should_show_payment_request_button() { return false; } + // Don't show on cart if there are required checkout fields. + if ( is_cart() && $this->has_required_checkout_fields() ) { + return false; + } + // Don't show on checkout if disabled. if ( is_checkout() && ! $this->should_show_prb_on_checkout_page() ) { return false; @@ -984,6 +989,11 @@ public function should_show_payment_request_button() { return false; } + // Don't show on product if there are required checkout fields. + if ( $this->is_product() && $this->has_required_checkout_fields() ) { + return false; + } + // Don't show if product on current page is not supported. if ( $this->is_product() && ! $this->is_product_supported( $this->get_product() ) ) { return false; @@ -1058,6 +1068,54 @@ public function should_show_prb_on_product_pages() { ); } + /** + * Returns true if the checkout has any required fields other than the default ones, false otherwise. + * to not be empty. + * + * @since 8.0.0 + * + * @return boolean + */ + public function has_required_checkout_fields() { + // Default WooCommerce Core required fields for billing and shipping. + $default_required_fields = [ + 'billing_first_name', + 'billing_last_name', + 'billing_country', + 'billing_address_1', + 'billing_city', + 'billing_state', + 'billing_postcode', + 'billing_phone', + 'billing_email', + 'shipping_first_name', + 'shipping_last_name', + 'shipping_country', + 'shipping_address_1', + 'shipping_city', + 'shipping_state', + 'shipping_postcode', + ]; + + $fields = WC()->checkout()->get_checkout_fields(); + $fields = array_merge( + $fields['billing'] ?? [], + $fields['shipping'] ?? [], + $fields['order'] ?? [], + $fields['account'] ?? [] + ); + + foreach ( $fields as $field_key => $field_data ) { + if ( false === array_search( $field_key, $default_required_fields, true ) ) { + if ( isset( $field_data['required'] ) && true === $field_data['required'] ) { + return true; + } + } + } + + return false; + } + /** * Returns true if a the provided product is supported, false otherwise. *