WhatsApp Business
What You'll Learn:
- Understand what the WhatsApp Business integration is and how it connects your store to EcartPay.
- Learn the recommended flow: connect → configure → receive orders → collect payment.
- Use the WhatsApp API endpoints, headers, and request bodies for connection, configuration, templates, and orders.
- Customize system message templates and understand Meta approval rules.
- Optionally enable in-chat payments with the Native Payment Flow.
What is WhatsApp Business Integration?
The WhatsApp Business integration lets you connect your WhatsApp Business Account (WABA) to EcartPay through Meta Embedded Signup. Once connected, you can:
- Receive catalog orders from customers in WhatsApp.
- Confirm or reject orders from the EcartPay dashboard or via API.
- Send payment links, reminders, and receipts through approved Meta message templates.
- Optionally collect payment inside WhatsApp using the Native Payment Flow.
- Receive copies of WhatsApp events at your own URL through
notify_url.
All API endpoints live under:
https://ecartpay.com/api/whatsapphttps://sandbox.ecartpay.com/api/whatsapp
Why is WhatsApp Important?
Conversational Commerce
Customers browse your Meta catalog and place orders directly in WhatsApp.
Automated Payments
EcartPay creates orders, payment links, and payment notifications from WhatsApp conversations.
Template-Based Messaging
System templates handle order updates and payment messages while following Meta messaging rules.
Native In-Chat Checkout
Optionally let customers review the order and pay without leaving WhatsApp.
Integration flow
You can manage everything from the EcartPay dashboard or automate it with the API. Both paths follow the same lifecycle.
Order statuses
| Status | Description |
|---|---|
pending_approve | Order received; waiting for your approval |
pending_payment | Order approved; payment message sent |
paid | Payment completed |
rejected | Order rejected |
Message delivery statuses
Each outbound payment or notification message may include:
| Status | Description |
|---|---|
sent | Accepted by Meta |
delivered | Delivered to the customer |
read | Read by the customer |
failed | Delivery failed — check delivery_error |
deleted | Message deleted |
Use delivery_status and delivery_error on WhatsApp orders to troubleshoot delivery issues.
How customers pay
| Mode | When | Customer experience |
|---|---|---|
| Checkout link | Default (use_native_flow: false) | Customer opens your EcartPay checkout from the message |
| Native flow | use_native_flow: true and flow is published | Customer pays inside WhatsApp |
| Wallet setup | Native flow enabled, customer has no saved card | Customer is prompted to save a card first; payment resumes automatically afterward |
Ecart Pay APIBy connecting WhatsApp Business to EcartPay, you can accept catalog orders, send compliant payment messages, and optionally collect payment inside WhatsApp.
IMPORTANTYou need a valid Authorization Token with WhatsApp scopes. See Authorization Token.
Required scopes
| Scope | Description |
|---|---|
read_whatsapp | Read connection status, templates, and orders |
write_whatsapp | Connect WhatsApp, update configuration, manage templates, and act on orders |
Include these headers on authenticated requests:
Authorization: {token}Content-Type: application/json(when sending a body)
API reference
| Method | Path | Scope | Purpose |
|---|---|---|---|
POST | /embedded-signup/callback | write_whatsapp | Connect after Meta Embedded Signup |
GET | /status | read_whatsapp | Connection health and config snapshot |
POST | /config | write_whatsapp | Update store settings |
POST | /phone/register | write_whatsapp | Register phone with Meta |
GET | /templates | read_whatsapp | List message templates |
GET | /templates/catalogs | read_whatsapp | List template categories and languages |
POST | /templates/sync | write_whatsapp | Refresh templates from Meta |
GET | /templates/{template_id} | read_whatsapp | Get one template |
PUT | /templates/{template_id} | write_whatsapp | Update editable template text |
GET | /orders | read_whatsapp | List WhatsApp orders |
GET | /orders/{whatsapp_order_id} | read_whatsapp | Get one order |
POST | /orders/{whatsapp_order_id}/confirm | write_whatsapp | Confirm order and send payment |
POST | /orders/{whatsapp_order_id}/reject | write_whatsapp | Reject order |
POST | /orders/{whatsapp_order_id}/resend | write_whatsapp | Resend payment message |
POST | /flows/provision | write_whatsapp | Set up native payment flow |
POST | /flows/send | write_whatsapp | Send a payment request via native flow |
Configuration is returned inside GET /status. There is no separate GET /config.
Connect WhatsApp Business
Call this after Meta Embedded Signup returns an authorization code.
Endpoint
POST https://ecartpay.com/api/whatsapp/embedded-signup/callbackPOST https://sandbox.ecartpay.com/api/whatsapp/embedded-signup/callback
Request body
code: Authorization code from Meta Embedded Signup. Required.waba_id: WhatsApp Business Account ID. Optional.phone_number_id: Connected phone number ID. Optional.business_id: Meta business ID. Optional.flow_finish_type:FINISHorFINISH_WHATSAPP_BUSINESS_APP_ONBOARDING. Optional.
Note: The authenticated account from your JWT is used. Any
account_idin the body is ignored.
What happens next
After a successful connection, EcartPay automatically:
- Subscribes your account to Meta webhooks.
- Registers your phone number when needed.
- Syncs your Meta catalog.
- Creates your system message templates.
- Provisions the native payment flow.
Example
curl --location 'https://sandbox.ecartpay.com/api/whatsapp/embedded-signup/callback' \
--header 'Authorization: {token}' \
--header 'Content-Type: application/json' \
--data '{
"code": "AQBx...",
"waba_id": "123456789012345",
"phone_number_id": "987654321098765",
"business_id": "112233445566778",
"flow_finish_type": "FINISH"
}'{
"_id": "68a4c3150b28a9584305a2a7",
"account_id": "68a4c3150b28a9584305a2a6",
"whatsapp_business_id": "123456789012345",
"phone_number_id": "987654321098765",
"embedded_signup_completed": true,
"verified": true,
"active": true,
"integration_type": "FINISH"
}Get WhatsApp status
Returns connection health and your current configuration.
Endpoint
GET https://ecartpay.com/api/whatsapp/statusGET https://sandbox.ecartpay.com/api/whatsapp/status
Response highlights
connected,phone_configured,phone_registered,is_catalog_connectedtemplates_provisioning:truewhile system templates are still being createddisplay_phone_number,verified_nameconfig: welcome message, auto-confirm, catalog, native flow settings
Example
curl --request GET \
--url https://sandbox.ecartpay.com/api/whatsapp/status \
--header 'Authorization: {token}'{
"connected": true,
"phone_configured": true,
"phone_registered": true,
"is_catalog_connected": true,
"templates_provisioning": false,
"display_phone_number": "+52 1 55 1234 5678",
"verified_name": "My Store",
"config": {
"welcome_message": "Welcome! How can we help you today?",
"auto_confirm_orders": true,
"whitelist": { "phone_numbers": [], "groups": [] },
"catalog_id": "1234567890",
"catalog_name": "My Catalog",
"use_native_flow": false,
"flow_id": "flow_abc123",
"flow_status": "PUBLISHED",
"flow_ready": true
}
}Update configuration
Endpoint
POST https://ecartpay.com/api/whatsapp/configPOST https://sandbox.ecartpay.com/api/whatsapp/config
Request body
business_name: Max 100 characters. Optional.welcome_message: Sent when a new conversation starts. Max 500 characters. Optional.products_message: Intro before a product list. Max 100 characters. Optional.products: Manual product list. Optional.title: Max 24 characters.description: Max 72 characters.price,currency(defaultMXN).
auto_confirm_orders: Skip manual approval for catalog orders. Defaulttrue. Optional.auto_send_product_list: Send your configured product list automatically. Optional.notify_url: Your URL to receive forwarded WhatsApp events. Optional.use_native_flow: Enable in-chat payments. Requires a published flow. Optional.
Unrecognized fields are ignored. The
whitelistshown inGET /statusis managed by EcartPay and is not set through this endpoint.
You cannot enableauto_confirm_orderswhile orders are inpending_approve.⚠️ You cannot enable
use_native_flowuntil the native payment flow is published.
Example
curl --location 'https://sandbox.ecartpay.com/api/whatsapp/config' \
--header 'Authorization: {token}' \
--header 'Content-Type: application/json' \
--data '{
"business_name": "My Store",
"welcome_message": "Welcome! Send us a catalog order or ask for help.",
"auto_confirm_orders": false,
"notify_url": "https://example.com/webhooks/whatsapp",
"use_native_flow": false
}'Register phone number
Registers your connected number with Meta if it is not already registered.
Endpoint
POST https://ecartpay.com/api/whatsapp/phone/registerPOST https://sandbox.ecartpay.com/api/whatsapp/phone/register
curl --request POST \
--url https://sandbox.ecartpay.com/api/whatsapp/phone/register \
--header 'Authorization: {token}'Templates
EcartPay creates system templates for your account after you connect. You can customize the message text; buttons, variables, names, and categories are protected.
You cannot create custom templates through the API — only the system templates below are supported.
List templates
GET https://ecartpay.com/api/whatsapp/templatesGET https://sandbox.ecartpay.com/api/whatsapp/templates
Query parameters: status, category, language, template_type, q, page, limit
Update template text
PUT https://ecartpay.com/api/whatsapp/templates/{template_id}
Body: components — only editable parts may change.
Rules for system templates:
- Keep the same variable placeholders (
{{1}},{{2}}, etc.) in the same order and count. - Do not change buttons, name, or category.
- After editing, Meta reviews the template again (
PENDING→APPROVED).
Sync templates
POST https://ecartpay.com/api/whatsapp/templates/sync
Refreshes template status from Meta.
System templates
Created automatically for your account. Each name includes a unique suffix (for example, ecartpay_order_confirmed_a1b2c3d).
| Template | Purpose |
|---|---|
request_payment | Send an open payment request |
order_received | Acknowledge a catalog order |
order_confirmed | Confirm order and share pay button |
order_rejected | Notify order rejection |
payment_received | Payment success receipt |
resend_payment | Payment reminder |
product_selected | Product selection acknowledgment |
wallet_onboarding | Customer needs an EcartPay account (native flow) |
wallet_add_card | Customer needs to save a card (native flow) |
payment_flow | Opens in-chat payment flow |
Template behavior
APPROVED: EcartPay sends the template message.PENDINGorREJECTED: EcartPay falls back to direct messages when Meta's 24-hour window allows it.
Wait for templates to reach APPROVED before relying on messages outside the 24-hour window.
Example — update template
curl --request PUT \
--url https://sandbox.ecartpay.com/api/whatsapp/templates/6968323a10d2ec0145dd7161 \
--header 'Authorization: {token}' \
--header 'Content-Type: application/json' \
--data '{
"components": [
{
"type": "BODY",
"text": "Thanks for your purchase!\nYour order of {{1}} item(s) is confirmed:\n{{2}}\nTotal: {{3}}"
}
]
}'Orders
WhatsApp orders represent catalog orders or payment requests from WhatsApp. After confirmation, each order links to an EcartPay order. The payment_link field contains the checkout URL sent to the customer.
List orders
GET https://ecartpay.com/api/whatsapp/ordersGET https://sandbox.ecartpay.com/api/whatsapp/orders
Query parameters: status, status_in, currency, order_id, q (customer phone or name), received_at_gte, received_at_lte, page, limit, sort
Get order
GET https://ecartpay.com/api/whatsapp/orders/{whatsapp_order_id}
Returns order details plus customer phone and name.
Confirm order
Confirms a pending_approve order, creates the EcartPay order, and sends the payment message.
POST https://ecartpay.com/api/whatsapp/orders/{whatsapp_order_id}/confirmPOST https://sandbox.ecartpay.com/api/whatsapp/orders/{whatsapp_order_id}/confirm
{
"success": true,
"message_id": "wamid.HBgNNTIx...",
"order_id": "6968323a10d2ec0145dd7162",
"payment_link": "https://checkout.ecartpay.com?id=6968323a10d2ec0145dd7162"
}Reject order
Rejects a pending_approve order and notifies the customer.
POST https://ecartpay.com/api/whatsapp/orders/{whatsapp_order_id}/reject
Body: reason — optional rejection message for the customer.
{
"success": true,
"message_id": "wamid.HBgNNTIx..."
}Resend payment
Resends the payment message for a pending_payment order.
POST https://ecartpay.com/api/whatsapp/orders/{whatsapp_order_id}/resend
Body: message — optional extra reminder text (checkout-link mode only).
{
"success": true,
"message_id": "wamid.HBgNNTIx..."
}Example — list orders
curl --request GET \
--url 'https://sandbox.ecartpay.com/api/whatsapp/orders?status=pending_payment&page=1&limit=10' \
--header 'Authorization: {token}'{
"count": 50,
"pages": 5,
"docs": [
{
"_id": "6968323a10d2ec0145dd715d",
"status": "pending_payment",
"items": [
{
"product_retailer_id": "SKU123",
"name": "Premium Bracelet",
"quantity": 2,
"item_price": 299.99,
"currency": "MXN"
}
],
"total_amount": 599.98,
"currency": "MXN",
"order_id": "6968323a10d2ec0145dd7162",
"order_number": "OR0000045939",
"payment_link": "https://checkout.ecartpay.com?id=6968323a10d2ec0145dd7162",
"customer_phone": "5215512345678",
"customer_name": "Juan Perez",
"delivery_status": "delivered"
}
]
}Note: list responses use
count(total matching orders),pages(total pages), anddocs. There is nopagefield in the response — passpageandlimitas query parameters.
Native payment flow
Let customers review the order and pay inside WhatsApp.
Enable native payments
- Connect WhatsApp (
POST /embedded-signup/callback). - Provision the flow:
POST /flows/provision. - Confirm
flow_statusisPUBLISHEDinGET /status. - Set
use_native_flow: trueviaPOST /config.
Wallet templates (wallet_onboarding, wallet_add_card) must be APPROVED in Meta before customers without a saved card can pay in-chat.
Provision flow
POST https://ecartpay.com/api/whatsapp/flows/provisionPOST https://sandbox.ecartpay.com/api/whatsapp/flows/provision
{
"flow_id": "flow_abc123",
"flow_status": "PUBLISHED",
"flow_ready": true,
"flow_template_name": "ecartpay_payment_flow_a1b2c3d",
"wallet_gate_templates": {
"onboarding": { "name": "ecartpay_wallet_onboarding_a1b2c3d", "status": "APPROVED" },
"add_card": { "name": "ecartpay_wallet_add_card_a1b2c3d", "status": "APPROVED" }
}
}Send payment request
Send a payment directly to a customer without a prior catalog order.
POST https://ecartpay.com/api/whatsapp/flows/sendPOST https://sandbox.ecartpay.com/api/whatsapp/flows/send
Body:
customer_idorphone— one is requiredconcept— required whenitemsis omitted (max 200 characters)total_amount— required whenitemsis omittedcurrency— defaultMXNitems— optional line items (name,quantity,price)order_id— reuse an existing EcartPay order instead of creating one
curl --location 'https://sandbox.ecartpay.com/api/whatsapp/flows/send' \
--header 'Authorization: {token}' \
--header 'Content-Type: application/json' \
--data '{
"phone": "5215512345678",
"concept": "Monthly subscription renewal",
"currency": "MXN",
"total_amount": 499.00
}'{
"success": true,
"flow_token": "6968323a10d2ec0145dd715d",
"whatsapp_order_id": "6968323a10d2ec0145dd715d",
"order_id": "6968323a10d2ec0145dd7162",
"payment_link": "https://checkout.ecartpay.com?id=6968323a10d2ec0145dd7162",
"message_id": "wamid.HBgNNTIx..."
}Wallet setup (native flow)
If a customer has no EcartPay wallet or no saved card, they receive a Save card message before the payment flow. After they complete setup, EcartPay automatically sends the payment request again.
Webhook forwarding
Meta sends WhatsApp events to EcartPay. If you set notify_url in your config, EcartPay forwards the original payload to your endpoint with:
X-Webhook-Forwarded: trueX-Hub-Signature-256: sha256={signature}
Your endpoint should respond with HTTP 200 quickly. EcartPay processes events asynchronously.
You do not need to configure Meta webhooks yourself — EcartPay handles that when you connect.
24-hour messaging window
WhatsApp allows free-form session messages only within 24 hours of the customer's last inbound message.
Outside that window, EcartPay sends an approved Meta template instead (payment, wallet, or order templates). If the required template is not approved, the request fails.
Error codes
| Code | Meaning |
|---|---|
| 384 | Customer is outside the 24-hour messaging window |
| 385 | Payment flow template required outside the window |
| 386 | Wallet template required outside the window |
| 387 | Message delivery was not confirmed by Meta |
| 388 | Payment message delivery was not confirmed |
| 389 | Native payment flow is not enabled or not published |
| 390 | Template message delivery was not confirmed |
Best practices
- Complete Embedded Signup before calling write endpoints.
- Use
GET /statusto verify connection, catalog, templates, and native flow readiness. - Resolve all
pending_approveorders before enablingauto_confirm_orders. - Provision and publish the native flow before setting
use_native_flow: true. - Wait for templates to reach
APPROVEDbefore sending payment messages outside the 24-hour window. - Check
delivery_statusanddelivery_errorwhen a customer says they did not receive a message. - Keep your
notify_urlendpoint fast and idempotent if you use webhook forwarding.
Troubleshooting
- Connection fails after Embedded Signup: The Meta
codemay have expired, or your token may lackwrite_whatsapp. - Customer did not receive payment message: Check
delivery_statusanddelivery_erroron the order. Common causes: template stillPENDING, or customer outside the 24-hour window. - Cannot enable native payments: Run
POST /flows/provision, confirmflow_statusisPUBLISHED, then setuse_native_flow: true. - Customer stuck on save-card message: They must complete wallet setup. Ensure
wallet_onboardingandwallet_add_cardtemplates areAPPROVED. - Template stuck in
PENDING: Meta review usually takes 24–48 hours. Messaging may use fallbacks during review. - Cannot enable auto-confirm: Confirm or reject all
pending_approveorders first. - WhatsApp configuration not found: Complete Embedded Signup successfully before other calls.
Related endpoints
| Method | Path | Scope | Purpose |
|---|---|---|---|
GET | /api/reports/whatsapp-orders | read_reports | Export WhatsApp orders report |