Difference between revisions of "Using the Spiffy Ajax API"

From Spiffy Stores Knowledge Base

 
(9 intermediate revisions by the same user not shown)
Line 19: Line 19:
  
 
== Wrapper Library Function Reference ==
 
== Wrapper Library Function Reference ==
 +
 +
=== Utility Functions ===
 +
 +
==== <code>Spiffy.formatMoney(price, format)</code> ====
 +
 +
Returns a formatted string, given a numberic price and optional format string.
 +
 +
The price is the floating-point value in the base unit of currency. For example, the price 1234.45 would be formatted as ''$1,234.56'' using the default format.
 +
 +
The format string can include any characters, along with a substitution variable with the following values:
 +
 +
* amount - Default formatting for the currency
 +
* amount_no_decimals - Uses only the base currency unit
 +
* amount_with_comma_separator - Uses a comma to specify the decimals
 +
* amount_no_decimals_with_comma_separator - Uses a comma decimal separator
 +
 +
For example, the default format string is
 +
<pre>
 +
'${{amount}}'
 +
</pre>
 +
 +
==== <code>Spiffy.onError(XMLHttpRequest, textStatus)</code> ====
 +
 +
==== <code>Spiffy.onCartUpdate(cart)</code> ====
 +
 +
==== <code>Spiffy.onItemAdded(line_item)</code> ====
 +
 +
==== <code>Spiffy.onProduct(product)</code> ====
 +
 +
==== <code>Spiffy.resizeImage(image, size)</code> ====
 +
 +
=== Ajax Calls ===
 +
 +
==== <code>Spiffy.addItem(variant_id, quantity, callback)</code> ====
 +
 +
==== <code>Spiffy.addItemFromForm(form_id, callback)</code> ====
 +
 +
==== <code>Spiffy.getCart(callback)</code> ====
 +
 +
==== <code>Spiffy.getProduct(handle, callback)</code> ====
 +
 +
==== <code>Spiffy.changeItem(variant_id, quantity, callback)</code> ====
 +
 +
==== <code>Spiffy.changeItemIndex(cart_index, quantity, callback)</code> ====
 +
 +
==== <code>Spiffy.removeItem(variant_id, callback)</code> ====
 +
 +
==== <code>Spiffy.removeItemIndex(cart_index, callback)</code> ====
 +
 +
==== <code>Spiffy.clear(callback)</code> ====
 +
 +
==== <code>Spiffy.updateCart(updates, callback)</code> ====
 +
 +
==== <code>Spiffy.updateCartFromForm(form_id, callback)</code> ====
 +
 +
==== <code>Spiffy.updateCartAttributes(attributes, callback)</code> ====
 +
 +
==== <code>Spiffy.updateCartNote(note, callback)</code> ====
  
 
== Spiffy Ajax API Reference ==
 
== Spiffy Ajax API Reference ==
Line 423: Line 481:
 
<pre>
 
<pre>
 
{
 
{
   updates: {12345: 2, 67890: 3}
+
   updates: { 12345: 2, 67890: 3 }
 
}
 
}
 
</pre>
 
</pre>
Line 470: Line 528:
  
 
<pre>
 
<pre>
jQuery.post('/cart/update.js', {updates: {2345345: 2, 364566: 3}});
+
jQuery.post('/cart/update.js', { updates: { 2345345: 2, 364566: 3 } });
 
</pre>
 
</pre>
  
Line 480: Line 538:
 
Similarly, a single line item can be updated as follows:
 
Similarly, a single line item can be updated as follows:
 
<pre>
 
<pre>
jQuery.post('/cart/update.js', {updates: {2345345: 2}});
+
jQuery.post('/cart/update.js', { updates: { 2345345: 2 } });
 
</pre>
 
</pre>
  
 
Finally, line items can be removed from the cart by setting their quantity to zero:
 
Finally, line items can be removed from the cart by setting their quantity to zero:
 
