@churnkey/react 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core.d.cts +324 -0
- package/dist/core.d.ts +324 -0
- package/dist/headless.d.cts +34 -0
- package/dist/headless.d.ts +34 -0
- package/dist/index.d.cts +41 -0
- package/dist/index.d.ts +41 -0
- package/dist/step-graph-DX8yCqq1.d.cts +644 -0
- package/dist/step-graph-DX8yCqq1.d.ts +644 -0
- package/dist/styles.css.d.ts +1 -0
- package/package.json +1 -1
package/dist/core.d.cts
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { Q as PlanOption, s as DirectCustomer, u as DirectSubscription, G as Mode, z as FlowConfig, E as FlowState, T as ReasonConfig, W as ResolvedStep, K as OfferDecision, d as Appearance } from './step-graph-DX8yCqq1.cjs';
|
|
2
|
+
export { A as AcceptedOffer, e as AppearanceVariables, B as BackButtonProps, f as BuiltInOfferConfig, g as BuiltInStep, h as BuiltInStepType, C as CancelFlowProps, c as CloseButtonProps, i as ComponentOverrides, j as ConfirmClassNames, k as ConfirmStep, a as ConfirmStepProps, l as ContactOffer, m as CustomComponents, n as CustomOfferConfig, o as CustomOfferProps, p as CustomStepConfig, q as CustomStepProps, D as DirectAddress, r as DirectCoupon, t as DirectPrice, v as DirectSubscriptionItem, w as DiscountOffer, x as FeedbackClassNames, y as FeedbackStep, F as FeedbackStepProps, M as ModalProps, H as OfferClassNames, I as OfferConfig, J as OfferCopy, L as OfferStep, O as OfferStepProps, P as PauseOffer, N as PlanChangeOffer, R as ReasonButtonProps, U as RebateOffer, V as RedirectOffer, X as Step, Y as StructuralClassNames, Z as SubscriptionStatus, _ as SuccessClassNames, $ as SuccessStep, S as SuccessStepProps, a0 as SurveyClassNames, a1 as SurveyStep, b as SurveyStepProps, a2 as TrialExtensionOffer } from './step-graph-DX8yCqq1.cjs';
|
|
3
|
+
import { CSSProperties } from 'react';
|
|
4
|
+
|
|
5
|
+
interface SdkConfig {
|
|
6
|
+
blueprintId: string;
|
|
7
|
+
steps: SdkStep[];
|
|
8
|
+
customer: DirectCustomer;
|
|
9
|
+
subscriptions: DirectSubscription[];
|
|
10
|
+
settings: SdkSettings;
|
|
11
|
+
/** Bandit key used for auto-optimization, if it ran. */
|
|
12
|
+
autoOptimizationKey?: string;
|
|
13
|
+
}
|
|
14
|
+
interface SdkSettings {
|
|
15
|
+
clickToCancelEnabled: boolean;
|
|
16
|
+
strictFTCComplianceEnabled: boolean;
|
|
17
|
+
discountCooldown?: number;
|
|
18
|
+
pauseCooldown?: number;
|
|
19
|
+
}
|
|
20
|
+
type SdkStep = SdkSurveyStep | SdkOfferStep | SdkFeedbackStep | SdkConfirmStep;
|
|
21
|
+
interface SdkStepBase {
|
|
22
|
+
guid: string;
|
|
23
|
+
title?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
}
|
|
26
|
+
interface SdkSurveyStep extends SdkStepBase {
|
|
27
|
+
type: 'survey';
|
|
28
|
+
reasons: SdkReason[];
|
|
29
|
+
}
|
|
30
|
+
interface SdkOfferStep extends SdkStepBase {
|
|
31
|
+
type: 'offer';
|
|
32
|
+
offer: SdkOffer;
|
|
33
|
+
}
|
|
34
|
+
interface SdkFeedbackStep extends SdkStepBase {
|
|
35
|
+
type: 'feedback';
|
|
36
|
+
placeholder?: string;
|
|
37
|
+
required?: boolean;
|
|
38
|
+
minLength?: number;
|
|
39
|
+
}
|
|
40
|
+
interface SdkConfirmStep extends SdkStepBase {
|
|
41
|
+
type: 'confirm';
|
|
42
|
+
}
|
|
43
|
+
interface SdkReason {
|
|
44
|
+
id: string;
|
|
45
|
+
label: string;
|
|
46
|
+
freeform?: boolean;
|
|
47
|
+
offer?: SdkOffer;
|
|
48
|
+
}
|
|
49
|
+
type SdkOffer = SdkDiscountOffer | SdkPauseOffer | SdkPlanChangeOffer | SdkTrialExtensionOffer | SdkRedirectOffer | SdkContactOffer | SdkRebateOffer;
|
|
50
|
+
interface SdkOfferBase {
|
|
51
|
+
/** Per-offer guid — used for analytics joins between presented and accepted offers. */
|
|
52
|
+
decisionId?: string;
|
|
53
|
+
copy: SdkOfferCopy;
|
|
54
|
+
}
|
|
55
|
+
interface SdkDiscountOffer extends SdkOfferBase {
|
|
56
|
+
type: 'discount';
|
|
57
|
+
couponId?: string;
|
|
58
|
+
percentOff?: number;
|
|
59
|
+
/** Smallest currency unit (cents for USD, etc.). */
|
|
60
|
+
amountOff?: number;
|
|
61
|
+
currency?: string;
|
|
62
|
+
durationInMonths?: number;
|
|
63
|
+
}
|
|
64
|
+
interface SdkPauseOffer extends SdkOfferBase {
|
|
65
|
+
type: 'pause';
|
|
66
|
+
months: number;
|
|
67
|
+
interval: 'month' | 'week';
|
|
68
|
+
datePicker?: boolean;
|
|
69
|
+
}
|
|
70
|
+
interface SdkPlanChangeOffer extends SdkOfferBase {
|
|
71
|
+
type: 'plan_change';
|
|
72
|
+
plans: PlanOption[];
|
|
73
|
+
}
|
|
74
|
+
interface SdkTrialExtensionOffer extends SdkOfferBase {
|
|
75
|
+
type: 'trial_extension';
|
|
76
|
+
days: number;
|
|
77
|
+
}
|
|
78
|
+
interface SdkRedirectOffer extends SdkOfferBase {
|
|
79
|
+
type: 'redirect';
|
|
80
|
+
url: string;
|
|
81
|
+
label?: string;
|
|
82
|
+
}
|
|
83
|
+
interface SdkContactOffer extends SdkOfferBase {
|
|
84
|
+
type: 'contact';
|
|
85
|
+
url?: string;
|
|
86
|
+
label?: string;
|
|
87
|
+
}
|
|
88
|
+
interface SdkRebateOffer extends SdkOfferBase {
|
|
89
|
+
type: 'rebate';
|
|
90
|
+
/** The rebate amount (pre-tax). The card is refunded this plus any tax charged on it. */
|
|
91
|
+
amountMinor: number;
|
|
92
|
+
currency: string;
|
|
93
|
+
/** Gross amount paid on the target invoice — the "you paid" row. */
|
|
94
|
+
amountPaidMinor: number;
|
|
95
|
+
/** amountPaidMinor minus the full refund (rebate plus its tax) — the "your net" row. */
|
|
96
|
+
netAfterRebateMinor: number;
|
|
97
|
+
paymentMethodBrand?: string;
|
|
98
|
+
paymentMethodLast4?: string;
|
|
99
|
+
}
|
|
100
|
+
interface SdkOfferCopy {
|
|
101
|
+
headline: string;
|
|
102
|
+
body: string;
|
|
103
|
+
cta: string;
|
|
104
|
+
declineCta: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface SessionCredentials {
|
|
108
|
+
appId: string;
|
|
109
|
+
customerId: string;
|
|
110
|
+
subscriptionId?: string;
|
|
111
|
+
authHash: string;
|
|
112
|
+
mode: Mode;
|
|
113
|
+
issuedAt: number;
|
|
114
|
+
}
|
|
115
|
+
/** Decode a session token created by `@churnkey/node`. */
|
|
116
|
+
declare function decodeSessionToken(token: string): SessionCredentials;
|
|
117
|
+
|
|
118
|
+
type ApiStepType = 'OFFER' | 'SURVEY' | 'CONFIRM' | 'FREEFORM' | 'CUSTOM';
|
|
119
|
+
type ApiOfferType = 'DISCOUNT' | 'PAUSE' | 'PLAN_CHANGE' | 'TRIAL_EXTENSION' | 'CONTACT' | 'REDIRECT' | 'REBATE' | 'CUSTOM';
|
|
120
|
+
type ApiPauseInterval = 'MONTH' | 'WEEK';
|
|
121
|
+
type ApiCouponType = 'PERCENT' | 'AMOUNT';
|
|
122
|
+
type ApiBillingInterval = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR';
|
|
123
|
+
type ApiMode = 'LIVE' | 'TEST' | 'SANDBOX';
|
|
124
|
+
interface StepViewed {
|
|
125
|
+
stepType: ApiStepType;
|
|
126
|
+
customStepType?: string;
|
|
127
|
+
guid?: string;
|
|
128
|
+
numChoices?: number;
|
|
129
|
+
start: string;
|
|
130
|
+
end?: string;
|
|
131
|
+
duration?: number;
|
|
132
|
+
}
|
|
133
|
+
interface PresentedOffer {
|
|
134
|
+
guid?: string;
|
|
135
|
+
offerType?: ApiOfferType;
|
|
136
|
+
customOfferType?: string;
|
|
137
|
+
accepted: boolean;
|
|
138
|
+
presentedAt: string;
|
|
139
|
+
acceptedAt?: string;
|
|
140
|
+
declinedAt?: string;
|
|
141
|
+
[key: string]: unknown;
|
|
142
|
+
}
|
|
143
|
+
interface AcceptedOfferPayload {
|
|
144
|
+
guid?: string;
|
|
145
|
+
offerType: ApiOfferType;
|
|
146
|
+
customOfferType?: string;
|
|
147
|
+
customOfferResult?: Record<string, unknown>;
|
|
148
|
+
couponId?: string;
|
|
149
|
+
couponType?: ApiCouponType;
|
|
150
|
+
couponAmount?: number;
|
|
151
|
+
couponDuration?: number;
|
|
152
|
+
pauseDuration?: number;
|
|
153
|
+
pauseInterval?: ApiPauseInterval;
|
|
154
|
+
newPlanId?: string;
|
|
155
|
+
newPlanPrice?: number;
|
|
156
|
+
trialExtensionDays?: number;
|
|
157
|
+
redirectUrl?: string;
|
|
158
|
+
rebateAmount?: number;
|
|
159
|
+
}
|
|
160
|
+
interface SessionCustomer {
|
|
161
|
+
id: string;
|
|
162
|
+
email?: string;
|
|
163
|
+
subscriptionId?: string;
|
|
164
|
+
planId?: string;
|
|
165
|
+
planPrice?: number;
|
|
166
|
+
currency?: string;
|
|
167
|
+
billingInterval?: ApiBillingInterval;
|
|
168
|
+
created?: string;
|
|
169
|
+
onTrial?: boolean;
|
|
170
|
+
customAttributes?: Record<string, unknown>;
|
|
171
|
+
}
|
|
172
|
+
interface SessionPayload {
|
|
173
|
+
blueprintId?: string;
|
|
174
|
+
surveyId?: string;
|
|
175
|
+
customer?: SessionCustomer;
|
|
176
|
+
canceled?: boolean;
|
|
177
|
+
aborted?: boolean;
|
|
178
|
+
surveyChoiceId?: string;
|
|
179
|
+
surveyChoiceValue?: string;
|
|
180
|
+
/** Free-text from a `freeform: true` reason. The reason's static `label` still travels on `surveyChoiceValue`. */
|
|
181
|
+
followupResponse?: string;
|
|
182
|
+
feedback?: string;
|
|
183
|
+
acceptedOffer?: AcceptedOfferPayload;
|
|
184
|
+
presentedOffers?: PresentedOffer[];
|
|
185
|
+
stepsViewed?: StepViewed[];
|
|
186
|
+
customStepResults?: Record<string, unknown>;
|
|
187
|
+
mode: ApiMode;
|
|
188
|
+
provider?: string;
|
|
189
|
+
embedVersion?: string;
|
|
190
|
+
clickToCancelEnabled?: boolean;
|
|
191
|
+
strictFTCComplianceEnabled?: boolean;
|
|
192
|
+
usedClickToCancel?: boolean;
|
|
193
|
+
autoOptimizationUsed?: boolean;
|
|
194
|
+
autoOptimizationKey?: string;
|
|
195
|
+
discountCooldown?: number;
|
|
196
|
+
pauseCooldown?: number;
|
|
197
|
+
discountCooldownApplied?: boolean;
|
|
198
|
+
pauseCooldownApplied?: boolean;
|
|
199
|
+
}
|
|
200
|
+
declare class ChurnkeyApi {
|
|
201
|
+
private creds;
|
|
202
|
+
private baseUrl;
|
|
203
|
+
constructor(creds: SessionCredentials, baseUrl?: string);
|
|
204
|
+
private get headers();
|
|
205
|
+
private orgUrl;
|
|
206
|
+
private request;
|
|
207
|
+
fetchConfig(customAttributes?: Record<string, unknown>): Promise<SdkConfig>;
|
|
208
|
+
applyDiscount(couponId: string, blueprintId?: string): Promise<void>;
|
|
209
|
+
pause(params: {
|
|
210
|
+
duration: number;
|
|
211
|
+
interval: string;
|
|
212
|
+
}): Promise<void>;
|
|
213
|
+
cancelSubscription(): Promise<void>;
|
|
214
|
+
changePlan(planId: string): Promise<void>;
|
|
215
|
+
extendTrial(days: number, blueprintId?: string): Promise<void>;
|
|
216
|
+
applyRebate(blueprintId?: string, offerGuid?: string): Promise<void>;
|
|
217
|
+
createSession(payload: SessionPayload): Promise<void>;
|
|
218
|
+
}
|
|
219
|
+
declare class AnalyticsClient {
|
|
220
|
+
private appId;
|
|
221
|
+
private baseUrl;
|
|
222
|
+
constructor(appId: string, baseUrl?: string);
|
|
223
|
+
createSession(payload: SessionPayload): Promise<void>;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Format an amount already in the major unit. Uses `narrowSymbol` so output
|
|
228
|
+
* reads "$29" rather than "US$29", and trims trailing zero fractions so
|
|
229
|
+
* whole amounts render compactly.
|
|
230
|
+
*/
|
|
231
|
+
declare function formatPrice(amount: number, currency?: string, locale?: string): string;
|
|
232
|
+
declare function calculateDiscountedPrice(originalPrice: number, percentOff: number): number;
|
|
233
|
+
/**
|
|
234
|
+
* Long-form access period end ("June 14, 2026") for the first subscription's
|
|
235
|
+
* current period. Returns null for canceled subscriptions, missing periods,
|
|
236
|
+
* and unparseable dates so Confirm can drop the "access continues until"
|
|
237
|
+
* notice cleanly instead of rendering "Invalid Date".
|
|
238
|
+
*/
|
|
239
|
+
declare function formatPeriodEnd(subscriptions: DirectSubscription[] | null | undefined, locale?: string): string | null;
|
|
240
|
+
|
|
241
|
+
declare class CancelFlowMachine {
|
|
242
|
+
private state;
|
|
243
|
+
private cachedSnapshot;
|
|
244
|
+
private callbacks;
|
|
245
|
+
private graph;
|
|
246
|
+
private listeners;
|
|
247
|
+
private apiClient;
|
|
248
|
+
private analyticsClient;
|
|
249
|
+
private directCustomer;
|
|
250
|
+
private directSubscriptions;
|
|
251
|
+
private customerAttributes;
|
|
252
|
+
private creds;
|
|
253
|
+
private config;
|
|
254
|
+
private blueprintId;
|
|
255
|
+
private localSteps;
|
|
256
|
+
private stepsViewed;
|
|
257
|
+
private presentedOffers;
|
|
258
|
+
private customStepResults;
|
|
259
|
+
private configMode;
|
|
260
|
+
private stepEnteredAt;
|
|
261
|
+
private aborted;
|
|
262
|
+
private history;
|
|
263
|
+
constructor(config: FlowConfig);
|
|
264
|
+
subscribe: (listener: () => void) => (() => void);
|
|
265
|
+
getSnapshot: () => FlowState;
|
|
266
|
+
get reasons(): ReasonConfig[];
|
|
267
|
+
get currentStep(): ResolvedStep | undefined;
|
|
268
|
+
/** The offer on the current step, or null. Always derived — no separate slot to drift. */
|
|
269
|
+
get currentOffer(): OfferDecision | null;
|
|
270
|
+
/** Whether `back()` would move anywhere — false on the first step and on success. */
|
|
271
|
+
get canGoBack(): boolean;
|
|
272
|
+
/**
|
|
273
|
+
* First step of a given type. Fine for the common "one step per type" case;
|
|
274
|
+
* flows with multiple of a type should key on currentStepId instead.
|
|
275
|
+
*/
|
|
276
|
+
getStepConfig(stepType: string): ResolvedStep | undefined;
|
|
277
|
+
/** Progress indicator index. Synthetic offers share their survey's slot. */
|
|
278
|
+
get stepIndex(): number;
|
|
279
|
+
get totalSteps(): number;
|
|
280
|
+
selectReason: (id: string) => void;
|
|
281
|
+
setFollowupResponse: (text: string) => void;
|
|
282
|
+
next: (result?: Record<string, unknown>) => void;
|
|
283
|
+
back: () => void;
|
|
284
|
+
accept: (result?: Record<string, unknown>) => Promise<void>;
|
|
285
|
+
decline: () => void;
|
|
286
|
+
setFeedback: (text: string) => void;
|
|
287
|
+
cancel: () => Promise<void>;
|
|
288
|
+
close: () => void;
|
|
289
|
+
destroy(): void;
|
|
290
|
+
initializeFromConfig(config: SdkConfig, apiClient: ChurnkeyApi, creds: SessionCredentials): void;
|
|
291
|
+
private isTokenMode;
|
|
292
|
+
private firstStep;
|
|
293
|
+
private surveyStep;
|
|
294
|
+
private buildInitialState;
|
|
295
|
+
private projectedNextStepId;
|
|
296
|
+
private transitionTo;
|
|
297
|
+
private setState;
|
|
298
|
+
private trackStepEnter;
|
|
299
|
+
private recordOfferPresented;
|
|
300
|
+
private markCurrentOfferAccepted;
|
|
301
|
+
private markCurrentOfferDeclined;
|
|
302
|
+
private notify;
|
|
303
|
+
private executeTokenAction;
|
|
304
|
+
private trackStepView;
|
|
305
|
+
private finalizeStepView;
|
|
306
|
+
private buildAcceptedOffer;
|
|
307
|
+
private enterSuccessStep;
|
|
308
|
+
private resolveSessionCustomer;
|
|
309
|
+
private buildBasePayload;
|
|
310
|
+
private recordAbort;
|
|
311
|
+
private recordOutcome;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
declare const BUILT_IN_STEP_TYPES: readonly string[];
|
|
315
|
+
declare const BUILT_IN_OFFER_TYPES: readonly string[];
|
|
316
|
+
declare function cn(...classes: (string | undefined | null | false)[]): string;
|
|
317
|
+
declare function appearanceToStyle(appearance?: Appearance): CSSProperties | undefined;
|
|
318
|
+
declare const defaultTitles: {
|
|
319
|
+
readonly survey: "Why are you cancelling?";
|
|
320
|
+
readonly feedback: "Any other feedback?";
|
|
321
|
+
readonly confirm: "Confirm cancellation";
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
export { AnalyticsClient, Appearance, BUILT_IN_OFFER_TYPES, BUILT_IN_STEP_TYPES, CancelFlowMachine, ChurnkeyApi, DirectCustomer, DirectSubscription, FlowConfig, FlowState, Mode, OfferDecision, PlanOption, ReasonConfig, ResolvedStep, type SdkConfig, type SdkConfirmStep, type SdkFeedbackStep, type SdkOffer, type SdkOfferCopy, type SdkOfferStep, type SdkReason, type SdkSettings, type SdkStep, type SdkSurveyStep, type SessionCredentials, type SessionPayload, appearanceToStyle, calculateDiscountedPrice, cn, decodeSessionToken, defaultTitles, formatPeriodEnd, formatPrice };
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { Q as PlanOption, s as DirectCustomer, u as DirectSubscription, G as Mode, z as FlowConfig, E as FlowState, T as ReasonConfig, W as ResolvedStep, K as OfferDecision, d as Appearance } from './step-graph-DX8yCqq1.js';
|
|
2
|
+
export { A as AcceptedOffer, e as AppearanceVariables, B as BackButtonProps, f as BuiltInOfferConfig, g as BuiltInStep, h as BuiltInStepType, C as CancelFlowProps, c as CloseButtonProps, i as ComponentOverrides, j as ConfirmClassNames, k as ConfirmStep, a as ConfirmStepProps, l as ContactOffer, m as CustomComponents, n as CustomOfferConfig, o as CustomOfferProps, p as CustomStepConfig, q as CustomStepProps, D as DirectAddress, r as DirectCoupon, t as DirectPrice, v as DirectSubscriptionItem, w as DiscountOffer, x as FeedbackClassNames, y as FeedbackStep, F as FeedbackStepProps, M as ModalProps, H as OfferClassNames, I as OfferConfig, J as OfferCopy, L as OfferStep, O as OfferStepProps, P as PauseOffer, N as PlanChangeOffer, R as ReasonButtonProps, U as RebateOffer, V as RedirectOffer, X as Step, Y as StructuralClassNames, Z as SubscriptionStatus, _ as SuccessClassNames, $ as SuccessStep, S as SuccessStepProps, a0 as SurveyClassNames, a1 as SurveyStep, b as SurveyStepProps, a2 as TrialExtensionOffer } from './step-graph-DX8yCqq1.js';
|
|
3
|
+
import { CSSProperties } from 'react';
|
|
4
|
+
|
|
5
|
+
interface SdkConfig {
|
|
6
|
+
blueprintId: string;
|
|
7
|
+
steps: SdkStep[];
|
|
8
|
+
customer: DirectCustomer;
|
|
9
|
+
subscriptions: DirectSubscription[];
|
|
10
|
+
settings: SdkSettings;
|
|
11
|
+
/** Bandit key used for auto-optimization, if it ran. */
|
|
12
|
+
autoOptimizationKey?: string;
|
|
13
|
+
}
|
|
14
|
+
interface SdkSettings {
|
|
15
|
+
clickToCancelEnabled: boolean;
|
|
16
|
+
strictFTCComplianceEnabled: boolean;
|
|
17
|
+
discountCooldown?: number;
|
|
18
|
+
pauseCooldown?: number;
|
|
19
|
+
}
|
|
20
|
+
type SdkStep = SdkSurveyStep | SdkOfferStep | SdkFeedbackStep | SdkConfirmStep;
|
|
21
|
+
interface SdkStepBase {
|
|
22
|
+
guid: string;
|
|
23
|
+
title?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
}
|
|
26
|
+
interface SdkSurveyStep extends SdkStepBase {
|
|
27
|
+
type: 'survey';
|
|
28
|
+
reasons: SdkReason[];
|
|
29
|
+
}
|
|
30
|
+
interface SdkOfferStep extends SdkStepBase {
|
|
31
|
+
type: 'offer';
|
|
32
|
+
offer: SdkOffer;
|
|
33
|
+
}
|
|
34
|
+
interface SdkFeedbackStep extends SdkStepBase {
|
|
35
|
+
type: 'feedback';
|
|
36
|
+
placeholder?: string;
|
|
37
|
+
required?: boolean;
|
|
38
|
+
minLength?: number;
|
|
39
|
+
}
|
|
40
|
+
interface SdkConfirmStep extends SdkStepBase {
|
|
41
|
+
type: 'confirm';
|
|
42
|
+
}
|
|
43
|
+
interface SdkReason {
|
|
44
|
+
id: string;
|
|
45
|
+
label: string;
|
|
46
|
+
freeform?: boolean;
|
|
47
|
+
offer?: SdkOffer;
|
|
48
|
+
}
|
|
49
|
+
type SdkOffer = SdkDiscountOffer | SdkPauseOffer | SdkPlanChangeOffer | SdkTrialExtensionOffer | SdkRedirectOffer | SdkContactOffer | SdkRebateOffer;
|
|
50
|
+
interface SdkOfferBase {
|
|
51
|
+
/** Per-offer guid — used for analytics joins between presented and accepted offers. */
|
|
52
|
+
decisionId?: string;
|
|
53
|
+
copy: SdkOfferCopy;
|
|
54
|
+
}
|
|
55
|
+
interface SdkDiscountOffer extends SdkOfferBase {
|
|
56
|
+
type: 'discount';
|
|
57
|
+
couponId?: string;
|
|
58
|
+
percentOff?: number;
|
|
59
|
+
/** Smallest currency unit (cents for USD, etc.). */
|
|
60
|
+
amountOff?: number;
|
|
61
|
+
currency?: string;
|
|
62
|
+
durationInMonths?: number;
|
|
63
|
+
}
|
|
64
|
+
interface SdkPauseOffer extends SdkOfferBase {
|
|
65
|
+
type: 'pause';
|
|
66
|
+
months: number;
|
|
67
|
+
interval: 'month' | 'week';
|
|
68
|
+
datePicker?: boolean;
|
|
69
|
+
}
|
|
70
|
+
interface SdkPlanChangeOffer extends SdkOfferBase {
|
|
71
|
+
type: 'plan_change';
|
|
72
|
+
plans: PlanOption[];
|
|
73
|
+
}
|
|
74
|
+
interface SdkTrialExtensionOffer extends SdkOfferBase {
|
|
75
|
+
type: 'trial_extension';
|
|
76
|
+
days: number;
|
|
77
|
+
}
|
|
78
|
+
interface SdkRedirectOffer extends SdkOfferBase {
|
|
79
|
+
type: 'redirect';
|
|
80
|
+
url: string;
|
|
81
|
+
label?: string;
|
|
82
|
+
}
|
|
83
|
+
interface SdkContactOffer extends SdkOfferBase {
|
|
84
|
+
type: 'contact';
|
|
85
|
+
url?: string;
|
|
86
|
+
label?: string;
|
|
87
|
+
}
|
|
88
|
+
interface SdkRebateOffer extends SdkOfferBase {
|
|
89
|
+
type: 'rebate';
|
|
90
|
+
/** The rebate amount (pre-tax). The card is refunded this plus any tax charged on it. */
|
|
91
|
+
amountMinor: number;
|
|
92
|
+
currency: string;
|
|
93
|
+
/** Gross amount paid on the target invoice — the "you paid" row. */
|
|
94
|
+
amountPaidMinor: number;
|
|
95
|
+
/** amountPaidMinor minus the full refund (rebate plus its tax) — the "your net" row. */
|
|
96
|
+
netAfterRebateMinor: number;
|
|
97
|
+
paymentMethodBrand?: string;
|
|
98
|
+
paymentMethodLast4?: string;
|
|
99
|
+
}
|
|
100
|
+
interface SdkOfferCopy {
|
|
101
|
+
headline: string;
|
|
102
|
+
body: string;
|
|
103
|
+
cta: string;
|
|
104
|
+
declineCta: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface SessionCredentials {
|
|
108
|
+
appId: string;
|
|
109
|
+
customerId: string;
|
|
110
|
+
subscriptionId?: string;
|
|
111
|
+
authHash: string;
|
|
112
|
+
mode: Mode;
|
|
113
|
+
issuedAt: number;
|
|
114
|
+
}
|
|
115
|
+
/** Decode a session token created by `@churnkey/node`. */
|
|
116
|
+
declare function decodeSessionToken(token: string): SessionCredentials;
|
|
117
|
+
|
|
118
|
+
type ApiStepType = 'OFFER' | 'SURVEY' | 'CONFIRM' | 'FREEFORM' | 'CUSTOM';
|
|
119
|
+
type ApiOfferType = 'DISCOUNT' | 'PAUSE' | 'PLAN_CHANGE' | 'TRIAL_EXTENSION' | 'CONTACT' | 'REDIRECT' | 'REBATE' | 'CUSTOM';
|
|
120
|
+
type ApiPauseInterval = 'MONTH' | 'WEEK';
|
|
121
|
+
type ApiCouponType = 'PERCENT' | 'AMOUNT';
|
|
122
|
+
type ApiBillingInterval = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR';
|
|
123
|
+
type ApiMode = 'LIVE' | 'TEST' | 'SANDBOX';
|
|
124
|
+
interface StepViewed {
|
|
125
|
+
stepType: ApiStepType;
|
|
126
|
+
customStepType?: string;
|
|
127
|
+
guid?: string;
|
|
128
|
+
numChoices?: number;
|
|
129
|
+
start: string;
|
|
130
|
+
end?: string;
|
|
131
|
+
duration?: number;
|
|
132
|
+
}
|
|
133
|
+
interface PresentedOffer {
|
|
134
|
+
guid?: string;
|
|
135
|
+
offerType?: ApiOfferType;
|
|
136
|
+
customOfferType?: string;
|
|
137
|
+
accepted: boolean;
|
|
138
|
+
presentedAt: string;
|
|
139
|
+
acceptedAt?: string;
|
|
140
|
+
declinedAt?: string;
|
|
141
|
+
[key: string]: unknown;
|
|
142
|
+
}
|
|
143
|
+
interface AcceptedOfferPayload {
|
|
144
|
+
guid?: string;
|
|
145
|
+
offerType: ApiOfferType;
|
|
146
|
+
customOfferType?: string;
|
|
147
|
+
customOfferResult?: Record<string, unknown>;
|
|
148
|
+
couponId?: string;
|
|
149
|
+
couponType?: ApiCouponType;
|
|
150
|
+
couponAmount?: number;
|
|
151
|
+
couponDuration?: number;
|
|
152
|
+
pauseDuration?: number;
|
|
153
|
+
pauseInterval?: ApiPauseInterval;
|
|
154
|
+
newPlanId?: string;
|
|
155
|
+
newPlanPrice?: number;
|
|
156
|
+
trialExtensionDays?: number;
|
|
157
|
+
redirectUrl?: string;
|
|
158
|
+
rebateAmount?: number;
|
|
159
|
+
}
|
|
160
|
+
interface SessionCustomer {
|
|
161
|
+
id: string;
|
|
162
|
+
email?: string;
|
|
163
|
+
subscriptionId?: string;
|
|
164
|
+
planId?: string;
|
|
165
|
+
planPrice?: number;
|
|
166
|
+
currency?: string;
|
|
167
|
+
billingInterval?: ApiBillingInterval;
|
|
168
|
+
created?: string;
|
|
169
|
+
onTrial?: boolean;
|
|
170
|
+
customAttributes?: Record<string, unknown>;
|
|
171
|
+
}
|
|
172
|
+
interface SessionPayload {
|
|
173
|
+
blueprintId?: string;
|
|
174
|
+
surveyId?: string;
|
|
175
|
+
customer?: SessionCustomer;
|
|
176
|
+
canceled?: boolean;
|
|
177
|
+
aborted?: boolean;
|
|
178
|
+
surveyChoiceId?: string;
|
|
179
|
+
surveyChoiceValue?: string;
|
|
180
|
+
/** Free-text from a `freeform: true` reason. The reason's static `label` still travels on `surveyChoiceValue`. */
|
|
181
|
+
followupResponse?: string;
|
|
182
|
+
feedback?: string;
|
|
183
|
+
acceptedOffer?: AcceptedOfferPayload;
|
|
184
|
+
presentedOffers?: PresentedOffer[];
|
|
185
|
+
stepsViewed?: StepViewed[];
|
|
186
|
+
customStepResults?: Record<string, unknown>;
|
|
187
|
+
mode: ApiMode;
|
|
188
|
+
provider?: string;
|
|
189
|
+
embedVersion?: string;
|
|
190
|
+
clickToCancelEnabled?: boolean;
|
|
191
|
+
strictFTCComplianceEnabled?: boolean;
|
|
192
|
+
usedClickToCancel?: boolean;
|
|
193
|
+
autoOptimizationUsed?: boolean;
|
|
194
|
+
autoOptimizationKey?: string;
|
|
195
|
+
discountCooldown?: number;
|
|
196
|
+
pauseCooldown?: number;
|
|
197
|
+
discountCooldownApplied?: boolean;
|
|
198
|
+
pauseCooldownApplied?: boolean;
|
|
199
|
+
}
|
|
200
|
+
declare class ChurnkeyApi {
|
|
201
|
+
private creds;
|
|
202
|
+
private baseUrl;
|
|
203
|
+
constructor(creds: SessionCredentials, baseUrl?: string);
|
|
204
|
+
private get headers();
|
|
205
|
+
private orgUrl;
|
|
206
|
+
private request;
|
|
207
|
+
fetchConfig(customAttributes?: Record<string, unknown>): Promise<SdkConfig>;
|
|
208
|
+
applyDiscount(couponId: string, blueprintId?: string): Promise<void>;
|
|
209
|
+
pause(params: {
|
|
210
|
+
duration: number;
|
|
211
|
+
interval: string;
|
|
212
|
+
}): Promise<void>;
|
|
213
|
+
cancelSubscription(): Promise<void>;
|
|
214
|
+
changePlan(planId: string): Promise<void>;
|
|
215
|
+
extendTrial(days: number, blueprintId?: string): Promise<void>;
|
|
216
|
+
applyRebate(blueprintId?: string, offerGuid?: string): Promise<void>;
|
|
217
|
+
createSession(payload: SessionPayload): Promise<void>;
|
|
218
|
+
}
|
|
219
|
+
declare class AnalyticsClient {
|
|
220
|
+
private appId;
|
|
221
|
+
private baseUrl;
|
|
222
|
+
constructor(appId: string, baseUrl?: string);
|
|
223
|
+
createSession(payload: SessionPayload): Promise<void>;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Format an amount already in the major unit. Uses `narrowSymbol` so output
|
|
228
|
+
* reads "$29" rather than "US$29", and trims trailing zero fractions so
|
|
229
|
+
* whole amounts render compactly.
|
|
230
|
+
*/
|
|
231
|
+
declare function formatPrice(amount: number, currency?: string, locale?: string): string;
|
|
232
|
+
declare function calculateDiscountedPrice(originalPrice: number, percentOff: number): number;
|
|
233
|
+
/**
|
|
234
|
+
* Long-form access period end ("June 14, 2026") for the first subscription's
|
|
235
|
+
* current period. Returns null for canceled subscriptions, missing periods,
|
|
236
|
+
* and unparseable dates so Confirm can drop the "access continues until"
|
|
237
|
+
* notice cleanly instead of rendering "Invalid Date".
|
|
238
|
+
*/
|
|
239
|
+
declare function formatPeriodEnd(subscriptions: DirectSubscription[] | null | undefined, locale?: string): string | null;
|
|
240
|
+
|
|
241
|
+
declare class CancelFlowMachine {
|
|
242
|
+
private state;
|
|
243
|
+
private cachedSnapshot;
|
|
244
|
+
private callbacks;
|
|
245
|
+
private graph;
|
|
246
|
+
private listeners;
|
|
247
|
+
private apiClient;
|
|
248
|
+
private analyticsClient;
|
|
249
|
+
private directCustomer;
|
|
250
|
+
private directSubscriptions;
|
|
251
|
+
private customerAttributes;
|
|
252
|
+
private creds;
|
|
253
|
+
private config;
|
|
254
|
+
private blueprintId;
|
|
255
|
+
private localSteps;
|
|
256
|
+
private stepsViewed;
|
|
257
|
+
private presentedOffers;
|
|
258
|
+
private customStepResults;
|
|
259
|
+
private configMode;
|
|
260
|
+
private stepEnteredAt;
|
|
261
|
+
private aborted;
|
|
262
|
+
private history;
|
|
263
|
+
constructor(config: FlowConfig);
|
|
264
|
+
subscribe: (listener: () => void) => (() => void);
|
|
265
|
+
getSnapshot: () => FlowState;
|
|
266
|
+
get reasons(): ReasonConfig[];
|
|
267
|
+
get currentStep(): ResolvedStep | undefined;
|
|
268
|
+
/** The offer on the current step, or null. Always derived — no separate slot to drift. */
|
|
269
|
+
get currentOffer(): OfferDecision | null;
|
|
270
|
+
/** Whether `back()` would move anywhere — false on the first step and on success. */
|
|
271
|
+
get canGoBack(): boolean;
|
|
272
|
+
/**
|
|
273
|
+
* First step of a given type. Fine for the common "one step per type" case;
|
|
274
|
+
* flows with multiple of a type should key on currentStepId instead.
|
|
275
|
+
*/
|
|
276
|
+
getStepConfig(stepType: string): ResolvedStep | undefined;
|
|
277
|
+
/** Progress indicator index. Synthetic offers share their survey's slot. */
|
|
278
|
+
get stepIndex(): number;
|
|
279
|
+
get totalSteps(): number;
|
|
280
|
+
selectReason: (id: string) => void;
|
|
281
|
+
setFollowupResponse: (text: string) => void;
|
|
282
|
+
next: (result?: Record<string, unknown>) => void;
|
|
283
|
+
back: () => void;
|
|
284
|
+
accept: (result?: Record<string, unknown>) => Promise<void>;
|
|
285
|
+
decline: () => void;
|
|
286
|
+
setFeedback: (text: string) => void;
|
|
287
|
+
cancel: () => Promise<void>;
|
|
288
|
+
close: () => void;
|
|
289
|
+
destroy(): void;
|
|
290
|
+
initializeFromConfig(config: SdkConfig, apiClient: ChurnkeyApi, creds: SessionCredentials): void;
|
|
291
|
+
private isTokenMode;
|
|
292
|
+
private firstStep;
|
|
293
|
+
private surveyStep;
|
|
294
|
+
private buildInitialState;
|
|
295
|
+
private projectedNextStepId;
|
|
296
|
+
private transitionTo;
|
|
297
|
+
private setState;
|
|
298
|
+
private trackStepEnter;
|
|
299
|
+
private recordOfferPresented;
|
|
300
|
+
private markCurrentOfferAccepted;
|
|
301
|
+
private markCurrentOfferDeclined;
|
|
302
|
+
private notify;
|
|
303
|
+
private executeTokenAction;
|
|
304
|
+
private trackStepView;
|
|
305
|
+
private finalizeStepView;
|
|
306
|
+
private buildAcceptedOffer;
|
|
307
|
+
private enterSuccessStep;
|
|
308
|
+
private resolveSessionCustomer;
|
|
309
|
+
private buildBasePayload;
|
|
310
|
+
private recordAbort;
|
|
311
|
+
private recordOutcome;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
declare const BUILT_IN_STEP_TYPES: readonly string[];
|
|
315
|
+
declare const BUILT_IN_OFFER_TYPES: readonly string[];
|
|
316
|
+
declare function cn(...classes: (string | undefined | null | false)[]): string;
|
|
317
|
+
declare function appearanceToStyle(appearance?: Appearance): CSSProperties | undefined;
|
|
318
|
+
declare const defaultTitles: {
|
|
319
|
+
readonly survey: "Why are you cancelling?";
|
|
320
|
+
readonly feedback: "Any other feedback?";
|
|
321
|
+
readonly confirm: "Confirm cancellation";
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
export { AnalyticsClient, Appearance, BUILT_IN_OFFER_TYPES, BUILT_IN_STEP_TYPES, CancelFlowMachine, ChurnkeyApi, DirectCustomer, DirectSubscription, FlowConfig, FlowState, Mode, OfferDecision, PlanOption, ReasonConfig, ResolvedStep, type SdkConfig, type SdkConfirmStep, type SdkFeedbackStep, type SdkOffer, type SdkOfferCopy, type SdkOfferStep, type SdkReason, type SdkSettings, type SdkStep, type SdkSurveyStep, type SessionCredentials, type SessionPayload, appearanceToStyle, calculateDiscountedPrice, cn, decodeSessionToken, defaultTitles, formatPeriodEnd, formatPrice };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z as FlowConfig, T as ReasonConfig, W as ResolvedStep, K as OfferDecision, s as DirectCustomer, u as DirectSubscription } from './step-graph-DX8yCqq1.cjs';
|
|
2
|
+
import 'react';
|
|
3
|
+
|
|
4
|
+
declare function useCancelFlow(config: FlowConfig): {
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
loadError: Error | null;
|
|
7
|
+
retry: () => void;
|
|
8
|
+
reasons: ReasonConfig[];
|
|
9
|
+
currentStep: ResolvedStep | undefined;
|
|
10
|
+
currentOffer: OfferDecision | null;
|
|
11
|
+
stepIndex: number;
|
|
12
|
+
totalSteps: number;
|
|
13
|
+
selectReason: (id: string) => void;
|
|
14
|
+
setFollowupResponse: (text: string) => void;
|
|
15
|
+
setFeedback: (text: string) => void;
|
|
16
|
+
accept: (result?: Record<string, unknown>) => Promise<void>;
|
|
17
|
+
decline: () => void;
|
|
18
|
+
cancel: () => Promise<void>;
|
|
19
|
+
next: (result?: Record<string, unknown>) => void;
|
|
20
|
+
back: () => void;
|
|
21
|
+
close: () => void;
|
|
22
|
+
step: string;
|
|
23
|
+
currentStepId: string;
|
|
24
|
+
selectedReason: string | null;
|
|
25
|
+
followupResponse: string;
|
|
26
|
+
feedback: string;
|
|
27
|
+
outcome: "saved" | "cancelled" | null;
|
|
28
|
+
isProcessing: boolean;
|
|
29
|
+
error: Error | null;
|
|
30
|
+
customer: DirectCustomer | null;
|
|
31
|
+
subscriptions: DirectSubscription[];
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { useCancelFlow };
|