Triggers
Every workflow starts with a trigger: the site event that makes the workflow run. You pick the trigger when you create the workflow, under Joinotify → Add new workflow, and it decides which placeholders and which conditions are available in the rest of the workflow.
A trigger only shows up when its integration is enabled under Joinotify → Settings → Integrations. Some have options of their own, which appear when you click the trigger node on the canvas — for example, limiting the workflow to one order status or to a single digital product.
The identifier in parentheses is the WordPress hook behind the trigger. It is what shows up in
the payload's hook and what extensions use; the parameters each one carries are in
Developer resources.
WooCommerce
Orders
| Trigger | When it fires |
|---|---|
New order (woocommerce_new_order) | An order is created, with any status |
Payment confirmed (woocommerce_payment_complete) | Once per order, when the gateway confirms the payment or the order moves from an unpaid status to "Processing" or "Completed" |
Order completed (woocommerce_order_status_completed) | The status changes to "Completed" |
Order status changed (woocommerce_order_status_changed) | Any status change — or only the one to the status chosen in the trigger options |
Order fully refunded (woocommerce_order_fully_refunded) | The whole order is refunded |
Order partially refunded (woocommerce_order_partially_refunded) | Part of the order is refunded |
"New order (Processing)" became "Payment confirmed" in 2.7.0
The old trigger ran every time the order entered "Processing" — including when someone moved it back to that status by hand — and did not run for orders that went straight to "Completed", such as those for virtual products. The new one runs once per order, at the moment the payment is confirmed. Saved workflows, imported files and templates move to the new trigger on their own during the update; nothing has to be rebuilt.
Digital products
| Trigger | When it fires |
|---|---|
Digital product access granted (woocommerce_grant_product_download_permissions) | WooCommerce grants the download to the customer |
Digital file downloaded (woocommerce_download_product) | The customer actually downloads a file from the order |
Both can be limited to a single digital product in the trigger options.
Delivering digital products
To deliver the files over WhatsApp, use Digital product access granted. The download links only exist from that moment on — on earlier triggers the download placeholders come back empty. To send one file per message, combine it with the Loop action.
Customers
| Trigger | When it fires |
|---|---|
Customer account created (woocommerce_created_customer) | WooCommerce creates a customer account |
The account can be created on the My account page, at the checkout (classic or block) or
on the order confirmation page, and the trigger can be limited to one of those places. It runs
at the end of the request, because the checkout only saves the billing phone after WooCommerce
reports that the account exists — so {{ wc_customer_phone }} is already filled in.
The User role and User metadata conditions are available on this trigger. The WordPress New user registration trigger still runs for these same accounts; use one or the other so you do not send two welcome messages.
Stock
| Trigger | When it fires |
|---|---|
Product low in stock (woocommerce_low_stock) | A sale brings the product to the low stock threshold set in WooCommerce |
Product out of stock (woocommerce_no_stock) | A sale takes the product's stock to zero |
Product back in stock (woocommerce_product_back_in_stock) | A product that was out of stock or on backorder is back in stock — once per return |
Back in stock notice sent (woocommerce_customer_stock_notification) | Once for each customer WooCommerce notifies that the product is back |
The first two fire at the same moment WooCommerce sends its stock e-mails, and are meant to alert the team. Product back in stock runs only once when a variation and its variable product come back together.
Back in stock notice sent is the one that talks to the customer: it follows WooCommerce's own back in stock notifications, whether their e-mail is on or off. A customer who signed up without being logged in is matched to the account registered with the same e-mail, when there is one.
The order placeholders do not exist on these triggers
Account creation and stock have no order. Since 2.7.0 the order placeholders are not even offered on them — use the customer and product ones, described in Placeholders.
WooCommerce Subscriptions
| Trigger | When it fires |
|---|---|
New subscription created (woocommerce_checkout_subscription_created) | A subscription is created at checkout |
Subscription is activated (woocommerce_subscription_status_active) | The subscription becomes "Active" |
Renewal payment received (woocommerce_subscription_payment_complete) | A renewal is paid |
Renewal payment failed (woocommerce_subscription_payment_failed) | A renewal fails |
Subscription renewal expired (woocommerce_subscription_status_expired) | The subscription comes to an end |
Subscription canceled (woocommerce_subscription_status_cancelled) | The subscription is cancelled |
WordPress
| Trigger | When it fires |
|---|---|
New user registration (user_register) | A user registers |
User login (wp_login) | A user logs in |
Password reset request (retrieve_password) | The user asks for the reset link |
User password recovery (password_reset) | The user completes the reset |
Post status changed (transition_post_status) | A post changes status |
Forms
| Trigger | Integration |
|---|---|
Form is sent (elementor_pro/forms/new_record) | Elementor |
Form is sent (wpforms_process_complete) | WPForms |
Payment processed by PayPal (wpforms_paypal_standard_process_complete) | WPForms |
The form fields come through the {{ field_id=[FIELD_ID] }} placeholder — see
Placeholders.
Flexify Checkout
| Trigger | When it fires |
|---|---|
| Lead capture via modal | The visitor leaves their contact in the capture modal |
| Lead capture via checkout | The visitor leaves their contact at checkout |
| Cart abandoned | The cart is considered abandoned |
| Abandoned cart is recovered | The customer comes back and completes the purchase |
| Order abandoned | An order is considered abandoned |
| Lost cart | The cart is considered lost |
The hooks live under Flexify_Checkout/Recovery_Carts/*, and the timing of each stage is set in
Flexify Checkout itself.
A trigger that is not listed here
Any plugin can register a trigger of its own, with its integration and placeholders, with PHP alone — see Developer resources.