Claude Code Plugins

Community-maintained marketplace

Feedback

WooCommerce development for WordPress e-commerce including custom product types, payment gateways, shipping methods, hooks, REST API, and store optimization. Use when building WooCommerce stores, customizing WooCommerce functionality, developing WooCommerce extensions, or debugging WooCommerce issues.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name woocommerce
description WooCommerce development for WordPress e-commerce including custom product types, payment gateways, shipping methods, hooks, REST API, and store optimization. Use when building WooCommerce stores, customizing WooCommerce functionality, developing WooCommerce extensions, or debugging WooCommerce issues.

WooCommerce Development

E-commerce development with WooCommerce for WordPress.

Essential Hooks

Product Hooks

// Modify product price display
add_filter( 'woocommerce_get_price_html', function( $price_html, $product ) {
    if ( $product->is_on_sale() ) {
        $price_html .= '<span class="sale-badge">Sale!</span>';
    }
    return $price_html;
}, 10, 2 );

// Add custom field to product
add_action( 'woocommerce_product_options_general_product_data', function() {
    woocommerce_wp_text_input( array(
        'id'          => '_custom_field',
        'label'       => __( 'Custom Field', 'textdomain' ),
        'description' => __( 'Enter custom value', 'textdomain' ),
        'desc_tip'    => true,
    ) );
} );

// Save custom field
add_action( 'woocommerce_process_product_meta', function( $post_id ) {
    $value = isset( $_POST['_custom_field'] ) ? sanitize_text_field( $_POST['_custom_field'] ) : '';
    update_post_meta( $post_id, '_custom_field', $value );
} );

Cart Hooks

// Add fee to cart
add_action( 'woocommerce_cart_calculate_fees', function( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }

    $subtotal = $cart->get_subtotal();

    // Add handling fee for orders under $50
    if ( $subtotal < 50 ) {
        $cart->add_fee( __( 'Handling Fee', 'textdomain' ), 5.00 );
    }
} );

// Validate cart items
add_action( 'woocommerce_check_cart_items', function() {
    $cart = WC()->cart;

    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $product = $cart_item['data'];

        // Check stock or custom validation
        if ( ! $product->is_in_stock() ) {
            wc_add_notice(
                sprintf( __( '%s is out of stock.', 'textdomain' ), $product->get_name() ),
                'error'
            );
        }
    }
} );

// Modify cart item data
add_filter( 'woocommerce_add_cart_item_data', function( $cart_item_data, $product_id, $variation_id ) {
    if ( isset( $_POST['custom_option'] ) ) {
        $cart_item_data['custom_option'] = sanitize_text_field( $_POST['custom_option'] );
    }
    return $cart_item_data;
}, 10, 3 );

Checkout Hooks

// Add custom checkout field
add_action( 'woocommerce_after_order_notes', function( $checkout ) {
    woocommerce_form_field( 'delivery_date', array(
        'type'        => 'date',
        'class'       => array( 'form-row-wide' ),
        'label'       => __( 'Preferred Delivery Date', 'textdomain' ),
        'required'    => true,
    ), $checkout->get_value( 'delivery_date' ) );
} );

// Validate custom field
add_action( 'woocommerce_checkout_process', function() {
    if ( empty( $_POST['delivery_date'] ) ) {
        wc_add_notice( __( 'Please select a delivery date.', 'textdomain' ), 'error' );
    }
} );

// Save custom field to order
add_action( 'woocommerce_checkout_update_order_meta', function( $order_id ) {
    if ( ! empty( $_POST['delivery_date'] ) ) {
        update_post_meta( $order_id, '_delivery_date', sanitize_text_field( $_POST['delivery_date'] ) );
    }
} );

Order Hooks

// After order is completed
add_action( 'woocommerce_order_status_completed', function( $order_id ) {
    $order = wc_get_order( $order_id );

    // Send to external system
    $data = array(
        'order_id'    => $order_id,
        'customer'    => $order->get_billing_email(),
        'total'       => $order->get_total(),
        'items'       => array(),
    );

    foreach ( $order->get_items() as $item ) {
        $data['items'][] = array(
            'product_id' => $item->get_product_id(),
            'quantity'   => $item->get_quantity(),
            'total'      => $item->get_total(),
        );
    }

    // Send to webhook
    wp_remote_post( 'https://api.example.com/orders', array(
        'body'    => wp_json_encode( $data ),
        'headers' => array( 'Content-Type' => 'application/json' ),
    ) );
} );

// Order status change
add_action( 'woocommerce_order_status_changed', function( $order_id, $old_status, $new_status, $order ) {
    // Custom notification logic
}, 10, 4 );

