Stack: WhatsApp Business Cloud API, Claude with function calling, Paystack Payment Links API. Tools: get_product_catalog(), create_payment_link(product_id, customer_name, customer_email). Flow: 1) WhatsApp webhook delivers customer message to your server. 2) Message + conversation history sent to Claude with tools. 3) Claude identifies product intent, calls get_product_catalog to confirm price. 4) Claude asks customer to confirm before creating link. 5) Claude calls create_payment_link — tool POSTs to Paystack /paymentrequest. 6) Link sent back via WhatsApp API. 7) charge.success webhook fires when customer pays — fulfill and notify.
// WhatsApp Business Cloud API webhook handler
app.post('/whatsapp/webhook', async (req, res) => {
res.sendStatus(200); // acknowledge immediately
var message = req.body.entry?.[0]?.changes?.[0]?.value?.messages?.[0];
if (!message || message.type !== 'text') return;
var from = message.from; // customer WhatsApp number
var text = message.text.body;
// Load conversation history from DB (keyed by phone number)
var history = await db.whatsappSessions.get(from) || [];
history.push({ role: 'user', content: text });
var response = await runSalesAgent(history, from);
// Send reply via WhatsApp Cloud API
await sendWhatsAppMessage(from, response.reply);
// Save updated history
history.push({ role: 'assistant', content: response.reply });
await db.whatsappSessions.set(from, history);
});
var salesTools = [
{
name: 'get_product_catalog',
description: 'Get the list of available products with prices.',
input_schema: { type: 'object', properties: {} },
},
{
name: 'create_payment_link',
description: 'Create a Paystack payment link for a confirmed order.',
input_schema: {
type: 'object',
properties: {
product_id: { type: 'string' },
customer_name: { type: 'string' },
customer_email: { type: 'string' },
},
required: ['product_id', 'customer_name', 'customer_email'],
},
},
];
async function runSalesAgent(history, customerPhone) {
var response = await anthropic.messages.create({
model: 'claude-opus-4-6',
max_tokens: 512,
tools: salesTools,
messages: history,
system: 'You are a sales agent for McTaba. Help customers find the right product and guide them to payment. Always confirm the order before creating a payment link. Collect customer name and email before creating a link.',
});
for (var block of response.content) {
if (block.type === 'tool_use') {
if (block.name === 'get_product_catalog') {
var catalog = await db.products.getAll(); // your product DB
// Feed result back and continue
return runSalesAgent([
...history,
{ role: 'assistant', content: response.content },
{ role: 'user', content: [{ type: 'tool_result', tool_use_id: block.id, content: JSON.stringify(catalog) }] },
], customerPhone);
}
if (block.name === 'create_payment_link') {
var product = await db.products.getById(block.input.product_id);
var linkRes = await fetch('https://api.paystack.co/paymentrequest', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
description: product.name,
amount: product.amount_kobo,
currency: 'NGN',
customer: { email: block.input.customer_email, first_name: block.input.customer_name },
}),
});
var link = (await linkRes.json()).data;
return { reply: 'Here is your payment link for ' + product.name + ': https://paystack.com/pay/' + link.offline_reference + '
It expires in 24 hours. Reply DONE once you have paid.' };
}
}
}
return { reply: response.content.find(b => b.type === 'text')?.text };
}
See agentic safety rails if you extend this agent to handle payouts or refunds.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course