Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a Variation to Cart using AJAX - WooCommerce API?

I have an item with the following data :

var item = {
  id : "124",
  name : "xxx",
  price : "13.13",
  quantity : 1,
  options : {
    "size" : "xl",
    "color": "pink"
  }
};

When the user clicks on "Add to Cart" I'd like to make an Ajax Request using the WC API and add the above item to the Cart.

jQuery.ajax({
   url: "some/woocommerce/api/add/to/cart/request/path",
   data: item,
   type: "POST"
});

Then on the Cart Page I'd like to make another Ajax Request using the WC API and retrieve the contents of the cart.

I haven't found any documentation (official or unofficial) on how to do that from the client using Javascript.

Does anyone know and can provide me with an example please?

Also, does anyone know why the WooCommerce Api Documentation is so horrible (lacking any kind of information regarding obvious/standard questions like the above). I'm seriously thinking of having our company switch to Shopify.

like image 427
Sprout Coder Avatar asked Dec 03 '14 11:12

Sprout Coder


People also ask

How add to cart works in WooCommerce?

WooCommerce Custom Add to Cart Button is a simple plugin to customize your store's add to cart buttons. It makes it easy to change the 'Add to cart' button text, add a cart icon to the button, or replace the text with just an icon. There are lots of reasons why you might want to change the add to cart text.

Does WooCommerce use Ajax?

The Ajax-Enabled, Layered Navigation extension for WooCommerce provides a richer user experience for your customer and is particularly well suited for stores that have a lot of variable products or products with a number of attributes.


1 Answers

You can investigate how WooCommerce is adding items to the cart via ajax directly in the code.... the callback is located in includes/class-wc-ajax.php. WooCommerce already does this on product "loops" (product archives), so I don't think you need to reinvent the wheel and if their existing code doesn't work for what you are trying to do, then you should be able to borrow heavily from it.

The beginning of that file has a loop with all the WooCommerce Ajax actions, but we can track down that the add to cart is basically this:

add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart', array( 'WC_AJAX', 'add_to_cart' ) );

And it's callback is a little further down the file:

/**
 * AJAX add to cart
 */
public static function add_to_cart() {
    ob_start();

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

    if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity ) ) {

        do_action( 'woocommerce_ajax_added_to_cart', $product_id );

        if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) {
            wc_add_to_cart_message( $product_id );
        }

        // Return fragments
        self::get_refreshed_fragments();

    } else {

        // If there was an error adding to the cart, redirect to the product page to show any errors
        $data = array(
            'error' => true,
            'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id )
        );

        wp_send_json( $data );

    }

    die();
}

If you want to view their add to cart ajax call, the JS for that is located in assest/js/frontend/add-to-cart.js.

EDIT

Now that I know you are looking to add a variation, maybe we can tweak the above.

First, I think you'll need to pass the AJAX url to your script:

wp_enqueue_script( 'wc-variation-add-to-cart', 'source-to-script/your-script.js' );

$vars = array( 'ajax_url' => admin_url( 'admin-ajax.php' ) );
wp_localize_script( 'wc-variation-add-to-cart', 'WC_VARIATION_ADD_TO_CART', $vars );

Then your AJAX call would look something like this:

jQuery.ajax({
    url: WC_VARIATION_ADD_TO_CART.ajax_url,
    data: {
        "action" : "woocommerce_add_variation_to_cart",
        "product_id" : "124",
        "variation_id" : "125",
        "quantity" : 1,
        "variation" : {
            "size" : "xl",
            "color": "pink"
        },
    },
    type: "POST"
});

Basically to add a specific variation you need the variation's ID in addition to all its specific options.

And finally the new callback for the woocommerce_add_variation_to_cart ajax action would be along the lines of the following:

add_action( 'wp_ajax_nopriv_woocommerce_add_variation_to_cart', 'so_27270880_add_variation_to_cart' );

function so_27270880_add_variation_to_cart() {

    ob_start();

    $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      = isset( $_POST['variation_id'] ) ? absint( $_POST['variation_id'] ) : '';
    $variations         = ! empty( $_POST['variation'] ) ? (array) $_POST['variation'] : '';

    $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations, $cart_item_data );

    if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ) ) {

        do_action( 'woocommerce_ajax_added_to_cart', $product_id );

        if ( get_option( 'woocommerce_cart_redirect_after_add' ) == 'yes' ) {
            wc_add_to_cart_message( $product_id );
        }

        // Return fragments
        WC_AJAX::get_refreshed_fragments();

    } else {

        // If there was an error adding to the cart, redirect to the product page to show any errors
        $data = array(
            'error' => true,
            'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id )
        );

        wp_send_json( $data );

    }

    die();
}

Mostly, I'm just copying WooCommerce's approach and adding in the 2 variables needed for adding variations. Totally untested, but I hope it helps.

like image 174
helgatheviking Avatar answered Sep 27 '22 17:09

helgatheviking