<pre>
 
<pre>
jQuery.post('/cart/update.js', {updates: {2345345: 0, 364566: 0}});
+
jQuery.post('/cart/update.js', { updates: { 2345345: 0, 364566: 0 } });
 
</pre>
 
</pre>
  
The properties of a line item can be set when an item is added to the cart. This means that the same variation can exist more than once in a cart.
+
The properties of a line item can be set when an item is added to the cart. This means that the same variation can exist more than once in a cart, as each line item can have different customization data.
  
If you use Line Item Properties you may end up with several items in the cart that share the same variant ID. How do you update the quantity of items in the cart when that happens? It turns out that you can also submit an array of numbers to /cart/update.js, where the size of the array will need to match the amount of line items in the cart.
+
This means that it may not be possible to identify a unique variation in a cart by its '''id''', as multiple line items in the cart may have the same '''id'''.
  
Example, say you have 3 line items in the cart, with quantities 1, 2 and 3, and you want to change those quantities to 3, 2 and 1, you can use the following:
+
If this is the case, then the only way to update the line item quantities is to provide an array of new quantities for each line item, where the order of elements in the array matches the order of line items in the cart.
  
jQuery.post('/cart/update.js', {updates: [3, 2, 1]});
+
When you use this method of updating line items, the number of elements in the array must match the number of line items in the cart.
  
If there's any problem with updating any quantity when submitting an array of number, there will be a 422 error, and the quantities will remain the same as they were.
+
For example, if you have 3 line items in the cart, with quantities 1, 2 and 3, and you want to update these quantities to 3, 2 and 1, you can use the following example:
  
To change the quantity of one line item, you will need to use /cart/change.js instead (see the following section) and provide the 1-based index of the item in the cart like so:
+
<pre>
 +
jQuery.post('/cart/update.js', { updates: [3, 2, 1] });
 +
</pre>
  
 +
