Customer Win-Back & Membership Recovery
Win back dormant customers and rescue members whose card bounced — booking or fixing it live on the call.
Last updated 2026-07-12
Screenshots




About Customer Win-Back & Membership Recovery
Customer Win-Back & Membership Recovery
Win back the customers you already earned — and stop losing the ones a bounced card would have quietly cancelled.
Customer Win-Back & Membership Recovery fuses the two highest-ROI retention plays a local business has into one app:
- Voluntary win-back — lapsed regulars who simply drifted away get a warm "we've missed you" call that makes a comeback offer and books the return visit on the spot.
- Involuntary churn rescue — the moment a member's card is declined, an agent calls to fix the card before the membership lapses by accident.
Built on the Telenow App Platform as a pure declarative app: the data model, the agent tools, the Stripe webhook, the recovery workflow, both vernacular-friendly agents, and the win-back playbook all run on-platform. No external server.
The problem (and the number)
For salons, gyms, spas, clinics, and restaurants, the cheapest revenue on earth is the customer you already have. Reactivating a past customer costs roughly 5–7× less than acquiring a new one, and past customers convert at 20–40% versus 5–20% for cold prospects. Yet most SMBs let dormant regulars quietly fade and let "failed payment" emails go unopened — and a huge share of membership cancellations are never even chosen: they're involuntary churn from an expired or reissued card. Customer Win-Back & Membership Recovery attacks both leaks with a phone call, the one channel that still books.
How it works
VOLUNTARY WIN-BACK INVOLUNTARY CHURN RESCUE
client list ──► dormant queue (by days-since-visit) Stripe ──(charge.failed webhook)──► stripe_failed hook
│ │ │ │
│ launch a bulk campaign over the dedupe on phone failed_payment row
│ dormant view (app-campaigns API) │ fires object.failed_payment.created
▼ ▼ ▼ ▼
Call now (per row) win-back agent dials each send_card_link (WhatsApp) card_recovery workflow
└──────────► find_client → "we've missed you" secure update-card link ├─ delay ~2 min
offer → book_return / mark_lost └─ outbound-call {{settings.recovery_agent_id}}
→ log_outcome ├─ flag membership failed_payment
└─ dials {{trigger.data.phone}}
→ card-recovery agent
find_membership → update card → mark_recovered / mark_churned
Everything the agents do on a call updates the same rows you see on the dashboard — and the Call now buttons on the Clients and Memberships pages dial the very same agents and tools.
Two paths, by design
- Dormant win-back is a campaign. It's a batch sweep over the
clientdormant view, launched at runtime via the app-key campaign API (below) — not a per-row workflow. That's the right shape for "dial my whole backlog." - Card rescue is declarative and real-time. A single decline should trigger a call within minutes, so it runs as an inbound hook → workflow with zero code.
Agent tools (used mid-call — all declarative)
| Tool | Does | Handler |
|---|---|---|
find_client | Look up a lapsed customer by phone (last visit, days away, lifetime value) | object.query client |
find_membership | Look up a member by phone (plan, card on file, status) | object.query membership |
book_return | Client accepts the offer — win-back | object.update client (match phone → status reactivated) |
mark_recovered | Member updates the card and it clears — churn saved | object.update membership (match phone → status recovered) |
mark_lost | Client says they won't return — keep the queue honest | object.update client (match phone → status lost) |
mark_churned | Member deliberately cancels — drop them from the rescue queue | object.update membership (match phone → status churned) |
log_outcome | Record the call result + whether a return was booked | object.create campaign_result |
Both bundled agents are multi-context flows: a deterministic lookup tool node (find_client / find_membership, looking the caller up in this app's data) → a conversation node that makes the offer / fixes the card and sets status.
Dashboard pages
- Customer Win-Back & Membership Recovery (dashboard) — KPI tiles (recovered revenue, win-back rate, saved memberships, dormant clients, cards to rescue), a client-status mix bar, the longest-gone dormant clients, and recent call outcomes. Also powers the platform
dashboard_widgetslot in a compact form. - Clients — the dormant win-back queue sorted by days-since-visit, with status filters, search, and per-client Call now (dials the win-back agent with the client's context).
- Memberships — the failed-payment rescue queue with the at-risk amount per member and per-member Call now (dials the card-recovery agent).
- Setup — configuration checklist, one-click Create agent for both bundled agents, and the post-install wiring steps.
Knowledge base
winback-playbook ships four real scripts both agents answer from: the "we've missed you" comeback offers, the card-update rescue script, retention talking points, and objection handling for win-back calls.
Install & post-install wiring
- Install Customer Win-Back & Membership Recovery into your org.
- Open Setup and click Create agent for both the win-back agent and the card-recovery agent (each auto-wired to the tools + playbook).
- Copy each new agent's ID into the app's settings: Win-back agent ID (
winback_agent_id, required) and Card-recovery agent ID (recovery_agent_id). - (Optional) Set Dormant threshold (
dormant_days, default 90) and WhatsApp channel ID (wa_channel) to auto-text the secure update-card link on a decline. - Point a Stripe charge.failed (or invoice.payment_failed) webhook at the app's
stripe_failedinbound hook (verified via theStripe-Signatureheader). Declines now flow in and auto-dial. - Import (or webhook in) your customer list as
clientrows so the dormant queue fills up.
Settings
| Key | Type | Notes |
|---|---|---|
winback_agent_id | text (required) | The agent your dormant campaigns + Clients "Call now" dial. |
recovery_agent_id | text | The agent the card_recovery workflow dials on a decline. |
dormant_days | number | No-visit days before a client is treated as dormant (default 90). |
wa_channel | text | WhatsApp channel for the secure update-card link. |
Bulk dialing the dormant queue (campaign API)
The card-rescue path (webhook → workflow → call) covers declines automatically. To launch the voluntary win-back across your whole dormant backlog, use the app-key campaign API over the client object's dormant view:
POST /api/app-campaigns
{
"agentId": "<win-back agent id>",
"targetQuery": { "status": "dormant" }, // over the `client` object
"result": { "object": "campaign_result" }
}
Every dialed client's result lands as a campaign_result row, which powers the dashboard's win-back rate.
Monetization
Customer Win-Back & Membership Recovery is billed on outcomes, not seats:
- Per reactivated client — a fee for each dormant client the win-back agent books back in (
reactivated), since each is revenue you'd otherwise have written off. - Per saved membership — a fee for each declined card the recovery agent rescues (
recovered), which prevents an involuntary cancellation and pulls the whole remaining membership value forward.
Because a reactivation and a saved membership are both worth many multiples of a single call, the app nets positive for the merchant on the very first save — and the dashboard's recovered revenue tile makes that ROI obvious at a glance.
Ready-made agents it ships
A warm, likeable agent that calls lapsed customers, reminds them why they loved you, makes a 'we've missed you' comeback offer, and books the return visit on the call. Can also help a customer update a card on file.
A calm, reassuring agent that calls a member the moment their card is declined, explains the failed charge, and walks them through updating the card on file so their membership never lapses by accident.
What your agents can do with it
Look up a lapsed customer by their phone number to see when they last visited, how long they've been away, and their lifetime value before you speak.
Look up a member by phone to see their plan, the card on file, and whether a recent payment failed, before helping them fix it.
Mark a dormant client as REACTIVATED once they accept the offer and agree to come back in (a booked return visit). This is a win-back.
Mark a member as RECOVERED after they update the card on file and the payment goes through. This saves the membership from involuntary churn.
Mark a client as LOST when they clearly say they will not be coming back, so the win-back queue stays honest and you stop dialing them.
Mark a member as CHURNED when they clearly choose to cancel their membership on purpose (not an accidental decline), so they leave the failed-payment rescue queue and you stop calling them.
Record the result of this win-back or card-recovery call (what was offered, what the customer said, and whether a return visit was booked).
Data it manages
Permissions it requests
Apps run inside your workspace under least-privilege scopes you can see up front. This app asks for:
objects:clientobjects:membershipobjects:failed_paymentobjects:campaign_resultagents:readcalls:initiatecalls:readai:llmwhatsapp:sendcampaigns:readuser:profileWhat's new in v1.1.0
Changelog
1.1.0 — 2026-07-12
- Renamed to Customer Win-Back & Membership Recovery (business-friendly) with a marketplace icon.
- Added real UI screenshots (dashboard + key pages).
- Dormant clients are now derived from days-since-visit (works for real imported lists); a card decline flags the membership and
mark_churnedwas added. - Verified end-to-end loop closure: trigger → workflow → call → agent tools → write-back → dashboard.
1.0.0
- Initial release.
- Data model:
client(name, phone, last_visit, days_since, lifetime_value, status, note) with adormantwin-back queue view (by days-since) plusreactivated/lostviews;membership(name, phone, plan, card_last4, status) withfailed_payments/recovered/churnedviews;failed_payment(phone, amount, card_last4, created_at) with arecentdeclines view; andcampaign_result(phone, outcome, booked) with abookedview. - Agent tools (declarative):
find_client,find_membership,book_return,mark_recovered,mark_lost,mark_churned,log_outcome. - Bundled agents: Win-back Agent — a warm "we've missed you" multi-context flow (deterministic
find_clientlookup → comeback offer → book the return / mark lost) — and Card-recovery Agent — a calm decline-rescue flow (find_membershiplookup → card-update script → mark recovered). Both auto-wired to the tools and the win-back playbook. - Knowledge base:
winback-playbook— the comeback offer menu, the card-update rescue script, retention talking points, and win-back objection handling. - Automation:
stripe_failedinbound webhook (HMAC-verified viaStripe-Signature, dedupe on phone);card_recoveryworkflow (flag the matching membershipfailed_paymentso it surfaces on the rescue queue → delay ~2 min → outbound card-recovery call);send_card_linkworkflow (WhatsApp the secure update-card link on a decline). - Dashboard UI: KPI tiles (recovered revenue, win-back rate, saved memberships, dormant clients, cards to rescue), a client-status mix bar, the longest-gone dormant clients, and recent call outcomes; also renders into the
dashboard_widgetslot in compact form. - Clients page: the dormant queue by days-since-visit, status filters, search, and per-client Call now (dials the win-back agent with context).
- Memberships page: the failed-payment rescue queue with at-risk amounts and per-member Call now (dials the card-recovery agent).
- Setup page: configuration checklist, one-click Create agent for both bundled agents, Stripe wiring, and the dormant-campaign API note.
- Self-seed: a fresh install auto-loads six realistic clients (three dormant, one reactivated, one lost, one active), two memberships (one failed, one recovered), a failed payment, and four call outcomes (removable) so every page looks alive on first open.
Publisher
Marketplace publisher · app reviewed by Telenow before listing.
Your data, your keys
Secrets, carrier credentials and API keys stored AES-GCM encrypted; TLS in transit; HMAC-signed webhooks.
Strict per-organization data isolation with role-based access for every member.
Every mutating action is logged and filterable, with CSV export for your records.
In-app DLT / regulatory flows, TCPA calling windows, and org-wide Do-Not-Call enforcement.
Install Customer Win-Back & Membership Recovery
Sign up free and get ₹300.00 in credit — no card required. Connect your number, pick a template, and go live in minutes.
