I've been on this problem since yesterday, writing and rewriting my code to fix this 400 XRH error. I cannot find a way to fix it.

Before showing you the code, here's some context:

I am trying to add variable products onto the archive loop. I've successfully brought the variation select form there and I can send the correct data with AJAX. The issue seems to be with the request.

Here's my code:

// The main php function

function variation_add_to_cart_product(){

    $product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
    $quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
    $variation_id = absint($_POST['variation_id']);
    $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
    $product_status = get_post_status($product_id);

    if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id) && 'publish' === $product_status) {

            do_action('woocommerce_ajax_added_to_cart', $product_id);

            if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
                    wc_add_to_cart_message(array($product_id => $quantity), true);

            WC_AJAX :: get_refreshed_fragments();
    } else {

            $data = array(
                    'error' => true,
                    'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));

            echo wp_send_json($data);


// Its actions

add_action( 'wp_ajax_variation_add_to_cart_product', 'variation_add_to_cart_product' );
add_action( 'wp_ajax_nopriv_variation_add_to_cart_product', 'variation_add_to_cart_product' );

// The loading of the javascript file and the ajax url

add_action( 'wp_enqueue_scripts', 'vl_load_js_script' );

function vl_load_js_script() {
    wp_register_script('vl_script', plugins_url( 'js/vl-js.js', __FILE__ ));

    $vl_ajax_array = array(
        'ajax_url' => admin_url( 'admin-ajax.php' )

    // pass Ajax Url to script.js
    wp_localize_script('vl_script', 'vl_script', $vl_ajax_array );
// The jQuery AJAX function

jQuery(function ($) {

  // Targeting the variation add_to_cart button
  $(document).on('click', '.vl_add_to_cart_button', function (e) {

    // Selecting the clicked button
    var $thisbutton = $(this),
      // Selecting the variation form
      $form = $thisbutton.parents('.woo-entry-inner').find('.woocommerce-variation-add-to-cart-enabled'),
      // Selecting the variation's product id
      product_id = $form.find('input[name=product_id]').val(),
      // Selecting the variation's id
      variation_id = $form.find('input[name=variation_id]').val(),
      // Selecting the variation's quantity
      variation_qty = $form.find('input[name=variation_qty]').val();

    // Creating the data array to send the data
    var data = {
      action: 'vl_ajax_add_to_cart',
      product_id: product_id,
      product_sku: '',
      quantity: variation_qty,
      variation_id: variation_id,

    $(document.body).trigger('adding_to_cart', [$thisbutton, data]);

      type: 'post',
      url: vl_script.ajax_url,
      data: data,
      beforeSend: function (response) {
      complete: function (response) {
      success: function (response) {

        if (response.error && response.product_url) {
          window.location = response.product_url;
        } else {
          $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $thisbutton]);

    return false;


The request payload sent is action=vl_ajax_add_to_cart&product_id=3468&product_sku=&quantity=5&variation_id=5249.

The response is 0.

The ajax address is localhost/biotruck/wp-admin/admin-ajax.php.

  • I see you're using the old admin-ajax.php API, that API isn't very friendly to debug, and doesn't give readable error messages. Have you considered using the new REST API endpoints? It would give you a pretty permalink URL to send AJAX requests to, and if there was a problem it would tell you what that problem is in a human readable message. The main change you'd need to make is to replace echo wp_send_json($data); with return $data and too swap $_POST references to instead use the variable it gives you
    – Tom J Nowell
    Nov 27, 2020 at 10:56
  • 1
    I'll give it a try, thanks for the information.
    – JAGENI Nat
    Nov 27, 2020 at 12:26

1 Answer 1


You declared this:


But then used this:

action: 'vl_ajax_add_to_cart',

Revealing the problem:

variation_add_to_cart_product != vl_ajax_add_to_cart

These 2 must match, and they do not.

  • 1
    That's was it! Thank you very much Tom!
    – JAGENI Nat
    Nov 27, 2020 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.