
WooCommerce Order Notifications: Get Instant Push Alerts on Every Sale
Stop refreshing your WooCommerce dashboard. Set up real-time push notifications for new orders, refunds, failed payments, and low stock — directly to your iPhone or Android.
WooCommerce Order Notifications: Get Instant Push Alerts on Every Sale
There's nothing quite like that dopamine hit when a new order drops. But constantly refreshing your WooCommerce backend — or relying on emails that land in a promotions tab — means you're always one step behind.
This guide shows you how to set up instant push notifications for WooCommerce that hit your phone in under a second after a customer places an order.
The Problem with Default WooCommerce Notifications
WooCommerce sends email notifications out of the box. But email has two fatal flaws for real-time alerting:
- Delivery delay — Gmail, Outlook, and others can hold emails for 30–120 seconds (or longer)
- No interruption — Email doesn't make your phone buzz or wake the screen at 2am when a big order comes in
For operators running lean — solo founders, small teams, restaurant owners, event managers — missing an order by even five minutes can mean a missed fulfillment window or a churned customer.
Push notifications solve both problems.
What We're Building
- Instant push to your phone on new WooCommerce order
- Alert on order refund requested
- Alert on failed payment (card declined)
- Low stock warning when inventory drops below threshold
- All powered by the FlowAlert REST API — no polling, no bloat
Prerequisites
- WooCommerce 7.0+ installed
- FlowAlert account + mobile app installed
- FlowAlert API Key created in your dashboard
The Core Helper
Add this to your theme's functions.php or a custom plugin file:
1<?php
2
3function flowalert_event($event, $title, $body, $priority = 'NORMAL', $data = []) {
4 wp_remote_post('https://api.flowalert.io/v1/events', [
5 'headers' => ['Content-Type' => 'application/json', 'X-Api-Key' => FLOWALERT_API_KEY],
6 'body' => wp_json_encode(compact('event', 'title', 'body', 'priority', 'data')),
7 'timeout' => 5,
8 'blocking' => false, // fire-and-forget — don't slow down the checkout
9 ]);
10}Pro tip: Set
blocking: falseso the notification call never adds latency to the customer's checkout experience.
New Order Notification
1add_action('woocommerce_new_order', function($order_id) {
2 $order = wc_get_order($order_id);
3 $total = $order->get_formatted_order_total();
4 $customer = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name();
5 $items = implode(', ', array_map(fn($i) => $i->get_name(), $order->get_items()));
6
7 flowalert_event(
8 'woo.new_order',
9 "💰 New Order #{$order_id} — {$total}",
10 "{$customer} ordered: {$items}",
11 'HIGH',
12 [
13 'order_id' => $order_id,
14 'total' => $order->get_total(),
15 'customer' => $customer,
16 'email' => $order->get_billing_email(),
17 ]
18 );
19});This fires the moment WooCommerce creates the order record — before payment is confirmed. If you only want to alert on paid orders, use this hook instead:
1add_action('woocommerce_payment_complete', function($order_id) {
2 $order = wc_get_order($order_id);
3 flowalert_event(
4 'woo.order_paid',
5 "✅ Payment Confirmed — Order #{$order_id}",
6 "{$order->get_billing_first_name()} paid {$order->get_formatted_order_total()}",
7 'HIGH'
8 );
9});Refund Request Alert
1add_action('woocommerce_order_refunded', function($order_id, $refund_id) {
2 $order = wc_get_order($order_id);
3 $refund = wc_get_order($refund_id);
4
5 flowalert_event(
6 'woo.order_refunded',
7 "⚠️ Refund Requested — Order #{$order_id}",
8 "{$order->get_billing_first_name()} requested a refund of {$refund->get_formatted_refund_amount()}",
9 'URGENT',
10 ['order_id' => $order_id, 'refund_amount' => $refund->get_refund_amount()]
11 );
12}, 10, 2);Failed Payment Alert
1add_action('woocommerce_order_status_failed', function($order_id) {
2 $order = wc_get_order($order_id);
3
4 flowalert_event(
5 'woo.payment_failed',
6 "❌ Payment Failed — Order #{$order_id}",
7 "{$order->get_billing_email()} — card declined for {$order->get_formatted_order_total()}",
8 'URGENT',
9 ['order_id' => $order_id, 'email' => $order->get_billing_email()]
10 );
11});Low Stock Alert
1add_action('woocommerce_low_stock', function($product) {
2 flowalert_event(
3 'woo.stock_low',
4 "📦 Low Stock: {$product->get_name()}",
5 "Only {$product->get_stock_quantity()} left in stock",
6 'HIGH',
7 ['product_id' => $product->get_id(), 'sku' => $product->get_sku(), 'stock' => $product->get_stock_quantity()]
8 );
9});
10
11add_action('woocommerce_no_stock', function($product) {
12 flowalert_event(
13 'woo.stock_empty',
14 "🚨 Out of Stock: {$product->get_name()}",
15 "{$product->get_name()} (SKU: {$product->get_sku()}) just sold out",
16 'URGENT',
17 ['product_id' => $product->get_id(), 'sku' => $product->get_sku()]
18 );
19});Setting Up Routing in FlowAlert
Once the events start flowing, set up routing rules in the FlowAlert dashboard. The keys below match the ones used in the PHP examples above — change them to match whatever keys you chose in your own code:
woo.new_order→ route to "Operations" group, priority HIGH, no acknowledgement requiredwoo.payment_failed→ route to "Finance" group, priority URGENT, requires acknowledgementwoo.stock_empty→ route to "Warehouse" group, priority URGENT, escalate after 10 minutes if unacknowledged
This way the right person gets paged for the right event — not everyone gets spammed for everything.
Alternatively, use woo.* as a single catch-all routing rule if you want one group to receive all WooCommerce alerts, then add filter conditions to split by event priority or data fields.
Multi-Store Setup
Running several WooCommerce stores? Create one FlowAlert workspace per business and issue separate API keys. Or use a single workspace and prefix your event keys with the store identifier (e.g. store1.new_order instead of woo.new_order), then use routing rules per event key to route each store's events separately.
Summary
WooCommerce push notifications don't require a separate SaaS subscription or a plugin that rewrites your checkout flow. A few lines of PHP, one API key, and you'll never miss another order — or another failed payment.


