WordPress Pro
Jeffallan/claude-skills
Develops WordPress themes, plugins, Gutenberg blocks and WooCommerce features with nonce, escaping and capability checks, phpcs linting and caching tuned for speed.
WooCommerce extension code review for HPOS compatibility, payment gateway security, cart optimization, and template overrides.
$ npx skills add jorgerosal/wordpress-skills --skill wp-woocommerce-dev -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install jorgerosal/wordpress-skills wp-woocommerce-dev --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/jorgerosal/wordpress-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/claude-skills/wp-woocommerce-dev .claude/skills/wp-woocommerce-dev && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "wp-woocommerce-dev" agent skill from https://github.com/jorgerosal/wordpress-skills/tree/main/claude-skills/wp-woocommerce-dev into .claude/skills/wp-woocommerce-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "wp-woocommerce-dev", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/jorgerosal/wordpress-skills/tree/main/claude-skills/wp-woocommerce-devType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add jorgerosal/wordpress-skills --skill wp-woocommerce-dev -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install jorgerosal/wordpress-skills wp-woocommerce-dev --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jorgerosal/wordpress-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/claude-skills/wp-woocommerce-dev .agents/skills/wp-woocommerce-dev && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "wp-woocommerce-dev" agent skill from https://github.com/jorgerosal/wordpress-skills/tree/main/claude-skills/wp-woocommerce-dev into .agents/skills/wp-woocommerce-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "wp-woocommerce-dev", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jorgerosal/wordpress-skills --skill wp-woocommerce-dev -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install jorgerosal/wordpress-skills wp-woocommerce-dev --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jorgerosal/wordpress-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/claude-skills/wp-woocommerce-dev .cursor/skills/wp-woocommerce-dev && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "wp-woocommerce-dev" agent skill from https://github.com/jorgerosal/wordpress-skills/tree/main/claude-skills/wp-woocommerce-dev into .cursor/skills/wp-woocommerce-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "wp-woocommerce-dev", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/jorgerosal/wordpress-skills.git --path claude-skills/wp-woocommerce-dev--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add jorgerosal/wordpress-skills --skill wp-woocommerce-dev -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install jorgerosal/wordpress-skills wp-woocommerce-dev --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jorgerosal/wordpress-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/claude-skills/wp-woocommerce-dev .gemini/skills/wp-woocommerce-dev && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "wp-woocommerce-dev" agent skill from https://github.com/jorgerosal/wordpress-skills/tree/main/claude-skills/wp-woocommerce-dev into .gemini/skills/wp-woocommerce-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "wp-woocommerce-dev", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install jorgerosal/wordpress-skills wp-woocommerce-devInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add jorgerosal/wordpress-skills --skill wp-woocommerce-dev -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/jorgerosal/wordpress-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/claude-skills/wp-woocommerce-dev .github/skills/wp-woocommerce-dev && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "wp-woocommerce-dev" agent skill from https://github.com/jorgerosal/wordpress-skills/tree/main/claude-skills/wp-woocommerce-dev into .github/skills/wp-woocommerce-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "wp-woocommerce-dev", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jorgerosal/wordpress-skills --skill wp-woocommerce-dev -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install jorgerosal/wordpress-skills wp-woocommerce-dev --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jorgerosal/wordpress-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/claude-skills/wp-woocommerce-dev .opencode/skills/wp-woocommerce-dev && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "wp-woocommerce-dev" agent skill from https://github.com/jorgerosal/wordpress-skills/tree/main/claude-skills/wp-woocommerce-dev into .opencode/skills/wp-woocommerce-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "wp-woocommerce-dev", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
wp-woocommerce-devWooCommerce extension code review for HPOS compatibility, payment gateway security, cart optimization, and template overrides.
Wp Woocommerce Dev is an agent skill from jorgerosal/wordpress-skills. WooCommerce extension code review for HPOS compatibility, payment gateway security, cart optimization, and template overrides. Use when reviewing WooCommerce extension code, payment gateway development, shipping methods, custom product types, cart operations, checkout customization, or when user mentions "WooCommerce review", "WooCommerce extension", "WooCommerce plugin", "payment gateway", "shipping method", "HPOS", "High-Performance Order Storage", "wcgetorders", "WCPaymentGateway", "WCShippingMethod", "cart…
Its SKILL.md is about 14k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/wc-extension-guide.md`, `references/wc-performance-guide.md` and `references/wc-template-guide.md`).
It sits in Development, covering REST APIs and Code review. It works with WooCommerce. The repository describes itself as: ✅ 🎉 Claude skills and Codex skills for Wordpress development❗️. The licence is MIT.
8 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 8c96442. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
rgFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Wp Woocommerce Dev loads about 14k tokens when it runs, and up to ~39k if it reads all its reference files. Until then it costs about 227 tokens; SKILL.md has 1,939 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from jorgerosal/wordpress-skills at commit 8c96442, republished under its MIT licence (© jorgerosal). 1,939 words, ~13,522 tokens.
.claude/skills/wp-woocommerce-dev/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.Systematic WooCommerce development review for WooCommerce 8.2+ through current 10.x. Core principle: WooCommerce has undergone a fundamental architectural shift—HPOS (High-Performance Order Storage) is default for new stores since WC 8.2 (October 2023), requiring all extensions to use CRUD APIs exclusively. Direct post access for orders is broken on modern WooCommerce installations.
Extensions must use WC_Data CRUD pattern (wc_get_order(), wc_get_orders(), WC_Order methods), Action Scheduler for background processing, and hooks-over-template-overrides for maintainability. Payment gateways must never store/log raw card data. Cart fragments must be conditionally loaded. Template overrides must preserve all action hooks.
Review validates HPOS compatibility, payment gateway security (code-level only, NOT PCI compliance audit), WooCommerce hook usage, template override quality, and performance patterns. Auto-detects WooCommerce context (extension, theme integration, payment gateway, shipping method, custom product type, WC Blocks integration) and adjusts review guidance. Report findings grouped by file with line numbers, severity labels (CRITICAL/WARNING/INFO), and BAD/GOOD code pairs.
Note: This skill touches all prior skills—security (payment data handling), plugin architecture (WC as extension), blocks (WC Blocks), themes (template overrides), and performance (cart fragments, queries). Cross-references provided throughout.
Use when:
Don't use for:
Follow this eight-step workflow for systematic WooCommerce reviews:
Extension/plugin:
WooCommerce in plugin header)before_woocommerce_init hookTheme integration:
Payment gateway:
WC_Payment_GatewayShipping method:
WC_Shipping_MethodCustom product type:
WC_ProductWC Blocks integration:
CRITICAL if missing:
declare_compatibility() call in before_woocommerce_init hookadd_action( 'before_woocommerce_init', ... ) with FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true )CRITICAL violations:
get_posts() or WP_Query with post_type='shop_order'get_post_meta() / update_post_meta() for order data$wpdb queries against wp_posts / wp_postmeta for ordersWARNING violations:
WP_Query with post_type='product' (future-breaking—custom product tables planned)GOOD patterns:
wc_get_order( $order_id )wc_get_orders( array( 'status' => 'completed', 'limit' => 10 ) )$order->get_meta( 'key' ), $order->update_meta_data( 'key', $value ), $order->save()Compatibility mode awareness:
Product access:
wc_get_product( $id ), WC_Product_QueryWP_Query with post_type='product' (use wc_get_products() instead)$wpdb queries against product tablesOrder access:
wc_get_order( $id ), wc_get_orders()get_posts() with post_type='shop_order'$wpdb queries for order dataWC_Data pattern:
->save() after modificationsCRITICAL violations:
error_log() or debug.logWARNING violations:
is_ssl() check before payment processingprocess_payment() validation:
$order->payment_complete( $transaction_id ) not manual status change$_POST card data—use tokenizationCross-reference:
Lifecycle hooks:
woocommerce_before_cart, woocommerce_after_cartwoocommerce_checkout_process, woocommerce_checkout_create_orderwoocommerce_thankyouwoocommerce_order_status_changedProduct data hooks:
woocommerce_product_options_* for admin fieldswoocommerce_process_product_meta for savingCheckout field hooks:
woocommerce_checkout_fields for adding fieldswoocommerce_checkout_update_order_meta for savingCart hooks:
woocommerce_add_cart_item_data for custom cart datawoocommerce_cart_calculate_fees for feeswoocommerce_check_cart_items for validationOrder status transitions:
woocommerce_order_status_{status} for specific status changes$order->set_status() with note, not direct post status changeCRITICAL violations:
do_action() hooksWARNING violations:
INFO suggestions:
Hooks-first philosophy:
do_action() calls from original templateCross-reference:
Cart fragments (wc-cart-fragments.js):
Product queries:
wp_posts for productsWP_Query with post_type='product'Action Scheduler:
wp_cron() for bulk WC operations (unreliable, traffic-dependent)as_enqueue_async_action(), as_schedule_single_action()Session handling:
WC_Session_HandlerCross-reference:
Suggest cross-referencing skills as appropriate:
/wp-sec-review/wp-plugin-review/wp-block-review/wp-theme-review/wp-perf-reviewCompatibility declaration (CRITICAL if missing):
// GOOD: 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
);
}
} );
// BAD: Missing declaration
// Extension silently breaks on HPOS-enabled storesDirect post access (CRITICAL):
get_posts() with 'post_type' => 'shop_order'new WP_Query( array( 'post_type' => 'shop_order' ) )get_post_meta( $order_id, ... ) for order dataupdate_post_meta( $order_id, ... ) for order data$wpdb->prepare() against wp_posts for ordersCRUD patterns (GOOD):
// GOOD: HPOS-compatible order access
$order = wc_get_order( $order_id );
$order->update_meta_data( 'custom_field', $value );
$order->save();
// GOOD: Query orders
$orders = wc_get_orders( array(
'status' => 'completed',
'limit' => 10,
'date_created' => '>=' . strtotime( '-30 days' )
) );
// BAD: Direct post access (breaks HPOS)
$orders = get_posts( array(
'post_type' => 'shop_order',
'post_status' => 'wc-completed'
) );
update_post_meta( $order_id, 'custom_field', $value );WC_Data base class:
WC_Data->save() calledOrder CRUD:
// GOOD: Complete order manipulation
$order = wc_get_order( $order_id );
$order->set_status( 'processing', 'Payment received' );
$order->update_meta_data( 'gift_message', $message );
$order->add_order_note( 'Custom note' );
$order->save(); // Single save after all changes
// BAD: Manual post status change
wp_update_post( array(
'ID' => $order_id,
'post_status' => 'wc-processing'
) );Product CRUD:
// GOOD: WC_Product_Query for product lists
$query = new WC_Product_Query( array(
'status' => 'publish',
'limit' => 10,
'category' => array( 'clothing' ),
'orderby' => 'date',
'order' => 'DESC'
) );
$products = $query->get_products();
// WARNING: WP_Query for products (future-breaking)
$products = new WP_Query( array(
'post_type' => 'product',
'posts_per_page' => 10
) );Custom data store registration:
// GOOD: Register custom data store
add_filter( 'woocommerce_data_stores', 'register_custom_data_store' );
function register_custom_data_store( $data_stores ) {
$data_stores['custom-order-type'] = 'Custom_Order_Data_Store';
return $data_stores;
}WC_Payment_Gateway class structure:
// GOOD: Complete payment gateway implementation
class WC_Gateway_Custom extends WC_Payment_Gateway {
public function __construct() {
$this->id = 'custom_gateway';
$this->has_fields = true;
$this->method_title = __( 'Custom Gateway', 'text-domain' );
$this->method_description = __( 'Description', 'text-domain' );
$this->init_form_fields();
$this->init_settings();
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id,
array( $this, 'process_admin_options' ) );
}
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
// CRITICAL: Always check HTTPS in production
if ( ! is_ssl() && 'yes' !== $this->get_option( 'testmode' ) ) {
wc_add_notice( __( 'SSL required', 'text-domain' ), 'error' );
return array( 'result' => 'failure' );
}
// GOOD: Use payment_complete() not manual status change
$order->payment_complete( $transaction_id );
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}
}CRITICAL security anti-patterns:
// CRITICAL: Never store raw card data
// BAD:
update_post_meta( $order_id, 'card_number', $_POST['card_number'] );
$wpdb->insert( 'payment_tokens', array( 'card' => $_POST['card_number'] ) );
// CRITICAL: Never log card data
// BAD:
error_log( 'Card: ' . $_POST['card_number'] );
wc_get_logger()->debug( 'CVV: ' . $_POST['cvv'] );
// GOOD: Use tokenization
$token = new WC_Payment_Token_CC();
$token->set_token( $gateway_token );
$token->set_gateway_id( $this->id );
$token->set_last4( substr( $card_number, -4 ) );
$token->set_card_type( $card_type );
$token->save();Refund handling:
// GOOD: Implement refund support
public function process_refund( $order_id, $amount = null, $reason = '' ) {
$order = wc_get_order( $order_id );
// Process refund via API
$result = $this->api_refund( $order, $amount );
if ( $result->success ) {
$order->add_order_note(
sprintf( __( 'Refunded %s', 'text-domain' ), $amount )
);
return true;
}
return false;
}Cross-reference:
WC_Shipping_Method class structure:
// GOOD: Complete shipping method implementation
class WC_Shipping_Custom extends WC_Shipping_Method {
public function __construct( $instance_id = 0 ) {
$this->id = 'custom_shipping';
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Custom Shipping', 'text-domain' );
$this->method_description = __( 'Description', 'text-domain' );
$this->supports = array( 'shipping-zones', 'instance-settings' );
$this->init();
}
public function calculate_shipping( $package = array() ) {
$rate = array(
'id' => $this->id . $this->instance_id,
'label' => $this->title,
'cost' => 10.00,
'calc_tax' => 'per_order'
);
$this->add_rate( $rate );
}
}Product type registration:
// GOOD: Register custom product type
add_filter( 'product_type_selector', 'add_custom_product_type' );
function add_custom_product_type( $types ) {
$types['custom-product'] = __( 'Custom Product', 'text-domain' );
return $types;
}
// GOOD: Product class extending WC_Product
class WC_Product_Custom extends WC_Product {
public function __construct( $product = 0 ) {
$this->product_type = 'custom-product';
parent::__construct( $product );
}
public function get_type() {
return 'custom-product';
}
}
// GOOD: Register product class
add_filter( 'woocommerce_product_class', 'load_custom_product_class', 10, 2 );
function load_custom_product_class( $classname, $product_type ) {
if ( 'custom-product' === $product_type ) {
$classname = 'WC_Product_Custom';
}
return $classname;
}Lifecycle hooks:
// GOOD: Order lifecycle hooks
add_action( 'woocommerce_checkout_process', 'validate_custom_checkout_field' );
add_action( 'woocommerce_checkout_create_order', 'save_custom_order_data', 10, 2 );
add_action( 'woocommerce_thankyou', 'custom_thankyou_action' );
add_action( 'woocommerce_order_status_changed', 'handle_status_change', 10, 4 );Product data hooks:
// GOOD: Product admin hooks
add_action( 'woocommerce_product_options_general_product_data', 'add_custom_field' );
add_action( 'woocommerce_process_product_meta', 'save_custom_field' );Checkout field hooks:
// GOOD: Add checkout field
add_filter( 'woocommerce_checkout_fields', 'add_gift_message_field' );
function add_gift_message_field( $fields ) {
$fields['order']['gift_message'] = array(
'type' => 'textarea',
'label' => __( 'Gift message', 'text-domain' ),
'required' => false
);
return $fields;
}
add_action( 'woocommerce_checkout_update_order_meta', 'save_gift_message' );
function save_gift_message( $order_id ) {
if ( ! empty( $_POST['gift_message'] ) ) {
$order = wc_get_order( $order_id );
$order->update_meta_data( 'gift_message', sanitize_textarea_field( $_POST['gift_message'] ) );
$order->save();
}
}Cart item data:
// GOOD: Add custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_data', 10, 2 );
function add_custom_cart_data( $cart_item_data, $product_id ) {
if ( isset( $_POST['custom_field'] ) ) {
$cart_item_data['custom_field'] = sanitize_text_field( $_POST['custom_field'] );
}
return $cart_item_data;
}Cart fees:
// GOOD: Add custom fee
add_action( 'woocommerce_cart_calculate_fees', 'add_custom_fee' );
function add_custom_fee() {
if ( WC()->cart->get_subtotal() > 100 ) {
WC()->cart->add_fee( __( 'Handling fee', 'text-domain' ), 5 );
}
}Cart validation:
// GOOD: Validate cart contents
add_action( 'woocommerce_check_cart_items', 'validate_cart_items' );
function validate_cart_items() {
if ( WC()->cart->get_cart_contents_count() < 3 ) {
wc_add_notice( __( 'Minimum 3 items required', 'text-domain' ), 'error' );
}
}Custom order status:
// GOOD: Register custom order status
add_action( 'init', 'register_awaiting_shipment_status' );
function register_awaiting_shipment_status() {
register_post_status( 'wc-awaiting-shipment', array(
'label' => __( 'Awaiting Shipment', 'text-domain' ),
'public' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop(
'Awaiting shipment <span class="count">(%s)</span>',
'Awaiting shipment <span class="count">(%s)</span>',
'text-domain'
)
) );
}
add_filter( 'wc_order_statuses', 'add_awaiting_shipment_to_order_statuses' );
function add_awaiting_shipment_to_order_statuses( $order_statuses ) {
$order_statuses['wc-awaiting-shipment'] = __( 'Awaiting Shipment', 'text-domain' );
return $order_statuses;
}
// GOOD: Set order status
$order = wc_get_order( $order_id );
$order->set_status( 'awaiting-shipment', 'Order ready for shipment' );Conditional dequeuing:
// GOOD: Conditional cart fragments loading
add_filter( 'woocommerce_get_script_data', 'conditional_cart_fragments', 10, 2 );
function conditional_cart_fragments( $data, $handle ) {
if ( 'wc-cart-fragments' === $handle ) {
// Only load on WC pages
if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
return null;
}
}
return $data;
}
// CRITICAL: Site-wide cart fragments loading
// BAD: No conditional dequeue - loads on every pageMini-Cart Block alternative:
// INFO: Recommend Mini-Cart Block migration
// Mini-Cart Block has built-in performance optimizations
// No cart fragments neededBackground processing:
// GOOD: Action Scheduler for bulk operations
function schedule_order_export() {
as_enqueue_async_action(
'process_order_export',
array( 'batch_id' => 123 ),
'wc-exports'
);
}
add_action( 'process_order_export', 'do_order_export', 10, 1 );
function do_order_export( $batch_id ) {
$orders = wc_get_orders( array(
'limit' => 100,
'offset' => $batch_id * 100
) );
foreach ( $orders as $order ) {
// Export logic
}
// Schedule next batch if needed
if ( count( $orders ) === 100 ) {
as_enqueue_async_action(
'process_order_export',
array( 'batch_id' => $batch_id + 1 ),
'wc-exports'
);
}
}
// WARNING: wp_cron for heavy WC tasks
// BAD:
wp_schedule_event( time(), 'hourly', 'process_order_export' );Signature verification:
// GOOD: Verify webhook signature
function verify_wc_webhook( $payload, $signature, $secret ) {
$expected = base64_encode( hash_hmac( 'sha256', $payload, $secret, true ) );
// CRITICAL: Use hash_equals to prevent timing attacks
return hash_equals( $expected, $signature );
}
// Webhook handler
$payload = file_get_contents( 'php://input' );
$signature = $_SERVER['HTTP_X_WC_WEBHOOK_SIGNATURE'] ?? '';
$delivery_id = $_SERVER['HTTP_X_WC_WEBHOOK_DELIVERY_ID'] ?? '';
// WARNING: Missing signature verification
if ( ! verify_wc_webhook( $payload, $signature, $secret ) ) {
http_response_code( 401 );
exit;
}
// GOOD: Check for duplicate delivery
if ( get_transient( 'wc_webhook_' . $delivery_id ) ) {
http_response_code( 200 );
exit;
}
set_transient( 'wc_webhook_' . $delivery_id, true, DAY_IN_SECONDS );
// GOOD: Process async via Action Scheduler
as_enqueue_async_action( 'process_wc_webhook', array( 'payload' => $payload ) );Preserving hooks:
// In child-theme/woocommerce/content-product.php
// GOOD: Preserve all action hooks from original template
do_action( 'woocommerce_before_shop_loop_item' );
do_action( 'woocommerce_before_shop_loop_item_title' );
// Custom content here
do_action( 'woocommerce_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item' );
// CRITICAL: Deleted hooks in template override
// BAD: No do_action() calls - breaks plugin integrationVersion tracking:
// GOOD: Template with version comment
/**
* Product loop template
*
* @version 8.9.0
*/
// WARNING: Outdated version
// Template version 3.6.0 when WC is 10.5 - may miss updatesHooks-first philosophy:
// BETTER: Use hooks instead of template override
add_action( 'woocommerce_shop_loop_item_title', 'add_custom_content', 15 );
function add_custom_content() {
// Custom content via hook - no template override needed
}
// INFO: Template override where hook exists
// Suggest using hook instead of copying entire templateCross-reference:
WooCommerce Blocks checkout integration (WOO-14):
// GOOD: Add checkout field via Additional Checkout Fields API (WC 8.6+)
add_action( 'woocommerce_init', 'register_custom_checkout_field' );
function register_custom_checkout_field() {
woocommerce_register_additional_checkout_field( array(
'id' => 'namespace/gift-message',
'label' => __( 'Gift message', 'text-domain' ),
'location' => 'order',
'type' => 'text'
) );
}WooCommerce REST API extensions (WOO-09):
// INFO: Custom REST endpoint registration
add_action( 'rest_api_init', 'register_custom_endpoint' );
function register_custom_endpoint() {
register_rest_route( 'wc/v3', '/custom-endpoint', array(
'methods' => 'GET',
'callback' => 'custom_endpoint_callback',
'permission_callback' => function() {
return current_user_can( 'manage_woocommerce' );
}
) );
}Coupon validation (WOO-21):
// GOOD: Custom coupon validation
add_filter( 'woocommerce_coupon_is_valid', 'validate_custom_coupon', 10, 3 );
function validate_custom_coupon( $valid, $coupon, $discount ) {
if ( WC()->cart->get_cart_contents_count() < 3 ) {
throw new Exception(
__( 'Coupon requires at least 3 items', 'text-domain' ),
109
);
}
return $valid;
}Session handling (WOO-18):
// WARNING: Custom session filter exceeding 30-day cap (WC 10.1+)
// BAD:
add_filter( 'wc_session_expiration', function() {
return 60 * DAY_IN_SECONDS; // Exceeds 30-day cap
} );
// GOOD: Respect 30-day cap
add_filter( 'wc_session_expiration', function() {
return 30 * DAY_IN_SECONDS; // Maximum allowed
} );Use these rg commands and shell checks for quick WooCommerce scanning. Organized by severity.
# HPOS declaration candidates
# If this returns nothing in a WooCommerce extension, the plugin likely lacks HPOS declaration.
rg -n "declare_compatibility\s*\(\s*['\"]custom_order_tables['\"]" . -g '*.php'
# get_posts/WP_Query with shop_order
rg -n "post_type.*shop_order|shop_order.*post_type" . -g '*.php'
# Direct $wpdb queries against wp_posts for orders
rg -n "\$wpdb.*wp_posts.*shop_order" . -g '*.php'
# Raw card data storage/logging
rg -n "card_number|card_cvv|cvv.*meta|card.*error_log" . -g '*.php'
# Template overrides without do_action() calls
find . -path "*/woocommerce/*.php" -exec rg -L "do_action|apply_filters" {} \;
# Webhook signature handling candidates (manually confirm verification logic)
rg -n "X-WC-Webhook-Signature|hash_hmac|verify" . -g '*.php'# WP_Query with post_type=product (compare these result sets manually)
rg -n "WP_Query|get_posts" . -g '*.php'
rg -n "post_type.*product|product.*post_type" . -g '*.php'
# Site-wide cart-fragments loading without conditional dequeue (manual context check)
rg -n "wc-cart-fragments|woocommerce_get_script_data|is_woocommerce|is_cart" . -g '*.php'
# wp_cron for bulk WC operations (manual context check)
rg -n "wp_schedule_event|wp_cron|wc_|order|product" . -g '*.php'
# Hardcoded API credentials
rg -n "api_key.*=.*['\"][A-Za-z0-9]{20,}" . -g '*.php'
# get_post_meta/update_post_meta for order fields
rg -n "get_post_meta.*order_id|update_post_meta.*order_id" . -g '*.php'
# Session filters exceeding 30-day cap (manual follow-up on returned values)
rg -n "wc_session_expiration|wc_session_expiring" . -g '*.php'# Template overrides where hooks exist
find . -path "*/woocommerce/*.php" -type f
# Missing object caching for repeated product loads
rg -n "wc_get_product" . -g '*.php'
# Action Scheduler candidates
rg -n "foreach.*wc_get_orders|foreach.*wc_get_products" . -g '*.php'
# WC Blocks integration opportunities
rg -n "woocommerce_register_additional_checkout_field|Store API" . -g '*.php'Note: WC-specific patterns need different context than generic WP. get_posts() for non-order post types is valid. WP_Query for standard posts/pages is valid. Only flag when combined with WC-specific post types.
Context-aware review notes based on file structure and patterns:
Detection: Main plugin file with WC dependency check, HPOS declaration Review focus: Full HPOS + CRUD + hook audit Most common context
Detection: woocommerce/ directory in theme with template overrides Review focus: Template override quality, hooks preservation Cross-reference: wp-theme-development for theme patterns
Detection: Class extending WC_Payment_Gateway
Review focus: Heightened security review (never store raw cards, HTTPS check, webhook verification)
Cross-reference: wp-security-review for general security
Detection: Class extending WC_Shipping_Method
Review focus: calculate_shipping() review, zone support, rate calculation
Detection: Class extending WC_Product
Review focus: Data store review, product type registration, class hierarchy
Detection: Store API usage, checkout block extension points Review focus: Surface-level review, Additional Checkout Fields API Cross-reference: wp-block-development for deep block patterns
Common WooCommerce patterns organized by concern. All examples follow WordPress PHP Coding Standards (spaces in parentheses, array() not [], Yoda conditions).
❌ BAD: Missing HPOS declaration
<?php
// Extension silently breaks on HPOS-enabled stores✅ GOOD: Declare compatibility in before_woocommerce_init hook
<?php
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
);
}
} );❌ BAD: Direct post access (breaks HPOS)
<?php
$orders = get_posts( array(
'post_type' => 'shop_order',
'post_status' => 'wc-completed'
) );
update_post_meta( $order_id, 'custom_field', $value );✅ GOOD: HPOS-compatible CRUD
<?php
$orders = wc_get_orders( array(
'status' => 'completed',
'limit' => 10
) );
$order = wc_get_order( $order_id );
$order->update_meta_data( 'custom_field', $value );
$order->save();❌ BAD: Direct meta functions
<?php
update_post_meta( $order_id, 'delivery_date', '2026-02-15' );
$date = get_post_meta( $order_id, 'delivery_date', true );✅ GOOD: WC_Order methods
<?php
$order = wc_get_order( $order_id );
$order->update_meta_data( 'delivery_date', '2026-02-15' );
$order->save();
$date = $order->get_meta( 'delivery_date', true );❌ BAD: WP_Query for products (future-breaking)
<?php
$products = new WP_Query( array(
'post_type' => 'product',
'posts_per_page' => 10
) );✅ GOOD: WC_Product_Query
<?php
$query = new WC_Product_Query( array(
'status' => 'publish',
'limit' => 10,
'category' => array( 'clothing' ),
'orderby' => 'date',
'order' => 'DESC'
) );
$products = $query->get_products();❌ BAD: Raw card data storage, missing HTTPS check
<?php
public function process_payment( $order_id ) {
// CRITICAL: Never store raw card data
update_post_meta( $order_id, 'card_number', $_POST['card_number'] );
// Process payment
$order = wc_get_order( $order_id );
$order->update_status( 'processing' ); // Manual status change
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}✅ GOOD: Tokenization, HTTPS check, payment_complete()
<?php
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
// Check HTTPS in production
if ( ! is_ssl() && 'yes' !== $this->get_option( 'testmode' ) ) {
wc_add_notice( __( 'SSL required', 'text-domain' ), 'error' );
return array( 'result' => 'failure' );
}
// Process via API (use tokenization, never store raw cards)
$result = $this->api_charge( $order );
if ( $result->success ) {
// Use payment_complete() not manual status change
$order->payment_complete( $result->transaction_id );
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}
return array( 'result' => 'failure' );
}✅ GOOD: Complete shipping method
<?php
class WC_Shipping_Custom extends WC_Shipping_Method {
public function __construct( $instance_id = 0 ) {
$this->id = 'custom_shipping';
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Custom Shipping', 'text-domain' );
$this->supports = array( 'shipping-zones', 'instance-settings' );
$this->init();
}
public function calculate_shipping( $package = array() ) {
$rate = array(
'id' => $this->id . $this->instance_id,
'label' => $this->title,
'cost' => 10.00,
'calc_tax' => 'per_order'
);
$this->add_rate( $rate );
}
}✅ GOOD: Register and implement custom product type
<?php
// Register product type
add_filter( 'product_type_selector', 'add_custom_product_type' );
function add_custom_product_type( $types ) {
$types['custom-product'] = __( 'Custom Product', 'text-domain' );
return $types;
}
// Product class
class WC_Product_Custom extends WC_Product {
public function __construct( $product = 0 ) {
$this->product_type = 'custom-product';
parent::__construct( $product );
}
public function get_type() {
return 'custom-product';
}
}
// Register product class
add_filter( 'woocommerce_product_class', 'load_custom_product_class', 10, 2 );
function load_custom_product_class( $classname, $product_type ) {
if ( 'custom-product' === $product_type ) {
$classname = 'WC_Product_Custom';
}
return $classname;
}✅ GOOD: Add cart item data
<?php
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_data', 10, 2 );
function add_custom_cart_data( $cart_item_data, $product_id ) {
if ( isset( $_POST['custom_field'] ) ) {
$cart_item_data['custom_field'] = sanitize_text_field( $_POST['custom_field'] );
}
return $cart_item_data;
}✅ GOOD: Add cart fee
<?php
add_action( 'woocommerce_cart_calculate_fees', 'add_custom_fee' );
function add_custom_fee() {
if ( WC()->cart->get_subtotal() > 100 ) {
WC()->cart->add_fee( __( 'Handling fee', 'text-domain' ), 5 );
}
}❌ BAD: Manual post status change
<?php
wp_update_post( array(
'ID' => $order_id,
'post_status' => 'wc-processing'
) );✅ GOOD: Use WC_Order::set_status()
<?php
$order = wc_get_order( $order_id );
$order->set_status( 'processing', 'Payment received' );
// Automatically saved✅ GOOD: Use payment_complete() for payment flow
<?php
$order = wc_get_order( $order_id );
$order->payment_complete( $transaction_id );❌ BAD: Deleted hooks in template override
<?php
// In child-theme/woocommerce/content-product.php
// CRITICAL: No do_action() calls - breaks plugin integration
?>
<li class="product">
<h2><?php the_title(); ?></h2>
<div class="price"><?php echo $product->get_price_html(); ?></div>
</li>✅ GOOD: Preserve all action hooks
<?php
// In child-theme/woocommerce/content-product.php
do_action( 'woocommerce_before_shop_loop_item' );
do_action( 'woocommerce_before_shop_loop_item_title' );
?>
<h2><?php the_title(); ?></h2>
<?php
do_action( 'woocommerce_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item' );✅ BETTER: Use hooks instead of template override
<?php
add_action( 'woocommerce_shop_loop_item_title', 'add_custom_content', 15 );
function add_custom_content() {
// Custom content via hook - no template override needed
}❌ BAD: Site-wide cart fragments loading
<?php
// No conditional dequeue - loads on every page
// CRITICAL performance issue✅ GOOD: Conditional dequeuing
<?php
add_filter( 'woocommerce_get_script_data', 'conditional_cart_fragments', 10, 2 );
function conditional_cart_fragments( $data, $handle ) {
if ( 'wc-cart-fragments' === $handle ) {
if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
return null;
}
}
return $data;
}✅ BETTER: Migrate to Mini-Cart Block
// Mini-Cart Block has built-in performance optimizations
// No cart fragments needed❌ BAD: wp_cron for bulk WC operations
<?php
wp_schedule_event( time(), 'hourly', 'process_order_export' );
add_action( 'process_order_export', 'do_export' );
function do_export() {
// Unreliable, traffic-dependent, no retry
}✅ GOOD: Action Scheduler for bulk operations
<?php
function schedule_order_export() {
as_enqueue_async_action(
'process_order_export',
array( 'batch_id' => 0 ),
'wc-exports'
);
}
add_action( 'process_order_export', 'do_order_export', 10, 1 );
function do_order_export( $batch_id ) {
$orders = wc_get_orders( array(
'limit' => 100,
'offset' => $batch_id * 100
) );
foreach ( $orders as $order ) {
// Export logic
}
// Schedule next batch if needed
if ( 100 === count( $orders ) ) {
as_enqueue_async_action(
'process_order_export',
array( 'batch_id' => $batch_id + 1 ),
'wc-exports'
);
}
}❌ BAD: Missing signature verification
<?php
// Webhook handler
$payload = file_get_contents( 'php://input' );
$data = json_decode( $payload );
// WARNING: No signature verification - allows forged webhooks
process_webhook( $data );✅ GOOD: HMAC-SHA256 verification with hash_equals()
<?php
function verify_wc_webhook( $payload, $signature, $secret ) {
$expected = base64_encode( hash_hmac( 'sha256', $payload, $secret, true ) );
return hash_equals( $expected, $signature );
}
// Webhook handler
$payload = file_get_contents( 'php://input' );
$signature = $_SERVER['HTTP_X_WC_WEBHOOK_SIGNATURE'] ?? '';
$delivery_id = $_SERVER['HTTP_X_WC_WEBHOOK_DELIVERY_ID'] ?? '';
if ( ! verify_wc_webhook( $payload, $signature, $secret ) ) {
http_response_code( 401 );
exit;
}
// Check for duplicate delivery
if ( get_transient( 'wc_webhook_' . $delivery_id ) ) {
http_response_code( 200 );
exit;
}
set_transient( 'wc_webhook_' . $delivery_id, true, DAY_IN_SECONDS );
// Process async
as_enqueue_async_action( 'process_wc_webhook', array( 'payload' => $payload ) );✅ GOOD: Additional Checkout Fields API (WC 8.6+)
<?php
add_action( 'woocommerce_init', 'register_custom_checkout_field' );
function register_custom_checkout_field() {
woocommerce_register_additional_checkout_field( array(
'id' => 'namespace/gift-message',
'label' => __( 'Gift message', 'text-domain' ),
'location' => 'order',
'type' => 'text',
'attributes' => array(
'maxLength' => 200
)
) );
}
// Access field value
$order = wc_get_order( $order_id );
$gift_message = $order->get_meta( 'namespace/gift-message' );✅ GOOD: Custom REST endpoint with authentication
<?php
add_action( 'rest_api_init', 'register_custom_endpoint' );
function register_custom_endpoint() {
register_rest_route( 'wc/v3', '/custom-endpoint', array(
'methods' => 'GET',
'callback' => 'custom_endpoint_callback',
'permission_callback' => function() {
return current_user_can( 'manage_woocommerce' );
}
) );
}✅ GOOD: Custom coupon validation
<?php
add_filter( 'woocommerce_coupon_is_valid', 'validate_custom_coupon', 10, 3 );
function validate_custom_coupon( $valid, $coupon, $discount ) {
if ( WC()->cart->get_cart_contents_count() < 3 ) {
throw new Exception(
__( 'Coupon requires at least 3 items', 'text-domain' ),
109
);
}
return $valid;
}❌ BAD: Exceeding 30-day cap
<?php
add_filter( 'wc_session_expiration', function() {
return 60 * DAY_IN_SECONDS; // Exceeds cap
} );✅ GOOD: Respect 30-day cap (WC 10.1+)
<?php
add_filter( 'wc_session_expiration', function() {
return 30 * DAY_IN_SECONDS; // Maximum allowed
} );✅ GOOD: Extend WC_Email class
<?php
class WC_Email_Custom extends WC_Email {
public function __construct() {
$this->id = 'custom_email';
$this->title = __( 'Custom Email', 'text-domain' );
$this->description = __( 'Email description', 'text-domain' );
$this->template_html = 'emails/custom-email.php';
$this->template_plain = 'emails/plain/custom-email.php';
parent::__construct();
}
public function trigger( $order_id ) {
$this->object = wc_get_order( $order_id );
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() );
}
}| Severity | Definition | Examples |
|---|---|---|
| CRITICAL | Extension will break on modern WC stores OR has security vulnerabilities | Missing HPOS compatibility declaration, direct post access for orders (get_posts/WP_Query with shop_order), direct database queries for orders/products, raw card data storage/logging (card_number in DB or error_log), template overrides with deleted action hooks, missing webhook signature verification, transmitting card data over HTTP |
| WARNING | Extension works but has quality/compatibility/performance issues | WP_Query for products (future-breaking), cart fragments site-wide loading, outdated template overrides (version mismatch), hardcoded API credentials in code, wp_cron() for bulk WC operations, session duration exceeding 30 days, get_post_meta/update_post_meta for order fields, missing HTTPS check in payment processing |
| INFO | Best practice improvements OR optimization opportunities | Template override where hook exists (suggest hook instead), Action Scheduler instead of wp_cron for light tasks, object caching for repeated product loads, WC Blocks integration opportunity, Additional Checkout Fields API usage, product object caching (WC 10.5+ experimental) |
Report findings grouped by FILE (PHP files organized by actual file path), with line numbers and severity labels. Use BAD/GOOD code pairs for each finding.
# WooCommerce Review: my-wc-extension
## FILE: includes/class-order-handler.php
### Line 45: CRITICAL - Direct post access for orders
get_posts() with post_type='shop_order' breaks on HPOS-enabled stores. Use wc_get_orders() instead.
❌ **BAD:**
```php
$orders = get_posts( array(
'post_type' => 'shop_order',
'post_status' => 'wc-completed'
) );✅ GOOD:
$orders = wc_get_orders( array(
'status' => 'completed',
'limit' => 10
) );update_post_meta() for order data breaks HPOS compatibility. Use WC_Order methods.
❌ BAD:
update_post_meta( $order_id, 'custom_field', $value );✅ GOOD:
$order = wc_get_order( $order_id );
$order->update_meta_data( 'custom_field', $value );
$order->save();Extension must declare HPOS compatibility status. Add before_woocommerce_init hook.
❌ BAD:
<?php
// No HPOS declaration - extension silently incompatible✅ GOOD:
<?php
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
);
}
} );Logging card data is a PCI violation and security breach. Never log payment information.
❌ BAD:
error_log( 'Processing card: ' . $_POST['card_number'] );✅ GOOD:
// Never log card data
// Use tokenization, log transaction IDs only
$this->log( 'Processing transaction: ' . $transaction_id );Check is_ssl() before processing payments in production mode.
❌ BAD:
public function process_payment( $order_id ) {
// Process payment without SSL check
}✅ GOOD:
public function process_payment( $order_id ) {
if ( ! is_ssl() && 'yes' !== $this->get_option( 'testmode' ) ) {
wc_add_notice( __( 'SSL required', 'text-domain' ), 'error' );
return array( 'result' => 'failure' );
}
// Process payment
}Cart fragments loading on every page causes performance issues. Add conditional dequeuing.
❌ BAD:
// No conditional dequeue - loads on all pages✅ GOOD:
add_filter( 'woocommerce_get_script_data', 'conditional_cart_fragments', 10, 2 );
function conditional_cart_fragments( $data, $handle ) {
if ( 'wc-cart-fragments' === $handle ) {
if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
return null;
}
}
return $data;
}Total issues: 7
HPOS compatibility risk: HIGH - Extension will break on modern WooCommerce stores
Security note: Payment security issues detected. Run /wp-sec-review for comprehensive security analysis.
Performance note: Cart fragments performance issue detected. Run /wp-perf-review for comprehensive performance analysis.
## Common Mistakes (WOO-25)
Patterns that look like issues but are NOT problems:
| Pattern | Why It's NOT a Problem | Context |
|---------|------------------------|---------|
| **get_posts() for custom post types (not orders)** | Valid when post type is not 'shop_order'. Only shop_order queries break HPOS. | Extensions can use get_posts() for their own post types |
| **WP_Query for standard posts/pages** | Valid for non-product queries. Only product queries flagged as WARNING. | Blog posts, custom post types are fine with WP_Query |
| **get_post_meta() for custom post types (not orders)** | Valid when not accessing order data. Only order meta breaks HPOS. | Custom post type meta operations work normally |
| **Template overrides in child themes** | Legitimate when hooks are preserved. Only flag if do_action() calls deleted. | Intentional customization with proper hook preservation |
| **wc-cart-fragments.js on cart/checkout/product pages** | Expected on WC pages. Only flag site-wide loading. | Conditional loading to WC pages is correct |
| **wp_cron() for lightweight non-WC tasks** | Acceptable for simple scheduled tasks. Only flag for heavy WC operations. | Daily cleanup, simple notifications are fine |
| **WC_Session usage within 30-day window** | Normal behavior. Only flag custom filters exceeding cap. | Standard session handling works correctly |
| **error_log() in non-payment code** | Acceptable debugging. Only flag in payment processing context. | General logging is fine, just not card data |
| **Direct $wpdb for custom tables (NOT WC core tables)** | Valid for extension's own tables. Only flag queries against wp_posts/wp_postmeta for WC data. | Custom table queries don't affect HPOS |
| **process_payment() accessing $_POST for custom fields** | Valid for non-card data (shipping notes, gift messages). Only flag raw card data access. | Custom checkout field handling is expected |
| **Template overrides without @version comment** | Missing metadata, not necessarily outdated. Only flag significant version mismatches. | Version tracking helps but absence isn't critical |
| **apiVersion 2 in WC Blocks integration** | Block-related, not WC-specific. Defer to wp-block-development. | Block patterns handled by block skill |
## Version Compatibility Reference
Quick reference for WooCommerce version requirements:
| Feature | WooCommerce Version | Notes |
|---------|---------------------|-------|
| WC_Data CRUD API | 3.0+ | Base class for all CRUD objects |
| wc_get_order(), wc_get_product() | 3.0+ | Preferred data access methods |
| Product attribute lookup table | 6.3+ | Indexed product attributes for filtering |
| Cart fragments no longer global by default | 7.8+ | Requires opt-in for site-wide loading |
| HPOS (Custom Order Tables) default | 8.2+ | New stores use HPOS by default |
| HPOS compatibility declaration required | 8.2+ | declare_compatibility() mandatory |
| Additional Checkout Fields API | 8.6+ | Block checkout field registration |
| Session 30-day cap enforced | 10.1+ | Maximum session duration limit |
| wc_enqueue_js() deprecated | 10.4+ | Use wp_add_inline_script() instead |
| Product object caching (experimental) | 10.5+ | Opt-in performance feature |
| Variation price caching improvements | 10.5+ | Automatic performance optimization |
| Batch analytics imports (100/12hrs) | 10.5+ | Background processing improvements |
## Deep-Dive References
For advanced WooCommerce development patterns, load these companion reference documents:
| Task | Reference to Load |
|------|-------------------|
| HPOS compatibility migration, payment gateway development (WC_Payment_Gateway lifecycle, process_payment flow, refund handling, security patterns), shipping methods (WC_Shipping_Method, calculate_shipping, zones), custom product types (register_product_type, data stores), order handling (WC_Order CRUD, status transitions), cart operations (cart item data, fees, validation), REST API extensions, Action Scheduler patterns, webhook security | `references/wc-extension-guide.md` |
| Template hierarchy (archive-product, content-product, single-product, cart, checkout, myaccount), override procedures (child theme woocommerce/ directory, version tracking), hooks-first philosophy (when to use hooks vs overrides, preserving action hooks), shop/product/cart/checkout theming, WooCommerce Blocks compatibility notes, email templates | `references/wc-template-guide.md` |
| Cart fragments analysis (problem, solutions, Mini-Cart Block), WC_Product_Query optimization, HPOS performance benefits, session handling (30-day cap, cleanup), Action Scheduler for background processing, transient and object caching strategies, variation price caching, product attribute lookup table, database optimization | `references/wc-performance-guide.md` |
**Note:** Reference docs provide deep-dive content. This SKILL.md is self-sufficient for standard WooCommerce reviews.
**Security crossover:** When encountering security-relevant patterns (payment data handling, REST API authentication, AJAX nonce verification, capability checks), this skill provides brief reminders but defers to wp-security-review for comprehensive security analysis. For detailed security patterns, use `/wp-sec-review` command.
**Plugin crossover:** When encountering plugin-level patterns (WC dependency checking, activation/deactivation, hooks architecture, REST API registration), this skill provides brief mentions but defers to wp-plugin-development for plugin architecture depth. For detailed plugin review, use `/wp-plugin-review` command.
**Block crossover:** When encountering WooCommerce Blocks integration (Store API, checkout block extension points, Additional Checkout Fields API), this skill provides brief mentions but defers to wp-block-development for block development depth. For detailed block patterns, use `/wp-block-review` command.
**Theme crossover:** When encountering template overrides in themes (woocommerce/ directory, template hierarchy, version tracking), this skill provides brief mentions but defers to wp-theme-development for theme development depth. For detailed theme review, use `/wp-theme-review` command.
**Performance crossover:** When encountering cart fragments, query optimization, caching strategies, this skill provides brief mentions but defers to wp-performance-review for comprehensive performance analysis. For detailed performance patterns, use `/wp-perf-review` command.© jorgerosal, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 3 other files (references) in claude-skills/wp-woocommerce-dev of jorgerosal/wordpress-skills.
Open the folder on GitHubat commit 8c96442
Wp Woocommerce Dev next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Wp Woocommerce Dev this skilljorgerosal/wordpress-skills | 101 | — | ~14k | Automated safety check: Pass | MIT | |
| WordPress ProJeffallan/claude-skills | 12k | — | ~1.6k | Automated safety check: Pass | MIT | |
| WooCommerce Code Reviewwoocommerce/woocommerce | 11k | 3 repos | ~1.1k | Automated safety check: Pass | Custom licence | |
| REST API Contract Reviewdecebals/claude-code-java | 751 | 1 repos | ~2.8k | Automated safety check: Pass | MIT | |
| WooCommerce Code GuardamElnagdy/guard-skills | 1.3k | — | ~2.2k | Automated safety check: Pass | MIT | |
| GitHub Actions Patbifrost-proxy/bifrost | 160 | — | ~2k | Automated safety check: Pass | MIT |
Jeffallan/claude-skills
Develops WordPress themes, plugins, Gutenberg blocks and WooCommerce features with nonce, escaping and capability checks, phpcs linting and caching tuned for speed.
woocommerce/woocommerce
Reviews WooCommerce code changes against the project's standards, flagging backend PHP architecture, naming, documentation, data integrity and testing violations.
decebals/claude-code-java
Reviews REST API design for correct HTTP verbs, versioning, DTO use, consistent responses and backward compatibility before an API change ships.
amElnagdy/guard-skills
Reviews generated or changed WooCommerce code for HPOS safety, CRUD use, checkout validation and money handling before it ships.
bifrost-proxy/bifrost
用 Personal Access Token 通过 GitHub REST API 分析 Actions CI 的失败 run/job/step、拉取日志、轮询运行状态、做 PR code review,并驱动 fix → push → watch → iterate 的闭环。Token 只从 GITHUBTOKEN 环境变量读取,不落盘、不回显。适合在 bifrost remote /…
harukiseller-droid/commerce-agent-bench
Review WooCommerce hooks, product data, template overrides, escaping, and regression risks.
jorgerosal/wordpress-skills
WordPress accessibility review for themes, blocks, plugins, and admin interfaces.
jorgerosal/wordpress-skills
WordPress ACF and content modeling review. An agent skill from jorgerosal/wordpress-skills.
jorgerosal/wordpress-skills
WordPress admin UI review and development guidance. An agent skill from jorgerosal/wordpress-skills.
jorgerosal/wordpress-skills
WordPress CI/CD and release engineering review guidance. An agent skill from jorgerosal/wordpress-skills.
jorgerosal/wordpress-skills
Headless WordPress and WPGraphQL review guidance. An agent skill from jorgerosal/wordpress-skills.
jorgerosal/wordpress-skills
WordPress migration and upgrade review. An agent skill from jorgerosal/wordpress-skills.
Works with
Categories
WooCommerce extension code review for HPOS compatibility, payment gateway security, cart optimization, and template overrides. Wp Woocommerce Dev is an agent skill from jorgerosal/wordpress-skills. WooCommerce extension code review for HPOS compatibility, payment gateway security, cart optimization, and template overrides.
Wp Woocommerce Dev fits situations like: reviewing WooCommerce extension code; payment gateway development; shipping methods; custom product types.
Run `npx skills add jorgerosal/wordpress-skills --skill wp-woocommerce-dev -a claude-code`. Or copy the skill folder (claude-skills/wp-woocommerce-dev in jorgerosal/wordpress-skills) into .claude/skills/wp-woocommerce-dev in your project. Claude Code loads it when a task matches its description.
Run `npx skills add jorgerosal/wordpress-skills --skill wp-woocommerce-dev -a codex`. Or copy the skill folder (claude-skills/wp-woocommerce-dev in jorgerosal/wordpress-skills) into .agents/skills/wp-woocommerce-dev in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jorgerosal/wordpress-skills --skill wp-woocommerce-dev -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/wp-woocommerce-dev, .gemini/skills/wp-woocommerce-dev, .github/skills/wp-woocommerce-dev and .opencode/skills/wp-woocommerce-dev in your project.
Going by SKILL.md and its folder, Wp Woocommerce Dev needs the command-line tools its instructions call (rg).
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Wp Woocommerce Dev is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 14k tokens (SKILL.md is roughly 54k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 25k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Wp Woocommerce Dev: WordPress Pro (Jeffallan/claude-skills, 12k stars), WooCommerce Code Review (woocommerce/woocommerce, 11k stars), REST API Contract Review (decebals/claude-code-java, 751 stars) and WooCommerce Code Guard (amElnagdy/guard-skills, 1.3k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
jorgerosal (a GitHub user) maintains it in jorgerosal/wordpress-skills, which has 101 GitHub stars. The repository holds 35 skills in this directory. The repository was last updated on June 7, 2026.
Source: jorgerosal/wordpress-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.