This component requires Memberscript #222. Add the following attributes to your Webflow elements before use:
- Trigger & Modal:
- `data-ms-retain="cancel-trigger"` — on the cancel button (set to `display: none` in Webflow; the script reveals it for eligible members)
- `data-ms-retain="modal"` — on the modal wrapper element - Modal States (script shows one at a time):
- `data-ms-retain="offer"` — the offer/discount pitch container
- `data-ms-retain="loading"` — the loading/spinner container
- `data-ms-retain="success"` — the confirmation container
- `data-ms-retain="error"` — the error message container - Buttons:
- `data-ms-retain="accept"` — accept/keep plan button
- `data-ms-retain="decline"` — decline/cancel anyway button
- `data-ms-retain="close"` — close button (supports multiple)
- `data-ms-retain="retry"` — retry button inside the error state - Config Attributes (on the modal wrapper element):
- `ms-retain-webhook` — your Make.com webhook URL
- `ms-retain-coupon` — your Stripe coupon ID
- `ms-retain-plan` — *(optional)* target a specific Memberstack plan ID
- `ms-retain-field` — *(optional)* JSON key for tracking, defaults to `retention_offered`
- `ms-retain-max-offers` — *(optional)* lifetime max offers, defaults to `1`
- `ms-retain-cooldown` — *(optional)* days before re-offering after decline, defaults to `30`
- `ms-retain-return-url` — *(optional)* return URL after Stripe portal, defaults to current page
- `ms-retain-display` — *(optional)* CSS display value for the modal, defaults to `flex`
Key Features
- Intercepts cancel clicks and shows a retention offer before the Stripe Customer Portal
- Only activates for members with an active subscription (type `SUBSCRIPTION`)
- Hides the cancel button entirely for members without the target plan
- Reveals the cancel button for members who do have the plan
- Targets a specific plan via `ms-retain-plan` or defaults to the first active subscription
- Fires a Make.com webhook to apply a Stripe coupon to the existing subscription
- Tracks offer history in Memberstack member JSON to prevent repeat offers
- Once accepted, the offer never shows again, cancel clicks go straight to Stripe portal
- Configurable max offers and cooldown period between declined offers
- Four modal states managed by the script: offer, loading, success, error
- Closes on backdrop click, Escape key, or close button
- Falls back to Stripe Customer Portal on decline or when ineligible
Potential Use Cases
- SaaS sites offering a discount to members about to cancel their monthly plan
- Membership communities with a "stay and save" offer before churn
- Course platforms retaining annual subscribers with a temporary price reduction
- Any Stripe-powered subscription site that wants to reduce voluntary cancellations