To send Cashfree or PayU payment notifications on WhatsApp, point the gateway's webhook at an endpoint you control, verify the signature, and have that endpoint fire an approved WhatsApp utility template to the customer's number. In India that costs about ₹0.215 per receipt on RichAutomate pay-as-you-go (Meta's utility rate plus a ₹0.10 platform fee). Replies inside the 24-hour customer service window carry no Meta charge.
This guide is for merchants who already collect money through Cashfree Payments or PayU India and want the WhatsApp side done properly: receipts that arrive in seconds, failed-payment nudges that bring buyers back, payment-link reminders, refund updates and a settlement alert for the owner. It covers the exact webhook events each gateway sends, how each one signs its payloads, what the gateways can already send on their own, and the three ways to route the events into WhatsApp. One point up front: RichAutomate has no built-in Cashfree or PayU connector, so every route below goes through a webhook, an automation tool or a few lines of your own code.
Which payment events deserve a WhatsApp message
Not every gateway event should reach the customer. A good rule: send a message when the customer would otherwise open their banking app to check what happened. Each message is a template, and the category decides the price. Receipts, failed-payment notices, refund updates and payment-link reminders are transactional, so they belong in Utility. A message that adds a discount or a "you might also like" block becomes Marketing and is billed at the higher marketing rate.
| Gateway event | WhatsApp message | Template category | Approx. cost per message (pay-as-you-go) |
|---|---|---|---|
Payment success (Cashfree PAYMENT_SUCCESS_WEBHOOK, PayU Successful) | Receipt: amount, order ID, transaction reference | Utility | ≈ ₹0.215 (Meta utility ≈ ₹0.115 + ₹0.10) |
Payment failed (Cashfree PAYMENT_FAILED_WEBHOOK, PayU Failed) | "Your payment didn't go through" plus a retry link | Utility | ≈ ₹0.215 |
Checkout abandoned (Cashfree PAYMENT_USER_DROPPED_WEBHOOK) | Neutral reminder that the order is still open | Utility, if it carries no offer | ≈ ₹0.215 |
Payment link unpaid near expiry (Cashfree PAYMENT_LINK_EVENT / your own scheduler) | Due-date reminder with the same link | Utility | ≈ ₹0.215 |
Refund processed (Cashfree REFUND_STATUS_WEBHOOK, PayU Refund) | Refund amount, reference, expected credit time | Utility | ≈ ₹0.215 |
| Settlement credited | Alert to the owner's own number | Utility | ≈ ₹0.215 |
| Failed payment + "10% off if you pay today" | Recovery offer | Marketing | Meta marketing rate + ₹0.10 |
Meta's India utility rate of about ₹0.115 is the figure in use at the time of writing. Meta revises its rate card, so check the current number before you budget. Once a customer replies, for example "when will my refund reach?", your answer inside the 24-hour customer service window is a free-form message with no Meta charge. The current plan prices and per-message fees are on the WhatsApp API pricing page.
Cashfree vs PayU webhooks: events, signatures and setup
Both gateways push events to a URL you register. They differ in payload format and in how you prove a request is genuine. Getting the signature check wrong is the most common reason a payment-to-WhatsApp pipeline either rejects real events or accepts forged ones.
| Cashfree Payments | PayU India | |
|---|---|---|
| Payment events | PAYMENT_SUCCESS_WEBHOOK, PAYMENT_FAILED_WEBHOOK, PAYMENT_USER_DROPPED_WEBHOOK (also PAYMENT_CHARGES_WEBHOOK) | Successful, Failed (status values success, failure, pending) |
| Refund events | REFUND_STATUS_WEBHOOK | Refund (plus a Dispute event) |
| Payment links | PAYMENT_LINK_EVENT, with link_status PAID, PARTIALLY_PAID, EXPIRED or CANCELLED | Payment-link events for success, failure and pending; check the payment-links docs for your account |
| Payload format | JSON for order payments; payment-link webhooks arrive as form data | Success and failure as form URL-encoded POST; refund and dispute as JSON |
| Signature | x-webhook-signature header = Base64(HMAC-SHA256(x-webhook-timestamp + raw body, your secret key)) | A hash field; recompute the SHA-512 reverse hash with your salt and compare |
| Customer phone field | data.customer_details.customer_phone | phone |
| Where to configure | Merchant Dashboard → Payment Gateway → Developers → Webhooks | Dashboard → Settings → Webhook → Create Webhook (some dashboard versions show it under Developers). Separate URLs for TEST and LIVE |
| Retries | Retries until it gets a 200. The default policy retries three times at 2, 10 and 30 minutes, and custom policies allow up to 10 | Webhook logs under Dashboard → Developers → Webhook logs |
Cashfree signature detail. Compute the HMAC over the raw request body exactly as received. Cashfree's docs warn that parsing the JSON first can change decimal values such as payment_amount and break the match. The docs label the key as your client secret on some pages and your webhook secret on others, so use the value your dashboard shows for the API version you integrated.
PayU reverse hash. For payment responses PayU documents the reverse hash as sha512(SALT|status||||||udf5|udf4|udf3|udf2|udf1|email|firstname|productinfo|amount|txnid|key), in lowercase hex. Missing UDFs are empty strings, and if the response carries additionalCharges it is prepended before the salt. PayU's hash verification tool lets you test a sample payload, so run one through it before going live. PayU also recommends calling its verify-payment API before you mark an order paid. The general pattern, ack fast and process async, is covered in our WhatsApp webhook signature verification guide.
Do Cashfree and PayU already send WhatsApp messages?
Partly, and only for payment links. Check your own dashboard before you build anything.
- Cashfree documents WhatsApp payment links: the link arrives as an interactive card with a Pay Now button, enabled with
link_notify.send_whatsapp(default false) next tosend_smsandsend_email. Cashfree describes it as a paid feature for selected merchants. By default the card goes out from Cashfree's own WhatsApp Business Account with Cashfree shown as the sender. To send it from your own WABA you share your WABA ID, BSP and expected volume, and the template must be approved as Utility. Cashfree's documented auto-reminders for payment links go over SMS and email. - PayU lists
viaEmail,viaSmsandviaWhatsappdelivery flags on its Create Payment Link API, plus a Share a Payment Link API for sending later. Whether your dashboard shows a WhatsApp button depends on your account, so check it.
What neither gateway covers is the rest of the lifecycle on your own number: branded receipts for checkout payments, failed-payment recovery, refund updates, owner settlement alerts, and a shared inbox where the customer's reply reaches your team. That gap is why merchants route webhooks into a WhatsApp Business API platform.
Three ways to connect Cashfree or PayU to RichAutomate
RichAutomate's built-in integrations are Zoho CRM, Razorpay, Google Sheets, the Meta Cloud API and built-in booking. Razorpay has its own built-in connector, covered in the Razorpay WhatsApp integration guide. Cashfree and PayU events reach RichAutomate through one of these three routes:
| Route | How it works | Best for | Watch out for |
|---|---|---|---|
| Zapier / Make / Pabbly Connect | The gateway webhook triggers a scenario. A step maps the amount, order ID and phone, then calls RichAutomate's send-template endpoint | Teams without a developer, under a few thousand events a month | Per-task pricing on the automation tool. Some tools can't verify HMAC signatures on incoming webhooks, so keep the URL secret and confirm the payment by API |
Your server → POST /api/v1/send-template | Your backend verifies the signature, normalises the phone and calls the API with a Bearer API key | Any volume. Full control over idempotency and retries | You maintain the code. Keep the API key server-side only |
Incoming Webhook flow trigger POST /api/v1/public/flows/{token}/trigger | Starts a RichAutomate chatbot flow. A field-mapping step pulls the phone and amount out of the JSON payload | Multi-step journeys, e.g. a failed payment followed by a reply-driven retry menu | The token in the URL is the credential, and the trigger cannot check Cashfree's or PayU's signature. Put a verifying relay in front, or confirm the payment by API before acting |
For the no-code route, the setup screens are in our Zapier WhatsApp integration guide. The same mapping works in Make and Pabbly Connect.
Send these messages on WhatsApp, from your own number
We get your templates approved on the official WhatsApp API and set up your first broadcast with you. ₹0 platform fee, you pay only Meta's per-message rate.
Code: Cashfree webhook to a WhatsApp receipt (Node.js)
This handler verifies Cashfree's signature against the raw body, acknowledges quickly so Cashfree doesn't retry, normalises the phone to 91XXXXXXXXXX and sends an approved utility template. The API key below is a placeholder.
const express = require('express'), crypto = require('crypto');
const app = express();
const CF_SECRET = process.env.CASHFREE_SECRET; // from the Cashfree dashboard
const RA_KEY = process.env.RA_API_KEY || 'YOUR_RICHAUTOMATE_API_KEY'; // placeholder
const TEMPLATES = { PAYMENT_SUCCESS_WEBHOOK: 'payment_receipt', PAYMENT_FAILED_WEBHOOK: 'payment_failed_retry' };
const toMsisdn = (p) => { // -> 91XXXXXXXXXX or null
const d = String(p || '').replace(/\D/g, '').replace(/^0+/, '');
if (d.length === 10) return '91' + d;
return d.length === 12 && d.startsWith('91') ? d : null;
};
app.post('/hooks/cashfree', express.raw({ type: '*/*' }), async (req, res) => {
const raw = req.body.toString('utf8');
const sig = crypto.createHmac('sha256', CF_SECRET)
.update(req.get('x-webhook-timestamp') + raw).digest('base64');
const got = Buffer.from(req.get('x-webhook-signature') || '');
if (got.length !== Buffer.byteLength(sig) || !crypto.timingSafeEqual(got, Buffer.from(sig))) return res.sendStatus(401);
res.sendStatus(200); // ack first; Cashfree retries non-200
const { type, data } = JSON.parse(raw);
const template = TEMPLATES[type], phone = toMsisdn(data?.customer_details?.customer_phone);
if (!template || !phone) return; // log and skip unknown events / non-Indian numbers
await fetch('https://richautomate.in/api/v1/send-template', {
method: 'POST',
headers: { Authorization: 'Bearer ' + RA_KEY, 'Content-Type': 'application/json',
'Idempotency-Key': type + ':' + data.payment.cf_payment_id }, // retries won't double-send
body: JSON.stringify({ phone, template, language: 'en',
variables: [String(data.order.order_amount), data.order.order_id] }),
});
});
app.listen(3000);
For PayU, the shape is the same with two changes. Parse the form-encoded body (express.urlencoded) instead of raw JSON, and replace the HMAC check with the SHA-512 reverse hash above, compared against the hash field. Map status === 'success' to the receipt template and failure to the retry template, and send nothing for pending until the verify API confirms. At higher volume, push each verified event onto a queue and send from a worker, so a slow API call never delays the 200 the gateway is waiting for.
Template copy that gets approved as Utility
Meta reviews category as well as wording. Templates that mix a receipt with a promotion are often recategorised as Marketing, which raises the cost of every message. Keep each one factual and tied to a transaction the customer started:
- payment_receipt: "Payment received: ₹{{1}} for order {{2}}. Reference {{3}}. Reply to this message if anything looks wrong."
- payment_failed_retry: "Your payment of ₹{{1}} for order {{2}} did not go through. No money was taken, or any amount debited will be reversed by your bank. You can retry here: {{3}}"
- payment_link_due: "Reminder: ₹{{1}} for {{2}} is due on {{3}}. Pay securely here: {{4}}"
- refund_update: "Your refund of ₹{{1}} for order {{2}} has been processed (ref {{3}}). Banks usually credit it within a few working days."
- settlement_alert (to the owner): "Settlement of ₹{{1}} credited for {{2}}. {{3}} transactions included."
Only promise the "No money was taken" wording if it matches your gateway's actual behaviour for that failure type, and adjust the refund timeline to what your gateway states. A receipt that later turns out wrong costs more trust than no receipt.
Worked examples: what it costs a Jaipur brand and a Pune institute
These are illustrative examples with round numbers, not customer data.
A Jaipur block-print D2C brand on Cashfree. It processes 3,000 prepaid orders a month and sees around 600 failed or abandoned checkouts. Receipts: 3,000 × ₹0.215 ≈ ₹645. Failed-payment and drop-off nudges: 600 × ₹0.215 ≈ ₹129. Refund updates for about 90 returns ≈ ₹19. That is roughly ₹793 a month in message costs. With an average order of ₹1,499, the nudges pay for themselves if one or two buyers come back. Treat any recovery rate as an assumption until you measure your own. Brands still taking a lot of cash on delivery can extend the same pipeline to nudge COD buyers toward prepaid.
A Pune coaching institute on PayU payment links. It sends fee links to 800 students each term, with up to three reminders before the due date and a receipt on payment. Worst case: 800 × 4 messages × ₹0.215 ≈ ₹688 a term, and less in practice because paid students drop out of the reminder sequence. Questions from parents ("can I pay in two parts?") answered inside the 24-hour window add no Meta charge. The reminder cadence that avoids annoying people is covered in our guide to WhatsApp payment reminders for overdue invoices.
On top of message costs, RichAutomate plans run Starter ₹499/mo, Pro ₹899/mo, White-label ₹1,199/mo and Custom, with ₹0 setup and a 14-day trial, and pay-as-you-go has no monthly floor. Billing is Client Pay: Meta bills its per-message charge to your card and RichAutomate adds ₹0.10 per message.
Mistakes that break payment notifications
- Sending on the redirect, not the webhook. The success URL fires when the browser returns, and many UPI customers close the tab before it does. Send only from the server-side webhook, after the signature check.
- No idempotency. Both gateways can deliver the same event more than once. Key each send on the payment ID plus the event type, or a retry becomes a second receipt.
- Raw 10-digit numbers. Checkout forms collect "98290 12345", "+91-9829012345" and "09829012345". Normalise all of them to
919829012345and drop anything that isn't a valid Indian mobile instead of guessing. - Messaging without consent. Collect WhatsApp opt-in at checkout ("Get order updates on WhatsApp"). Templates sent to people who never agreed lead to blocks and reports, which lower your quality rating. Nothing guarantees a number won't be restricted, so follow Meta's messaging policy on every send.
- Promotional copy in a utility slot. A coupon inside a failed-payment template can get it reclassified as Marketing. Send offers, if you send them at all, as a separate marketing template to opted-in buyers.
- Ignoring pending. UPI payments sometimes sit in pending. Telling a customer "failed" when the money lands ten minutes later creates a support ticket. Wait for the final status.
Frequently asked questions
Does RichAutomate integrate directly with Cashfree or PayU? No. RichAutomate has no built-in Cashfree or PayU connector. Events reach it through Zapier, Make or Pabbly Connect, through your own server calling POST /api/v1/send-template with an API key, or through an Incoming Webhook flow trigger with a field-mapping step. Razorpay is the payment gateway with a built-in integration.
Are payment receipts on WhatsApp utility or marketing messages? Utility, as long as the template only confirms a transaction the customer started. At about ₹0.115 from Meta plus ₹0.10 platform fee, each receipt costs roughly ₹0.215 on pay-as-you-go. Adding offers makes it Marketing.
How do I verify a Cashfree webhook? Take the x-webhook-timestamp header, prepend it to the raw request body, compute HMAC-SHA256 with your secret key, Base64-encode the result and compare it with x-webhook-signature. Use the raw body, never re-serialised JSON.
How do I verify a PayU payment webhook? Recompute the SHA-512 reverse hash, SALT|status||||||udf5|udf4|udf3|udf2|udf1|email|firstname|productinfo|amount|txnid|key, and compare it with the hash field. Then confirm the transaction with PayU's verify-payment API before marking the order paid.
Can Cashfree or PayU send payment links on WhatsApp by themselves? Cashfree offers WhatsApp payment links as a paid feature for selected merchants, sent from Cashfree's WABA by default or from yours. PayU's payment-links API has a viaWhatsapp flag. Neither covers branded receipts, failed-payment recovery, refund updates and owner alerts on your own number, so check your current dashboard for what your account has enabled.
Ready to wire your gateway to WhatsApp? Start a 14-day RichAutomate trial, create your utility templates, generate an API key and point your first Cashfree or PayU webhook at it.