Retention
Revenue Recovery's cancellation screen as a connector's member surface runs it — the question and the one offer in the core's words, the reason and the note written down, the offer taken or passed on, and every refusal with a stable reason.
Subscriby\Connector\Core\Retention. The screen is the core's: the creator decides whether the
question is asked and which offers the project makes, the core picks the one offer the member's
payment method can honour and phrases every sentence in the member's language, and the dashboard
reads every answer. A connector is one more place a member meets it. The contract takes the
InstallationRef the conversation runs on and the IdentityRecord of the account that is talking,
finds the project behind the one and the member behind the other, and answers in summaries whose
every sentence the core already wrote. A bot never composes an offer from a kind and a figure; it
prints what it was handed and reports what was tapped, and the portal and the bot ask and offer the
same things in the same words.
cancellationScreenFor()
$screen = $this->retention->cancellationScreenFor($bot->installationRef(), $chat->identityRecord());
if ($screen === null) {
return; // no live membership to cancel: no screen
}
$screen->subscriptionId; // the membership the screens are about
$screen->projectName; $screen->planName; // for the confirmation's words
$screen->asksReason; // false when the creator switched the question off
foreach ($screen->reasons as $reason) {
$reason->code; // too_expensive
$reason->label; // "Too expensive", in the member's language
}
$screen->offer?->kind; // RetentionOfferKind::Pause | Discount | ReturnCoupon, or null for no offer
$screen->offer?->headline; // "Take a month off instead?"
$screen->offer?->sentence; // what the offer does, in one sentence
$screen->offer?->acceptLabel; // the button's words
$screen->offer?->couponCode; // the code, on a return coupon
$screen->accessEndsOn; // when a cancellation would end access, formatted, or nullNull while the account holds no live membership to cancel. reasons is empty when the project
switched the question off, and offer is null when the project makes no offer on the member's
payment method or the creator's plan lacks the offers, so a connector draws the screens it is
handed and no other: the reason when asksReason, the offer when there is one, then its own
confirmation.
recordCancellationFeedback()
try {
$record = $this->retention->recordCancellationFeedback($installation, $chat->identityRecord(), $code, $note);
} catch (RetentionRefused $refused) {
$this->send($chat, $refused->getMessage()); // reason_unknown, invalid_note, ...
}
$record->id; // park it for the offer step
$record->offer; // the offer to show next, derived again by the core, or nullWrites the row the dashboard's Cancellations face shows, tells the creator under the Revenue
Recovery alert class, raises subscription.cancellation_feedback, and answers the offer to show
next. $note is the sentence the member typed or null when they skipped it; a note over 500
characters is invalid_note, a code the screen did not list is reason_unknown.
takeOffer()
try {
$outcome = $this->retention->takeOffer($installation, $chat->identityRecord(), $record?->id);
} catch (RetentionRefused $refused) {
// cancellation_unknown, offer_unavailable, gateway_refused
}
$outcome->kind; // what they got
$outcome->keepsSubscription; // true for a pause or a discount, false for a return coupon
$outcome->sentence; // what happens next, in the member's language
$outcome->couponCode; // the code to restate, on a return couponThe offer is derived again by the core, never taken from the connector, so a stale screen cannot
claim an offer the creator has since withdrawn (offer_unavailable). A pause holds the charge at
the gateway first and pauses access second; a discount is applied at the gateway; a return coupon
is handed over on the screen and in a message, and the cancellation goes on, which is why
keepsSubscription is what a connector branches on: a pause or a discount ends the conversation
with the sentence and a way back, a return coupon goes on to the connector's own confirmation with
the code restated. gateway_refused means the gateway would not hold the charge or carry the
discount; relay the sentence and offer the confirmation. Pass null as the id when the project
asked no question.
declineOffer()
$record = $this->retention->declineOffer($installation, $chat->identityRecord(), $record?->id); // null when no offer was madeNotes that the member passed on the offer, so the offers shown are counted against the offers taken on the creator's figures. Call it when the member taps past the offer, before the confirmation.
Refusals
Every method throws Subscriby\Connector\Exceptions\RetentionRefused. getMessage() is the core's
sentence in the member's language, which is what you relay; reason is stable and yours to branch
on: installation_unknown (the ref names no project), member_unknown, subscription_unknown (no
live membership), reason_unknown, invalid_note, cancellation_unknown (the id names none of the
member's rows), offer_unavailable and gateway_refused.
What is not here
The cancellation itself stays the connector's own confirmation, run through the subscription port
as it always was, so a free trial still cancels outright and the decoy-guarded confirmation keeps
its code. The creator's switches are
RetentionManagement's; the grace ladder, the sequences
and the figures are the core's whole subsystem and never a connector's to write.
Read it fresh
The screen and the offer are computed when you ask; park the record's id across two taps, never
the screen. The creator may switch the question or an offer off between them, and the core answers
offer_unavailable rather than honouring a screen that no longer stands.
How is this guide?
Last updated on
Referral Management
A project's Referral Program as a connector's creator surface runs it — the options a setup needs, the programme in the core's words with its figures, the save from a draft, the pause, the resume and the delete, affiliates listed and read with their balances and payout details, approved, suspended and enrolled from a member search, and payouts recorded against what is payable.
Retention Management
A project's Revenue Recovery settings as a connector's creator surface runs them — the grace window with its ladder in words, the question, the digest and the three offers with the coupons a creator may pick, read whole and saved one field at a time.