Features
Back-in-stock alerts
Letting customers subscribe to a sold-out product and messaging them when it returns.
A shopper lands on a sold-out product, leaves their WhatsApp number, and gets one message when it is available again. Use it when you have demand you cannot currently fill and no way to capture it. The alternative is that the visitor leaves and never comes back.
What has to be true first
- A registered number
- As with every event.
- The back_in_stock template approved
- Meta template name
back_in_stock, category MARKETING. - The back_in_stock event switched on
- Off by default in the event catalog.
- The feature switched on
- WooCommerce:
bis_enabled, default off. Shopify: Back-in-stock alerts on the Features tab, default off. Without both the feature switch and the event switch, sign-ups are refused and nothing is stored. - Shopify only: the App Proxy configured
- The subscribe form posts through Shopify's App Proxy. Without it the form has nowhere to submit.
Subscribing from the product page
There is no shortcode. With bis_enabled on, the form is rendered automatically in the product summary of any product that is currently out of stock, and nowhere else. Nothing needs to be added to a template.
The form has one visible field:
- WhatsApp number, a
telinput, required, placeholder+91 98765 43210. Pre-filled from the logged-in customer's billing phone when there is one. - The submit button's text is the Button label setting, default Notify me on WhatsApp.
- A hidden honeypot field, a nonce, and the product id are submitted alongside.
For a theme that wants to do it in JavaScript there is a REST route instead, POST /wp-json/wac/v1/back-in-stock, taking phone, product_id, an optional variation_id and a nonce. An expired nonce returns This form has expired. Reload the page and try again.
What the shopper sees back, exactly:
Done. We will message you on WhatsApp as soon as this is back.You are already on the list for this product.That does not look like a phone number we can message. Include the country code.Too many requests from this connection. Try again in an hour.Stock alerts are not available for this product.
A submission that trips the honeypot is answered as if it succeeded, deliberately, a bot learns nothing from it.
Setting up the Shopify snippet
Configure the App Proxy
In the Partner Dashboard, under Apps → your app → Configuration → App proxy:
App proxy settings Subpath prefix apps Subpath whatsapp Proxy URL https://<your app's public URL>/proxyThat makes the storefront path
/apps/whatsapp/back-in-stockreach the app.Add the snippet to your theme
Online Store → Themes → Edit code → Snippets → Add a new snippet, namedwhatsapp-back-in-stock, and paste in the snippet shipped with the app.Render it in the product template
Open your product template,
sections/main-product.liquidin Dawn and most Online Store 2.0 themes,sections/product-template.liquidortemplates/product.liquidin older ones, and add one line where you want the form, usually just after the Add to cart button:sections/main-product.liquid {% render 'whatsapp-back-in-stock' %}Adjust the copy if you want to
The strings live at the top of the snippet and can be edited in place:
whatsapp-back-in-stock.liquid assign proxy_path = '/apps/whatsapp/back-in-stock' assign heading = 'Sold out, get a WhatsApp alert' assign intro = 'Leave your number and we will message you once on WhatsApp when this is back.' assign button_label = 'Notify me' assign consent_note = 'By signing up you agree to receive one WhatsApp message about this product. Reply STOP at any time.' assign placeholder = '+91 98765 43210'Turn the feature and the event on
Back-in-stock alerts on the Features tab, and theback_in_stockevent with an approved template on the Notifications tab. Without both, sign-ups are refused and nothing is stored.
The form hides itself unless the selected variant is sold out, and follows variant changes as the shopper switches between them.

