Store API is now considered stable

The new Store API is something we’ve been building alongside the Cart and Checkout Blocks for the past two years. It not only powers the new Block based Cart and Checkout experience, but also the various product Blocks as well.

As part of WooCommerce Blocks 7.2 (and the upcoming WooCommerce 6.4 release) this API can now be considered stable. It has been finalised, versioned, and can now be utilised by developers more easily!

What is the Store API exactly?

Making sure that Store API is agnostic to the view part was a critical step. Along the way, we also tried to make it environment agnostic.

Nadir Seghir, Cart & Checkout Engineer

The WooCommerce Store API provides public REST API endpoints for the development of customer-facing cart, checkout, and product functionality.

Since it follows many of the patterns used in the WordPress REST API, it should be familiar to developers who have worked with APIs before.

Whilst the Store API is heavily utilised by the Cart and Checkout Blocks, it is built in such a way that it works independently so it can be consumed by anyone.


What blocks are using the Store API?

The Store API is already being used throughout WooCommerce Blocks.

All Products Block

Gets products from the Store API to display via the wc/store/v1/products endpoint. The product filter blocks also use Store API to limit which products are shown.

Cart Block

Updates cart items, calculates totals, and shows available shipping options/shipping calculator. Also has a coupon form. Gets data via wc/store/v1/cart.

Checkout Block

Updates customer session data, calculates shipping, and creates orders/processes payments via the wc/store/v1/checkout endpoint.


How does the Store API compare to the WC REST API?

The main difference between the Store API and WC REST API is that the Store API allows unauthenticated access to store data, for example, products. This makes it suitable for a variety of use-cases, including custom frontends.

This is an unauthenticated API. It does not require API keys or authentication tokens for access.

Another difference is that the Store API has support for Cart data. This allows for cart operations such as adding items to the cart, updating quantities, applying coupons, and submitting orders. Only the current customer’s cart can be accessed.

Data returned from the Store API is always reflective of the current user (cookie-based), whereas the WC REST API allows more extensive access to any data, should you have the correct access rights.


API Versioning

Now that a v1 of the API has been released (under the namespace wc/store/v1), this API can be considered stable.

The Store API establishes a contract between itself and API consumers via the use of Schema. This contract should not be broken unless absolutely necessary.

As our guiding principles explain, no breaking changes are permitted, only changes which are backwards compatible. Some examples of allowed changes include:

  • Adding new properties to schema
  • Adding new routes, endpoints, methods
  • Adding optional request parameters
  • Re-ordering response fields

If ever the need arises for a non-backwards compatible change, we’d release a new version (wc/store/v2) leaving the v1 route intact and unaltered.


Examples

Here is a basic example showing how to query products using cURL and return the results in JSON format:

curl "https://example-store.com/wp-json/wc/store/v1/products"

Here is another example, querying a single product by it’s ID and sending the results to jq for formatting:

 curl "https://store.local/wp-json/wc/store/v1/products/35" | jq '.'
The JSON response for a single product

Using Insomnia API client

To demonstrate what is possible using the Store API, we can actually go through the entire purchase flow using just an API client–not even visiting the store!

First, I can get a list of products from /wc/store/v1/products. This returns products in JSON format and shows product IDs and pricing information:

200 OK products response

We can then pick which product we’d like to add to the cart, and go ahead and add it via the /wc/store/v1/cart/add-item route. This will either add the item to the cart, returning the new updated cart object, or return an error response if something went wrong.

Adding items to the cart via the Store API

With the item now in the cart, we can attempt to purchase it using the /wc/store/v1/checkout endpoint. This requires a billing and shipping address, and a chosen payment method. The payload we send looks something like this:

{
    "billing_address": {
        "first_name": "Steve",
        "last_name": "Stevenson",
        "email": "test@test.com",
        "address_1": "41 Some Street",
        "city": "Townford",
        "postcode": "CB25 6FG",
        "country": "GB"
    },
    "shipping_address": {
        "first_name": "Steve",
        "last_name": "Stevenson",
        "address_1": "41 Some Street",
        "city": "Townford",
        "postcode": "CB25 6FG",
        "country": "GB"
    },
    "payment_method": "bacs"
}

We also need a special header (Nonce) to confirm the user actually wants to checkout. This header is returned via other requests so can be stored in your client.

Adding the nonce header via Insomnia

Once we send our payload and Nonce header, we’ll get either an error or success response back from the API, and we’re done! We can now see the successfully placed order in WooCommerce admin!

200 OK response from the checkout

With this success, we can now see the successfully placed order in WooCommerce admin!

The order that was placed via the Store API

Further Reading

If you’d like to learn more about the Store API and how you can use it in extensions or custom code, check out the following resources:

