Cart, Checkout & Order Flow

WordPress E-Commerce with WooCommerce

Chapter 4 · Cart, Checkout & Order Flow

Chapter 3 covered the pages a shopper sees — Cart and Checkout, whether rendered by shortcode or block. This chapter covers what actually happens behind those pages: how a cart is tracked before any order exists, what checkout genuinely does at the moment it's submitted, and the full status lifecycle an order moves through afterward.

The Cart Is a Session, Not Yet an Order

Adding a product to the cart does not create an order, or any row in wp_posts at all. WooCommerce tracks cart contents as session data — tied to the shopper's own browser session, not to any permanent database record representing a purchase.

Where that session data actually lives
For a logged-in customer, or a guest with cookies enabled, WooCommerce persists session data (cart contents, applied coupons) in its own dedicated wp_woocommerce_sessions table — a custom table, not wp_posts or wp_postmeta, and not PHP's own default file-based session storage. This is a second real example of WooCommerce reaching for a purpose-built table when the general posts/postmeta pattern genuinely doesn't fit, alongside Chapter 1's own High-Performance Order Storage material.

A practical consequence: an abandoned cart — items added, checkout never completed — leaves no order anywhere in the store's order list. It exists only as a session row, and WooCommerce automatically expires and cleans up old, inactive sessions after a configurable period.

Checkout: Where a Cart Actually Becomes an Order

Submitting the checkout form is the one moment a session's cart contents become a real, permanent order — a row WooCommerce can report on, email, and track, independent of whether that specific browser session still exists.

  1. WooCommerce re-validates the cart — checking each item's current stock and price against what's actually configured right now, not what was cached when the item was added
  2. Shipping and tax are calculated (Chapter 6's own territory) based on the shipping address entered
  3. A new order is created — a shop_order post, or an HPOS order row per Chapter 1's own note on order storage — with an initial status of pending payment
  4. The chosen payment gateway (Chapter 5) takes over to actually collect payment
  5. Once payment is confirmed, the order's status changes automatically, and stock is reduced (see below)
Re-validation is why prices and stock in the cart aren't final
A product's price or stock level can change between "added to cart" and "checkout submitted" — WooCommerce always uses the live, current value at the moment of checkout, not whatever value was shown when the item was first added. A store that changes a price mid-day will see the new price applied to any checkout completed after the change, even for items added to the cart before it.

Order Statuses — The Full Lifecycle

StatusWhat it means
Pending paymentOrder created, awaiting payment — the default status the moment checkout is submitted
On holdAwaiting payment confirmation from a manual or delayed method (e.g. bank transfer), stock is typically reduced
ProcessingPayment received; stock reduced; awaiting fulfillment (shipping a physical item, or delivering a service)
CompletedFulfillment finished — order processed and (if applicable) shipped/delivered
CancelledCancelled by an admin or the customer — stock is typically restored
RefundedFully or partially refunded after payment
FailedPayment failed or was declined — no successful payment was ever received
Draft / Checkout draftAn order record created automatically as the customer fills in the checkout form, before it's actually submitted — used internally, not shown to store admins as a real order
A digital-only store may skip "Processing" entirely
A store selling only downloadable products (with nothing to physically ship) commonly moves an order straight from Pending payment to Completed once payment succeeds, since there's no separate fulfillment step to track — Processing exists specifically to represent the gap between "paid" and "fulfilled," which only exists at all when fulfillment isn't instantaneous.

Stock Reduction Timing

Chapter 2 covered what stock management tracks; this is when WooCommerce actually decrements it, a setting under WooCommerce → Settings → Products → Inventory:

OptionBehavior
Reduce stock when an order is placed (default)Stock is decremented as soon as the order reaches Pending payment, before payment is confirmed
Hold stock (minutes)An unpaid Pending payment order reserves stock only temporarily; if payment isn't completed within this window, the reservation is released and stock returns to being available to other shoppers
A real, honest tension worth naming
Reducing stock immediately at "Pending payment" protects against overselling a genuinely limited item during a payment delay, but it also means an abandoned, never-paid checkout can temporarily tie up stock another shopper would otherwise have been able to buy — exactly what the "Hold stock" timeout exists to bound. There's no setting that eliminates this trade-off entirely; only how long it's allowed to last.

Hands-On Exercises

Exercise 1

A customer adds an item to their cart, then closes the browser tab without checking out. Explain what record of this, if any, exists in the store's own order list, and where the cart's contents were actually being tracked before the tab was closed.

📄 View solution
Exercise 2

A store owner raises a product's price at 2pm. A customer who added that item to their cart at 1pm finally checks out at 3pm. Which price do they pay, and why, according to this chapter's own checkout re-validation material?

📄 View solution
Exercise 3

Explain why a store selling only downloadable products might never see an order reach the "Processing" status, connecting your answer to what this chapter says that status specifically represents.

📄 View solution

Chapter 4 Quick Reference

  • A cart is session data — for logged-in/cookie-enabled shoppers, stored in the dedicated wp_woocommerce_sessions table, not wp_posts
  • Checkout is the moment a session's cart becomes a real order — stock and price are re-validated against current live values, not cached cart values
  • Order statuses: Pending payment → (On hold /) Processing → Completed, with Cancelled/Refunded/Failed as exit paths, plus an internal Draft/Checkout draft status before submission
  • Stock reduction timing is configurable — at order placement (default, protects against overselling) versus a "Hold stock" timeout (protects against ties-up-stock abandoned checkouts) — a genuine trade-off, not a solved problem
  • Next chapter: Payment Gateways