No confirmation message is sent
The reason is worth understanding, because it looks like an omission. A confirmation would be a business-initiated message to somebody who has never written to the store, so it needs its own approved template, it costs a marketing conversation, and it is not what the shopper asked for. They asked to be told when the product returns.
The shopper gets an on-page confirmation instead, which is immediate and free. The Shopify API deliberately does not reveal whether the row was new, so a first-time and a repeat sign-up look identical.
Rate limits
WooCommerce
| Field | Required | Type | Description |
|---|---|---|---|
| 5 per hour, per IP address | No | limit | Not per phone and not per product. The address is hashed before it is stored, so a plain IP list never lands in the options table. Over the limit the shopper sees Too many requests from this connection. Try again in an hour. |
Shopify
| Field | Required | Type | Description |
|---|---|---|---|
| 100 per hour, per shop | No | limit | Checked first. Over it, the shopper sees This store has taken too many stock alerts in the last hour. Try again later. |
| 5 per hour, per phone number | No | limit | Per shop and phone. Over it: You can sign up for 5 alerts an hour. Try again later. |
Both Shopify limits are rolling one-hour windows and both return 429 with a Retry-After of one hour. The successful response also reports the per-phone limit, so a theme can show it.
When the alert is sent
Three hooks fire the check, woocommerce_product_set_stock, woocommerce_variation_set_stock and woocommerce_product_set_stock_status. They stay registered even when the feature is switched off, so subscribers collected earlier still get their message.
Up to 500 waiting subscribers are served per restock. A variation coming back also serves people who subscribed on the parent product page.
Six or more subscribers are sent as one batch call; five or fewer go one at a time. Test mode always uses the one-at-a-time path.
The variables
back_in_stock
| Field | Required | Type | Description |
|---|---|---|---|
| productName | Yes | string | Product name. Example: Arnica Montana 30CH |
| productLink | Yes | string | Product page link. Example: https://example.com/product/arnica-30ch |
WooCommerce maps these to {product_name} and {product_url} by default.
What the customer receives
🔔 Good news, *{{1}}* is back in stock!
Grab it here before it sells out again: {{2}}
You're receiving this because you asked to be notified.🔔 Good news, Arnica Montana 30CH is back in stock!
Grab it here before it sells out again: https://example.com/product/arnica-30ch
You're receiving this because you asked to be notified.
Reply STOP to unsubscribe
12:04back_in_stock message, shown with its approved example values.It is a marketing template, so the approved version carries the footer Reply STOP to unsubscribe. The last line exists because a shopper who signed up weeks ago will not necessarily remember doing so.
Deduplication
- One row per product and number
- Enforced by a unique index rather than a lookup first, so a double-tapped button cannot create two rows. A repeat sign-up reopens the existing row instead.
- Dedupe key
- WooCommerce:
back_in_stock:<rowId>:<productId>. Shopify:back_in_stock:<subscriberId>. - Rows are marked, not deleted
- After sending, the subscription becomes “notified” with a timestamp rather than being removed, so you can see who was told what.
- A permanent skip counts as done
- A subscriber refused for consent reasons is marked notified too. A skip is as final as a send, and leaving the row open would retry it on every future stock change.
- A credit failure does not
- In a batch, subscribers missing from the response stay waiting on purpose. The batch endpoint stops at the first credit failure, and marking those rows would silently drop real people.
When it does not fire
- The feature or the event is off. Both default to off, and both are required.
- The
back_in_stocktemplate is not approved. - The number could not be read as an international one. Sign-up is refused at the form, before anything is stored.
- The number is on the opt-out register. WooCommerce refuses the sign-up outright with
Stock alerts are not available for this product.Shopify saysThis number has asked not to receive messages from this store. Reply START on WhatsApp to opt back in. - A rate limit was hit. See above.
- The product is not actually back in stock. The check re-reads stock before sending.
- The subscriber has already been notified. Their row is no longer waiting.
- The nonce expired (WooCommerce) or the proxy signature did not verify (Shopify).
- Credits ran out part-way through a batch. The remaining subscribers stay waiting rather than being marked as told.
Cost
back_in_stock is MARKETING, 8 credits to an Indian number and 18 elsewhere under the shipped default rate card. A restock of a popular product can therefore fan out to a real bill in one go: 500 waiting subscribers is around 4,000 credits.
The fan-out uses the batch endpoint, which stops at the first credit failure and leaves the remaining subscribers waiting. Check the balance before a big restock, see Credits and billing.
