Updated on October 25, 2026
For creators who sell online courses and other digital products, the official WhatsApp Business API connects the payment platform to the buyer’s WhatsApp: when a sale is approved, the platform’s webhook (often called a postback) reaches your system, which immediately sends a utility template with the access link. The same flow reminds buyers about payments they started but didn’t finish, and support happens inside the 24-hour window that opens when the student replies. Everything runs on the creator’s official number, with no personal phone or unofficial tool involved.
This guide covers the full flow, the template for each step, sample code to receive the webhook and the Meta rules that separate utility from marketing in this kind of operation. Examples come from Brazil, where this business model (known locally as infoprodutos) is large and payments often go through PIX or boleto.
The three moments where WhatsApp matters
| Moment | Trigger | Message | Likely category |
|---|---|---|---|
| Access granted | Webhook for an approved purchase | Members area link and login | Utility |
| Pending payment | Webhook for a generated PIX or boleto | Reminder with the payment link | Utility, if there’s no persuasion |
| Support | Message from the student | Free-form replies, human or automated | Service, inside the window |
An abandoned cart (the person left checkout without generating a payment) is a different case. Meta states explicitly that cart reminders are marketing, even if the user requested them. See recovering PIX, boleto and abandoned carts.
Prerequisites
- A number registered on the official API and approved templates.
- A payment platform that sends webhook notifications for purchase events. Check your platform’s documentation for the events it sends and how to validate where requests come from.
- The buyer’s phone number collected at checkout, with a clear notice that they’ll receive messages about their purchase on WhatsApp.
- A service that receives the webhook and calls the WhatsApp API. It can be your own code or a tool like n8n.
Want to try it while you read? Create a Vectalk account and send your first message through the official API. Create free account →
The templates
Access granted
{
"name": "access_granted",
"language": "en_US",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}. Your payment for {{2}} was approved and your access is ready. Log in with the email {{3}} using the button below.",
"example": { "body_text": [["Paula", "Example Course", "paula@email.com"]] }
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Open members area",
"url": "https://members.example.com/login/{{1}}",
"example": ["https://members.example.com/login/a1b2c3"]
}
]
}
]
}
It’s a confirmation of a purchase the customer made, with no offer. Don’t add “check out our other course too” here: Meta says order messages can’t promote products, upsell or cross-sell, and a template mixing utility and marketing content is classified as marketing. See how Meta classifies templates.
Pending payment (PIX or boleto)
In Brazil, many purchases are paid by PIX (the Central Bank’s instant payment system, with a QR code or a copy-and-paste code) or boleto (a bank payment slip with a due date, paid at a bank or in an app, which doesn’t clear instantly). When the platform generates the payment and it isn’t completed, a reminder often helps.
{
"name": "payment_pending",
"language": "en_US",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}. Your order for {{2}} is waiting for payment by {{3}}, due on {{4}}. If you've already paid, please ignore this notice.",
"example": { "body_text": [["Paula", "Example Course", "boleto", "10/28/2026"]] }
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "View payment",
"url": "https://pay.example.com/{{1}}",
"example": ["https://pay.example.com/order123"]
}
]
}
]
}
Meta’s own utility examples include payment reminders. What turns it into marketing is persuasion: “last spots”, “the price is going up”, “grab it now”, a bonus for paying today. If you want that tone, create a marketing template and send it only to people with a marketing opt-in.
Code: from webhook to template
A Node.js service that receives the webhook, checks its origin, translates the platform’s event into one of your own and sends the right template. Event and field names vary between platforms, so the code uses a translation layer.
import express from 'express';
const app = express();
app.use(express.json());
// Map your platform's events to internal events.
// The names on the left are examples; use the ones in your platform's docs.
const EVENTS = {
'purchase.approved': 'approved',
'pix.generated': 'pending',
'boleto.generated': 'pending',
'purchase.refunded': 'refunded',
};
app.post('/postback', async (req, res) => {
if (req.get('x-platform-token') !== process.env.PLATFORM_TOKEN) {
return res.sendStatus(401);
}
res.sendStatus(200);
const p = req.body;
const event = EVENTS[p.event];
if (!event) return;
const order = await saveOrder(p); // idempotent: ignore repeats
if (order.alreadyProcessed(event)) return;
if (event === 'approved') {
const token = await grantAccess(order);
await sendTemplate(order.phone, 'access_granted',
[order.firstName, order.product, order.email], token);
}
if (event === 'pending') {
await schedule(order.id, '2h', async () => {
if ((await findOrder(order.id)).status !== 'pending') return;
await sendTemplate(order.phone, 'payment_pending',
[order.firstName, order.product, order.method, order.dueDate], order.paymentId);
});
}
if (event === 'refunded') await revokeAccess(order);
});
async function sendTemplate(to, name, body, urlSuffix) {
return fetch('https://apis.vectalk.com.br/api/messages', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VECTALK_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
messaging_product: 'whatsapp',
to,
type: 'template',
template: {
name,
language: { code: 'en_US' },
components: [
{ type: 'body', parameters: body.map((text) => ({ type: 'text', text })) },
{ type: 'button', sub_type: 'url', index: '0', parameters: [{ type: 'text', text: urlSuffix }] },
],
},
}),
});
}
Three details that save headaches:
- Idempotency. Platforms resend webhooks when they don’t get a quick response. Store the order ID and event, and never send the same template twice.
- Wait before the reminder. A generated PIX may be paid a few minutes later. Waiting and checking the status again avoids chasing someone who already paid.
- Origin validation. Use the token or signature your platform provides. The header in the example is illustrative.
Support inside the 24-hour window
When the student replies to any message, the 24-hour customer service window opens, and you can answer with free text, audio, video, PDFs and buttons with no new template. Common course questions (I didn’t get the email, I forgot my password, where’s the lesson, I want my certificate) fit well in a button menu or an automated assistant with a handoff to a human. The WhatsApp Business policy requires clear paths to a human agent when you use automation.
For automated welcome and away messages, see welcome and away messages on the API.
Launches, live classes and announcements
A live class reminder for someone who signed up, an event reminder and a “cart is open” announcement are different cases. Reminding a registrant of the class time they signed up for may be utility; announcing that sales are open is marketing. See event notices: utility or marketing. For campaigns, use a marketing opt-in and stay within the portfolio’s messaging limit.
Opt-in and privacy law
The WhatsApp Business policy requires that the person gave you their number and permission to receive messages from your business, and that requests to stop are honored. At checkout, a line like “I’ll receive messages about my purchase and access on WhatsApp” covers transactional messages. For offers, ask for a separate opt-in. In Brazil, the LGPD (General Data Protection Law, Law 13,709/2018) also applies to the buyer’s phone and email; check the legal basis and retention period with your lawyer. This article is not legal advice. See how to build an opt-in list.
How to do it with Vectalk
With Vectalk, you create templates with POST /templates, send them with POST /messages (type: "template", with a dynamic URL button) and receive student replies on the webhook registered with POST /webhooks, in Meta’s format. Vectalk runs on the official Cloud API and pays Meta for you, so you don’t need a card on file with Meta. See the template documentation and create your account.
Frequently asked questions
Can I send access as free-form text instead of a template?
Only if the buyer messaged you on WhatsApp in the last 24 hours. For most purchases they haven’t, so access has to go out as a template.
Is a boleto reminder utility or marketing?
A neutral payment reminder for an order the customer created tends to be utility. Add artificial urgency, a bonus or a discount and it becomes marketing. Meta has the final say.
What about abandoned carts?
Meta classifies cart reminders as marketing. Use a marketing template and send it only to people who opted in.
The platform sent the same webhook twice. Will the student get access twice?
Only if your system doesn’t handle repeats. Store the order ID and event, and skip anything already processed.
Do I need a separate number for each product?
It’s not required. The brand’s official number can handle access and support. If you run several brands, separate numbers help with organization and display names.
Official sources checked on October 25, 2026: Template category guidelines, Utility templates, Pricing, Messaging limits, WhatsApp Business Messaging Policy, Law 13,709/2018 (LGPD), Vectalk API documentation.
Put your business on the official WhatsApp
Create your account, connect your number to the official API (you can keep the app with coexistence) and start serving customers and sending messages.