The above method requires you to update the quantities of all line items in the cart. It's possible to change just one line item by using the '''/cart/change.js''' call instead, where the line item is specified using a 1-origin based line item index.
 +
<pre>
 
jQuery.post('/cart/change.js', { line: 1, quantity: 1 });
 
jQuery.post('/cart/change.js', { line: 1, quantity: 1 });
 +
</pre>
  
To change the quantity of the second line item in the cart, you'll use this:
+
Similarly, to change the quantity of the second line item in the cart, we use this example:
 
+
<pre>
 
jQuery.post('/cart/change.js', { line: 2, quantity: 1 });
 
jQuery.post('/cart/change.js', { line: 2, quantity: 1 });
 +
</pre>
  
 
=== <code>POST /cart/change.js</code> ===
 
=== <code>POST /cart/change.js</code> ===
  
This call sets the quantity of an item already in the cart.
+
This call updates the quantity of an item already in the cart.
  
POST data
+
POST data is required and takes the form:
 +
<pre>
 +
{
 +
  id: 234234,
 +
  quantity: 2
 +
}
 +
</pre>
  
 +
If the product uses custom options, then a composite variation ''id'' is used indicate which combination of custom options is to be used with the variation.
 +
<pre>
 
{
 
{
   quantity: 1,
+
   id: '334234_1',
   id: 794864053
+
   quantity: 2
 
}
 
}
 +
</pre>
  
Response The JSON of the cart.
+
The ''quantity'' indicates how many items you wish to add to the cart for the specified variation.
  
If you use Line Item Properties you may end up with several items in the cart that share the same variant ID. How do you update the quantity of an item in the cart that has specific line item properties? Once you have identified the 1-based index of the item in the cart, you can use the line property instead of id like so:
+
The cart is returned in response to this call in JSON format.
  
 +
As described in the previous section, line item properties mean that line items cannot necessarily be uniquely identified in the cart by their '''id'''. In these cases it is necessary to use the 1-origin based index of the line item in the cart.
 +
<pre>
 
{
 
{
   quantity: 1,
+
   line: 1,
   line: 1
+
   quantity: 10
 
}
 
}
 +
</pre>
  
jQuery.post('/cart/change.js', { quantity: 1, line: 1 });
+
For example,
 +
<pre>
 +
jQuery.post('/cart/change.js', { line: 1, quantity: 10 });
 +
</pre>
  
Caution
+
The '/cart/update.js' and '/cart/change.js' calls appear to do very similar things, but there are important differences.
  
Although /cart/update.js and /cart/change.js may seem like they accomplish the same function, they truly are quite different. The /cart/update.js controller allows updates to several items at once, including items that may not yet be in the cart (it will add them), and it also allows updates of cart attributes and the cart note. The /cart/change.js controller is only able to update the quantity of one item at a time, and that item must be in the cart already. If the item is not in the cart, /cart/change.js will not add it and it will then return a 404 error. Whereas the /cart/update.js controller updates no quantity when any of the requested update cannot be met, the /cart/change.js controller, on the other hand, will adjust the quantity to add all items in stock if what is requested is greater than what's available. Use your browser's JavaScript console to test things out if you're not sure about the behavior of the different request URLs.
+
The '/cart/update.js' call allows several line items to be updated at once, including items that may not yet be in the cart. These new items will be automatically added to the cart. In addition, the cart note and attributes can also be updated using this call.
  
=== <code>POST /cart/clear.js</code> ===
+
The '/cart/change.js' call can only update the quantity of one line item at a time, and that line item must alreay be in the cart.
  
This call sets all quantities of all line items in the cart to zero.
+
If the item is not in the cart, '/cart/change.js' will not add it.
  
Response The JSON of an empty cart. This does not remove cart attributes nor the cart note.
+
=== <code>POST /cart/clear.js</code> ===
  
Example:
+
This call empties the cart by setting the quantities of all line items in the cart to zero.
  
 +
An empty cart is returned in JSON format. The cart attributes and note are preserved.
 +
<pre>
 
{
 
{
   "token": "1d19a32178501c44ef2223d73c54d16d",
+
   "token": "618409804635da614f1060f363bec493",
   "note": null,
+
   "note": "",
   "attributes": {},
+
   "attributes": "",
   "total_price": 0,
+
   "total_price": "0.00",
 +
  "cart_discount": "0.00",
 
   "total_weight": 0,
 
   "total_weight": 0,
 
   "item_count": 0,
 
   "item_count": 0,
   "items": [],
+
   "items": [
   "requires_shipping": false
+
   
 +
  ],
 +
   "exchange_rate": 0.6297373387,
 +
  "currency": "GBP"
 
}
 
}
 +
</pre>
  
 +
=== Processing Requests Synchronously ===
  
You're building a quick order form? Beware
+
Ajax requests that update the cart must be queued and sent synchronously to the server.
Caution
 
 
 
Ajax requests that update the cart must be queued and sent synchronously to the server. Meaning: you must wait for your 1st ajax callback, to send your 2nd request, and then wait for its callback to send your 3rd request, etc.
 
 
 
Your request queue can be a very simple JavaScript array:
 
  
 +
A request queue can be created simply by using a Javascript array.
 +
<pre>
 
Spiffy.queue = [];
 
Spiffy.queue = [];
 +
</pre>
  
As you examine your quantity fields, you will add requests to that queue:
+
All you need to do is to search through all the quantity fields, and add the requests to the queue.
 
+
<pre>
 
jQuery('.quantity').each(function() {
 
jQuery('.quantity').each(function() {
 
   Spiffy.queue.push( {
 
   Spiffy.queue.push( {
 
     variantId: jQuery(this).data('variant-id'),
 
     variantId: jQuery(this).data('variant-id'),
 
     quantity: parseInt(jQuery(this).val(), 10) || 0
 
     quantity: parseInt(jQuery(this).val(), 10) || 0
   } );
+
   });
 
});
 
});
 +
</pre>
  
When you are done, you start your engine, using for instance Spiffy.addItem.
+
Once the queue is ready to process, you can call the Ajax API, using the wrapper function '''Spiffy.addItem''' for example.
  
The callback of this Ajax request should call a function that shifts (removes) a request from Spiffy.queue and then call Spiffy.addItem with the variantId and quantity stored in the next request. Of course, you'll check if the queue has any requests left in it. If it's empty, you must cheerfully redirect to the cart page.
+
The callback for this Ajax request should be a function that removes the most recently processed request from '''Spiffy.queue''' and then calls '''Spiffy.addItem''' again to process the next request, for as long as requests remain in the queue to be processed.
  
Something like this:
+
For example:
 
+
<pre>
Spiffy.moveAlong = function() {
+
Spiffy.procesQueue = function() {
  // If we still have requests in the queue, let's process the next one.
+
   if (Spiffy.queue.length > 0) {
   if (Spiffy.queue.length) {
 
 
     var request = Spiffy.queue.shift();
 
     var request = Spiffy.queue.shift();
     Spiffy.addItem(request.variantId, request.quantity, Spiffy.moveAlong);
+
     Spiffy.addItem(request.variantId, request.quantity, Spiffy.processQueue);
   }
+
   } else {
  // If the queue is empty, we will redirect to the cart page.
+
    // If the queue is empty, then redirect back to the cart page.
  else {
 
 
     document.location.href = '/cart';
 
     document.location.href = '/cart';
 
   }
 
   }
 
};
 
};
 
+
</pre>
Spiffy.moveAlong must be called within the callback of each Ajax request.
 

Latest revision as of 12:59, 28 August 2015

You can access the Spiffy Ajax API from your theme to enhance your customers' experience on your store.

The Spiffy Ajax API allows your customer to add items to the cart, update quantities in the cart and fetch information about the cart, all without requiring a page refresh. You can use the API to create 'add to cart' buttons that keep the customer on the product pages.

The Spiffy Ajax API also allows you to directly fetch information about a particular product using its handle.

Simple Access using the Wrapper Library

If you are using the jQuery JavaScript framework in your theme, then you can use the Spiffy Ajax API wrapper library to simplify the use of the API.

Of course, it's not necessary to use the wrapper library, or to code in jQuery to use the Ajax API, but if you do use the wrapper library, then a lot of the detailed API access work has already been done for you.

To use the Spiffy Ajax API jQuery wrapper library, you will need to include the following code in your theme.liquid file.

{{ 'jquery.js' | global_asset_url | script_tag }}
{{ 'api.jquery.js' | global_asset_url | script_tag }}

Wrapper Library Function Reference

Utility Functions

Spiffy.formatMoney(price, format)

Returns a formatted string, given a numberic price and optional format string.

The price is the floating-point value in the base unit of currency. For example, the price 1234.45 would be formatted as $1,234.56 using the default format.

The format string can include any characters, along with a substitution variable with the following values:

  • amount - Default formatting for the currency
  • amount_no_decimals - Uses only the base currency unit
  • amount_with_comma_separator - Uses a comma to specify the decimals
  • amount_no_decimals_with_comma_separator - Uses a comma decimal separator

For example, the default format string is

'${{amount}}'

Spiffy.onError(XMLHttpRequest, textStatus)

Spiffy.onCartUpdate(cart)

Spiffy.onItemAdded(line_item)

Spiffy.onProduct(product)

Spiffy.resizeImage(image, size)

Ajax Calls

Spiffy.addItem(variant_id, quantity, callback)

Spiffy.addItemFromForm(form_id, callback)

Spiffy.getCart(callback)

Spiffy.getProduct(handle, callback)

Spiffy.changeItem(variant_id, quantity, callback)

Spiffy.changeItemIndex(cart_index, quantity, callback)

Spiffy.removeItem(variant_id, callback)

Spiffy.removeItemIndex(cart_index, callback)

Spiffy.clear(callback)

Spiffy.updateCart(updates, callback)

Spiffy.updateCartFromForm(form_id, callback)

Spiffy.updateCartAttributes(attributes, callback)

Spiffy.updateCartNote(note, callback)

Spiffy Ajax API Reference

GET /products/<product-handle>.js

Retrieve a product using the product handle and return the results as a JSON representation of the product.

Example:

{
  "id": 3121506,
  "title": "T-Shirt",
  "handle": "t-shirt",
  "url": "/products/t-shirt",
  "description": "<p>Featuring distressed edges & short sleeves.</p>",
  "created_at": "2008-07-16T08:25:09+10:00",
  "updated_at": "2015-06-24T14:04:58+10:00",
  "vendor": "Spiffy Stores",
  "type": "T-Shirts",
  "tags": [
    "clothing",
    "t-shirt"
  ],
  "price": "16.30",
  "price_max": "19.45",
  "price_min": "16.30",
  "available": true,
  "price_varies": true,
  "compare_at_price": "0.00",
  "compare_at_price_max": "12.59",
  "compare_at_price_min": "0.00",
  "compare_at_price_varies": true,
  "images": [
    {
      "id": 1840,
      "product_id": 3121506,
      "type": "Product",
      "position": 1,
      "alt": "",
      "src": "http://mystore.spiffystores.com/sites/1/products/1506_limet_000_full.jpg"
    },
    {
      "id": 1841,
      "product_id": 3121506,
      "type": "Product",
      "position": 2,
      "alt": "",
      "src": "http://mystore.spiffystores.com/sites/1/products/1506_tealt_000_full.jpg"
    }
  ],
  "featured_image": {
    "id": 1840,
    "product_id": 3121506,
    "type": "Product",
    "position": 1,
    "alt": "",
    "src": "http://mystore.spiffystores.com/sites/1/products/1506_limet_000_full.jpg"
  },
  "options": [
    "Size",
    "Colour",
    "Thread Colour"
  ],
  "option_values": [
    [
      "S",
      "M",
      "L",
      "XL",
      "XXL",
      "XXXL"
    ],
    [
      "Orange",
      "Green",
      "Purple",
      "Red"
    ],
    [
      "Teal",
      "Yellow"
    ]
  ],
  "option_combos": [
    [
      "0.0",
      "Teal"
    ],
    [
      "0.6297373387",
      "Yellow"
    ]
  ],
  "variant_option_index": 2,
  "variants": [
    {
      "id": "1691_0",
      "title": "S/Orange Teal",
      "price": "16.30",
      "compare_at_price": "0.00",
      "discount": "0.00",
      "available": true,
      "inventory": true,
      "inventory_quantity": 10,
      "inventory_management": "spiffy",
      "inventory_policy": "deny",
      "weight": 100,
      "sku": "SHIRT002",
      "barcode": "",
      "requires_shipping": true,
      "taxable": true,
      "free_shipping": false,
      "ship_separately": false,
      "option1": "S",
      "option2": "Orange",
      "option3": null,
      "options_id": 0
    },
    {
      "id": "1691_1",
      "title": "S/Orange Yellow",
      "price": "16.69",
      "compare_at_price": "0.00",
      "discount": "0.00",
      "available": true,
      "inventory": true,
      "inventory_quantity": 10,
      "inventory_management": "spiffy",
      "inventory_policy": "deny",
      "weight": 100,
      "sku": "SHIRT002",
      "barcode": "",
      "requires_shipping": true,
      "taxable": true,
      "free_shipping": false,
      "ship_separately": false,
      "option1": "S",
      "option2": "Orange",
      "option3": null,
      "options_id": 1
    },
    {
      "id": "1690_0",
      "title": "M/Green Teal",
      "price": "16.61",
      "compare_at_price": "0.00",
      "discount": "0.00",
      "available": true,
      "inventory": true,
      "inventory_quantity": 93,
      "inventory_management": "spiffy",
      "inventory_policy": "deny",
      "weight": 100,
      "sku": "SHIRT001",
      "barcode": "",
      "requires_shipping": true,
      "taxable": true,
      "free_shipping": false,
      "ship_separately": false,
      "option1": "M",
      "option2": "Green",
      "option3": null,
      "options_id": 0
    },
    
...
    {
      "id": "2137_1",
      "title": "XXXL/Orange Yellow",
      "price": "19.84",
      "compare_at_price": "12.59",
      "discount": "0.00",
      "available": true,
      "inventory": true,
      "inventory_quantity": 20,
      "inventory_management": "spiffy",
      "inventory_policy": "deny",
      "weight": 0,
      "sku": "SHIRT007",
      "barcode": "",
      "requires_shipping": true,
      "taxable": true,
      "free_shipping": false,
      "ship_separately": false,
      "option1": "XXXL",
      "option2": "Orange",
      "option3": null,
      "options_id": 1
    }
  ],
  "exchange_rate": 0.6297373387,
  "currency": "GBP"
}

Example call using jQuery:

jQuery.getJSON('/products/t-shirt.js', function(product) {
  alert('The title of this product is ' + product.title);
});

POST /cart/add.js

A product variation can be added to the cart using this call.

POST data is required and takes the form:

{
  id: 234234,
  quantity: 2
}

If the product uses custom options, then a composite variation id is used indicate which combination of custom options is to be used with the variation.

{
  id: '334234_1',
  quantity: 2
}

The quantity indicates how many items you wish to add to the cart for the specified variation.

The data can also be sent from a form if it is serialized.

  jQuery.post('/cart/add.js', $('form[action="/cart/add"]').serialize());

You can also add an item to the cart with Line Item Properties, in addition to the quantity and id.

jQuery.post('/cart/add.js', {
  id: 3453663,
  quantity: 1,
  properties: {
    'gift wrapping': 'Yes',
    'card message': 'So pleased to meet you last week.'
  }
});

Only a single variation can be added to the cart with this Ajax request. Multiple variations can be added by queuing up several Ajax requests synchronously.

If the variation is added to the cart successfully, the cart line item is returned in JSON format.

{
  "cart_index": 1,
  "variant_id": 1771,
  "product_id": 1504,
  "options_id": 1,
  "title": "Artichoke - Tiny - Silk metallic<span><br/>Signs<br/>Sign 10% Off</span>",
  "price": "6.77",
  "discount": "1.35",
  "quantity": 2,
  "line_price": "12.19",
  "sku": "9111003",
  "grams": 20,
  "note": null,
  "taxable": true,
  "message": "",
  "vendor": "Spiffy Stores",
  "url": "/products/artichoke",
  "image": "/site/products/1504_artichoke_01_full.jpg",
  "handle": "artichoke",
  "product_title": "Artichoke",
  "product_description": "The Globe Artichoke is a perennial thistle originating in southern Europe around the Mediterranean. It grows to 1.5-2 m tall, with arching, deeply ...",
  "product_type": "Vegetables",
  "variant_title": "Tiny",
  "variant_options": [
    "Tiny"
  ],
  "requires_shipping": true
}

If the item is already in the cart, then the quantity will be equal to the new quantity for that item.

If a non-existent variation is added to the cart, an error will be returned instead, as follows:

{
  "message": "Cart Error",
  "status": 422,
  "description": "Variation not found"
}

All error messages are returned as JSON data structures.

The error code is:

422 (Unprocessable Entity)

Other errors may be returned if exception conditions with the cart are detected. For example, each cart supports only a limited number of items and if this value is exceeded, then an error is returned.

If an item is sold out, then the error message returned is:

"The product 'VARIATION' is already sold out"

If there are items in stock, then it is possible add these items to the cart. The actual number of items requested are reserved, but the actual inventory check is not performed until the customer proceeds to the checkout where the actual number of items ordered may need to be reduced if there are not enough still in stock to meet the requested number.

GET /cart.js

Retrieve the cart contents as a JSON data structure.

For example, the cart will look something like this:

{
  "token": "618409804635da614f1060f363bec493",
  "note": "This is a test cart note.",
  "attributes": "",
  "total_price": "24.37",
  "cart_discount": "2.71",
  "total_weight": 0,
  "item_count": 4,
  "items": [
    {
      "cart_index": 1,
      "variant_id": 1771,
      "product_id": 1504,
      "options_id": 1,
      "title": "Artichoke - Tiny - Silk metallic<span><br/>Signs<br/>Sign 10% Off</span>",
      "price": "6.77",
      "discount": "2.71",
      "quantity": 4,
      "line_price": "24.37",
      "sku": "9111003",
      "grams": 40,
      "note": null,
      "taxable": true,
      "message": "",
      "vendor": "Spiffy Stores",
      "url": "/products/artichoke",
      "image": "/site/products/1504_artichoke_01_full.jpg",
      "handle": "artichoke",
      "product_title": "Artichoke",
      "product_description": "The Globe Artichoke is a perennial thistle originating in southern Europe around the Mediterranean. It grows to 1.5-2 m tall, with arching, deeply ...",
      "product_type": "Vegetables",
      "variant_title": "Tiny",
      "variant_options": [
        "Tiny"
      ],
      "requires_shipping": true
    }
  ],
  "exchange_rate": 0.6297373387,
  "currency": "GBP"
}

Example of a response for an empty cart:

{
  "token": "618409804635da614f1060f363bec493",
  "note": "",
  "attributes": "",
  "total_price": "0.00",
  "cart_discount": "0.00",
  "total_weight": 0,
  "item_count": 0,
  "items": [
    
  ],
  "exchange_rate": 0.6297373387,
  "currency": "GBP"
}

POST /cart/update.js

This call can be used to change cart attributes, the cart note and the line item quantities in the cart.

POST data is required and takes the following forms.

For a single line item, just provide the variation id and quantity required.

{
  id: 72331312,
  quantity: 2
}

If the product uses custom options, then a composite variation id is used indicate which combination of custom options is to be used with the variation.

{
  id: '334234_1',
  quantity: 2
}

Multiple line items can be updated in a single call, where the keys of the updates are the variation ids of the required line items.

{
  updates: { 12345: 2, 67890: 3 }
}

The quantity indicates how many items you wish to add to the cart for the specified variation.

The data may also be sent in serialized form from the form data fields.

The contents of the cart in JSON format are returned from this call.

The cart note can also be updated.

{
  note: "This is an updated cart note."
}

Similarly, the cart attributes can be updated.

{
  attributes[key1]: "First attribute",
  attributes[key2]: "Second attribute"
} 

The result of this call would be:

{
  "token": "618409804635da614f1060f363bec493",
  "note": "",
  "attributes": {
    "key1": "First attribute",
    "key2": "Second attribute"
  },
  "total_price": "0.00",
  "cart_discount": "0.00",
  "total_weight": 0.0,
  "item_count": 0,
  "items": [],
  "exchange_rate": 0.6297373387,
  "currency": "AUD"
}

If the cart is empty the following jQuery example will add 2 items of variation 2345345 and 3 items of variant 364566:

jQuery.post('/cart/update.js', { updates: { 2345345: 2, 364566: 3 } });

This same result can be achieved with slightly different syntax:

jQuery.post('/cart/update.js', "updates[2345345]=2&updates[364566]=3");

Similarly, a single line item can be updated as follows:

jQuery.post('/cart/update.js', { updates: { 2345345: 2 } });

Finally, line items can be removed from the cart by setting their quantity to zero:

jQuery.post('/cart/update.js', { updates: { 2345345: 0, 364566: 0 } });

The properties of a line item can be set when an item is added to the cart. This means that the same variation can exist more than once in a cart, as each line item can have different customization data.

This means that it may not be possible to identify a unique variation in a cart by its id, as multiple line items in the cart may have the same id.

If this is the case, then the only way to update the line item quantities is to provide an array of new quantities for each line item, where the order of elements in the array matches the order of line items in the cart.

When you use this method of updating line items, the number of elements in the array must match the number of line items in the cart.

For example, if you have 3 line items in the cart, with quantities 1, 2 and 3, and you want to update these quantities to 3, 2 and 1, you can use the following example:

jQuery.post('/cart/update.js', { updates: [3, 2, 1] });

The above method requires you to update the quantities of all line items in the cart. It's possible to change just one line item by using the /cart/change.js call instead, where the line item is specified using a 1-origin based line item index.

jQuery.post('/cart/change.js', { line: 1, quantity: 1 });

Similarly, to change the quantity of the second line item in the cart, we use this example:

jQuery.post('/cart/change.js', { line: 2, quantity: 1 });

POST /cart/change.js

This call updates the quantity of an item already in the cart.

POST data is required and takes the form:

{
  id: 234234,
  quantity: 2
}

If the product uses custom options, then a composite variation id is used indicate which combination of custom options is to be used with the variation.

{
  id: '334234_1',
  quantity: 2
}

The quantity indicates how many items you wish to add to the cart for the specified variation.

The cart is returned in response to this call in JSON format.

As described in the previous section, line item properties mean that line items cannot necessarily be uniquely identified in the cart by their id. In these cases it is necessary to use the 1-origin based index of the line item in the cart.

{
  line: 1,
  quantity: 10
}

For example,

jQuery.post('/cart/change.js', { line: 1, quantity: 10 });

The '/cart/update.js' and '/cart/change.js' calls appear to do very similar things, but there are important differences.

The '/cart/update.js' call allows several line items to be updated at once, including items that may not yet be in the cart. These new items will be automatically added to the cart. In addition, the cart note and attributes can also be updated using this call.

The '/cart/change.js' call can only update the quantity of one line item at a time, and that line item must alreay be in the cart.

If the item is not in the cart, '/cart/change.js' will not add it.

POST /cart/clear.js

This call empties the cart by setting the quantities of all line items in the cart to zero.

An empty cart is returned in JSON format. The cart attributes and note are preserved.

{
  "token": "618409804635da614f1060f363bec493",
  "note": "",
  "attributes": "",
  "total_price": "0.00",
  "cart_discount": "0.00",
  "total_weight": 0,
  "item_count": 0,
  "items": [
    
  ],
  "exchange_rate": 0.6297373387,
  "currency": "GBP"
}

Processing Requests Synchronously

Ajax requests that update the cart must be queued and sent synchronously to the server.

A request queue can be created simply by using a Javascript array.

Spiffy.queue = [];

All you need to do is to search through all the quantity fields, and add the requests to the queue.

jQuery('.quantity').each(function() {
  Spiffy.queue.push( {
    variantId: jQuery(this).data('variant-id'),
    quantity: parseInt(jQuery(this).val(), 10) || 0
  });
});

Once the queue is ready to process, you can call the Ajax API, using the wrapper function Spiffy.addItem for example.

The callback for this Ajax request should be a function that removes the most recently processed request from Spiffy.queue and then calls Spiffy.addItem again to process the next request, for as long as requests remain in the queue to be processed.

For example:

Spiffy.procesQueue = function() {
  if (Spiffy.queue.length > 0) {
    var request = Spiffy.queue.shift();
    Spiffy.addItem(request.variantId, request.quantity, Spiffy.processQueue);
  } else {
    // If the queue is empty, then redirect back to the cart page.
    document.location.href = '/cart';
  }
};