WhatsApp Business

What You'll Learn:

  1. Understand what the WhatsApp Business integration is and how it connects your store to EcartPay.
  2. Learn the recommended flow: connect → configure → receive orders → collect payment.
  3. Use the WhatsApp API endpoints, headers, and request bodies for connection, configuration, templates, and orders.
  4. Customize system message templates and understand Meta approval rules.
  5. 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/whatsapp
  • https://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

StatusDescription
pending_approveOrder received; waiting for your approval
pending_paymentOrder approved; payment message sent
paidPayment completed
rejectedOrder rejected

Message delivery statuses

Each outbound payment or notification message may include:

StatusDescription
sentAccepted by Meta
deliveredDelivered to the customer
readRead by the customer
failedDelivery failed — check delivery_error
deletedMessage deleted

Use delivery_status and delivery_error on WhatsApp orders to troubleshoot delivery issues.

How customers pay

ModeWhenCustomer experience
Checkout linkDefault (use_native_flow: false)Customer opens your EcartPay checkout from the message
Native flowuse_native_flow: true and flow is publishedCustomer pays inside WhatsApp
Wallet setupNative flow enabled, customer has no saved cardCustomer is prompted to save a card first; payment resumes automatically afterward
👍

Ecart Pay API

By connecting WhatsApp Business to EcartPay, you can accept catalog orders, send compliant payment messages, and optionally collect payment inside WhatsApp.


⚠️

IMPORTANT

You need a valid Authorization Token with WhatsApp scopes. See Authorization Token.


Required scopes

ScopeDescription
read_whatsappRead connection status, templates, and orders
write_whatsappConnect 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

MethodPathScopePurpose
POST/embedded-signup/callbackwrite_whatsappConnect after Meta Embedded Signup
GET/statusread_whatsappConnection health and config snapshot
POST/configwrite_whatsappUpdate store settings
POST/phone/registerwrite_whatsappRegister phone with Meta
GET/templatesread_whatsappList message templates
GET/templates/catalogsread_whatsappList template categories and languages
POST/templates/syncwrite_whatsappRefresh templates from Meta
GET/templates/{template_id}read_whatsappGet one template
PUT/templates/{template_id}write_whatsappUpdate editable template text
GET/ordersread_whatsappList WhatsApp orders
GET/orders/{whatsapp_order_id}read_whatsappGet one order
POST/orders/{whatsapp_order_id}/confirmwrite_whatsappConfirm order and send payment
POST/orders/{whatsapp_order_id}/rejectwrite_whatsappReject order
POST/orders/{whatsapp_order_id}/resendwrite_whatsappResend payment message
POST/flows/provisionwrite_whatsappSet up native payment flow
POST/flows/sendwrite_whatsappSend 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/callback
  • POST 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: FINISH or FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING. Optional.

Note: The authenticated account from your JWT is used. Any account_id in the body is ignored.

What happens next

After a successful connection, EcartPay automatically:

  1. Subscribes your account to Meta webhooks.
  2. Registers your phone number when needed.
  3. Syncs your Meta catalog.
  4. Creates your system message templates.
  5. 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/status
  • GET https://sandbox.ecartpay.com/api/whatsapp/status

Response highlights

  • connected, phone_configured, phone_registered, is_catalog_connected
  • templates_provisioning: true while system templates are still being created
  • display_phone_number, verified_name
  • config: 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/config
  • POST 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 (default MXN).
  • auto_confirm_orders: Skip manual approval for catalog orders. Default true. 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 whitelist shown in GET /status is managed by EcartPay and is not set through this endpoint.

⚠️

You cannot enable auto_confirm_orders while orders are in pending_approve.

⚠️ You cannot enable use_native_flow until 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/register
  • POST 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/templates
  • GET 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 (PENDINGAPPROVED).

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).

TemplatePurpose
request_paymentSend an open payment request
order_receivedAcknowledge a catalog order
order_confirmedConfirm order and share pay button
order_rejectedNotify order rejection
payment_receivedPayment success receipt
resend_paymentPayment reminder
product_selectedProduct selection acknowledgment
wallet_onboardingCustomer needs an EcartPay account (native flow)
wallet_add_cardCustomer needs to save a card (native flow)
payment_flowOpens in-chat payment flow

Template behavior

  • APPROVED: EcartPay sends the template message.
  • PENDING or REJECTED: 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/orders
  • GET 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}/confirm
  • POST 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), and docs. There is no page field in the response — pass page and limit as query parameters.



Native payment flow

Let customers review the order and pay inside WhatsApp.

Enable native payments

  1. Connect WhatsApp (POST /embedded-signup/callback).
  2. Provision the flow: POST /flows/provision.
  3. Confirm flow_status is PUBLISHED in GET /status.
  4. Set use_native_flow: true via POST /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/provision
  • POST 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/send
  • POST https://sandbox.ecartpay.com/api/whatsapp/flows/send

Body:

  • customer_id or phoneone is required
  • concept — required when items is omitted (max 200 characters)
  • total_amount — required when items is omitted
  • currency — default MXN
  • items — 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: true
  • X-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

CodeMeaning
384Customer is outside the 24-hour messaging window
385Payment flow template required outside the window
386Wallet template required outside the window
387Message delivery was not confirmed by Meta
388Payment message delivery was not confirmed
389Native payment flow is not enabled or not published
390Template message delivery was not confirmed

Best practices

  • Complete Embedded Signup before calling write endpoints.
  • Use GET /status to verify connection, catalog, templates, and native flow readiness.
  • Resolve all pending_approve orders before enabling auto_confirm_orders.
  • Provision and publish the native flow before setting use_native_flow: true.
  • Wait for templates to reach APPROVED before sending payment messages outside the 24-hour window.
  • Check delivery_status and delivery_error when a customer says they did not receive a message.
  • Keep your notify_url endpoint fast and idempotent if you use webhook forwarding.

Troubleshooting

  • Connection fails after Embedded Signup: The Meta code may have expired, or your token may lack write_whatsapp.
  • Customer did not receive payment message: Check delivery_status and delivery_error on the order. Common causes: template still PENDING, or customer outside the 24-hour window.
  • Cannot enable native payments: Run POST /flows/provision, confirm flow_status is PUBLISHED, then set use_native_flow: true.
  • Customer stuck on save-card message: They must complete wallet setup. Ensure wallet_onboarding and wallet_add_card templates are APPROVED.
  • 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_approve orders first.
  • WhatsApp configuration not found: Complete Embedded Signup successfully before other calls.

Related endpoints

MethodPathScopePurpose
GET/api/reports/whatsapp-ordersread_reportsExport WhatsApp orders report