For feedback, reporting issues, or submitting feature requests, you can do so here on GitHub.


Keep yourself in the loop!

This field is hidden when viewing the form
This field is hidden when viewing the form
This field is hidden when viewing the form


36 responses to “Store API is now considered stable”

  1. Store API allows unauthenticated access to store data, for example, products. This makes it suitable for a variety of use-cases, including custom frontends.

    This allows for cart operations such as adding items to the cart, updating quantities, applying coupons, and submitting orders. Only the current customer’s cart can be accessed.

    Looks like this might be something prone to abuse by scammers and people who buy products on discount to resell them later. Will this be off by default?

    1. Hi! Everything that store API allows is already possible via the store itself and via AJAX requests. The store API is formalising this interface so it can be used by client-side apps. As mentioned in the post, it’s already being used by several Blocks, so it’s on by default (disabling it would prevent such Blocks from functioning).

  2. David Anderson Avatar
    David Anderson

    Does this bypass plugins that apply restrictions or make changes on the current checkout page, until they are updated to be integrated?
    e.g. Suppose a plugin currently applies a restriction on the checkout page – does the API now provide a way round that?

    1. Behind the scenes, this API still uses the global WooCommerce cart object, and checkout validation hooks, so as long as the plugin uses those, it should be covered. If it’s client-side validation targeting the checkout shortcode, it won’t be compatible.

  3. I immediately checked out all the examples and tested them – awesome!

    One thing that is a bit unclear for me: how do we handle payment methods like Stripe and PayPal? I can see that we can add “payment_data” in /wc/store/v1/checkout to add additional data.

    That means someone would implement PayPal/Stripe on the client-side, the users fulfill the payment, and we would send the data to WooCommerce, right?

    Are there any examples of this?

    1. Hi Patrick

      Payment methods are slightly more complex in that support relies on some integration code that I didn’t want to cover here.

      We have some guidelines for gateway integrations: https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/trunk/docs/extensibility/README.md#checkout-payment-methods

      Payment gateways can extend the Store API and handle posted payment_data to fulfil requests. Usually, they also require some extra code in the client too to collect what data they require. If you want to look at a gateway that integrates with the Checkout Block and the Store API, Stripe is one such example. https://wordpress.org/plugins/woocommerce-gateway-stripe/

      Glad the examples worked for you!

      1. Hey Mike,

        thanks for the link to the guidelines!

        Looks really promising. It’s cool that there are ways to handle the entire transaction.

        One last question:

        Is there a way to restore the cart created via API on the website?
        I can see that we get the cart hash in the response. Could we use that to get/restore the cart?

        Sorry for keep asking questions, haha 🙂

        Have a nice parental leave!

        Patrick

        1. senadir Avatar

          Hey! the cart is still linked via cookies and sessions, so if you pass those to the server, you can get the cart back, you can also use the hash to restore it manually if you want.

  4. i don’t use php ,when i use storeApi,how to get Nonces , by storeApi or other way ?

    1. senadir Avatar

      Hey! You get a nonce on each request you do to Store API, and you need to provide a Nonce on all POST requests, meaning you can GET /store/cart which will have the nonce in a header, and pass it back for your future requests.

      It’s best if you have a middleware that intercept, hold, and pass back nonces for your requests.

  5. how to get Nonces by api ?

  6. philipnd Avatar
    philipnd

    Does the store API not support variable products? If I’m adding a simple product, it works with the following, but what if I need to add by variation id?:
    {
    “id”: 66064,
    “quanity”: 10
    }

    1. senadir Avatar
      senadir

      To add a product by variation, you need to pass the variation data in your request:

      [code lang=text]
      {
      "id": 375,
      "quantity": 1,
      "variation": [
      {
      "attribute": "pa_color",
      "value": "blue"
      },
      {
      "attribute": "pa_size",
      "value": "large"
      }
      ]
      }
      [/code]

  7. How do I add a variable product to the cart?

    1. senadir Avatar
      senadir

      Yes it does, check the comment above for an example.

      1. Thank you very much

  8. Dinesh Patel Avatar
    Dinesh Patel

    How can i pass custom meta data to cart item and fetch in wp-json/wc/store/v1/cart endpoint..?

    1. senadir Avatar
      senadir

      Using the woocommerce_get_item_data filter

      [code lang=text]
      add_filter( 'woocommerce_get_item_data', function( $data, $cart_item ) {
      $product = $cart_item['data'];
      if ( $product->get_id() === $myId ) {
      $data[] = [
      "name" => "meta-field",
      "value" => "10"
      ];
      }
      return $data;
      }, 10, 2 );
      [/code]

      1. Dinesh Patel Avatar
        Dinesh Patel

        Thank you for your reply. I want to add custom data to cart for endpoint like below..

        wc/store/v1/cart/add-item

        {
        “id”: 120,
        “quantity”: 1,
        “variation”: [
        {
        “attribute”: “pa_color”,
        “value”: “blue”
        }
        ],
        “item_data”: [
        {
        “name” : “ring_size”,
        “value” : “5”
        },
        {
        “name” : “metal”,
        “value” : “gold”
        }
        ],
        }

        In above example i want to add item_data to cart as custom data..

        1. senadir Avatar
          senadir

          Passing custom meta data isn’t possible right now, but might be in the future once we start looking into more custom product types and custom plugins.

  9. Dinesh Patel Avatar
    Dinesh Patel

    How can i manage user cart with guest cart? When i am adding products in cart as guest customer its working fine but i want to move all the cart items of guest to specific customer account when customer logs in… How can i manage customer login and pass all cart data to that customer..?

    1. senadir Avatar
      senadir

      To merge carts (the existing user cart with the guest cart) you need to pass the same woocommerce_cart_hash cookie when you log in your user, this will merge your carts.

  10. Dinesh Patel Avatar
    Dinesh Patel

    Can you tell me list of hooks available for customization of Store api query and data like traditional rest api.?

    1. senadir Avatar
      senadir

      Store API doesn’t provide the same APIs you have in REST API to customize the output. What exactly are you looking to customize?

      1. Dinesh Patel Avatar
        Dinesh Patel

        I want to customize wp-json/wc/store/v1/products endpoint for listing products with custom meta queries, products by category slug tax query and return custom extra data to response json.

        1. senadir Avatar
          senadir

          Returning custom data can be done using ExtendRestAPI, see this endpoint.

          For querying with custom tax queries, this is possible but in a testing stage using __unstable-tax-[taxonomy-slug], see this PR.

          You currently can’t filter posts by meta queries.

  11. how to update / edit customer address details using rest api

    1. Nadir Seghir Avatar
      Nadir Seghir

      Hey! You can use the wc/store/cart/update-customer endpoint to update the current customer information.

  12. Cupid Chakma Avatar
    Cupid Chakma

    How to handle data for attributes that has value ‘any’, if an attribute for example ‘pa_cars’ alias ‘Cars’ has been set inside the variation array as an object. Once the data is sent using add-item api for the attribute that has value ‘any’ for variation product. Still it shows error, that ‘Cars’ is a required field how to fix that?

  13. mohd israr ansari Avatar
    mohd israr ansari

    how to get nonce value ? i was testing store apis in postman, I added few items from wordpress website items are adding. then i called wc/store/cart api , i m getting all cart items also but when i am calling wc/stroe/add-to-cart api then i m getting error – “woocommerce_rest_missing_nonce”. after 2 days i saw postman adding one header value – X-WC-Store-API-Nonce – “3437(random string)” when i pass this value in header then add to cart api worked. but when i call remove item api then i m getting error woocommerce_rest_invalid_nonce can u please post one blog on this issue and explain how to get nonce values and how to pass it into header

    1. Nadir Seghir Avatar
      Nadir Seghir

      You get a nonce value on each response you get from Store API, a common pattern is to initially fetch /wc/store/cart on load, and save the response Nonce header, and use that in subsequent requests.

  14. Hey we are currently using Authorize.net and paypal as our payment gateway system on our website. Will it be possible to use store api and pass billing details through api to let woocommerce continue handling the payments.

    1. Nadir Seghir Avatar
      Nadir Seghir

      If you’re using them with regular Checkout (block or shortcode) it should be fine and there should be no extra work from your side, if you’re building your own Checkout on top of Store API, then yeah, you can pass whatever you want with it.

  15. Trying to wrap my head around this. Would it be possible to create a non-headless checkout page using the nonce and cart-token from a headless store? In Shopify it’s possible to refer to the cart id on the checkout page. I would love to do the same thing passing the cart-token as a query-string to the WC checkout page.

    Giving up on cookies because of CORS’s makes it to difficult.

    1. Nadir Seghir Avatar
      Nadir Seghir

      Yes, but this would require some custom code on your part.

      Basically, when a request comes in to a page, WooCommerce checks if a header is present with Cart-Token, and would load the Cart-Token session handler, otherwise, it will continue with the cookie handler.

      What you can do is to hook up a bit earlier, check if a query string with your cart token is present, and assign it as a header to that request. The rest should work fine.

      Keep in mind that Cart Token only work for logged out users, logged in users would still be presented with the same Cart :/ You might need to write a new SessionHandler for that until we cover it from our side.

  16. Hi it’s possible to add product bundle with add-item ?

Leave a Reply

Your email address will not be published. Required fields are marked *