Launch pricing: Lock in Pro at $79/yr before prices go up View pricing →

Track batches and lot numbers in WooCommerce

If you sell anything with an expiration date, a single stock number per product hides the information that actually matters: which units expire first, and which lot they came from. Two deliveries of the same SKU can sit in the same “stock: 100” while one batch expires in March and the other in May. Core WooCommerce can’t tell them apart — it tracks one quantity per product, with no batches, no lot numbers and no per-unit dates.

Batch tracking fixes that. With the Sellinor Product Expiration Dates Pro add-on you record each delivery as its own batch, and WooCommerce keeps the dates, quantities and lot numbers straight for you — including which lot shipped on which order.

Record each delivery as a batch

Batch tracking is enabled per product (or per variation), not globally, so you only turn it on where it matters. In the Expiration tab of the product editor, toggle Enable batch tracking and the single date field is replaced by a batch interface where you click Add Batch for each shipment.

Every batch holds:

  • Quantity — units in this batch.
  • Expiration date — when this batch expires.
  • Batch Reference (optional) — this is where your lot or batch number lives.
  • Notes (optional) — free text for supplier, PO or storage details.

A single SKU can hold several open batches at once, each with its own date and quantity. The product’s sellable stock is simply the sum of its batches — and that sync is automatic. The batch total is authoritative: if you edit WooCommerce’s stock field directly it gets overwritten back to the sum of your sellable batches, so you always manage stock by editing batches. Full setup is in the batch & lot tracking docs.

For variable products, batches live on each variation rather than the parent. The parent itself can’t hold batches — you enable tracking on the individual variations that need it.

Sell the first-expiring lot, automatically

The point of tracking lots isn’t paperwork — it’s rotation. Deduction uses FEFO (First Expired, First Out): when an order comes in, the plugin fills it starting from the batch closest to expiring, only moving to the next batch when one is exhausted. Nobody picks the lot by hand, and you don’t accidentally ship May’s stock while March’s sits behind it.

It holds up under real-store messiness:

  • The exact batch (or batches) used are recorded on the order, so you always know what shipped.
  • Refunds and cancellations return units to the correct batch, not a generic stock pool.
  • Expired batches stop counting toward sellable stock, so they can’t be sold (unless you deliberately opt in — see below).
  • The whole deduction runs inside a database transaction, so simultaneous orders don’t double-spend a batch.

If FEFO is the part you care about most, the WooCommerce FEFO guide walks through the rotation logic in more depth.

When the batches can’t cover an order

A good batch system has to be honest about stock you don’t physically have. If an order needs more units than your batches can supply, the plugin does not quietly complete it. The order goes on hold and an order note names the affected item, so you can add a batch or adjust the order before fulfilling. That’s the difference between tracking real inventory and just tracking a number.

Lot traceability for recalls

This is where batch tracking earns its place for food, supplements, cosmetics and pharmacy stock. Because every order records the batch it was fulfilled from, a recall stops being a guessing game: you can identify which orders received a given lot instead of contacting your entire customer list.

The activity log backs that up with a full audit trail. Every batch event is written down — created, stock deducted (with the order number), adjusted, swapped, expired or deleted — giving you a per-product history of exactly what moved and when. Entries older than 90 days are cleaned up automatically so the log stays usable.

You can also surface lot data to customers: with Show batches in customer emails enabled, order confirmation emails include the batch reference and expiry date for the items purchased — handy if buyers need to reconcile their own stock against a recall notice.

Fixing an allocation after the fact

Sometimes the right lot to ship isn’t the one FEFO picked — a damaged carton, a customer-specific requirement. You can reassign a line item’s batch on an existing order without cancelling it: open the order, hover the batch label on the line item and click Change. A modal lists every eligible batch, and selecting one atomically returns stock to the original batch and deducts from the new one. Batch swaps work on Processing, On-hold and Completed orders, and each swap is logged with the old batch, the new batch, the order number and who made the change.

Optional: keep selling while one batch is expired

By default, an expired batch drops out of sellable stock. If you’d rather keep a product purchasable as long as one valid batch remains, the Allow selling expired batches setting (under Products → Expirations → Settings → General) puts expired batches back in the FEFO queue — and because they have the earliest dates, they sell first. FEFO ordering by expiry is always in effect either way; this toggle only decides whether expired stock counts. The expiry actions docs cover how this interacts with hiding and out-of-stocking products.

Free vs Pro

The free plugin gives every simple product and every variation a single expiration date and can automatically hide it or set it out of stock when that date passes (or a set number of days before), with cart and checkout protection on top. That’s enough if you only ever hold one date per product.

Batch and lot tracking needs Pro, because it’s the part that records multiple dated lots per SKU and runs FEFO across them. Pro is $79/year for one site or $199/year for unlimited sites (Agency), both with a 14-day free trial. Pro runs alongside the free plugin rather than replacing it.

One reassurance worth knowing: if a Pro license ever lapses, your existing batches keep working and FEFO deduction continues on new orders — you simply can’t create new batches until you renew. Your batch data and history are never thrown away.

A quick note on the database: batch tracking’s concurrency protection holds several database locks at once, which needs MySQL 5.7+ or MariaDB 10.x. Most modern hosts already meet this; on older servers, simultaneous orders aren’t fully protected against stock conflicts.

If you receive dated stock in shipments — which is most perishable and regulated inventory — batch tracking is what turns “stock: 100” into something you can actually rotate and trace. For a worked example on regulated goods, see supplement expiry & lot tracking.

Frequently asked questions

Does WooCommerce support batch or lot tracking out of the box?

No. Core WooCommerce stores one stock quantity per product, with no per-batch quantities, lot numbers or expiration dates. To track multiple batches per product you need the Sellinor Product Expiration Dates Pro add-on, which adds per-batch tracking and automatic First Expired, First Out deduction.

What information can I record for each batch?

Each batch has a quantity and an expiration date, plus two optional fields: a Batch Reference (use this for your lot or batch number) and free-text Notes for things like supplier or storage details. A single product can hold several batches at once, each with its own date and quantity.

How is stock deducted across batches when an order comes in?

Deduction uses FEFO — First Expired, First Out. When an order is placed the plugin takes stock from the batch closest to expiring first, only moving to the next batch when one runs out. The exact batch or batches used are recorded on the order, and refunds or cancellations return the units to the correct batch.

Can I trace which orders received a specific lot for a recall?

Yes. Because every order records the batch it was fulfilled from, you can identify which orders received a given lot. Every batch action — created, deducted with the order number, adjusted, swapped, expired or deleted — is also written to the activity log, giving you a full per-product batch history.

What happens if an order needs more units than my batches hold?

The plugin will not silently complete an order with stock you do not physically have. If batch stock is insufficient, the order is placed on hold and an order note lists the affected item, so you can add a batch or adjust the order before fulfilling it. This prevents overselling.

Do I need Pro for batch tracking, and what does it cost?

Yes. The free plugin tracks a single expiration date per product or variation and can hide or out-of-stock it automatically when expired. Per-batch lot tracking and FEFO deduction are part of the Pro add-on, which is $79/year for one site or $199/year for unlimited sites (Agency), with a 14-day free trial.

Add batch & lot tracking to WooCommerce

Record every delivery as a batch with its own lot number, expiry date and quantity — then let WooCommerce deduct the first-expiring lot automatically and record it on each order.

See plans & download free

Or read the documentation.