SuperAPI AI Directory

woocommerce

Coding & development

View repository

Updated 10-15 20:06

About this skill

WooCommerce Plugin Development

Overview

WooCommerce is an open-source e-commerce plugin for WordPress, powering over 36% of all online stores. It transforms a WordPress installation into a fully functional e-commerce platform with product management, cart, checkout, payment processing, shipping, and order management.

WooCommerce follows the WordPress extension model -- plugins extend core functionality through a hook-based architecture. WooCommerce adds its own extensive layer of hooks, filters, REST API endpoints, and abstract classes on top of WordPress's plugin system. Extensions can add payment gateways, shipping methods, product types, checkout fields, admin pages, reporting dashboards, and storefront modifications.

The platform has evolved significantly with the introduction of High-Performance Order Storage (HPOS), block-based checkout, and the WooCommerce Admin React-based interface. Modern WooCommerce plugin development must account for these architectural shifts while maintaining backward compatibility with classic implementations.

WooCommerce plugins are distributed through the WordPress.org plugin directory (free), the WooCommerce.com marketplace (premium), or independently through developer websites. All distribution channels require GPL-compatible licensing. The WordPress.org review process enforces security standards, coding quality, and adherence to plugin guidelines.

Plugin Structure

Every WooCommerce plugin starts with a main PHP file containing the WordPress plugin header. WooCommerce-specific headers declare version compatibility:

<?php
/**
 * Plugin Name: My WooCommerce Plugin
 * Plugin URI: https://example.com/my-woo-plugin
 * Description: A brief description of the plugin.
 * Version: 1.0.0
 * Author: Developer Name
 * Author URI: https://example.com
 * License: GPL-2.0-or-later
 * Text Domain: my-woo-plugin
 * Domain Path: /languages
 * Requires at least: 6.0
 * Requires PHP: 7.4
 * WC requires at least: 8.0
 * WC tested up to: 9.4
 * Woo: 12345:abc123def456
 */

The WC requires at least and WC tested up to headers tell WooCommerce which versions the plugin supports. The Woo header is required for plugins sold on WooCommerce.com marketplace.

Activation and Dependency Checks

Before initializing, verify that WooCommerce is active. Hook into plugins_loaded to check for the WooCommerce class, and display an admin notice if WooCommerce is missing. Never call WooCommerce functions at the top level of the plugin file -- always wait for the woocommerce_loaded action.

HPOS Feature Declaration

All new plugins must declare HPOS compatibility. Without this declaration, WooCommerce displays a compatibility warning in the admin:

add_action('before_woocommerce_init', function () {
    if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
            'custom_order_tables', __FILE__, true
        );
    }
});

For full plugin structure details including autoloading, directory layout, and initialization patterns, see references/architecture.md.

Hook System

WooCommerce's hook system is the primary mechanism for extending functionality. It builds on WordPress's core add_action() and add_filter() API.

Actions vs Filters

  • Actions execute code at specific points in the WooCommerce lifecycle (order created, payment processed, email sent). They do not return values.
  • Filters modify data as it passes through the system (change product price, alter checkout fields, modify email content). They receive a value and must return it (modified or not).

Priority System

Hooks accept a priority parameter (default 10). Lower numbers execute first. Use priorities strategically:

  • 1-9 -- Execute before most other plugins.
  • 10 -- Default priority. Most plugins use this.
  • 11-99 -- Execute after most plugins. Useful for overriding other plugin behavior.
  • 100+ -- Execute last. Use for final modifications.

Critical WooCommerce Hooks

The most commonly used hooks fall into categories:

Category Key Hooks
Product woocommerce_product_options_general_product_data, woocommerce_process_product_meta
Cart woocommerce_add_to_cart, woocommerce_cart_calculate_fees, woocommerce_before_calculate_totals
Checkout woocommerce_checkout_process, woocommerce_checkout_order_processed, woocommerce_checkout_create_order
Order woocommerce_new_order, woocommerce_order_status_changed, woocommerce_payment_complete
Admin woocommerce_admin_order_data_after_billing_address, woocommerce_product_data_tabs
Email woocommerce_email_before_order_table, woocommerce_email_order_details

For a comprehensive categorized list with code examples, see references/hooks-and-filters.md.

Development Setup

Local WordPress Environments

Several tools provide local WordPress development environments:

  • LocalWP (Local by Flywheel) -- GUI-based, one-click WordPress setup with SSL, mailbox, and live link sharing. Recommended for beginners.
  • wp-env -- Official WordPress Docker-based environment. Define configuration in .wp-env.json and run npx @wordpress/env start. Ideal for CI/CD.
  • DDEV -- Docker-based PHP development environment with WordPress recipes.
  • VVV (Varying Vagrant Vagrants) -- Vagrant-based, heavier but highly configurable.

