WooCommerce Development
When to use
- Writing or modifying a WooCommerce extension (plugin)
- Working with orders, products, customers, or subscriptions programmatically
- Extending WooCommerce REST API endpoints
- Customizing checkout, cart, or payment flows
- Adding custom product types or order statuses
- Integrating with WooCommerce hooks and filters
- Building payment gateway or shipping method extensions
Inputs required
- The WooCommerce version installed on the target site (9.0+ assumed)
- Whether HPOS (High-Performance Order Storage) is enabled (assume yes)
- Which WooCommerce APIs are relevant: orders, products, customers, subscriptions, settings
Procedure
0) Verify WooCommerce context
Before writing any WooCommerce code:
- Check that WooCommerce is active:
if ( ! class_exists( 'WooCommerce' ) ) return;
- Confirm HPOS compatibility — never query
wp_posts directly for orders
- Use
woocommerce_loaded or plugins_loaded hooks for initialization
1) Use HPOS-compatible APIs exclusively
CRITICAL: WooCommerce 9.0+ uses HPOS (custom order tables) by default. Direct $wpdb queries against wp_posts/wp_postmeta for orders will BREAK on HPOS-enabled stores.
Safe API usage:
// Orders — ALWAYS use wc_get_orders() or WC_Order_Query
$orders = wc_get_orders( array(
'status' => 'completed',
'limit' => 50,
'orderby' => 'date',
'order' => 'DESC',
) );
// Products — use wc_get_products() or wc_get_product()
$product = wc_get_product( $product_id );
// Customers — use WC_Customer class
$customer = new WC_Customer( $user_id );
See: references/hpos-compatibility.md
2) Follow WooCommerce hook patterns
WooCommerce provides hooks at every stage of the lifecycle. Use them instead of overriding templates or modifying core behavior.
Key hook categories:
- Cart:
woocommerce_before_cart, woocommerce_cart_calculate_fees, woocommerce_add_to_cart_validation
- Checkout:
woocommerce_checkout_process, woocommerce_checkout_order_processed, woocommerce_payment_complete
- Orders:
woocommerce_order_status_changed, woocommerce_new_order, woocommerce_order_refunded
- Products:
woocommerce_product_options_general_product_data, woocommerce_process_product_meta
- Emails:
woocommerce_email_classes, woocommerce_email_before_order_table
See: references/hooks-reference.md
3) Extend properly — don't hack core
- Payment gateways: Extend
WC_Payment_Gateway, implement process_payment(), register via woocommerce_payment_gateways filter
- Shipping methods: Extend
WC_Shipping_Method, implement calculate_shipping(), register via woocommerce_shipping_methods filter
- Emails: Extend
WC_Email, register via woocommerce_email_classes filter
- Product types: Extend
WC_Product, register via woocommerce_product_class filter
- Settings: Use
WC_Settings_API trait or add settings tabs via woocommerce_get_settings_pages
See: references/extending-woocommerce.md
4) Security for WooCommerce
- Use
current_user_can( 'manage_woocommerce' ) for admin-level WC operations
- Use
wc_clean() and wc_sanitize_textarea() for WooCommerce-specific sanitization
- Never expose API keys, payment credentials, or customer PII in responses
- Use
$wpdb->prepare() for any custom database queries
- Validate order ownership before exposing order data:
$order->get_customer_id() === get_current_user_id()
See: references/security.md
5) REST API extensions
WooCommerce REST API (v3) is at /wp-json/wc/v3/. To extend it:
add_filter( 'woocommerce_rest_api_get_rest_namespaces', function( $controllers ) {
$controllers['wc/v3']['my-endpoint'] = 'My_REST_Controller';
return $controllers;
} );
For custom fields on existing endpoints, use woocommerce_rest_prepare_* and woocommerce_rest_insert_* filters.
See: references/rest-api.md
Verification
Failure modes / debugging
- "Call to undefined function wc_get_orders()" — WooCommerce not loaded yet. Move code to
woocommerce_loaded hook.
- Orders not found — HPOS migration may be incomplete. Check
wc_get_container()->get( OrdersTableDataStore::class ) status.
- Payment gateway not appearing — Check
is_available() method, supported currencies, and woocommerce_payment_gateways filter priority.
- Email not sending — Check
WC_Emails::instance(), verify template exists, check email is enabled in WooCommerce > Settings > Emails.
Escalation
1---2name: woocommerce3description: Use when developing WooCommerce extensions, customizing store behavior, or working with WooCommerce APIs: HPOS-compatible data access, product/order/customer APIs, hooks, payment gateways, shipping methods, emails, and REST API extensions.4---56# WooCommerce Development78## When to use910- Writing or modifying a WooCommerce extension (plugin)11- Working with orders, products, customers, or subscriptions programmatically12- Extending WooCommerce REST API endpoints13- Customizing checkout, cart, or payment flows14- Adding custom product types or order statuses15- Integrating with WooCommerce hooks and filters16- Building payment gateway or shipping method extensions1718## Inputs required1920- The WooCommerce version installed on the target site (9.0+ assumed)21- Whether HPOS (High-Performance Order Storage) is enabled (assume yes)22- Which WooCommerce APIs are relevant: orders, products, customers, subscriptions, settings2324## Procedure2526### 0) Verify WooCommerce context2728Before writing any WooCommerce code:29301. Check that WooCommerce is active: `if ( ! class_exists( 'WooCommerce' ) ) return;`312. Confirm HPOS compatibility — never query `wp_posts` directly for orders323. Use `woocommerce_loaded` or `plugins_loaded` hooks for initialization3334### 1) Use HPOS-compatible APIs exclusively3536**CRITICAL:** WooCommerce 9.0+ uses HPOS (custom order tables) by default. Direct `$wpdb` queries against `wp_posts`/`wp_postmeta` for orders will BREAK on HPOS-enabled stores.3738Safe API usage:39```php40// Orders — ALWAYS use wc_get_orders() or WC_Order_Query41$orders = wc_get_orders( array(42 'status' => 'completed',43 'limit' => 50,44 'orderby' => 'date',45 'order' => 'DESC',46) );4748// Products — use wc_get_products() or wc_get_product()49$product = wc_get_product( $product_id );5051// Customers — use WC_Customer class52$customer = new WC_Customer( $user_id );53```5455See: `references/hpos-compatibility.md`5657### 2) Follow WooCommerce hook patterns5859WooCommerce provides hooks at every stage of the lifecycle. Use them instead of overriding templates or modifying core behavior.6061Key hook categories:62- **Cart**: `woocommerce_before_cart`, `woocommerce_cart_calculate_fees`, `woocommerce_add_to_cart_validation`63- **Checkout**: `woocommerce_checkout_process`, `woocommerce_checkout_order_processed`, `woocommerce_payment_complete`64- **Orders**: `woocommerce_order_status_changed`, `woocommerce_new_order`, `woocommerce_order_refunded`65- **Products**: `woocommerce_product_options_general_product_data`, `woocommerce_process_product_meta`66- **Emails**: `woocommerce_email_classes`, `woocommerce_email_before_order_table`6768See: `references/hooks-reference.md`6970### 3) Extend properly — don't hack core7172- **Payment gateways**: Extend `WC_Payment_Gateway`, implement `process_payment()`, register via `woocommerce_payment_gateways` filter73- **Shipping methods**: Extend `WC_Shipping_Method`, implement `calculate_shipping()`, register via `woocommerce_shipping_methods` filter74- **Emails**: Extend `WC_Email`, register via `woocommerce_email_classes` filter75- **Product types**: Extend `WC_Product`, register via `woocommerce_product_class` filter76- **Settings**: Use `WC_Settings_API` trait or add settings tabs via `woocommerce_get_settings_pages`7778See: `references/extending-woocommerce.md`7980### 4) Security for WooCommerce8182- Use `current_user_can( 'manage_woocommerce' )` for admin-level WC operations83- Use `wc_clean()` and `wc_sanitize_textarea()` for WooCommerce-specific sanitization84- Never expose API keys, payment credentials, or customer PII in responses85- Use `$wpdb->prepare()` for any custom database queries86- Validate order ownership before exposing order data: `$order->get_customer_id() === get_current_user_id()`8788See: `references/security.md`8990### 5) REST API extensions9192WooCommerce REST API (v3) is at `/wp-json/wc/v3/`. To extend it:9394```php95add_filter( 'woocommerce_rest_api_get_rest_namespaces', function( $controllers ) {96 $controllers['wc/v3']['my-endpoint'] = 'My_REST_Controller';97 return $controllers;98} );99```100101For custom fields on existing endpoints, use `woocommerce_rest_prepare_*` and `woocommerce_rest_insert_*` filters.102103See: `references/rest-api.md`104105## Verification106107- [ ] No direct SQL queries against `wp_posts`/`wp_postmeta` for orders (HPOS-safe)108- [ ] All WC functions called after `woocommerce_loaded` or `plugins_loaded`109- [ ] WooCommerce existence check before any WC-dependent code110- [ ] Payment/shipping extensions use proper abstract class inheritance111- [ ] Customer PII is not exposed in logs, error messages, or API responses112- [ ] Custom order statuses registered via `wc_register_order_type` or `register_post_status` + `wc_order_statuses` filter113114## Failure modes / debugging115116- **"Call to undefined function wc_get_orders()"** — WooCommerce not loaded yet. Move code to `woocommerce_loaded` hook.117- **Orders not found** — HPOS migration may be incomplete. Check `wc_get_container()->get( OrdersTableDataStore::class )` status.118- **Payment gateway not appearing** — Check `is_available()` method, supported currencies, and `woocommerce_payment_gateways` filter priority.119- **Email not sending** — Check `WC_Emails::instance()`, verify template exists, check email is enabled in WooCommerce > Settings > Emails.120121## Escalation122123- [WooCommerce Developer Documentation](https://developer.woocommerce.com/docs/)124- [WooCommerce GitHub Issues](https://github.com/woocommerce/woocommerce/issues)125- [WooCommerce REST API Reference](https://woocommerce.github.io/woocommerce-rest-api-docs/)