Skip to content

WhatsApp order confirmation (v1) ​

Send each new order to Otpera. The customer gets a WhatsApp message with the order details and a one-tap choice: Confirm, Postpone delivery or Cancel. Otpera records the answer and notifies your system by webhook. Use it to cut failed cash-on-delivery (COD) deliveries and returns.

Using Shopify? You don't need code. See Shopify.

Flow ​

text
1. Store / backend ── POST /orders ───────────────▶ Otpera
2. Otpera          ── WhatsApp order summary + poll ▶ Customer
3. Customer        ── taps Confirm / Postpone / Cancel
4. Otpera          ── order.status_changed webhook ─▶ Your server
EndpointScopePurpose
POST /ordersorders:writeCreate an order and send confirmation
GET /orders/{id}orders:readOrder with items, history and messages
POST /orders/{id}/confirmation/resendorders:writeRe-send the WhatsApp confirmation

Create an order ​

POST /orders

Body ​

FieldTypeRequiredNotes
externalIdstring ≤ 120yesYour order number. Unique per source.
sourceenumnoapi (default), shopify, easyorder, vondera, woocommerce, custom
customer.phonestringyesE.164 (+201012345678) or Egyptian local 01XXXXXXXXX
customer.namestringno
customer.emailstringno
currencyISO 4217yese.g. EGP
items[]1–200 itemsyes{ name, quantity, unitPrice, variant?, sku? }
shippinginteger (minor units)noDefault 0
discountinteger (minor units)noDefault 0
totalinteger (minor units)noOptional cross-check; must equal items + shipping − discount, otherwise 422
paymentMethodstring ≤ 40noe.g. cod
shippingAddressobjectno{ line1, line2, city, region, postalCode, country } (country is 2 letters)
sourceStatusstring ≤ 60noYour store's own status, informational

Money is in minor units

unitPrice: 45000 with currency: "EGP" means EGP 450.00 (piastres).

Example ​

bash
curl -X POST https://api.otpera.com/api/v1/orders \
  -H "Authorization: Bearer $OTPERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042" \
  -d '{
    "externalId": "1042",
    "customer": { "phone": "+201012345678", "name": "Mona Adel" },
    "currency": "EGP",
    "items": [
      { "name": "Desk lamp", "quantity": 1, "unitPrice": 45000 },
      { "name": "Ceramic mug", "quantity": 2, "unitPrice": 12000 }
    ],
    "shipping": 5000,
    "paymentMethod": "cod",
    "shippingAddress": { "line1": "12 Tahrir St", "city": "Cairo", "country": "EG" }
  }'

Response 201 Created ​

json
{
  "data": {
    "id": "3c9e…",
    "external_id": "1042",
    "source": "api",
    "confirmation_status": "pending",
    "total_minor": 74000,
    "currency": "EGP",
    "created_at": "2026-11-05T10:00:00.000Z",
    "duplicate": false
  }
}

The response header Otpera-Confirmation tells you what happened to the WhatsApp message: sent, disabled, no_number, send_failed or error.

Sending the same (source, externalId) again returns 200 with duplicate: true and no second message.

Confirmation statuses ​

StatusMeaning
pendingWaiting for the customer
confirmedCustomer confirmed
cancelledCustomer cancelled
needs_reviewCustomer asked to postpone, or the reply was unclear: a team member decides
expiredNo answer within the window you set

Customers answer with a tappable WhatsApp poll, or by typing 1 (confirm), 2 (postpone) or 3 (cancel). Reading the message never counts as confirmation.

Resend the confirmation ​

POST /orders/{id}/confirmation/resend re-sends the WhatsApp message for the same order (no duplicate order).

  • Only while pending or needs_review; 409 once answered.
  • Max 5 per order per hour.
json
{ "data": { "sent": true, "messageId": "…" } }

Get the answer ​

Subscribe to order.status_changed in Dashboard → Webhooks:

json
{
  "id": "evt_…",
  "type": "order.status_changed",
  "created_at": "2026-11-05T10:04:12.000Z",
  "workspace_id": "…",
  "data": {
    "order": { "id": "3c9e…", "external_id": "1042", "source": "api" },
    "from": "pending",
    "to": "confirmed",
    "actor_type": "customer",
    "reason": "whatsapp_choice"
  }
}

See Webhooks for signatures and retries. You can also poll GET /orders/{id}.

otpera.com · WhatsApp order confirmation & OTP