1

I've been creating an autofill checkout pile of code for WooCommerce so that when I get people from my software to get a link to my site to purchase something. But I've been having trouble getting to work, even with incognito and a URL with dummy data in it. If someone can tell me what I'm doing wrong, or I need to put it somewhere else.

My code:

function custom_autofill_checkout_fields() {
    // Only run on checkout page
    if (!is_checkout()) {
        return;
    }

    // Get URL parameters
    $autofill_fields = array(
        'billing_first_name' => isset($_GET['fname']) ? sanitize_text_field($_GET['fname']) : '',
        'billing_last_name' => isset($_GET['lname']) ? sanitize_text_field($_GET['lname']) : '',
        'billing_email' => isset($_GET['email']) ? sanitize_email($_GET['email']) : '',
        'billing_phone' => isset($_GET['phone']) ? sanitize_text_field($_GET['phone']) : '',
        'billing_company' => isset($_GET['company']) ? sanitize_text_field($_GET['company']) : '',
        'billing_address_1' => isset($_GET['address1']) ? sanitize_text_field($_GET['address1']) : '',
        'billing_address_2' => isset($_GET['address2']) ? sanitize_text_field($_GET['address2']) : '',
        'billing_city' => isset($_GET['city']) ? sanitize_text_field($_GET['city']) : '',
        'billing_state' => isset($_GET['state']) ? sanitize_text_field($_GET['state']) : '',
        'billing_postcode' => isset($_GET['postcode']) ? sanitize_text_field($_GET['postcode']) : '',
        'billing_country' => isset($_GET['country']) ? sanitize_text_field($_GET['country']) : '',
        
        // Copy billing to shipping if requested
        'ship_to_different_address' => isset($_GET['ship_different']) && $_GET['ship_different'] === '1' ? true : false,
        
        // Shipping fields
        'shipping_first_name' => isset($_GET['ship_fname']) ? sanitize_text_field($_GET['ship_fname']) : '',
        'shipping_last_name' => isset($_GET['ship_lname']) ? sanitize_text_field($_GET['ship_lname']) : '',
        'shipping_company' => isset($_GET['ship_company']) ? sanitize_text_field($_GET['ship_company']) : '',
        'shipping_address_1' => isset($_GET['ship_address1']) ? sanitize_text_field($_GET['ship_address1']) : '',
        'shipping_address_2' => isset($_GET['ship_address2']) ? sanitize_text_field($_GET['ship_address2']) : '',
        'shipping_city' => isset($_GET['ship_city']) ? sanitize_text_field($_GET['ship_city']) : '',
        'shipping_state' => isset($_GET['ship_state']) ? sanitize_text_field($_GET['ship_state']) : '',
        'shipping_postcode' => isset($_GET['ship_postcode']) ? sanitize_text_field($_GET['ship_postcode']) : '',
        'shipping_country' => isset($_GET['ship_country']) ? sanitize_text_field($_GET['ship_country']) : '',
        
        // Order notes
        'order_comments' => isset($_GET['notes']) ? sanitize_textarea_field($_GET['notes']) : '',
    );

    // Add products to cart if product_id is provided
    if (isset($_GET['product_id'])) {
        $product_id = intval($_GET['product_id']);
        $quantity = isset($_GET['quantity']) ? intval($_GET['quantity']) : 1;
        
        // Clear cart first if requested
        if (isset($_GET['clear_cart']) && $_GET['clear_cart'] === '1') {
            WC()->cart->empty_cart();
        }
        
        // Add product to cart
        if ($product_id > 0) {
            WC()->cart->add_to_cart($product_id, $quantity);
        }
    }
    
    // Set checkout fields
    foreach ($autofill_fields as $field => $value) {
        if (!empty($value)) {
            WC()->customer->set_props(array($field => $value));
        }
    }
    
    // Add JavaScript to handle form field autofilling
    add_action('wp_footer', 'custom_autofill_checkout_javascript');
}
add_action('wp_loaded', 'custom_autofill_checkout_fields');

/**
 * Add JavaScript to ensure the checkout form fields are populated
 */