Custom Product Types

// Register custom product type
add_action( 'init', function() {
    class WC_Product_Subscription extends WC_Product {
        public function __construct( $product = 0 ) {
            $this->product_type = 'subscription';
            parent::__construct( $product );
        }

        public function get_type() {
            return 'subscription';
        }

        // Custom methods
        public function get_subscription_period() {
            return $this->get_meta( '_subscription_period' );
        }
    }
} );

// Add to product type selector
add_filter( 'product_type_selector', function( $types ) {
    $types['subscription'] = __( 'Subscription', 'textdomain' );
    return $types;
} );

// Show price fields
add_action( 'woocommerce_product_options_general_product_data', function() {
    global $product_object;

    if ( 'subscription' === $product_object->get_type() ) {
        woocommerce_wp_select( array(
            'id'      => '_subscription_period',
            'label'   => __( 'Billing Period', 'textdomain' ),
            'options' => array(
                'month' => __( 'Monthly', 'textdomain' ),
                'year'  => __( 'Yearly', 'textdomain' ),
            ),
        ) );
    }
} );

Payment Gateways

class WC_Gateway_Custom extends WC_Payment_Gateway {
    public function __construct() {
        $this->id                 = 'custom_gateway';
        $this->icon               = '';
        $this->has_fields         = true;
        $this->method_title       = __( 'Custom Gateway', 'textdomain' );
        $this->method_description = __( 'Custom payment gateway.', 'textdomain' );

        $this->supports = array(
            'products',
            'refunds',
        );

        $this->init_form_fields();
        $this->init_settings();

        $this->title       = $this->get_option( 'title' );
        $this->description = $this->get_option( 'description' );
        $this->enabled     = $this->get_option( 'enabled' );
        $this->api_key     = $this->get_option( 'api_key' );

        add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
    }

    public function init_form_fields() {
        $this->form_fields = array(
            'enabled' => array(
                'title'   => __( 'Enable/Disable', 'textdomain' ),
                'type'    => 'checkbox',
                'label'   => __( 'Enable Custom Gateway', 'textdomain' ),
                'default' => 'no',
            ),
            'api_key' => array(
                'title'       => __( 'API Key', 'textdomain' ),
                'type'        => 'password',
                'description' => __( 'Enter your API key', 'textdomain' ),
            ),
        );
    }

    public function process_payment( $order_id ) {
        $order = wc_get_order( $order_id );

        // Process payment with external API
        $response = wp_remote_post( 'https://api.payment.com/charge', array(
            'body' => array(
                'amount'   => $order->get_total(),
                'currency' => $order->get_currency(),
                'token'    => sanitize_text_field( $_POST['payment_token'] ),
            ),
            'headers' => array(
                'Authorization' => 'Bearer ' . $this->api_key,
            ),
        ) );

        $body = json_decode( wp_remote_retrieve_body( $response ), true );

        if ( isset( $body['success'] ) && $body['success'] ) {
            $order->payment_complete( $body['transaction_id'] );
            WC()->cart->empty_cart();

            return array(
                'result'   => 'success',
                'redirect' => $this->get_return_url( $order ),
            );
        } else {
            wc_add_notice( $body['error'] ?? __( 'Payment failed', 'textdomain' ), 'error' );
            return array( 'result' => 'fail' );
        }
    }

    public function process_refund( $order_id, $amount = null, $reason = '' ) {
        $order = wc_get_order( $order_id );

        $response = wp_remote_post( 'https://api.payment.com/refund', array(
            'body' => array(
                'transaction_id' => $order->get_transaction_id(),
                'amount'         => $amount,
            ),
        ) );

        $body = json_decode( wp_remote_retrieve_body( $response ), true );

        if ( isset( $body['success'] ) && $body['success'] ) {
            return true;
        }

        return new WP_Error( 'refund_failed', $body['error'] ?? 'Refund failed' );
    }
}

// Register gateway
add_filter( 'woocommerce_payment_gateways', function( $gateways ) {
    $gateways[] = 'WC_Gateway_Custom';
    return $gateways;
} );

REST API

Custom Endpoints

add_action( 'rest_api_init', function() {
    register_rest_route( 'custom/v1', '/products/featured', array(
        'methods'             => 'GET',
        'callback'            => 'get_featured_products',
        'permission_callback' => '__return_true',
    ) );
} );

