woocommerce-plugin-development
Included with Lifetime
$97 forever
Create custom WooCommerce plugins using action/filter hooks, the Settings API, and REST API extensions to add features without modifying core
platform-woocommercewoocommercewordpresspluginhooksfiltersphpsettings-api
What this skill does
# WooCommerce Plugin Development
## Overview
Build custom WooCommerce plugins that extend store functionality using WordPress hooks (actions and filters), the WooCommerce Settings API, custom post types and meta boxes, REST API extensions, and HPOS (High-Performance Order Storage) compatibility. This skill covers plugin architecture, the WooCommerce lifecycle hooks for orders and products, and patterns for building maintainable, upgrade-safe extensions.
## When to Use This Skill
- When building a custom feature that extends WooCommerce (custom shipping, payment, or discount logic)
- When creating a plugin that adds admin settings and configuration pages
- When hooking into the WooCommerce checkout, order, or product lifecycle
- When extending the WooCommerce REST API with custom endpoints
- When migrating a plugin to support HPOS (High-Performance Order Storage)
## Core Instructions
1. **Set up the plugin boilerplate**
```php
<?php
/**
* Plugin Name: My Custom WooCommerce Extension
* Description: Adds custom functionality to WooCommerce
* Version: 1.0.0
* Author: Your Name
* Requires Plugins: woocommerce
* WC requires at least: 8.0
* WC tested up to: 9.0
*
* @package MyWooExtension
*/
defined('ABSPATH') || exit;
// Check if WooCommerce is active
if (!in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
return;
}
define('MWE_VERSION', '1.0.0');
define('MWE_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('MWE_PLUGIN_URL', plugin_dir_url(__FILE__));
// Declare HPOS compatibility
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
);
}
});
// Initialize the plugin after WooCommerce loads
add_action('woocommerce_loaded', function () {
require_once MWE_PLUGIN_DIR . 'includes/class-mwe-main.php';
MWE_Main::instance();
});
```
2. **Use WooCommerce hooks for order lifecycle events**
```php
class MWE_Order_Handler {
public function __construct() {
// Order status transitions
add_action('woocommerce_order_status_completed', [$this, 'on_order_completed'], 10, 2);
add_action('woocommerce_order_status_changed', [$this, 'on_status_change'], 10, 4);
// New order created
add_action('woocommerce_checkout_order_created', [$this, 'on_order_created']);
// Payment complete
add_action('woocommerce_payment_complete', [$this, 'on_payment_complete']);
// Before/after order item saved (HPOS compatible)
add_action('woocommerce_new_order_item', [$this, 'on_new_order_item'], 10, 3);
}
public function on_order_completed(int $order_id, \WC_Order $order): void {
// Example: trigger fulfillment via external API
$items = $order->get_items();
$shipping_address = $order->get_address('shipping');
foreach ($items as $item) {
$product = $item->get_product();
$sku = $product->get_sku();
$quantity = $item->get_quantity();
// Call your external fulfillment service
$this->send_to_fulfillment($sku, $quantity, $shipping_address);
}
$order->add_order_note('Order sent to fulfillment service.');
}
public function on_status_change(int $order_id, string $from, string $to, \WC_Order $order): void {
// Log status transitions
error_log(sprintf(
'Order #%d transitioned from %s to %s',
$order_id, $from, $to
));
}
}
```
3. **Add settings using the WooCommerce Settings API**
```php
class MWE_Settings {
public function __construct() {
add_filter('woocommerce_settings_tabs_array', [$this, 'add_settings_tab'], 50);
add_action('woocommerce_settings_tabs_mwe_settings', [$this, 'render_settings']);
add_action('woocommerce_update_options_mwe_settings', [$this, 'save_settings']);
}
public function add_settings_tab(array $tabs): array {
$tabs['mwe_settings'] = __('My Extension', 'my-woo-extension');
return $tabs;
}
public function render_settings(): void {
woocommerce_admin_fields($this->get_settings());
}
public function save_settings(): void {
woocommerce_update_options($this->get_settings());
}
private function get_settings(): array {
return [
[
'title' => __('General Settings', 'my-woo-extension'),
'type' => 'title',
'id' => 'mwe_general_settings',
],
[
'title' => __('Enable Feature', 'my-woo-extension'),
'desc' => __('Enable the custom feature', 'my-woo-extension'),
'id' => 'mwe_enable_feature',
'type' => 'checkbox',
'default' => 'yes',
],
[
'title' => __('API Key', 'my-woo-extension'),
'desc' => __('Enter your external service API key', 'my-woo-extension'),
'id' => 'mwe_api_key',
'type' => 'text',
'css' => 'min-width: 300px;',
],
[
'title' => __('Processing Mode', 'my-woo-extension'),
'id' => 'mwe_processing_mode',
'type' => 'select',
'options' => [
'sync' => __('Synchronous', 'my-woo-extension'),
'async' => __('Asynchronous (Queue)', 'my-woo-extension'),
],
'default' => 'sync',
],
[
'type' => 'sectionend',
'id' => 'mwe_general_settings',
],
];
}
}
```
4. **Modify product data with filters**
```php
class MWE_Product_Customizer {
public function __construct() {
// Add a custom product tab in admin
add_filter('woocommerce_product_data_tabs', [$this, 'add_product_tab']);
add_action('woocommerce_product_data_panels', [$this, 'render_product_panel']);
add_action('woocommerce_process_product_meta', [$this, 'save_product_meta']);
// Modify price display on frontend
add_filter('woocommerce_get_price_html', [$this, 'modify_price_display'], 10, 2);
// Add custom data to cart item
add_filter('woocommerce_add_cart_item_data', [$this, 'add_custom_cart_data'], 10, 3);
// Display custom data in cart
add_filter('woocommerce_get_item_data', [$this, 'display_cart_item_data'], 10, 2);
// Save custom data to order item
add_action('woocommerce_checkout_create_order_line_item', [$this, 'save_order_item_meta'], 10, 4);
}
public function add_product_tab(array $tabs): array {
$tabs['mwe_custom'] = [
'label' => __('Custom Fields', 'my-woo-extension'),
'target' => 'mwe_custom_product_data',
'class' => [],
'priority' => 80,
];
return $tabs;
}
public function render_product_panel(): void {
global $post;
echo '<div id="mwe_custom_product_data" class="panel woocommerce_options_panel">';
wp_nonce_field('mwe_save_product_meta', 'mwe_product_meta_nonce');
woocommerce_wp_text_input([
Related in platform-woocommerce
woocommerce-blocks
IncludedCustomize WooCommerce checkout and cart pages using Gutenberg blocks with server-side rendering, slot-fills, and extensibility hooks
platform-woocommerce
woocommerce-subscriptions
IncludedAdd subscription products to WooCommerce with automatic recurring billing, renewal notifications, and subscriber self-service management
platform-woocommerce
woocommerce-rest-api
IncludedIntegrate or build headless frontends on WooCommerce using its REST API for products, orders, customers, and coupons with key authentication
platform-woocommerce
woocommerce-performance
IncludedFix slow WooCommerce stores by optimizing database queries, clearing transients, enabling Redis object caching, and configuring page caching
platform-woocommerce