WP-CLI

WP-CLI is the command-line interface for WordPress. Essential commands for WooCommerce development:

wp plugin activate my-woo-plugin
wp wc product list --user=admin
wp wc order create --customer_id=1 --user=admin
wp option get woocommerce_default_country
wp transient delete --all

WooCommerce Beta Tester

Install the WooCommerce Beta Tester plugin to test against upcoming WooCommerce releases. This catches compatibility issues before they reach production stores. Enable beta updates in WooCommerce > Settings > Advanced > WooCommerce.com and select the desired release channel (beta, release candidate, or nightly).

Debug Configuration

Enable WordPress debug mode in wp-config.php:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);

Use wc_get_logger() for structured logging within WooCommerce context. Log files appear under wp-content/uploads/wc-logs/ and are viewable in WooCommerce > Status > Logs.

Recommended Developer Tools

  • Query Monitor -- WordPress debugging plugin that shows database queries, hooks fired, HTTP requests, and PHP errors. Invaluable for identifying performance bottlenecks and hook execution order.
  • WooCommerce Admin Test Helper -- Reset WooCommerce admin features and onboarding states for testing.
  • Code Snippets -- Test hook callbacks and filters without creating a full plugin.
  • Debug Bar -- Inspect WordPress internals, including cache hits and conditional functions.

For testing strategies including PHPUnit setup, E2E tests, and mocking patterns, see references/testing.md.

Key Integration Patterns

Pattern Base Class Key Method(s) Reference
Payment Gateway WC_Payment_Gateway process_payment(), init_form_fields() payment-gateway.md
Shipping Method WC_Shipping_Method calculate_shipping(), init_form_fields() shipping-method.md
Product Type WC_Product get_type(), custom data stores architecture.md
Checkout Blocks IntegrationInterface get_script_handles(), get_script_data() storefront-and-blocks.md
Admin Settings WC_Integration init_form_fields(), process_admin_options() admin-extension.md
REST Endpoint WC_REST_Controller register_routes(), get_items() rest-api.md

Each integration pattern follows the same lifecycle: extend the abstract class, implement required methods, register with WooCommerce via the appropriate hook. WooCommerce discovers registered extensions through specific filter hooks -- woocommerce_payment_gateways for gateways, woocommerce_shipping_methods for shipping, and woocommerce_integrations for settings integrations. The registration hook fires during WooCommerce initialization, so the plugin must be loaded before that point.

For headless and external integrations, WooCommerce provides two REST APIs. The WC REST API v3 handles administrative operations (managing products, orders, customers) with consumer key/secret authentication. The Store API serves the block-based cart and checkout with session-based authentication. See references/rest-api.md for endpoint details, custom controller creation, and webhook configuration.

HPOS Compatibility

High-Performance Order Storage (HPOS) replaces the WordPress wp_posts and wp_postmeta tables with dedicated WooCommerce order tables. This dramatically improves query performance for stores with large order volumes.

Key Rules for HPOS Compatibility

  1. Never access wp_posts or wp_postmeta directly for order data. Use the WooCommerce CRUD API ($order->get_meta(), $order->update_meta_data()).
  2. Never use get_post_meta() or update_post_meta() on order IDs. These bypass HPOS entirely.
  3. Use OrderUtil::get_order_type() to determine if an ID is an order, not get_post_type().
  4. Query orders with wc_get_orders(), not WP_Query or direct SQL.
  5. Declare HPOS support in the plugin header via FeaturesUtil::declare_compatibility().
// Correct: HPOS-compatible order meta access
$order = wc_get_order($order_id);
$custom_value = $order->get_meta('_my_custom_field');
$order->update_meta_data('_my_custom_field', 'new_value');
$order->save();

// Wrong: Direct post meta (breaks HPOS)
$custom_value = get_post_meta($order_id, '_my_custom_field', true);
update_post_meta($order_id, '_my_custom_field', 'new_value');

WooCommerce Blocks

WooCommerce Blocks provide a modern, block-based cart and checkout experience built with React. The block-based checkout is now the default for new WooCommerce installations.

Extending Block Checkout

Register a checkout block integration by implementing Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface:

use Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface;

class My_Blocks_Integration implements IntegrationInterface {
    public function get_name() { return 'my-plugin'; }
    public function initialize() { /* register scripts */ }
    public function get_script_handles() { return ['my-plugin-checkout-block']; }
    public function get_editor_script_handles() { return []; }
    public function get_script_data() { return ['ajaxUrl' => admin_url('admin-ajax.php')]; }
}

On the JavaScript side, use the @woocommerce/blocks-checkout package to register components in checkout slots:

import { registerCheckoutBlock } from '@woocommerce/blocks-checkout';