function get_featured_products( WP_REST_Request $request ) {
    $args = array(
        'post_type'      => 'product',
        'posts_per_page' => $request->get_param( 'per_page' ) ?: 10,
        'tax_query'      => array(
            array(
                'taxonomy' => 'product_visibility',
                'field'    => 'name',
                'terms'    => 'featured',
            ),
        ),
    );

    $products = wc_get_products( $args );

    return array_map( function( $product ) {
        return array(
            'id'         => $product->get_id(),
            'name'       => $product->get_name(),
            'price'      => $product->get_price(),
            'image'      => wp_get_attachment_url( $product->get_image_id() ),
            'permalink'  => $product->get_permalink(),
        );
    }, $products );
}

Extend Existing Endpoints

// Add custom field to product API response
add_filter( 'woocommerce_rest_prepare_product_object', function( $response, $product, $request ) {
    $response->data['custom_field'] = $product->get_meta( '_custom_field' );
    $response->data['stock_status_label'] = $product->is_in_stock() ? 'Available' : 'Out of Stock';
    return $response;
}, 10, 3 );

// Allow updating custom field via API
add_action( 'woocommerce_rest_insert_product_object', function( $product, $request, $creating ) {
    if ( isset( $request['custom_field'] ) ) {
        $product->update_meta_data( '_custom_field', sanitize_text_field( $request['custom_field'] ) );
        $product->save();
    }
}, 10, 3 );

Performance

Query Optimization

// Disable unnecessary features
add_filter( 'woocommerce_background_image_regeneration', '__return_false' );
add_filter( 'woocommerce_enable_nocache_headers', '__return_false' );

// Limit product queries
add_filter( 'loop_shop_per_page', function() {
    return 24; // Products per page
} );

// Cache expensive queries
function get_best_sellers( $limit = 5 ) {
    $cache_key = 'wc_best_sellers_' . $limit;
    $products  = get_transient( $cache_key );

    if ( false === $products ) {
        global $wpdb;

        $products = $wpdb->get_results( $wpdb->prepare( "
            SELECT p.ID, p.post_title, SUM(oim.meta_value) as total_sales
            FROM {$wpdb->posts} p
            INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON p.ID = oi.order_item_name
            INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
            WHERE oim.meta_key = '_qty'
            AND p.post_type = 'product'
            AND p.post_status = 'publish'
            GROUP BY p.ID
            ORDER BY total_sales DESC
            LIMIT %d
        ", $limit ) );

        set_transient( $cache_key, $products, HOUR_IN_SECONDS );
    }

    return $products;
}

// Clear cache on order
add_action( 'woocommerce_order_status_completed', function() {
    delete_transient( 'wc_best_sellers_5' );
} );

AJAX Cart

// Update cart via AJAX
add_action( 'wp_ajax_update_cart_item', 'ajax_update_cart_item' );
add_action( 'wp_ajax_nopriv_update_cart_item', 'ajax_update_cart_item' );

function ajax_update_cart_item() {
    check_ajax_referer( 'wc_cart_nonce', 'nonce' );

    $cart_item_key = sanitize_text_field( $_POST['cart_item_key'] );
    $quantity      = absint( $_POST['quantity'] );

    if ( $quantity > 0 ) {
        WC()->cart->set_quantity( $cart_item_key, $quantity );
    } else {
        WC()->cart->remove_cart_item( $cart_item_key );
    }

    WC_AJAX::get_refreshed_fragments();
}

Email Customization

// Add content to order emails
add_action( 'woocommerce_email_order_details', function( $order, $sent_to_admin, $plain_text, $email ) {
    if ( 'customer_completed_order' === $email->id ) {
        echo '<h2>Thank you for your order!</h2>';
        echo '<p>Your order will be shipped within 2-3 business days.</p>';
    }
}, 5, 4 );

// Custom email
class WC_Email_Custom extends WC_Email {
    public function __construct() {
        $this->id             = 'custom_email';
        $this->title          = __( 'Custom Email', 'textdomain' );
        $this->description    = __( 'Custom email notification', 'textdomain' );
        $this->template_html  = 'emails/custom-email.php';
        $this->template_plain = 'emails/plain/custom-email.php';

        parent::__construct();
    }

    public function trigger( $order_id ) {
        if ( ! $order_id ) return;

        $this->object = wc_get_order( $order_id );
        $this->recipient = $this->object->get_billing_email();

        if ( ! $this->is_enabled() || ! $this->get_recipient() ) return;

        $this->send(
            $this->get_recipient(),
            $this->get_subject(),
            $this->get_content(),
            $this->get_headers(),
            $this->get_attachments()
        );
    }
}

add_filter( 'woocommerce_email_classes', function( $emails ) {
    $emails['WC_Email_Custom'] = new WC_Email_Custom();
    return $emails;
} );