Shopify can send a WhatsApp message through MsgOrb when an order is fulfilled, paid or cancelled. Setup takes about ten minutes per trigger.
Why this uses Shopify Flow
Shopify's built-in webhooks cannot send custom headers, and MsgOrb authenticates with an x-api-key header. So the connection runs through Shopify Flow, Shopify's own free automation app, whose Send HTTP request action can send headers.
Flow itself is free on every Shopify plan, but the Send HTTP request action is limited to the Grow, Advanced and Plus plans. On Basic or Starter you can still install Flow, but that action will not appear, so use a middleware service such as Zapier or Make to call MsgOrb with the header instead.
Before you start
- 1Open Delivery and create the starter Delivery Notification template with the link on the page, then wait for Meta to approve it. Its blanks are
customer_name,order_id,delivery_statusandtracking_url, which is exactly what the body below sends. - 2Select it in *Template to send*, and fill each box with the matching field name from the body:
{{recipient_phone}},{{customer_name}},{{order_id}},{{delivery_status}}and{{tracking_url}}. Save. - 3Copy your endpoint URL (it already contains your business id) and your API key from the same page.
Using a different template? Name the body's fields after that template's blanks instead, and fill the boxes the same way.
Build the workflow
- 1In your Shopify admin open Flow, then Create workflow.
- 2Click Select a trigger, search
order fulfilled, and choose Order fulfilled. - 3Click the + below the trigger, choose Action, and search
httpfor Send HTTP request. - 4Set HTTP method to
POSTand URL to the endpoint you copied. It must begin withhttps://www.msgorb.com. - 5Add two headers:
x-api-keywith your API key, andContent-Typewithapplication/json. - 6Paste this into Body:
{
"recipient_phone": "{{order.shippingAddress.phone}}",
"customer_name": "{{order.customer.firstName}}",
"order_id": "{{order.name}}",
"delivery_status": "Shipped",
"tracking_url": "{{order.statusPageUrl}}"
}- 1Click Save, then Turn on workflow.
Flow variables use Shopify's own names (order.customer.firstName, order.shippingAddress.phone), not the snake_case names in Shopify's classic webhooks. If a variable is rejected, use Add a variable beside the body field to pick the equivalent from the list.
Choosing each value
recipient_phone. Use whichever phone your checkout actually collects: order.shippingAddress.phone, order.phone or order.customer.phone. It must include the country code, such as +12145550123. MsgOrb never guesses a country, so a local number like (469) 688-4871 is rejected with HTTP 400. If your checkout makes phone optional, orders without one will be rejected too; make the field required in Settings → Checkout if WhatsApp updates matter to you.
tracking_url. Needed because the starter template has a {{tracking_url}} blank. order.statusPageUrl is Shopify's order status page, which always exists and shows the carrier tracking once it is added, so it works even when a fulfillment has no tracking number. To send the carrier link directly instead, loop over the fulfillments in the body:
{% for f in order.fulfillments %}{% for t in f.trackingInfo %}{{t.url}}{% endfor %}{% endfor %}An empty result is rejected as a missing field, so only use the carrier link if every fulfillment carries tracking.
delivery_status. A fixed word like Shipped is fine, since this workflow only runs on fulfillment.
Use the www address
Use https://www.msgorb.com, never https://msgorb.com. The apex domain redirects, and Flow does not resend the request body after a redirect, so the notification silently never arrives and nothing appears in your logs. See A webhook never arrives.
Test before you rely on it
- 1Add
&dry_run=1to the URL and fulfill a test order. Open the Delivery page: the Connection Logs show whether the phone, fields and template all pass, and nothing is sent. - 2Switch to
&test_send=1to send a real message without the template. It only reaches a number that has messaged your business number in the last 24 hours, so message it from your own phone first and use that phone on the test order. - 3Remove the flag. Live notifications go out through the approved template.
A 202 means MsgOrb queued the message. Whether WhatsApp delivered it appears on Delivery and Queue Health.
Order created, paid or cancelled
The starter delivery template talks about a shipment and needs a tracking link, so it is the wrong fit for confirmations and cancellations. Use the Status Update page for those, with its starter Status Update Notification template, whose blanks are subject_name and current_status.
Build a separate workflow for each trigger (Order created, Order paid, Order cancelled). Copy the endpoint from Status Update, so the URL carries type=status-update, select that template and fill its boxes with {{recipient_phone}}, {{subject_name}} and {{current_status}}, then use this body:
{
"recipient_phone": "{{order.shippingAddress.phone}}",
"subject_name": "{{order.customer.firstName}}",
"current_status": "Order {{order.name}} has been confirmed"
}Change current_status to fit the trigger, for example Order {{order.name}} has been cancelled.
If you regenerate the API key
The old key stops working immediately. Every Flow workflow returns *401 Invalid API key* until you paste the new key into its x-api-key header.