Zoho Creator — Payment Status Console
A single console in Zoho Creator to track invoice status and trigger one-click actions (SMS, WhatsApp, payment link) that speed up collections.

- Row actions: Send SMS (Twilio), Send WhatsApp (Superchat/BSP), Send Tabby payment link
- Fields: Amount, Currency, Status, Invoice No, Link, Expires, Attempts, Owner
- Webhooks update status to Paid/Failed automatically; receipts can be emailed
What this console does
A finance agent opens one place in Zoho Creator to see unpaid invoices and click one of three row actions: SEND SMS (via Twilio), SEND WHATSAPP (via Superchat/BSP), and Send Tabby Payment Link. The app generates a secure payment link, sends it through the selected channel, tracks attempts, and updates status automatically when the customer pays.
How it works (end-to-end)
- Agent clicks a row action. Creator runs a server function (Deluge) so keys/tokens never touch the browser.
- For Tabby, the function calls the Payments API to create a one-time link (amount, currency, invoice ref, customer info). The link & expiry are saved on the record.
- The same function sends the link by SMS (Twilio) or WhatsApp(Superchat/BSP) using Creator Connections (secure auth).
- When the customer pays, a webhook from the PSP hits a Creator endpoint, which flips the status to Completed, stamps the time, and logs a receipt.
- A post-payment routine writes back to Zoho Books (record payment against the invoice) and updates Zoho CRM (contact’s last_payment fields, notes).
Data model (key fields)
Name,Phone,Email,Invoice_Number,Amount,CurrencyPayment_Status(Generated | Sent | Completed | Failed | Expired)Payment_Link,Expires_At,Attempts,Channel,Owner
Integrations (Creator Connections + APIs)
- Twilio SMS — POST to Twilio Messages API with
To,From,Body. Use a Creator Connection (Basic/OAuth) so you don’t store secrets in code. - Superchat / WhatsApp BSP — POST a WhatsApp text template or plain text payload to the provider’s messages endpoint; pass the Tabby link in template variables.
- Tabby — Create a one-time payment link with amount/currency & an order reference (invoice no). Save the returned
urlandexpires_at. - Zoho Books — On success, create a Customer Payment against the invoice (rather than just toggling a status), attach the gateway transaction id, and email the receipt if required.
- Zoho CRM — Upsert the Contact by email/phone, update
Last_Payment_Status,Last_Payment_At, and add a note with the invoice reference.
Deluge Function
1) Create a Tabby link, store it, and send by SMS
// Assume this runs in a Creator workflow or page action
inv_no = input.Invoice_Number;
amount = input.Amount;
currency = input.Currency;
customer_phone = input.Phone;
customer_name = input.Name;
// 1) Create payment link (Tabby)
payload = {
"amount": amount,
"currency": currency,
"buyer": {"phone": customer_phone, "name": customer_name},
"order": {"reference_id": inv_no}
};
tabby_resp = invokeurl
[
url: "<TABBY_BASE>/payments/links" // configured in your Connection
type: POST
content-type: "application/json"
body: payload.toString()
connection: "tabby_conn"
];
link = tabby_resp.get("url");
expiry = tabby_resp.get("expires_at");
// Persist on the record
input.Payment_Link = link;
input.Expires_At = expiry;
input.Payment_Status = "Sent";
input.Attempts = ifnull(input.Attempts,0) + 1;
input.Channel = "SMS";
// 2) Send SMS (Twilio)
// === Twilio creds & message (replace with your values or app variables) ===
account_sid = "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
api_key = "SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // API Key SID (recommended)
api_secret = "your_api_key_secret"; // API Key Secret
from_num = "+1XXXXXXXXXX"; // your Twilio number (or use MessagingServiceSid)
to_num = "+9715XXXXXXXX";
body_text = "Your invoice INV-0004 is ready. Pay: https://example.com/pay/INV-0004";
// === Endpoint (same as cURL) ===
url_str = "https://api.twilio.com/2010-04-01/Accounts/" + account_sid + "/Messages.json";
// === Form fields (urlencoded) ===
params = Map();
params.put("To", to_num);
params.put("From", from_num); // OR: params.put("MessagingServiceSid","MGxxxxxxxxxxxxxxxxxxxx");
params.put("Body", body_text);
// === Basic Auth header: "Basic base64(api_key:api_secret)" ===
auth_header = "Basic " + base64Encode(api_key + ":" + api_secret);
resp = invokeurl
[
url : url_str
type : POST
parameters: params // sends as application/x-www-form-urlencoded
headers : {"Authorization": auth_header}
];
// Twilio returns JSON with fields like sid, status, error_code, error_message
sid = resp.get("sid");
if(sid != null)
{
info "SMS queued. SID: " + sid;
}
else
{
info "Twilio error: " + resp;
}2) Send the same link via WhatsApp (Superchat/BSP)
header = {"X-API-KEY": "auth_12394ru02wdoncn3d034"};
params = {
"to": [
{
"identifier": "hello@superchat.de"
}
],
"from": {
"channel_id": "mc_12394ru02wdoncn3d034",
"name": "Jane Smith"
},
"content": {
"type": "text",
"body": "Hi " + customer_name + ", pay invoice " + inv_no + " here: " + link"
},
"in_reply_to": "string"
}
wa_resp = invokeurl
[
url: "https://api.superchat.com/v1.0/messages"
type: POST
parameters: params.toString()
headers: header
];3) Function to mark as Completed in Books/CRM
// Expose this as a Creator API endpoint; verify signature from provider!
status = param("status");
inv_ref = param("order_reference") ?: "";
rec = Payment_Status[Invoice_Number == inv_ref];
if(rec != null)
{
if(status == "PAID")
{
rec.Payment_Status = "Completed";
rec.Paid_At = zoho.currenttime;
// Zoho Books: record payment
books_resp = invokeurl
[
url: "https://books.zoho.com/api/v3/customerpayments"
type: POST
parameters: {"customer_id": rec.Customer_ID, "amount": rec.Amount, "invoices":[{"invoice_id": rec.Invoice_ID,"amount_applied": rec.Amount}]}.toString()
connection: "zohobooks_conn"
];
// Zoho CRM: update contact payment info
data = {"Last_Payment_Status":"Completed","Last_Payment_At":rec.Paid_At};
crm_resp = zoho.crm.updateRecord("Contacts", data, "zohocrm_conn");
}
}Operational niceties
- Templates: Centralize SMS/WhatsApp templates with placeholders (invoice, amount, link, expiry).
- Retries: If a send fails, store the provider error and allow a one-click retry; cap attempts.
- Jobs: Nightly job to expire old links and re-generate if still unpaid.
- Audit: Log who sent what, when, and via which channel (Creator notes or a child form).
- Security: Use Creator Connections, never hard-code secrets; verify webhook signatures; restrict roles.
- Books/CRM IDs: Store
Invoice_ID,Customer_ID,CRM_Contact_IDfor reliable write-backs.
User flow (what I demo)
- Filter by status = Generated, pick an invoice, click Send Tabby Payment Link.
- Link is created, saved, and sent by WhatsApp or SMS; status flips to Sent.
- Payment completes; webhook marks Completed, Books gets a Customer Payment, CRM is updated.