Reactivation
A PAUSED user returns to ACTIVE through one of two operations. Error bodies of the collect flow are the CollectOnReactivationError schema in the API Specification.
| Flow | Operation | Summary |
|---|---|---|
|
Admin API only. Reactivates without collecting money and unblocks Auth0. |
|
|
App flow. Collects the outstanding float and the subscription payment, then reactivates. |
MX Reactivation
-
The user must exist (
404) and bePAUSED(400). -
The current membership (or the
BASEdefault) is re-written with an empty status,reactivation_datenow, eventREACTIVATEand an empty event source. -
The user becomes
ACTIVEand the Auth0 account is unblocked. -
200with an empty body.
Collect-on-Reactivation
The body is optional; tier defaults to base and is resolved to its current version from the GrowthBook tier config (400 INVALID_TIER when unknown).
-
Load the user (
500); anINVESTIGATEuser is405 USER_UNDER_INVESTIGATION. -
Load the current membership (or the base default) and apply the cooldown (
405 REACTIVATION_COOLDOWN). -
Find the user’s fee waiver: a settlement participant matched to the user who has not forfeited and whose 18 months have not ended (program
settlement; one who has not started yet qualifies), otherwise an active win-back offer, an unarchivedMEMBERSHIP_WAIVER_OFFERwhoseexpires_athas not passed (see Tags used by this service). A read failure is500 UNEXPECTED_ERROR, so a user holding a waiver is never charged by mistake. The settlement waiver applies on its own; a win-back offer only when the body asks for it withwaiver_program: winback. A win-back request is refused with409, before anything is collected, when there is no usable offer (WAIVER_OFFER_NOT_FOUND) or the user’s membership history has a reactivation waived underwinbackin the last 6 months (WAIVER_RECENTLY_USED; a history read failure is500 UNEXPECTED_ERROR). -
Without a waiver, Float Service payback for reactivation:
404means no outstanding float,402means a partial repayment and carriesamount_remaining, any other failure is500 FLOAT_REPAYMENT_FAILED. With one, the payback is skipped and an active float stays owed. -
Subscription Service reactivation with the tier and version, and the
waiverto write when there is one, which the Subscription Service records without checking: a settlement waiver asprogramandends_at, the end of the participant’s 18 months (18 months from the start of this hour for one starting now); a win-back asprogram,cycles(the offer’soffer_length) andcohort:201created the subscription,200means it was already active (no subscription receipt), anything else is500 SUBSCRIPTION_PAYMENT_FAILED. After a waived201, a win-back offer tag getswaiver_used_atand is archived, and a settlement participant who had not started the waiver getsstarted_atnow (failures logged). One who already started keeps theirstarted_at, so the 18 months stay anchored to it and a reactivation never restarts them. -
Write the new membership (
<TIER>/MONTHLYat the resolved version, empty status,reactivation_datenow,waiver_programset to the waiver’s program when waived and empty otherwise, eventMANUAL_REACTIVATION, empty source) and set the userACTIVE(500 UNEXPECTED_ERROR). -
Persist every active Plaid item in the Transactions Service (removes their expiry); failures are logged because the user has already been charged.
-
Ask the Underwriting Service to recalculate (failure logged).
-
Fire the first-debit-card event.
-
Send the receipt when anything was collected and answer
201(no float, or float fully repaid) or206(a float balance remains) withfull_success,amount_collected(float plus subscription, dollars) andamount_remaining.
Metrics user.membership.reactivation (tag full_success:) and prod.manual.reactivations.
Cooldown
A membership whose reactivation_date plus REACTIVATION_LIMIT_DAYS (60 days in both environments) is still in the future cannot reactivate again.
Receipt
Segment event user-reactivation-receipt:
| Field | Value |
|---|---|
|
Subscription period from the Subscription Service, |
|
Float amount collected plus the subscription amount |
|
The two components ( |
|
RFC3339 timestamp |
|
|
|
Last digits of the card, from the float response or the subscription response |
|
Requested tier, upper-cased |
Source: pkg/api/reactivations.go