registerCheckoutBlock({
    metadata: { name: 'my-plugin/custom-field', parent: ['woocommerce/checkout-fields-block'] },
    component: MyCustomFieldBlock,
});

Store API

The WooCommerce Store API serves block-based cart and checkout. Extend it to expose custom data to checkout blocks. Use ExtendSchema to add data to cart/checkout API responses and register_endpoint_data to attach custom schemas.

For complete block integration patterns, see references/storefront-and-blocks.md.

Anti-Patterns

Avoid these common mistakes in WooCommerce plugin development:

Direct Database Access for Orders

Never query $wpdb->posts or $wpdb->postmeta for order data. This breaks HPOS compatibility and bypasses WooCommerce's data layer, cache, and hooks.

Bypassing WooCommerce CRUD API

Always use $order->get_total(), $order->get_billing_email(), $product->get_price() instead of accessing internal properties or post meta directly. The CRUD methods handle data stores, caching, and format conversions.

Hardcoding URLs

Never hardcode site URLs, asset URLs, or API endpoints. Use plugins_url(), admin_url(), wc_get_endpoint_url(), and rest_url() to generate URLs dynamically.

Ignoring Nonce Verification

All form submissions and AJAX requests must verify WordPress nonces with wp_verify_nonce() or check_ajax_referer(). Skipping nonce verification opens the plugin to CSRF attacks.

Loading Assets Everywhere

Enqueue scripts and styles only on pages where they are needed. Use is_checkout(), is_cart(), is_product(), and similar conditional functions to target specific pages.

Ignoring Block Checkout

Plugins that only support classic checkout (shortcode-based) are increasingly incompatible with new installations. Support both classic and block checkout flows.

Modifying Orders via Direct SQL

Never run UPDATE or INSERT queries against wp_posts, wp_postmeta, or the HPOS tables (wp_wc_orders, wp_wc_orders_meta) directly. Use wc_get_order() to retrieve orders and the CRUD methods to modify them. Direct SQL bypasses validation, caching, and hook triggers, leading to data inconsistency.

Not Sanitizing or Escaping

All user input flowing into the database must pass through sanitization functions (sanitize_text_field(), absint(), sanitize_email()). All output rendered in HTML must be escaped (esc_html(), esc_attr(), esc_url(), wp_kses_post()). Skipping sanitization or escaping is the most common reason for plugin rejection on WordPress.org.

Shipping and Tax Assumptions

Never assume a store uses a specific currency, tax mode, or shipping structure. Use WooCommerce helper functions (get_woocommerce_currency(), wc_tax_enabled(), wc_prices_include_tax()) to query the store configuration. Hardcoded assumptions break internationalization.

Data Handling and CRUD

WooCommerce provides a CRUD (Create, Read, Update, Delete) abstraction for all core data types. Use these APIs instead of direct WordPress functions:

Object Retrieve Query
Product wc_get_product($id) wc_get_products($args)
Order wc_get_order($id) wc_get_orders($args)
Customer new WC_Customer($id) get_users($args)
Coupon new WC_Coupon($code) wc_get_orders(['type' => 'shop_coupon'])

All CRUD objects share the same meta API:

$object->get_meta('_key');              // Read
$object->update_meta_data('_key', $v);  // Write (in memory)
$object->save();                        // Persist to database
$object->delete_meta_data('_key');      // Remove

Always call $object->save() after modifying data. Meta changes are batched in memory until saved, which reduces database writes.

For detailed architecture including autoloading, custom tables, template overrides, and WP-CLI commands, see references/architecture.md.

Reference Files

  • Architecture -- Plugin file structure, autoloading, headers, HPOS declaration, activation hooks, settings registration
  • Hooks and Filters -- Complete categorized hook reference with code examples and priority system
  • REST API -- WC REST API v3, authentication, custom endpoints, Store API, batch operations
  • Admin Extension -- Settings tabs, product data panels, order meta boxes, WooCommerce Admin pages
  • Storefront and Blocks -- Block checkout extensions, Store API, template overrides, product page customization
  • Checkout and Cart -- Checkout field customization, cart fees, validation, block checkout integration
  • Payment Gateway -- WC_Payment_Gateway extension, tokenization, refunds, 3D Secure, webhook handling
  • Shipping Method -- WC_Shipping_Method extension, rate calculation, shipping zones, tracking integration
  • Testing -- PHPUnit setup, WC test helpers, E2E testing, WP-CLI testing, debug logging
  • Publishing -- WordPress.org submission, readme.txt format, SVN workflow, WooCommerce.com marketplace

Example Files

  • Basic Plugin -- Minimal complete WooCommerce plugin with HPOS support, dependency check, and settings page
  • Payment Gateway -- Payment gateway skeleton with form fields, payment processing, webhooks, and refund support