Send quotes & invoices via WhatsApp directly from Odoo. No Meta API · No monthly fees · Works with any WhatsApp account
Send a pre-filled message with quote number, amount, and secure links to sign, refuse, or ask a question.
Send the invoice with the due amount, due date, and a direct payment link from the Odoo customer portal.
Dedicated reminder buttons for quotes (have you seen it?) and invoices (please pay), with interactive response links
Each portal link (refuse, question, seen, pay) uses its own unique UUID token, regenerated on every WhatsApp send. Tokens expire after a configurable number of days.
A daily cron creates a follow-up activity for the salesperson when a quotation has had no response, or when an invoice is overdue. Configurable delays — set 0 to disable.
The "Ask a question" link is limited to a configurable number of uses (default 3). A red "Revoke links" button instantly invalidates all active portal links.
Templates automatically selected based on the customer's language (partner.lang). 8 customisable templates with a length warning above 600 characters.
Every send is logged in the chatter with sender, number, and message. Activities are created and closed automatically
Each salesperson sets their WhatsApp number in their profile. Company fallback number used when none is configured.
WhatsApp Sales Free adds green “Send via WhatsApp” and “Remind via WhatsApp” buttons directly on your Odoo quotations and customer invoices. One click opens WhatsApp with a pre-filled message including secure portal links — no Meta Business API, no webhook, no monthly cost.
The module uses the free wa.me protocol: Odoo builds the message, your salesperson clicks once to open WhatsApp (web or app), and sends it. Everything is traced in the chatter and closed as a done activity.
Hello John Smith,
Please find below your quotation *S00042* for a total amount of *12 500.00 EUR*.
Do not hesitate to contact me for any questions.
Best regards,
Alice Dupont
Acme Corp
——————————–
✅ Sign and confirm
https://your-odoo.com/my/orders/42?access_token=…
❌ Refuse the quotation
https://your-odoo.com/sale/whatsapp/refuse/42?token=…
💬 Ask a question
https://your-odoo.com/sale/whatsapp/question/42?token=…
Hello John Smith,
We are following up on your quotation *S00042* for a total of *12 500.00 EUR*.
Have you had a chance to review it?
Best regards,
Alice Dupont
Acme Corp
━━━━━━━━━━━━━━━━━━━━
👀 Yes, I’ve reviewed it
https://your-odoo.com/sale/whatsapp/seen/42?token=…
✅ I’d like to sign it
https://your-odoo.com/my/orders/42?access_token=…
💬 I have a question
https://your-odoo.com/sale/whatsapp/question/42?token=…
❌ I decline
https://your-odoo.com/sale/whatsapp/refuse/42?token=…
Hello John Smith,
This is a friendly reminder that your invoice *INV/2025/00042* for *12 500.00 EUR* is awaiting payment.
Due date: *31/03/2025*
Thank you for your trust.
Best regards,
Alice Dupont
Acme Corp
━━━━━━━━━━━━━━━━━━━━
💳 Pay online
https://your-odoo.com/my/invoices/42?access_token=…
✅ I have already made the transfer
https://your-odoo.com/invoice/whatsapp/paid/42?token=…
All portal pages are lightweight, public (no login required), and accessible on any device.
| Customer Action | What Happens in Odoo |
|---|---|
| ✅ Signs the quotation | Redirected to Odoo portal signature page |
| ❌ Refuses the quotation | Chatter note + To-do activity for salesperson + all quotation tokens invalidated |
| 💬 Asks a question | HTML form → message saved in chatter + activity (max N uses per link) |
| 👀 Confirms they reviewed it | Chatter note + pending reminder activity closed |
| 💳 Pays online | Redirected to Odoo payment portal |
| ✅ Confirms transfer made | Chatter note + activity “Please verify payment” |
| Feature | Detail |
|---|---|
| Per-action UUID tokens | Each link type (refuse, question, seen, paid) has its own unique UUID token. A leaked link cannot be used for a different action. |
| Token rotation | All tokens are regenerated on every WhatsApp send. Old links are immediately invalidated. |
| Token expiration | Links expire after a configurable number of days (default: 7). Expired links return a friendly error page. |
| Revoke links button | Red button on the quotation / invoice form to instantly invalidate all active portal links. |
| Refusal invalidation | When a customer refuses, all remaining quotation tokens (question, seen) are cleared at once. |
| Question anti-spam | The “Ask a question” link is limited to N uses per send (configurable, default 3). Resets on next send. |
Settings → Users → [Salesperson] → WhatsApp
Enter the number in international format: +33612345678
Settings → Sales → WhatsApp → Company WhatsApp Number
Used when the salesperson has no number configured.
Contacts → [Contact] → “Uses WhatsApp” checkbox
The send button is only active for contacts marked as WhatsApp users.
Settings → Sales → WhatsApp
| Setting | Default | Description |
|---|---|---|
| Token Expiration (days) | 7 | Days before portal links expire. Set to 0 to disable. |
| Max questions per link | 3 | Max uses of the “Ask a question” link per send. Set to 0 for unlimited. |
Settings → Sales → WhatsApp → Automatic follow-up activities
| Setting | Default | Description |
|---|---|---|
| Quotation follow-up after (days) | 0 (off) | Days after WhatsApp send with no response before creating a follow-up activity for the salesperson. |
| Invoice overdue follow-up after (days) | 0 (off) | Days after invoice due date before creating a follow-up activity if still unpaid. |
ℹ️ Activities, not automatic messages. The cron creates an Odoo activity for the salesperson — it does not send WhatsApp messages automatically (which would require the Meta API). The salesperson sees the activity in their inbox and clicks the WhatsApp button themselves.
Settings → Sales → WhatsApp
| Template | Language | Used for |
|---|---|---|
| Quotation Template 🇫🇷 | French clients | Send button on quote |
| Quotation Template 🇬🇧 | Other clients | Send button on quote |
| Quotation Reminder 🇫🇷 | French clients | Remind button on quote |
| Quotation Reminder 🇬🇧 | Other clients | Remind button on quote |
| Invoice Template 🇫🇷 | French clients | Send button on invoice |
| Invoice Template 🇬🇧 | Other clients | Send button on invoice |
| Invoice Reminder 🇫🇷 | French clients | Payment reminder on invoice |
| nvoice Reminder 🇬🇧 | Other clients | Payment reminder on invoice |
| Variable | Description |
|---|---|
{partner_name} |
Customer name |
{order_name} |
Quotation number (e.g. S00042) |
{amount_total} |
Total amount (formatted) |
{invoice_name} |
Invoice number |
{amount_due} |
Remaining amount due |
{currency} |
Currency code (EUR, USD…) |
{due_date} |
Invoice due date (DD/MM/YYYY) |
{salesperson_name} |
Salesperson full name |
{company_name} |
Company name |
{order_url} |
Portal link to sign the quotation |
{refuse_url} |
Link to refuse (creates activity, invalidates all tokens) |
{question_url} |
Link to the question form (limited uses) |
{seen_url} |
Link to confirm quotation reviewed (reminder only) |
{invoice_url} |
Portal link to pay online |
{paid_url} |
Link to confirm payment made (reminder only) |
⚠️ Recommended template length: under 600 characters. Longer messages may be truncated by the browser URL bar or some WhatsApp clients. A warning is displayed in the settings page when a template exceeds this limit.
No. The salesperson clicks the button, Odoo opens WhatsApp with the message pre-filled, and the salesperson clicks Send manually. This is by design — it avoids requiring any Meta approval or paid API. The automatic follow-up feature creates Odoo activities for the salesperson, not automatic WhatsApp sends.
They land on a lightweight Odoo portal page (no login required). Their action (refuse, question, seen, paid confirmation) is immediately logged in the chatter and an activity is created for the salesperson. If the customer refuses, all remaining portal links (question, seen) are immediately invalidated.
Yes. Each action (refuse, question, seen, paid) uses its own unique UUID token, separate from Odoo’s generic access_token. Tokens are regenerated on every WhatsApp send, expire after a configurable number of days (default 7), and are invalidated when the customer refuses. You can also revoke all links manually with the “Revoke WhatsApp links” button on the form.
The module is developed and tested for Odoo 19. It may work on 17/18 with minor adjustments but this is not officially supported.
Yes. All 8 templates (quotation/invoice × send/reminder × FR/EN) are fully customisable in Settings → Sales → WhatsApp. Changes apply immediately, no restart required. A warning is shown if a template exceeds 600 characters.
| Feature | WhatsApp Sales Free | Meta WABA — Odoo native (paid |
|---|---|---|
| Cost | 🆓 Free forever | 💰 Per-message fees + setup |
| Meta account required | ❌ No | ✅ Yes — verified Meta Business account |
| Template approval | ❌ Not required | ✅ Required per template (24–72 h) |
| Works with personal WhatsApp | ✅ Yes (personal or Business app) | ❌ No — WABA only |
| Sending | 1 manual click — salesperson sends from their phone | Fully automatic via Meta API |
| Automatic send (no click) | ❌ No — follow-up creates Odoo activities | ✅ Yes |
| Customer replies in Odoo | Via secure portal links (refuse, question, seen, pay) | Via bidirectional webhook |
| Setup time | 5 minutes | Days / weeks |
Notre équipe d'experts Odoo est à votre service
Support téléphonique pour toutes vos questions techniques