Payments
Ask for a payment
/paymentsScope payments:sendSends WhatsApp's own payment request, Review and pay. The customer pays without leaving WhatsApp, with Google Pay, PhonePe or any UPI app, and the money goes to your own payment gateway.
If the customer wrote to you in the last 24 hours, the request goes as a message and needs no template. Otherwise WhatsApp only allows a template, so name one in templateName: a Utility template with a Review and pay button, created in the dashboard. Pass templateName every time and it is used only when needed. See The 24-hour window.
First, switch on Payments within WhatsApp for the number in the dashboard (Settings, Integrations, Payments). Follow the payment with Get a payment.
Body
tostringrequiredThe customer's phone number with country code, for example
+919876543210.amountnumberrequiredRupees, from 1 to 500000, up to 2 decimals.
descriptionstringrequiredWhat is being paid for, shown on the payment screen. Up to 60 characters.
messagestringThe text above Review and pay, when it goes as a message. Defaults to the description.
fromstringWhich of your WhatsApp numbers to send from. Defaults to the number the customer last wrote to, then your default number.
templateNamestringA template with a Review and pay button, used when the customer has not written to you in the last 24 hours.
languagestringThe template's language. Defaults to the template's own.
variablesobjectThe template's variables, as for Send a template message.
headerMediaUrlstringA public https link to the file, when the template has an image, video or document header.
Good to know
sentAssays how it went:messageortemplate.- A request can be paid for 30 minutes as a message, and for 3 days as a template. After that
statusbecomesexpired. - Keep the
id: Get a payment reads it back. A payment is confirmed with WhatsApp's own record before it shows aspaid. - To hear the moment it is paid, subscribe a webhook to payment.paid (and
payment.expired). Each call is logged and retried until your system answers, with the sameid, so you need not poll.
Errors
| Status | Code | When |
|---|---|---|
| 400 | WINDOW_CLOSED | The customer has not written in the last 24 hours and no templateName was given. |
| 400 | NOT_A_PAYMENT_TEMPLATE | templateName names a template without a Review and pay button. |
| 400 | PAYMENTS_NOT_ENABLED | Payments within WhatsApp are not switched on for the number. |
| 400 | BILLING_ADDRESS_INCOMPLETE | Your billing address is incomplete. WhatsApp needs it on every payment request. |
Plus the errors any endpoint can return, such as a missing key or scope. See Errors.
# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.
curl -X POST "https://api.wamafy.com/api/v1/public/payments" \
-H "Authorization: Bearer $WAMAFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+919876543210",
"amount": 499,
"description": "Order 1042",
"message": "Your order is packed and ready to go."
}'{
"success": true,
"data": {
"id": "5d7f9b1c-3e5a-4c7e-9a1b-3c5e7a9b1d24",
"referenceId": "wp-mv5jrp6d-aba359af",
"status": "created",
"amount": 499,
"currency": "INR",
"to": "919876543210",
"paymentId": null,
"paidAt": null,
"expiresAt": "2026-10-13T10:30:00.000Z",
"refundedAmount": 0,
"refunds": [],
"createdAt": "2026-10-13T10:00:00.000Z",
"sentAs": "message",
"messageId": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQzU"
}
}Base URL https://api.wamafy.com/api/v1/public
More examples
Outside the 24-hour window
The customer has not written in the last 24 hours, so the request goes as your Review and pay template, with its variables.
# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.
curl -X POST "https://api.wamafy.com/api/v1/public/payments" \
-H "Authorization: Bearer $WAMAFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+919812345678",
"amount": 1200,
"description": "Gold plan renewal",
"templateName": "payment_due",
"variables": {
"1": "Priya"
}
}'