# From WhatsApp Message to Courier Booking: The Pipeline Behind Order Automation

Shopkeepers take orders as free-text WhatsApp messages. Here is how an AI pipeline turns them into validated courier bookings: extract, validate, confirm, book, then track.

Published 2026-10-28. 2 min read. Category: Automation. By Mutahar Aslam, Founder & CEO of Paraline Tech.

## Key takeaways

- Treat the model as an extractor that must return a fixed structure, never as the thing that books parcels.
- Validate everything the model returns before it touches a courier API.
- When the message is unclear, ask a person; do not guess an address.
- Make the booking call safe to retry so a network error never creates two parcels.

For many small online shops, the order arrives as a WhatsApp message: a name, a phone number, an address half in English and half not, and an amount to collect. Someone then retypes it into a courier's booking form. It is slow, and one mistyped digit sends a parcel to the wrong place.

We built an order-to-shipment pipeline that takes the message as it is and produces a validated courier booking, with tracking and labels afterwards. It is multi-tenant: each merchant connects their own courier API keys, and we integrate with Leopards and GoEx. This is the design, step by step.

## The principle: the model reads, code decides

An AI model is very good at reading messy text. It is a poor choice for the part that has consequences. So the pipeline is split:

- **The model** extracts fields from the message.
- **Ordinary code** validates them, asks for confirmation when needed, and books the parcel.

That one split makes the system debuggable. When something goes wrong you can see whether the model misread the message or the code mishandled a valid order.

## Step 1: extract into a fixed structure

Ask the model for a specific structure, not prose, and check that what comes back actually matches it.

```ts
import { z } from "zod";

const Order = z.object({
  customerName: z.string().min(1),
  phone: z.string().min(1),
  address: z.string().min(1),
  city: z.string().min(1),
  codAmount: z.number().nonnegative(),
  items: z.string().optional(),
});

// The model's output is data from outside your system. Parse it, never trust it.
const parsed = Order.safeParse(modelOutput);
if (!parsed.success) return needsHuman(message, parsed.error);
```

If parsing fails, do not retry forever and do not guess. Mark the message as needing a person.

## Step 2: validate against the real world

A well-formed order can still be wrong. Check things the model cannot know: that the phone number has a valid format for the country, that the city is one the courier serves, that the amount is plausible for this merchant. Reject or flag anything that fails, with a reason a human can read.

## Step 3: confirm when unsure

If the address is vague or a field was inferred rather than stated, ask the merchant to confirm before booking. A short confirmation costs seconds. A wrongly delivered parcel costs a customer.

## Step 4: book safely

Booking calls the courier's API with the merchant's own key. Network calls fail, so the booking must be safe to repeat: record that this order has been booked before calling, and check that record on every retry, so a timeout never creates two parcels.

## Step 5: tracking and labels

After booking, store the tracking number, fetch the shipping label, and keep the order status in step with the courier's, so the merchant sees one place instead of several courier dashboards.

## Keeping merchants separate

Because each merchant brings their own courier credentials, treat those keys as secrets: store them encrypted, never log them, and make sure one merchant's data can never appear in another's session. Multi-tenancy is a security feature as much as a convenience.

## When this approach fits

It pays off when a business takes orders in a chat app, books with one or two couriers, and does enough volume that retyping hurts. If you take a handful of orders a week, a form is simpler.

If you would like this built around your couriers and your ordering habits, [talk to Paraline Tech](https://paralinetech.com/contact). The project is summarised in the [Order-to-Shipment AI case study](https://paralinetech.com/work/whatsapp-courier-automation).

## Common questions

### Can an AI read an order message reliably?

It is good at pulling a name, phone number, address and amount out of messy text, but not perfect. That is why the output is validated and uncertain cases are sent to a person.

### Why not let the model call the courier directly?

Because a wrong guess becomes a real parcel. Keeping the booking in ordinary code, after validation, makes failures visible and reversible.

### Does each merchant need their own courier account?

In our system, yes: merchants bring their own courier API keys (Leopards and GoEx are supported), and each merchant's data is kept separate.

Canonical page: https://blog.paralinetech.com/whatsapp-order-messages-to-courier-bookings