function custom_autofill_checkout_javascript() {
    if (!is_checkout()) {
        return;
    }
    
    ?>
    <script type="text/javascript">
    jQuery(document).ready(function($) {
        // Get URL parameters
        const urlParams = new URLSearchParams(window.location.search);
        
        // Map URL parameters to checkout fields
        const fieldMap = {
            'fname': '#billing_first_name',
            'lname': '#billing_last_name',
            'email': '#billing_email',
            'phone': '#billing_phone',
            'company': '#billing_company',
            'address1': '#billing_address_1',
            'address2': '#billing_address_2',
            'city': '#billing_city',
            'state': '#billing_state',
            'postcode': '#billing_postcode',
            'country': '#billing_country',
            'ship_fname': '#shipping_first_name',
            'ship_lname': '#shipping_last_name',
            'ship_company': '#shipping_company',
            'ship_address1': '#shipping_address_1',
            'ship_address2': '#shipping_address_2',
            'ship_city': '#shipping_city',
            'ship_state': '#shipping_state',
            'ship_postcode': '#shipping_postcode',
            'ship_country': '#shipping_country',
            'notes': '#order_comments'
        };
        
        // Fill form fields from URL parameters
        Object.entries(fieldMap).forEach(([param, selector]) => {
            if (urlParams.has(param)) {
                $(selector).val(urlParams.get(param)).trigger('change');
            }
        });
        
        // Handle shipping to different address
        if (urlParams.has('ship_different') && urlParams.get('ship_different') === '1') {
            $('#ship-to-different-address-checkbox').prop('checked', true).trigger('change');
        }
        
        // Ensure fields update when form refreshes
        $(document.body).on('updated_checkout', function() {
            // Re-apply values after checkout updates
            Object.entries(fieldMap).forEach(([param, selector]) => {
                if (urlParams.has(param)) {
                    $(selector).val(urlParams.get(param)).trigger('change');
                }
            });
        });
    });
    </script>
    <?php
}

/**
 * Helper function to generate an autofill checkout URL
 * 
 * @param array $customer_data Customer data to pre-fill
 * @param int|array $product_id Product ID or array of product IDs and quantities to add to cart
 * @param bool $clear_cart Whether to clear the cart before adding products
 * @return string The checkout URL with pre-fill parameters
 */
function generate_autofill_checkout_url($customer_data, $product_id = null, $clear_cart = true) {
    $checkout_url = wc_get_checkout_url();
    $params = array();
    
    // Add customer data parameters
    foreach ($customer_data as $key => $value) {
        $params[$key] = urlencode($value);
    }
    
    // Add product parameters if provided
    if ($product_id !== null) {
        $params['product_id'] = $product_id;
        $params['clear_cart'] = $clear_cart ? '1' : '0';
    }
    
    // Build URL with query string
    $checkout_url = add_query_arg($params, $checkout_url);
    
    return $checkout_url;
}
New contributor
user30403951 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
3
  • Questions: how/when are you calling this custom_prefill_checkout_fields() function exactly? And you said that you're having problems "getting it to work", what problems exactly? Commented 7 hours ago
  • Hi, essentially what im trying to do is get a URL that has my customers details on it for billing. Every time i have tried a URL with dummy data in it, it doesnt enter any details. I'm not entirely sure what im getting wrong. My code will be updated on the original post. Commented 6 hours ago
  • Welcome to SO, please provide stackoverflow.com/help/minimal-reproducible-example so we can reproduce and try to help you, this is out of context. Please edit it :)
    – Marco
    Commented 11 mins ago

1 Answer 1

0

You can replace wp_loaded hook with woocommerce_checkout_init action hook and for your javascript you can use wc_enqueue_js() dedicated function that includes jQuery ready event.

Try the following:

function custom_autofill_checkout_fields() {
    // Only run on checkout page
    if (!is_checkout()) {
        return;
    }

    // Get URL parameters
    $autofill_fields = array(
        'billing_first_name' => isset($_GET['fname']) ? sanitize_text_field($_GET['fname']) : '',
        'billing_last_name' => isset($_GET['lname']) ? sanitize_text_field($_GET['lname']) : '',
        'billing_email' => isset($_GET['email']) ? sanitize_email($_GET['email']) : '',
        'billing_phone' => isset($_GET['phone']) ? sanitize_text_field($_GET['phone']) : '',
        'billing_company' => isset($_GET['company']) ? sanitize_text_field($_GET['company']) : '',
        'billing_address_1' => isset($_GET['address1']) ? sanitize_text_field($_GET['address1']) : '',
        'billing_address_2' => isset($_GET['address2']) ? sanitize_text_field($_GET['address2']) : '',
        'billing_city' => isset($_GET['city']) ? sanitize_text_field($_GET['city']) : '',
        'billing_state' => isset($_GET['state']) ? sanitize_text_field($_GET['state']) : '',
        'billing_postcode' => isset($_GET['postcode']) ? sanitize_text_field($_GET['postcode']) : '',
        'billing_country' => isset($_GET['country']) ? sanitize_text_field($_GET['country']) : '',
        
        // Copy billing to shipping if requested
        'ship_to_different_address' => isset($_GET['ship_different']) && $_GET['ship_different'] === '1' ? true : false,
        
        // Shipping fields
        'shipping_first_name' => isset($_GET['ship_fname']) ? sanitize_text_field($_GET['ship_fname']) : '',
        'shipping_last_name' => isset($_GET['ship_lname']) ? sanitize_text_field($_GET['ship_lname']) : '',
        'shipping_company' => isset($_GET['ship_company']) ? sanitize_text_field($_GET['ship_company']) : '',
        'shipping_address_1' => isset($_GET['ship_address1']) ? sanitize_text_field($_GET['ship_address1']) : '',
        'shipping_address_2' => isset($_GET['ship_address2']) ? sanitize_text_field($_GET['ship_address2']) : '',
        'shipping_city' => isset($_GET['ship_city']) ? sanitize_text_field($_GET['ship_city']) : '',
        'shipping_state' => isset($_GET['ship_state']) ? sanitize_text_field($_GET['ship_state']) : '',
        'shipping_postcode' => isset($_GET['ship_postcode']) ? sanitize_text_field($_GET['ship_postcode']) : '',
        'shipping_country' => isset($_GET['ship_country']) ? sanitize_text_field($_GET['ship_country']) : '',
        
        // Order notes
        'order_comments' => isset($_GET['notes']) ? sanitize_textarea_field($_GET['notes']) : '',
    );

    // Add products to cart if product_id is provided
    if (isset($_GET['product_id'])) {
        $product_id = intval($_GET['product_id']);
        $quantity = isset($_GET['quantity']) ? intval($_GET['quantity']) : 1;
        
        // Clear cart first if requested
        if (isset($_GET['clear_cart']) && $_GET['clear_cart'] === '1') {
            WC()->cart->empty_cart();
        }
        
        // Add product to cart
        if ($product_id > 0) {
            WC()->cart->add_to_cart($product_id, $quantity);
        }
    }
    
    // Set checkout fields
    foreach ($autofill_fields as $field => $value) {
        if (!empty($value)) {
            WC()->customer->set_props(array($field => $value));
        }
    }
    custom_autofill_checkout_js();
}
add_action('woocommerce_checkout_init', 'custom_autofill_checkout_fields');

/**
 * Add JavaScript to ensure the checkout form fields are populated
 */
function custom_autofill_checkout_js() {
    wc_enqueue_js("
        // Get URL parameters
        const urlParams = new URLSearchParams(window.location.search);
        
        // Map URL parameters to checkout fields
        const fieldMap = {
            'fname': '#billing_first_name',
            'lname': '#billing_last_name',
            'email': '#billing_email',
            'phone': '#billing_phone',
            'company': '#billing_company',
            'address1': '#billing_address_1',
            'address2': '#billing_address_2',
            'city': '#billing_city',
            'state': '#billing_state',
            'postcode': '#billing_postcode',
            'country': '#billing_country',
            'ship_fname': '#shipping_first_name',
            'ship_lname': '#shipping_last_name',
            'ship_company': '#shipping_company',
            'ship_address1': '#shipping_address_1',
            'ship_address2': '#shipping_address_2',
            'ship_city': '#shipping_city',
            'ship_state': '#shipping_state',
            'ship_postcode': '#shipping_postcode',
            'ship_country': '#shipping_country',
            'notes': '#order_comments'
        };
        
        // Fill form fields from URL parameters
        Object.entries(fieldMap).forEach(([param, selector]) => {
            if (urlParams.has(param)) {
                $(selector).val(urlParams.get(param)).trigger('change');
            }
        });
        
        // Handle shipping to different address
        if (urlParams.has('ship_different') && urlParams.get('ship_different') === '1') {
            $('#ship-to-different-address-checkbox').prop('checked', true).trigger('change');
        }
        
        // Ensure fields update when form refreshes
        $(document.body).on('updated_checkout', function() {
            // Re-apply values after checkout updates
            Object.entries(fieldMap).forEach(([param, selector]) => {
                if (urlParams.has(param)) {
                    $(selector).val(urlParams.get(param)).trigger('change');
                }
            });
        });
    ");
}

It should better work.

Note that woocommerce_checkout_init is only triggered on WooCommerce checkout page.

Your helper function generate_autofill_checkout_url remains unchanged.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.