Plugin Hooks Reference (wpec_*)
All hooks use the wpec_ prefix. Parameters shown with types.
Lifecycle Hooks
wpec_initialized (action)
Fired after the plugin has fully initialized (Bootstrap complete).
| Parameter | Type | Description |
|---|---|---|
$bootstrap | Bootstrap | The plugin bootstrap instance |
add_action('wpec_initialized', function($bootstrap) {
// Plugin is ready — register custom services, post types, etc.
});
wpec_register_services (action)
Fired during service registration phase. Use to register custom services in the DI container.
| Parameter | Type | Description |
|---|---|---|
$container | Container | The DI container instance |
add_action('wpec_register_services', function($container) {
$container->singleton(MyCustomService::class, function() {
return new MyCustomService();
});
});
wpec_components_loaded (action)
Fired after all plugin components (admin, API controllers, etc.) are loaded.
| Parameter | Type | Description |
|---|---|---|
$bootstrap | Bootstrap | The plugin bootstrap instance |
wpec_activated (action)
Fired when the plugin is activated. Use for setup tasks (create tables, seed data, etc.).
Parameters: None
wpec_deactivated (action)
Fired when the plugin is deactivated. Use for cleanup.
Parameters: None
add_action('wpec_deactivated', function() {
wp_clear_scheduled_hook('my_custom_cron');
});
Product Hooks
Filters
| Hook | Parameters | Returns | Description |
|---|---|---|---|
wpec_product_price | $price, $product | float | Modify product display price |
wpec_product_sale_price | $salePrice, $product | float|null | Modify sale price |
wpec_product_is_purchasable | $isPurchasable, $product, $quantity | bool | Control if product can be bought |
wpec_product_not_purchasable_message | $message, $product | string | Custom "not available" message |
wpec_product_query_args | $args | array | Modify product listing query |
wpec_product_before_save | $data, $product, $isUpdate | array | Modify data before DB write |
// B2B pricing: 20% discount for wholesale customers
add_filter('wpec_product_price', function($price, $product) {
if (current_user_can('wholesale_customer')) {
return $price * 0.80;
}
return $price;
}, 10, 2);
// Force exclude out-of-stock on frontend
add_filter('wpec_product_query_args', function($args) {
if (!is_admin()) {
$args['exclude_out_of_stock'] = true;
}
return $args;
});
Actions
| Hook | Parameters | Description |
|---|---|---|
wpec_before_save_product | $product, $isUpdate | Before product is saved to DB |
wpec_product_saved | $product, $isUpdate | After product is saved |
wpec_before_delete_product | $id | Before product deletion |
wpec_product_deleted | $id | After product is deleted |
add_action('wpec_product_saved', function($product, $isUpdate) {
if ($isUpdate) {
cdn_purge('/products/' . $product->getSlug());
}
}, 10, 2);
API Response Filters
| Hook | Parameters | Returns | Description |
|---|---|---|---|
wpec_api_product_response | $data, $product | array | Transform single product API response |
wpec_api_products_response | $data, $args, $total | array | Transform product list API response |
add_filter('wpec_api_product_response', function($data, $product) {
$data['estimated_delivery'] = calculate_delivery_date($product->getId());
$data['is_bestseller'] = get_post_meta($product->getId(), '_is_bestseller', true);
return $data;
}, 10, 2);
Shop, Search & Category Hooks
Filters
| Hook | Parameters | Returns | Description |
|---|---|---|---|
wpec_product_sort_options | $orderbyMap | array | Add/modify sort dropdown options |
wpec_products_per_page | $perPage | int | Change products per page (default: 20) |
wpec_api_category_response | $data | array | Transform category API response |
wpec_search_results | $results, $query | array | Modify search results before returning |
// Add "popularity" sort option
add_filter('wpec_product_sort_options', function($map) {
$map['popularity'] = 'p.sales_count';
$map['rating'] = 'p.average_rating';
return $map;
});
// Add "did you mean" suggestions
add_filter('wpec_search_results', function($results, $query) {
if (empty($results['products']['items'])) {
$results['suggestions'] = get_search_suggestions($query);
}
return $results;
}, 10, 2);
Cart Hooks
Actions
| Hook | Parameters | Description |
|---|---|---|
wpec_item_added_to_cart | $item, $cart | After item is added to cart |
wpec_cart_item_updated | $item, $cart | After cart item quantity is updated |
wpec_item_removed_from_cart | $item, $cart | After item is removed from cart |
wpec_cart_cleared | $cart | After entire cart is emptied |
add_action('wpec_item_added_to_cart', function($item, $cart) {
analytics_track('add_to_cart', [
'product_id' => $item['product_id'],
'quantity' => $item['quantity'],
'cart_total' => $cart->getTotal(),
]);
}, 10, 2);
Filters
| Hook | Parameters | Returns | Description |
|---|---|---|---|
wpec_cart_item_price | $price, $product, $variant, $quantity | float | Modify item price before adding to cart |
wpec_cart_calculated_totals | $totals, $cart | array | Modify final cart totals (subtotal, tax_total, shipping_total, discount_total, grand_total) |
// Volume discount: 10% off when buying 5+
add_filter('wpec_cart_item_price', function($price, $product, $variant, $quantity) {
if ($quantity >= 5) {
return $price * 0.90;
}
return $price;
}, 10, 4);
// Add handling fee for orders under 30 EUR
add_filter('wpec_cart_calculated_totals', function($totals, $cart) {
if ($totals['subtotal'] < 30) {
$totals['grand_total'] += 2.50;
}
return $totals;
}, 10, 2);
Checkout & Order Hooks
Actions
| Hook | Parameters | Description |
|---|---|---|
wpec_checkout_initialized | $checkout | Checkout process begins (before validation) |
wpec_before_create_order | $order, $checkout | Before order is saved to DB |
wpec_order_created | $order, $checkout | After order is created |
wpec_checkout_completed | $checkout, $order | After checkout fully completes (order + payment initiated) |
wpec_order_saved | $order | Every time an order is saved (create or update) |
wpec_order_before_delete | $order | Before order is deleted |
wpec_order_status_changed | $order, $newStatus, $oldStatus | When order status changes |
wpec_order_payment_status_changed | $orderId, $status | When payment status changes |
wpec_order_fulfillment_status_changed | $orderId, $status | When fulfillment status changes |
add_action('wpec_order_created', function($order, $checkout = null) {
if ($order->getTotal() > 500) {
notify_manager('High-value order: #' . $order->getOrderNumber());
}
}, 10, 2);
add_action('wpec_order_status_changed', function($order, $newStatus, $oldStatus) {
if ($newStatus === 'completed') {
award_loyalty_points($order->getCustomerId(), $order->getTotal());
}
}, 10, 3);
Filters
| Hook | Parameters | Returns | Description |
|---|---|---|---|
wpec_order_number_prefix | $prefix | string | Modify order number prefix (default: 'ORD-') |
wpec_checkout_payment_gateways | $methods | array | Filter available payment gateways |
wpec_checkout_shipping_methods | $methods, $checkout | array | Filter available shipping methods |
wpec_checkout_order_meta | $orderMeta, $checkout | array | Add custom order metadata |
// Custom order number prefix
add_filter('wpec_order_number_prefix', function($prefix) {
return 'MYSHOP-'; // MYSHOP-00001, MYSHOP-00002, etc.
});
// Hide COD for orders over 200 EUR
add_filter('wpec_checkout_payment_gateways', function($methods) {
$cart = wpec_get_cart();
if ($cart && $cart->getGrandTotal() > 200) {
return array_filter($methods, fn($m) => $m['id'] !== 'cod');
}
return $methods;
});
// Add free shipping for orders over 50 EUR
add_filter('wpec_checkout_shipping_methods', function($methods, $checkout) {
if ($checkout->getSubtotal() >= 50) {
array_unshift($methods, [
'id' => 0, 'title' => 'Free Shipping',
'cost' => 0, 'formatted_cost' => '0.00',
]);
}
return $methods;
}, 10, 2);
Payment Hooks
Actions
| Hook | Parameters | Description |
|---|---|---|
wpec_payment_gateways_init | $manager | After all gateways registered — use to add custom gateways |
wpec_payment_processed | $order, $gatewayId, $result | After payment is processed through any gateway |
wpec_payment_completed | $order, $transactionId | Payment successfully completed (callback confirmed) |
wpec_payment_failed | $order | Payment failed |
wpec_refund_processed | $order, $amount, $result | After refund is processed |
wpec_gateway_log | $gatewayId, $message, $level | Payment gateway log messages (info/error/debug) |
add_action('wpec_payment_gateways_init', function($manager) {
$manager->register('my_gateway', new MyCustomGateway());
});
add_action('wpec_payment_completed', function($order, $transactionId) {
auto_generate_invoice($order);
}, 10, 2);
add_action('wpec_gateway_log', function($gatewayId, $message, $level) {
if ($level === 'error') {
error_log("[Payment:{$gatewayId}] {$message}");
}
}, 10, 3);
Shipping Hooks
Filters
| Hook | Parameters | Returns | Description |
|---|---|---|---|
wpec_shipping_cost | $cost, $method, $cartTotal, $cartWeight, $itemCount | float | Modify calculated shipping cost |
wpec_shipping_methods | $methods, $country, $cartTotal, $cartWeight | array | Filter available shipping methods after zone matching |
wpec_tracking_url | $url, $carrier, $trackingNumber | string|null | Modify/add tracking URL for a carrier |
// Add surcharge for remote areas
add_filter('wpec_shipping_cost', function($cost, $method, $cartTotal, $cartWeight, $itemCount) {
$remotePostcodes = ['64100', '65500', '69300'];
if (in_array(get_current_shipping_postcode(), $remotePostcodes)) {
return $cost + 2.00;
}
return $cost;
}, 10, 5);
// Add custom courier tracking
add_filter('wpec_tracking_url', function($url, $carrier, $trackingNumber) {
if ($carrier === 'my_courier') {
return 'https://mycourier.gr/track/' . $trackingNumber;
}
return $url;
}, 10, 3);
Inventory / WMS Hooks
Actions
| Hook | Parameters | Description |
|---|---|---|
wpec_stock_changed | $productId, $variantId, $warehouseId, $movement | After any stock movement (sale, restock, adjustment, transfer) |
wpec_low_stock | $productId, $name, $sku, $totalStock | Product stock falls below low-stock threshold |
add_action('wpec_stock_changed', function($productId, $variantId, $warehouseId, $movement) {
if ($movement['type'] === 'sale') {
sync_marketplace_stock($productId, $variantId);
}
}, 10, 4);
add_action('wpec_low_stock', function($productId, $name, $sku, $totalStock) {
slack_notify("#inventory", "Low stock: {$name} (SKU: {$sku}) — {$totalStock} remaining");
}, 10, 4);
Purchasing Hooks
Actions
| Hook | Parameters | Description |
|---|---|---|
wpec_po_sent | $poId, $po | After a Purchase Order is sent to supplier |
wpec_goods_received | $grnId, $grn, $po | After a Goods Received Note is processed |
add_action('wpec_goods_received', function($grnId, $grn, $po) {
// Update accounting, notify warehouse team
}, 10, 3);
Invoicing Hooks
Actions
| Hook | Parameters | Description |
|---|---|---|
wpec_invoice_issued | $invoiceId, $invoice | After an invoice is created/issued |
add_action('wpec_invoice_issued', function($invoiceId, $invoice) {
// Send invoice PDF to customer, sync to accounting
}, 10, 2);
Marketplace Hooks
Actions
| Hook | Parameters | Description |
|---|---|---|
wpec_marketplace_order_created | $order, $marketplace | New order from marketplace (e.g., Skroutz) |
wpec_marketplace_order_updated | $order, $marketplace, $changes | Marketplace order updated |
wpec_marketplace_order_accepted | $order, $marketplace | Order accepted by merchant |
wpec_marketplace_order_rejected | $order, $marketplace | Order rejected |
wpec_marketplace_order_ready | $order, $marketplace | Order marked ready for pickup/shipping |
add_action('wpec_marketplace_order_created', function($order, $marketplace) {
// Auto-print shipping label, notify warehouse
}, 10, 2);
Email Hooks
Actions
| Hook | Parameters | Description |
|---|---|---|
wpec_before_email_send | $templateType, $recipient, $subject, $data | Just before wp_mail() is called |
wpec_email_sent | $templateType, $recipient, $result | After email is sent |
Filters
| Hook | Parameters | Returns | Description |
|---|---|---|---|
wpec_email_subject | $subject, $templateType, $data | string | Modify email subject line |
wpec_email_content | $content, $templateType, $data | string | Modify email body (before HTML wrapping) |
wpec_email_recipients | $recipient, $templateType, $data | string | Modify email recipients |
wpec_email_html | $html, $templateType, $data | string | Modify complete HTML email (after wrapping) |
wpec_email_headers | $headers, $templateType, $data | array | Modify email headers (From, CC, BCC, etc.) |
wpec_email_template_data | $data | array | Add custom placeholders for all email templates |
// Add store prefix to all email subjects
add_filter('wpec_email_subject', function($subject, $type, $data) {
return '[MyStore] ' . $subject;
}, 10, 3);
// CC warehouse on shipment emails
add_filter('wpec_email_recipients', function($recipient, $type, $data) {
if ($type === 'shipment_created') {
$recipient .= ', warehouse@mystore.gr';
}
return $recipient;
}, 10, 3);
// Add BCC to accounting for invoice emails
add_filter('wpec_email_headers', function($headers, $type, $data) {
if ($type === 'invoice_issued') {
$headers[] = 'Bcc: accounting@mystore.gr';
}
return $headers;
}, 10, 3);
// Add custom placeholders
add_filter('wpec_email_template_data', function($data) {
$data['support_email'] = 'support@mystore.gr';
$data['support_phone'] = '+30 210 1234567';
return $data;
});
Licensing Hooks
Filters
| Hook | Parameters | Returns | Description |
|---|---|---|---|
wpec_license_gate | $result, $featureId, $tier | bool | Override license gate check for a feature |
// Grant access to a specific ERP feature for starter tier
add_filter('wpec_license_gate', function($result, $featureId, $tier) {
if ($featureId === 'erp.custom_reports' && $tier === 'starter') {
return true;
}
return $result;
}, 10, 3);