Duesly
Collect recurring payments on WhatsApp — customers on a cycle, automatic reminders, payment links that settle themselves, and a chase that stops after two follow-ups.
Duesly is for a business with customers who pay it on a cycle and who currently chases them by hand. Veloria Home uses it for customers who pay their annual maintenance contract in monthly or quarterly instalments.
You add each customer once: name, WhatsApp number, amount and how often. Duesly raises each payment when the cycle comes around, reminds the customer on WhatsApp, follows up if it isn't paid, and stops asking after two follow-ups.
It's an app inside Campaigns, so it needs the Growth or Enterprise plan, and every message it sends obeys your sending rules. Setting it up and every action in it are for admins; members can read it.
Setting it up #
- 1
Install it
Open Campaigns and press Set up Duesly on the Recurring collections card. You need a connected WhatsApp number; reminders go from the workspace's default number.
- 2
Choose how customers pay
On the Settings tab, under 1. How customers pay: your own UPI or QR, or a connected Razorpay account. This decides more than convenience; see How you get paid.
- 3
Choose what customers receive
Under 2. What customers receive, pick an approved reminder template and map its placeholders. See Choosing the messages.
- 4
Save
Save and finish setup. It's enabled once both status chips at the top read Ready and Template selected.
- 5
Add your customers
On the Customers tab, Add customer, one at a time.
The four tabs #
| Tab | What it's for |
|---|---|
| Today | What needs attention: the collection snapshot, overdue payments, and what's coming up. |
| Payments | Every payment: overdue, open, upcoming and paid, with how hard each has been chased. |
| Customers | Who pays you, how much, on what cycle, what they've paid, and what's outstanding. |
| Settings | How customers pay, and what the reminders say. |
The header shows Duesly's state: Collecting, Setup needed or Paused, with Pause reminders (or Resume) beside it.
Today #
- Collection snapshot: Outstanding (still expected), Overdue (need a decision), Due this week, and Collected this month. The line above it gives the number of active customers and their monthly value.
- Needs your attention lists overdue payments with Record paid, and Send follow-up (or Send reminder) while the chase allows another message.
- Coming up lists the next payments and what will happen next.
- The card at the bottom shows the collection mode, with Change collection settings.
Adding a customer #
Customers → Add customer:
| Field | Notes |
|---|---|
| Name | Required. Appears in the reminder. |
| WhatsApp number | Required. With a country code, or written as a local number in your workspace's country. |
| Email (optional) | Used on the payment receipt, if you send one. |
| What they pay for | Free text, such as Comprehensive AMC — split AC. Appears in the reminder. |
| Amount (₹) | Required, in rupees. |
| How often | Every week, month, 3 months, 6 months or year, or Custom, which asks Every how many days? |
| Day of the month | For monthly and longer cycles. Left empty, it follows the start date. See Billing cycles. |
| First payment due | Leave empty to start today. |
| Notes (optional) | Only your team sees these. |
Every customer you add also becomes a contact, so their conversations sit in one place. If that link fails, the customer is still saved and reminders still go out; the row says Not linked to a contact — retry.
The customer list has All, Active, Paused and Cancelled views and a search. Each row has:
- the edit button;
- Pause (No new payments will be raised for them) or Activate;
- remove, which cancels their open payments and stops the reminders. Everything they already paid is kept.
There's no bulk import, in the console or the API. To add many customers from code, create them one at a time with the Duesly API.
Changing an amount
A new amount applies to payments raised from now on. Payments are raised two cycles ahead, so the next one or two are usually raised already, and they keep the amount your customer was actually asked for.
Billing cycles #
Calendar cycles are calendar-correct. A customer billed on the 31st is billed on 28 February, not the 3rd of March; rolling into the next month would slide every later cycle forward.
Set Day of the month if you want the preferred day to come back after a short month: with it set to 31, March is billed on the 31st again. Left empty, each payment follows the previous one, so after February the customer stays on the 28th.
Payments are raised two cycles ahead, so you can see each customer's next payment date.
How you get paid #
This is the decision everything else follows from. Choose under Settings → 1. How customers pay.
Option A: your own UPI or QR #
| Field | What it does |
|---|---|
| UPI ID | Looks like name@bank. Goes into the reminder. |
| Payable to | The name your customer sees in their UPI app. |
| QR code image URL | A link to your QR image, from your website or storage. The reminder attaches it. |
| Anything to add to the reminder? | A line such as please share the UPI reference once you have paid. |
Your customer pays you directly; nothing passes through Amomic-AI. There is no automatic follow-up in this mode. Instead, Payments lists every unpaid payment with a one-tap Paid and a Follow up you send when you know the money hasn't arrived.
Why manual mode has no auto follow-up #
This is deliberate. A UPI transfer into your bank leaves no signal Duesly can read, so it can't know a payment happened. An automatic follow-up in this mode would routinely chase people who have already paid, and being chased for money you've already sent is one of the fastest ways to lose a customer's trust.
Automatic follow-ups exist only where a gateway can say whether the money arrived. Follow up automatically is switched off and can't be turned on in UPI mode.
Option B: connect Razorpay #
Each reminder carries a hosted Razorpay payment link. When it's paid:
- the payment closes itself;
- the remaining follow-ups are cancelled;
- a receipt goes out, if you turned receipts on;
- the link is cancelled so nobody can pay twice.
Because the gateway reports payments, the follow-ups can run on their own.
What we can and cannot see
We never see a card number. Your customer pays on Razorpay's own page. Your API keys are stored encrypted and never shown again, including to you.
Connecting Razorpay #
Choose Connect Razorpay, then enter:
| Field | Where it comes from |
|---|---|
| Key ID | Razorpay dashboard → Account & Settings → API Keys |
| Key secret | Shown once when you generate the key pair. Stored encrypted. |
| Webhook secret | You choose it: at least 16 characters. Use the same value when you add Duesly's webhook in Razorpay (below). |
The keys are checked with Razorpay before they're saved, so a typo fails straight away. Once connected, the panel reads Connected as your key id, with Disconnect.
Razorpay webhook #
One step happens in Razorpay's dashboard, and it's the step people miss.
- 1
Copy the URL
Under One more step in your Razorpay dashboard, copy the webhook URL. It's specific to your workspace.
- 2
Add it in Razorpay
In the Razorpay dashboard, Settings → Webhooks, add the URL and subscribe it to
payment_link.paid. - 3
Use the same secret
Enter the webhook secret you chose in Duesly.
Without it, a paid link doesn't close its payment: the money arrives and Duesly keeps chasing. Until the secret is set, the connection shows Webhook not set up.
Disconnecting
Disconnect forgets the API key and switches new payments to manual UPI, which you collect and mark paid yourself. No new payment links are created. It also turns Follow up automatically off; turn it back on if you reconnect.
Links already sent stay payable, and their payments are still recorded automatically: Duesly keeps the webhook secret they were sent under and keeps checking Razorpay's notifications against it. Leave the webhook in your Razorpay dashboard until those links have expired. If no webhook secret was set when you disconnected, there is nothing to check against: record those payments with Paid.
Choosing the messages #
Under Settings → 2. What customers receive:
| Setting | What it does |
|---|---|
| Reminder | Required. The approved template sent when a payment is due. |
| Follow-up | Optional. Left empty, the reminder template is reused. |
| Payment received | Optional thank-you once a payment is recorded. |
| Send the reminder this many days early | 0 to 14. 0 sends it on the due date. |
| Define template variables | Tells Duesly what fills each {{n}} in the chosen template: Customer name, Amount, Plan or billing period, Due date, or Payment link or UPI. A template can have at most five placeholders. |
| Follow up automatically | One follow-up a day, twice, then the payment is marked stopped. Razorpay only; on by default. |
| Send a receipt | Sends the Payment received template when a payment is recorded. Needs that template. |
Customer preview shows the chosen template filled with example values, and Payment value shows what fills a Payment link or UPI placeholder. Create or generate opens the template composer if you need a new template; it still needs Meta's approval.
By default the placeholders run in this order, most essential first, so a shorter template loses the least important detail:
| Placeholder | Value |
|---|---|
{{1}} |
Customer name |
{{2}} |
Amount, formatted (₹1,249.00) |
{{3}} |
What it's for, and the period |
{{4}} |
The due date |
{{5}} |
A payment link, or your UPI ID |
The reminder ladder #
Three messages, then it stops.
Upcoming ──(due date)──▶ Reminder ──(+1 day)──▶ Follow-up ──(+1 day)──▶ Secondfollow-up ──(+1 day)──▶ Stopped chasingAt any point: paid ──▶ Paid (follow-ups cancelled, link cancelled)waived ──▶ Waived (your decision)
- One reminder, on the due date, or up to 14 days earlier.
- At most two follow-ups, one a day, with Razorpay and Follow up automatically on.
- Then the payment is marked Stopped chasing and left for you.
Stopped chasing doesn't mean the customer refused. It means Duesly has stopped asking. The payment stays on Payments for you to handle in person: a call, a conversation, a waiver.
A Paid late? button appears on these payments, but recording a payment on one fails today: only open payments can be marked paid. If a customer pays after the chase ended, keep the reference in your own records for now.
You can also step in early. On Payments, Remind now sends the reminder for an upcoming payment straight away, and Follow up sends the next follow-up. Follow up is disabled once a reminder and two follow-ups have gone out.
The limit is fixed
A reminder and two follow-ups is the maximum, and no setting, plan or API call raises it. A payment reminder must not be able to become harassment.
Payments #
The Payment register has Overdue, Open, Upcoming and Paid views. Each row shows the customer and due date, the amount and period, the status with dots for how many of the three messages have gone out, the next step, and the payment link. See the message that went out opens the campaign the reminder was sent in, with its per-recipient outcome.
| Status | Meaning |
|---|---|
| Upcoming | Raised, not yet reminded. |
| Reminded | The reminder went out. |
| Followed up / Followed up twice | One or two follow-ups went out. |
| Paid | Recorded as paid, by the gateway or by you. |
| Stopped chasing | The ladder ended unpaid. |
| Waived | You stopped collecting it on purpose. |
| Cancelled | The customer was removed or their plan changed. |
Recording a payment #
Paid (on Payments) or Record paid (on Today) opens Record payment from the customer. Used constantly in UPI mode, and now and then with Razorpay for cash, a bank transfer or a cheque.
| Field | Notes |
|---|---|
| Amount received (₹) | You can record less than was asked for. It's recorded as it happened. |
| When | The payment date; today by default. |
| Reference (optional) | A UPI transaction id or cheque number. |
| Note (optional) | Anything else. |
Mark as paid stops all further reminders for that payment, and cancels its payment link so nobody pays twice.
Waive stops collecting a payment on purpose: Duesly stops every reminder for this payment and it is never counted as collected. From the console the reason recorded is Waived from the console; the Duesly API accepts your own.
Troubleshooting #
From your own code #
Customers, payments and recording payments are all on the API, and payment.paid and payment.declined webhooks fire as they happen. See Duesly API.