Product Inventory Management

One common need for online stores is being able to track inventory levels for products on your store - decreasing inventory as successful transactions are made, and preventing products from being added to the cart if no stock is available.

FoxyCart is a little different that other solutions available in that it doesn't manage your products for you - instead products are defined as links and forms on your website which send over the product details to the cart. As FoxyCart doesn't maintain your products, it then by association isn't able to track your existing inventory levels either. That said though, there is a number of features which can assist managing your store's inventory levels.

Existing Integrations

There are already some integrations which can assist with varying parts of the following details for your store already. Depending on the systems you're using - you may be able to make use of these to help with inventory tracking and remove some of the custom development required:

Requirements

In order to track inventory levels for your store - the main component that you will need within your set up is somewhere that you can track the inventory for each product, as well as some ability to update that value. This could be a text file that is updated via server-side code, or it could be a database connected to a CMS - whatever works best for your needs.

You will also want to structure your products with a unique identifier that can be used to update the correct inventory value after transactions are completed. We generally recommend utilising the code attribute for products for this - but you can use any custom product attribute you need.

Basic Inventory Tracking

At a basic level - a store can make use of the transaction webhook to dynamically update inventory levels for products as successful transactions are completed. The webhook works by sending a summary of each transaction as they're completed - allowing you to update the inventory value on your side.

You can also make use of the quantity_max attribute for products, setting that within your add to cart links or forms to the current inventory level to prevent a singular customer from being able to order more than currently available.

With those two pieces configured, you will have basic inventory tracking working and your add to carts will dynamically update as transactions are completed. This can work really well for stores that don't have a high transaction volume - where the chances of two or more checkouts happening at the same time is low, or there isn't a huge concern for potentially over-selling stock on occasion.

Intermediate Inventory Tracking

Taking the basic tracking a step further, you can also add in the ability to limit how long a single product is allowed to be in the customers cart for, and perform a final inventory check right before the transaction is sent to the gateway for payment.

Limiting Product Lifetime In The Cart

Along with the quantity_max attribute noted in the basic inventory tracking above, there is also an expires attribute for products. This can either be an amount of time in minutes, or a future date/time represented as an epoch timestamp in seconds. If a product is added to the cart with an expires parameter set, it will automatically be removed from the customers cart if that date/time passes before the customer has completed the transaction.

Depending on your product requirements, there is also a configuration setting available on the “Advanced” settings page to require that all products within your store make use of an expires attribute. This can be a way to ensure that a product never accidentally ends up in the cart without the expires value set - meaning that a customer could have that product in their cart indefinitely.

Confirming Inventory Before Final Checkout

One downside of the basic inventory tracking approach is that there is a potential for the stock level to have changed between the customer adding the product to the cart and them finally completing the checkout. To minimise the chances of that happening, you can add in a check right before the customer completes their checkout to confirm that inventory is still available at that point. This way, if a customer added a product to the cart but only attempted to complete the checkout hours (or even days) later, they can be prevented from doing so if another customer has purchased the remaining stock in the meantime.

To achieve that, this will make use of the pre-payment webhook functionality. This feature sends a request right as the customer attempts to complete the checkout to an endpoint of your choosing. This endpoint receives a payload with all of the details of the transaction - including the products in the cart, the address the customer has entered and custom fields from the checkout.

At your endpoint, you can perform a quick check to confirm that there is still adequate stock available for the customers order. If there is, you can simply let the checkout attempt proceed and be sent on to the gateway. If not though, you can stop the checkout and send the customer back to the checkout with a custom error message.

You can also make use of our API to quickly modify the cart for the customer - removing or updating products dynamically as required before sending them back to the checkout. The payload sent to the endpoint includes data from the API already - so you can use the URI's included within the payload to be able to interact with those resources straight away.

Advanced Inventory Tracking

If there is a need to ensure that you never oversell on the stock you have available, there are some features available that can assist with that too. This can be especially true for stores that are selling one-off items, or products with very specific limits such as event ticket sales.

Beyond the approaches already detailed above, you can also make use of the following functionality:

Your System

To more tightly manage your inventory, you'll need to expand your existing set up to also include the ability to track inventory locks. These are essentially temporary holds on specific quantities of your inventory when a customer adds them to their cart. As an example, if you're tracking inventory within a database, you could have an additional table within the database to store these locks. That table could include columns for the transaction ID, product ID or code and how long the lock should be set for.

On your add to cart page, when determining what the stock level is for a given product, you would take the products normal inventory level, but then remove from that any locks that exist for that product and are still active. This adjusted value can then be used to set whether the product is out of stock and also for the quantity_max value.

Add To Cart

When setting the expires attribute that was detailed in the intermediate tracking section above - we'd recommend setting it to be before the inventory lock within your database is set to expire. That way you can give a little bit of breathing room between the cart product expiring and the lock clearing in your database to prevent any possibility of overlaps between stock becoming available again before it has actually expired in the cart for the customer that has that specific stock.

Tracking Cart Changes

​ ​Our javascript functionality includes events for customer interactions with the cart, including adding products, updating quantities and removing products. These events can be used to add in custom calls to your systems to add/update/remove inventory locks for that product as needed.

The specific events you could utilise would be cart-submit.done, cart-item-quantity-update.done and cart-item-remove.done. Within the custom callback you add to these events, you would call an endpoint script on your server which would perform the necessary actions. This javascript would be included through the “Configuration” page in your store's FoxyCart administration, using the “footer” textarea of the “Add custom header and footer code to your templates” option.

You can detect what changes were made to the cart by checking the params parameter of the event callback functions, and utilise the FC.json cart object to access any details needed.

Pre & Post Payment Webhooks

​ While both are detailed above on the page, within the more advanced approach:

Within the pre-payment webhook you could ensure that all existing inventory locks match the current contents of the cart, and if not - ensure that there is enough stock still available to support the difference (if it's higher) and act accordingly.

For the transaction webhook, along with adjusting the actual inventory level, you would clear out any inventory locks that were set for this transaction.

Site Tools