
WhatsApp Payments API (Brazil): Order Details, Order Status, and Why WhatsApp Never Reconciles a Single Rupee or Real
WhatsApp now lets a business send an itemized order bubble straight inside the chat and collect payment without the buyer ever leaving the app — but the API is region-locked, field-strict, and deliberately blind to whether the money actually arrived.
The WhatsApp Payments API (Brazil) feature turns a normal chat thread into a checkout flow. A business sends an order_details interactive message with a header image, an itemized list, and a “Review and Pay” button. The buyer pays inside WhatsApp using Pix, a payment link, Boleto, or one-click card checkout. The business then sends an order_status message back into the same thread to update the order bubble to processing, then paid. It looks like a native checkout — but the payment rail underneath is entirely separate from WhatsApp, and that separation is where most integrations get into trouble.
Region lock: this is not a global WhatsApp feature. The Payments API documented here is Brazil-specific — currency must be BRL, the amount offset must be 100, and payment_type must be br. A separate India variant exists with its own mechanics (UPI, dynamic VPA, different payment gateways). The two are not interchangeable, and a business outside these markets does not have access to either.
WhatsApp Payments API: what the order_details message actually contains
Header
Optional image. If left out, the API defaults to the first product’s catalog image — a silent fallback that can put the wrong photo on an order bubble if a business assumes the header is required.
Body
Required text, capped at 1024 characters, supports emoji and light markdown.
Footer
Optional, capped at 60 characters.
Action
Required. Must carry the fixed name review_and_pay plus a parameters object — reference_id, currency, total_amount, and an optional itemized order object.
reference_id is the one field that quietly breaks integrations
Every order_details message needs a reference_id: letters, numbers, underscores, dashes, and dots only, capped at 60 characters, and it must be unique per message for that business. Resend a message for the same order without changing it and the two messages collide. Meta’s own guidance is to append a sequence number on any resend — a detail that is easy to skip on a first build and hard to notice until an order silently shows the wrong status because two messages are pointing at the same ID.
The math has to balance exactly
| Field | Rule |
|---|---|
| subtotal.value | Must exactly equal the sum of each item’s amount (or sale_amount) times quantity |
| total_amount.value | Must exactly equal subtotal plus tax plus shipping minus discount |
| offset | Must be 100 for BRL — a fixed-point, cents-style encoding that trips up first-time integrations |
| expiration.timestamp | Must be at least 300 seconds in the future |
| order.status at creation | Can only be pending — every other status is set later via a separate order_status message |
A mismatched subtotal or total is the kind of error that looks like a rounding bug in testing and becomes a rejected order in production.
order_status: pushing updates back into the same thread
Once the buyer pays, the business sends an order_status message to update the same order bubble — order.status moves through pending, processing, partially_shipped, shipped, completed, or canceled, and payment.status separately tracks pending, captured, or failed. Canceling an order that already has a successful or pending payment against it fails outright — the API returns a dedicated cancellation-failure error rather than silently allowing it.
The Order Details Template: the same object, wrapped in Meta’s review process
There is also a template version — order_details_template — built as a normal WhatsApp message template with a fixed ORDER_DETAILS button type. It goes through the standard template category, review, and approval flow (UTILITY or MARKETING), and the header can carry a PDF invoice via a document attachment. The underlying order fields and character limits are identical to the direct interactive message; the tradeoff is template-review turnaround in exchange for a reusable, pre-approved order format.
WhatsApp Payments API integrations require an application-level reconciliation layer because the payment rail, order state, and chat message each have their own lifecycle.
Before launch, map every WhatsApp Payments API order to an internal reference, preserve currency precision, and record each status transition. This prevents a successful checkout from looking like a failed chat update.
What WhatsApp will never do for you
Meta’s own documentation states it plainly: WhatsApp does not support payment reconciliation. The business is responsible for reconciling each payment with its own payment service provider using the reference_id from the order. WhatsApp only carries the message thread and the order_status updates — the actual money movement, settlement, and reconciliation logic live entirely outside WhatsApp, in whatever PSP integration the business builds.
Where implementations commonly stall
Assuming the Payments API is global
It is scoped to specific markets. Building against the Brazil fields for an India rollout, or vice versa, does not work — the currency, offset, and payment_type constraints are market-specific.
Getting the offset and rounding wrong
The fixed-point cents-style encoding and the exact subtotal/total match requirement reject orders that look correct at a glance.
Reusing a reference_id on resend
No sequence suffix on a resent order_details message means two messages collide on the same ID.
Building reconciliation as an afterthought
Since WhatsApp never confirms payment on its own, a business needs its PSP webhook and reference_id matching logic in place before launch, not after the first disputed order.
This sits alongside WhatsApp’s other interactive message types and the wider WhatsApp Business API / Cloud API setup support service, connects to WhatsApp interactive messages (reply buttons, lists, CTA URLs), and to the underlying WhatsApp Embedded Signup and Tech Provider onboarding flow that most Payments-enabled numbers are provisioned through.
For current region and payload requirements, consult the official WhatsApp Payments API documentation before requesting access or shipping a production flow.
For Brazil, a WhatsApp Payments API deployment should validate the order_details payload before sending it and store the reference_id exactly as received.
A production WhatsApp Payments API service should treat order_status as an event to reconcile, not as proof that the external payment provider has settled funds.
When a WhatsApp Payments API response is delayed, keep the order open, retry safely, and reconcile by idempotent reference rather than creating a duplicate charge.
Need Us to Get Your Meta App 100% Approved?
Stop losing weeks to repeated rejections. With 500+ apps approved, we handle your entire submission from start to finish. You get 100% Approval or a 100% Refund — and for your complete safety, you can hire us directly through Upwork or Fiverr Escrow (or use the WhatsApp / Calendar buttons in the header & footer).
Chat on WhatsApp