Decisions that shape a WooCommerce store
Extensions or custom code
The WooCommerce marketplace has an extension for almost everything, and a maintained extension is usually cheaper to own than code written for you. We still say no to some of them. An extension earns its place when it does one job, is actively updated and declares compatibility with current WooCommerce features. When you would need three plugins and a snippet to approximate one business rule, a small custom plugin of a few hundred lines is easier to test and to reason about. See WooCommerce plugin development for how we build those.
Block checkout or classic checkout
WooCommerce now has two checkouts. The classic one is a PHP template driven by long-standing hooks, and many older extensions depend on it. The block checkout is rendered in the browser and talks to the Store API, which makes it quicker to use and easier to edit visually, though custom fields and gateways must be written for it specifically. Hooks that added a field to the classic form do nothing on the block version. Before choosing, we list every extension that touches checkout and check each one against both. Mixed setups, where half the plugins expect one checkout and half the other, are the most common cause of "paid but pending" orders we see.
HPOS and the order tables
High-performance order storage moves orders out of the WordPress posts and postmeta tables into tables designed for orders, addresses and order metadata. Order queries get faster and the database is easier to index. The risk sits in old code that reads orders with post functions instead of the order object. Our migration routine is the same every time: scan plugins and theme code for direct post access, enable compatibility mode so both stores stay in sync, verify counts and totals, then switch the authoritative source and keep a way back.
Payments are a conversation, not a click
A card payment involves a redirect or a popup, an authentication step and a webhook that arrives seconds or minutes later. Orders get stuck when the store relies on the customer returning to the thank-you page. We treat the webhook as the source of truth, make handlers safe to run twice, and log every gateway event against the order so support can see what happened.
Speed at scale
Slow stores usually suffer from uncached logged-in pages, heavy variation data, a backlog of scheduled actions and autoloaded options left behind by removed plugins. We measure first with query monitoring and server profiling, then fix in order of impact. Cart, checkout and account pages are excluded from page caching, and everything else is cached hard.