
Subscription Plan Retention modal
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
