Payments are on the Growth and Pro plans. On a smaller plan you cannot send a payment request or change your payment setup. Test mode is never limited. See Plans and limits.
WhatsApp payments are for Indian businesses charging in INR. Brazil and Mexico have their own Meta flows that LazyApp does not offer yet. See other countries.
Three ways to collect
payment_gateway is the smoothest for the contact. LazyApp reads the result from WhatsApp, and you can look it up or refund it here. The other two are useful when you already use Cashfree or Razorpay, or have no WhatsApp payment setup yet.
Before you start
- Accept WhatsApp’s payment terms. Meta asks the business to accept them in WhatsApp Manager the first time. Until then, payment calls fail with a plain message and a link to the terms.
- Add a payment setup (for
payment_gatewayor a UPI ID). In the console, open Payments → Set up payments. You can also callPOST /v1/payments/configurations. - Or add your gateway keys (for
upi_intent_linkandpayment_link). Open Payments → Set up payments → Gateway accounts, or callPOST /v1/payments/gateway-accounts.
Payment setups
A payment setup links a WhatsApp account to a payment gateway or a UPI ID. Meta calls it a payment configuration.payments:write
A gateway setup comes back with
status: needs_connecting and a link_url. Open it, sign in to the gateway and approve. Meta then sends LazyApp an update and the setup turns active. If the link expires, call POST /v1/payments/configurations/{id}/link for a fresh one.
Gateway accounts
payments:write
Set
is_sandbox: true for gateway test keys. The response includes a webhook_url and a key_hint (the last four characters), never the keys. Add the webhook_url in your gateway’s dashboard. That is how LazyApp hears that a UPI or link payment went through. LazyApp checks each gateway webhook’s signature before using it.
GET /v1/payments/gateway-accounts lists them, and DELETE /v1/payments/gateway-accounts/{id} removes one (204).
Ask for payment
messages:send
Amounts are in paise (49900 is ₹499). LazyApp works out the subtotal, tax, shipping, discount and total the way Meta checks them, so the request is never refused for a rounding mismatch.
The response is the payment (
201):
Outside the 24-hour window
Inside the customer service window you can send the request as is. Outside it, use an approved template:- Order details template (default): a template with a Review and pay button. Pass
"template": { "name": "order_payment_v1", "language": "en" }. - Link button (Enhanced Payment Links): a template whose URL button ends in a variable, for example
https://rzp.io/{{1}}. Pass"template": { "name": "pay_link_v1", "style": "link_button" }withpayment.method: payment_link. LazyApp fills the button with the end of your payment link, and refuses links that do not start with the button’s address. Meta turns Enhanced Payment Links on for each business.
POST /v1/payments/templates, or under Payments → Set up payments → Templates:
Scope:
templates:write. The template goes to Meta for review like any other, and shows in your Templates list straight away as pending.
After the request
LazyApp updates the payment as soon as WhatsApp or your gateway reports it:
A late “pending” never undoes a payment that already arrived.
Order status
status is processing, partially_shipped, shipped, completed or canceled. WhatsApp only allows forward moves. For example, a completed order cannot go back to shipped, and a paid order cannot be canceled. LazyApp refuses those before sending, and rolls back if WhatsApp refuses one anyway. Outside the 24-hour window, pass an order_status template as template.
When a UPI intent payment through your gateway succeeds, LazyApp moves the order to processing for you. That is the update WhatsApp needs to show the order as paid.
Webhooks
The payload is the payment object above. See webhook events.
Errors
Payment errors come back as one plain sentence inmessage. When WhatsApp sent a code, code is provider_<code> and retryable says whether trying again can help.
Retryable failures answer
502. Others answer 422.