Developers

Guides

Markdown

Order notifications over WhatsApp and SMS

A complete recipe for a messaging app that sends customers order, payment and delivery confirmations and abandoned-cart reminders through the messaging provider the merchant chooses.

How it works

LARM does not send messages on your app's behalf, and needs no special integration with your provider. Your app receives order webhooks and sends the message from the merchant's account with the provider the merchant chooses (WhatsApp Business, a Saudi SMS provider, or another).

You needScope
The order webhook and its contentsorders:read
Customer name and E.164 phone numbercustomers:read
The digital code in the messageorders.digital:read
Abandoned-cart reminderscarts:read

Choose the Messaging & marketing category when you create the app.

1. Subscribe to webhooks

JSON
{
  "endpoint_url": "https://app.example.com/larm/webhooks",
  "event_types": ["order.created", "order.paid", "order.status.updated", "order.digital.delivered", "abandoned_cart.created"],
  "payload_version": 1
}

2. Send the right message

Node.js
app.post('/larm/webhooks', express.raw({ type: 'application/json' }), async (req, res) => {
  const event = verifyLarmWebhook(req.body, req.headers, secrets)   // as in the Webhooks guide
  res.sendStatus(204)                                                 // acknowledge immediately

  const order = event.data
  const phone = order.customer?.phone                                 // +9665… or null
  if (!phone || await alreadySent(event.id)) return

  switch (event.type) {
    case 'order.paid':
      await provider.send(phone, `Thank you ${order.customer.name}, we received payment for order #${order.number}. Track it at ${order.order_url}`)
      break
    case 'order.digital.delivered':
      for (const item of order.digital_items ?? [])
        await provider.send(phone, `${item.name}: ${item.value}`)
      break
    case 'order.status.updated':
      if (order.status === 'completed') await provider.send(phone, `Your order #${order.number} is complete.`)
      break
    case 'abandoned_cart.created':
      await provider.send(phone, `Your cart is waiting: ${order.checkout_url}`)
      break
  }
  await markSent(event.id)
})
  • Acknowledge before sending. A slow response counts as a failure and the webhook is retried.
  • **Store event.id** and ignore duplicates, so the customer never receives a message twice.
  • order.created arrives before payment. For an "order placed" message use order.paid, unless the merchant wants alerts for unpaid orders.

3. Respect the customer

  • Send only messages about the order itself. Marketing messages require the customer's consent under telecom regulations, and the merchant and your app are responsible for them.
  • An abandoned-cart reminder is a single message. Do not send a repeated sequence.
  • On [customers.redact](/guides/app-uninstall), delete the customer's phone number and message history.

Try it

From the Webhook log in the Developer Portal, send a test webhook for any topic to your endpoint, and watch the delivery and response. On a development store, create an order and pay it with the test payment method to see the full sequence.

    ↑↓ moveEnter openEsc close