Magento 2.1 – Add to Cart via JavaScript

cartjavascriptmagento-2.1magento2

I'm currently trying to add a product (with custom options) to the cart via JavaScript in Magento 2.1.

I've implemented a solution in the past for Magento 1.9, but this solution no longer works for the new Magento version. The old solution retrieved the quoteId for the current user and then created an add-to-cart-link which added the product to the cart. But it seems there is no more such link and the retrieving of the quote id also won't work anymore.

Until now I was able to create a new quote/cart id and add a product to this cart:

function AddToCart(data) {
    var sku = data.sku;
    var qty = data.quantity;

    // create a new quote
    var request = jQuery.ajax({
        url: "http://foo.com/rest/default/V1/guest-carts",
        method: "POST",
        dataType: "json"
    }).done(function( quoteId ) {
        // add the product if quote creation was successful
        var data = {
            "cartItem": {
                "sku": sku,
                "qty": qty,
                "quote_id": quoteId
            }
        };
        jQuery.ajax({
            url: "http://foo.com/rest/default/V1/guest-carts/"+quoteId+"/items/",
            method: "POST",
            dataType: "json",
            data: JSON.stringify(data)
        }).done(function( response ) {
            console.log("Product added to cart. ");
        }).fail(function( jqXHR, textStatus ) {
            console.log("Add to cart failed. " + textStatus);
        });
    }).fail(function( jqXHR, textStatus ) {
        console.log("Couldn't retrieve the QuoteId. " + textStatus);
    });
}

Problems with this code:

  • The cart is not in anyway associated with the currently active client/user, it's just an invisible cart where I add the product(s). I can interact with the cart via API, but it's not shown to the client
  • Furthermore this code only works for guests and not for customers who are logged in
  • A new cart will be created each time, ignoring existing user carts

My questions now are:

  • Is there a way to retrieve the quote id for a guest? (Question 1 , Question 2 and other questions only apply for logged in customers). The quote id could then be used to add the product to an existing cart
  • Is there a way to assign a guest to a cart? There seems to be an API call which assigns a customer to a cart (/V1/guest-carts/{cartId}), but this only works for users who are logged in since a customerId is required
  • Is there any other way (which I havn't found yet) to add a product to the cart via JavaScript?

Best Answer

So I finally was able to add a product to the current customers cart.

Steps

  • Get the "add to cart" url from the product which you want to add to the cart (PHP needed)
  • Add the form key to the url
  • Add your custom options to the body of the POST call via FormData

Code

Product id (NOT the sku), custom option id and the redirect url must be replaced with your values. The custom option id can be found by:

  • trial and error (they start at 1 and increment for each new option)
  • REST call How can i get custom options from product in magento 2?
  • Put a product with custom options into the cart and checkout the network tab in chrome, there you can see the ids of the custom options in the request body

Place this code into any *.phtml file.

<script type="application/javascript">
function AddToMagentoCart() {
    var addToCartUrl = "<?php
    $productId = 1; // <--- set correct product id (e.g. 1)
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId);
    $addToCartUrl = $objectManager->get('Magento\Checkout\Helper\Cart')->getAddUrl($product);
    echo $addToCartUrl.'form_key/'; ?>";

    // add form key
    var formKey = jQuery.cookie("form_key");
    addToCartUrl += formKey;

    // add options
    var formData = new FormData();
    formData.append("product", <?php echo $productId ?>);
    formData.append("selected_configurable_option", "");
    formData.append("related_product", "");
    formData.append("form_key", formKey);
    formData.append("options[2]", "Some custom data, foo bar"); // <--- set correct optionId (e.g. 2)
    formData.append("qty", cp.Menge);

    // make POST call with the custom options as body element
    var request = jQuery.ajax({
        url: addToCartUrl,
        method: "POST",
        processData: false,
        contentType: false,
        data: formData
    }).done(function( response ) { // redirect to cart if call was successful
        window.location = "http://example.com/checkout/cart"; // <--- set correct redirect link
    }).fail(function( jqXHR, textStatus ) {
        console.log("Couldn't add product to cart. " + textStatus);
    });
};
</script>

Note

I have not found a solution on how to set the price of an item. I guess it's not possible at all, because it would pose a security risk. The client should never tell the server how much an item should cost.

Thanks to those questions/answers/comments