WhatsApp order notifications from your app: a working example

Send order confirmations and shipping updates over WhatsApp from Node or Next.js with a REST API — test keys, templates, idempotent retries and signed delivery webhooks.

October 14, 2026 · 4 min read

Order updates are the most useful thing a shop can send on WhatsApp: short, expected and read within minutes. Wiring them into your own app takes four pieces — an approved template, an API key, one POST per event and a webhook for what happens next. This guide walks through each with code you can adapt.

SendFromChat is an independent product and is not affiliated with Meta or WhatsApp. It runs on Meta's official WhatsApp Cloud API; you keep your own WhatsApp Business account.

The short version

  1. Get an order-update template approved (usually minutes, sometimes up to 24 hours).
  2. Build with a test key, which runs every check and sends nothing.
  3. Send one POST /messages per order event, with an Idempotency-Key so a retry never double-sends.
  4. Listen for signed webhooks for delivery status and customer replies.

1. A template for the message

Messages you start outside a 24-hour conversation window must use a template Meta has approved (how the window works). An order update is a Utility template, for example:

Hi {{1}}, your order {{2}} has shipped. Track it here: {{3}}

Create it on the dashboard, or ask your assistant to draft and submit it. It's checked against Meta's formatting rules before submission, so common rejection reasons are caught before Meta sees it (the rules, explained). Meta also offers a library of ready-made order and delivery templates that don't need the usual review.

Only message customers who agreed to WhatsApp updates (how to collect opt-in).

2. A key you can't hurt yourself with

On the dashboard's Developers page, create a test key (sfc_test_…). It checks the plan, opt-outs, the template and the 24-hour window, then stops: nothing is sent, saved or counted. Build with it, then swap in a live key (sfc_live_…) for production.

Keep keys on your server. If you build with Claude Code, you can ask it to "add WhatsApp order notifications to my app"; it can store the key in your environment settings without the key appearing in the chat (connect your assistant).

3. Send on each order event

// lib/whatsapp.js — runs on your server only
export async function notifyShipped(order) {
  const res = await fetch("https://sendfromchat.com/api/v1/messages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SENDFROMCHAT_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": `order-${order.id}-shipped`,
    },
    body: JSON.stringify({
      to: order.customerPhone, // international format, e.g. +491512345678
      template: {
        name: "order_shipped",
        language: "en_US",
        variables: [order.customerName, `#${order.number}`, order.trackingUrl],
      },
    }),
  });
  const body = await res.json();
  if (!res.ok) throw new Error(`${body.error?.type}: ${body.error?.message}`);
  return body; // { id: "wamid…", status: "accepted", … }
}

Two details matter here:

  • The idempotency key comes from the event, not from the attempt. order-4821-shipped stays the same on every retry, so a network blip or a job re-run returns the first response instead of sending a second message.
  • Handle the errors by type. opted_out, window_closed and template_not_approved are WhatsApp's rules, not bugs; log them and move on. warmup_limit means a new number hit today's cap, so retry later. The full list is in the REST API reference.

4. Know what happened next

POST /messages returns 202 accepted, which means Meta took it, not that the customer read it. For the rest, add a webhook endpoint on the Developers page and subscribe to message.status (sent, delivered, read, failed with a reason) and message.received (the customer replied).

Each request carries a SendFromChat-Signature header: an HMAC-SHA256 of the timestamp and the raw body. Verify it before you trust the payload, and skip event id values you've already handled, because deliveries can repeat. The REST API reference has the verification function and the event payloads.

What about replies?

When a customer answers, a 24-hour window opens and you can reply with free-form text, with no template. Replies, auto-replies and chatbot messages are free and unlimited on every plan; only messages you start count toward the monthly allowance (plans and limits). If you'd rather not code the replies, a chatbot flow can handle the common questions and hand over to a person.

Costs, in plain terms

Two separate things: SendFromChat's flat monthly plan (from $19), and Meta's per-message charge, which Meta bills to your own WhatsApp Business account at its published rates, with no markup from us. Rates depend on the message category and the recipient's country; see WhatsApp API pricing and Meta's current rate card.

A note for EU and UK customers

SendFromChat stores data in Mumbai, India. Transfers from the EU and UK are covered by the Standard Contractual Clauses and the UK Addendum in our Data Processing Agreement, and the sub-processors are listed publicly. Read it before you decide; our GDPR guide covers consent, opt-out and records on your side.

Try it

Start the 30-day free trial (no card), connect a number, and send yourself a test message with the key from the Developers page. Weighing other routes? See SendFromChat vs Twilio and using Meta's Cloud API directly.

Do this from your AI assistant

SendFromChat connects Claude, ChatGPT, Cursor or any MCP client to the WhatsApp Business API — templates, bulk sends, inbox, chatbots and sequences, just by asking. 30 days free, no card.

Start free