Improving the session table

One question I get asked from time to time is “Why does CoCart have it’s own session handler / database table?”

The reason for this is the default session handler is not designed to support guest customers outside of the site. It’s designed for the purpose of handling session requests with your browser.

Although guest customers were given a unique generated ID, this could only be tracked using the cookie WooCommerce stores on your device when browsing the store.

This does not help for a headless architect/setup when handling the cart outside of the site. So a new session handler was created in order to support guest customers for better tracking.

But why a new session table?

Well to begin with it was only experimental to test the new session handler but after sometime developing the new handler, I decided to keep it place for future developments.

This would allow me to alter the session table after without interfering with WooCommerce default session table structure.

This secures CoCart by making sure it still works should WooCommerce decide to change how their session table is structured in the future.

Now for the improvements

Although small, these additions I think are a great help to store managers and developers.

The new additions to the session table are “Cart Source” and “Cart Created“.

Now carts can be identified if they were created via CoCart or WooCommerce with the date and timestamp for when the cart was created the moment the first item was added to the cart.

I think this is a great addition and with that a new free add-on will be available that will allow you to view carts in session from your WordPress dashboard.

Screenshot is a work in progress.

This is something users have been asking for and it has defiantly helped me with testing CoCart during it’s development.

Hope you like the new additions and add-on coming soon.

Grouped Products now accepted

If you been wanting to add grouped products to the cart, well now you can in CoCart v3.

Bare in mind this is not the same as adding products in bulk. You are required to pass the product ID of the container product that is a grouped product along with the items it contains you wish to add to the cart.

Simply adding the container product to the cart will not automatically assume you want to add one of every item in the grouped product to the cart.

Adding a grouped product to the cart via CoCart acts exactly the same as you would on a normal WooCommerce store setup.

You need a minimum of one item in the grouped product along with the quantity of that item in order to successfully add the product to the cart.

curl -X POST https://example.com/wp-json/cocart/v2/add-items \
  -H "Content-Type: application/json" \
  -d '{
	"id": "91", /* Grouped product container. */
	"quantity": {
		"71": 2, /* Product ID: Quantity. */
		"72": 1
	}
}'

Each item from the grouped product added is validated. Any item that has restrictions from stock to quantity limits gone over will return an error response detailing which products could not be added.

So that is grouped products.

What about other bundled product types?

Support for developers have also been added to the API in order for extensions to add support for their product bundle types.

More product types will be supported in CoCart Pro in the future.

New Add-on in Development: Carts in Session

One of the many things users have requested, (that WooCommerce don’t provide by default) is the ability to view the carts in session.

Today I am happy to share a MVP of an add-on I’m developing that will allow you to do just that.

It is currently only available on GitHub. As it is in the alpha stage, there is still work to be done but it will give you the basics to begin with.

I look forward to your feedback and requests.

Enjoy.

S├ębastien.

Support your extension for the new CoCart API

With CoCart v3 near a code freeze, I’m excited to share that the new API is more connected to the front-end of WooCommerce than before.

New matching filters are included for the cart response so you can connect any of the filters you may have already used in your WooCommerce extension to filter the cart template to do the same for CoCart.

For example, your extension may have changed how the subtotal displays in the cart using woocommerce_cart_item_subtotal.

The same can be done for CoCart using cocart_cart_item_subtotal returning the same results and using the same arguments the filter uses.

This enables your extension to be compatible no matter what the store owner decides to use. Its that simple and only one additional line of code is required.

Take WooCommerce Free Gift Coupons extension for example. All that is required for the subtotal to match via the REST API is to apply the matching filter like so.

add_filter( 'cocart_cart_item_price', array( 'WC_Free_Gift_Coupons', 'cart_item_price' ), 10, 2 );

Matching filters

WooCommerce FilterCoCart Filter
woocommerce_cart_item_namecocart_cart_item_name
woocommerce_cart_item_pricecocart_cart_item_price
woocommerce_cart_item_quantitycocart_cart_item_quantity
woocommerce_cart_item_subtotalcocart_cart_item_subtotal
All filters use the same arguments and are in the same order.

If you need any assistance, you can join me and other developers in the CoCart Community via Slack.

I look forward to seeing more WooCommerce extensions supporting CoCart.

P.S. Not all matching filters can just be placed, some results may have to return formatted a little differently depending on how you have developed your extension for that particular area.

CoCart JavaScript Library v1.0.0 Release Notes

Updated: 25th January 2021

Excited to share finally a JavaScript library to help with your headless store development. Much like the WooCommerce JavaScript Library, this one is designed so authentication is optional.

Where to get it?

You can install the JavaScript Library simply running this command in your terminal.

npm install --save @cocart/cocart-rest-api

If you wish to contribute to the project you can access the GitHub repository.

Example of Use

// import CoCartAPI from "@cocart/cocart-rest-api"; // Supports ESM
const CoCartAPI = require("@cocart/cocart-rest-api").default;
 
const CoCart = new CoCartAPI({
  url: "http://example.com"
});

You can decide to use CommonJS (CJS) or ECMAScript Modules (ESM).

Since there is only one API version at this time there is no need to define the version when setting up your API constant. All that is required is the URL of your site.

FYI

This library will NOT support the LEGACY API of CoCart.

If you are authenticating a customer then you need to set the consumerKey (a.k.a Username) and consumerSecret (a.k.a Password).

// import CoCartAPI from "@cocart/cocart-rest-api"; // Supports ESM
const CoCartAPI = require("@cocart/cocart-rest-api").default;
 
const CoCart = new CoCartAPI({
  url: "http://example.com",
  consumerKey: "sebtest123",
  consumerSecret: "happycoding24"
});

You can then proceed to use the library to make requests like so.

Get Cart

// Get Cart
CoCart.get("get-cart", {
  thumb: true, // Returns product thumbnail
})
.then((response) => {
  // Successful request
  console.log("Response Status:", response.status);
  console.log("Response Headers:", response.headers);
  console.log("Response Data:", response.data);
})
.catch((error) => {
  // Invalid request, for 4xx and 5xx statuses
  console.log("Response Status:", error.response.status);
  console.log("Response Headers:", error.response.headers);
  console.log("Response Data:", error.response.data);
})
.finally(() => {
  // Always executed.
});

Add item to cart

// Add item to cart
CoCart.post("add-item", {
  product_id: "32",
  quantity: 1
})
.then((response) => {
  // Successful request
  console.log("Response Status:", response.status);
  console.log("Response Headers:", response.headers);
  console.log("Response Data:", response.data);
})
.catch((error) => {
  // Invalid request, for 4xx and 5xx statuses
  console.log("Response Status:", error.response.status);
  console.log("Response Headers:", error.response.headers);
  console.log("Response Data:", error.response.data);
})
.finally(() => {
  // Always executed.
});

You can view other examples provided in the documentation. Simply click on Node.js in the top right corner to see the command.