@churnkey/react 0.3.0 → 0.4.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.
Files changed (34) hide show
  1. package/dist/{chunk-42SJA62X.cjs → chunk-4BMB42WI.cjs} +6 -6
  2. package/dist/{chunk-42SJA62X.cjs.map → chunk-4BMB42WI.cjs.map} +1 -1
  3. package/dist/{chunk-LVUDBCQ2.cjs → chunk-BDBZ5OS3.cjs} +4 -3
  4. package/dist/chunk-BDBZ5OS3.cjs.map +1 -0
  5. package/dist/{chunk-YZERGV7F.js → chunk-F4ESJBOS.js} +3 -3
  6. package/dist/{chunk-YZERGV7F.js.map → chunk-F4ESJBOS.js.map} +1 -1
  7. package/dist/{chunk-SQ35G4LA.js → chunk-G57YLYM5.js} +4 -3
  8. package/dist/chunk-G57YLYM5.js.map +1 -0
  9. package/dist/{chunk-UNSSI6KX.js → chunk-QYNW3HF3.js} +35 -5
  10. package/dist/chunk-QYNW3HF3.js.map +1 -0
  11. package/dist/{chunk-2VQNWZWO.cjs → chunk-SNTKIKHU.cjs} +35 -5
  12. package/dist/chunk-SNTKIKHU.cjs.map +1 -0
  13. package/dist/core.cjs +14 -14
  14. package/dist/core.d.cts +18 -4
  15. package/dist/core.d.ts +18 -4
  16. package/dist/core.js +2 -2
  17. package/dist/headless.cjs +3 -3
  18. package/dist/headless.d.cts +1 -1
  19. package/dist/headless.d.ts +1 -1
  20. package/dist/headless.js +2 -2
  21. package/dist/index.cjs +151 -99
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +5 -3
  24. package/dist/index.d.ts +5 -3
  25. package/dist/index.js +57 -6
  26. package/dist/index.js.map +1 -1
  27. package/dist/{step-graph-ChlSCUGk.d.cts → step-graph-DKvaV3Dg.d.cts} +17 -2
  28. package/dist/{step-graph-ChlSCUGk.d.ts → step-graph-DKvaV3Dg.d.ts} +17 -2
  29. package/dist/styles.css +45 -8
  30. package/package.json +1 -1
  31. package/dist/chunk-2VQNWZWO.cjs.map +0 -1
  32. package/dist/chunk-LVUDBCQ2.cjs.map +0 -1
  33. package/dist/chunk-SQ35G4LA.js.map +0 -1
  34. package/dist/chunk-UNSSI6KX.js.map +0 -1
@@ -65,6 +65,9 @@ var ChurnkeyApi = class {
65
65
  async extendTrial(days, blueprintId) {
66
66
  await this.request(this.orgUrl("cancel-flow/actions/extend-trial"), { days, blueprintId });
67
67
  }
68
+ async applyRebate(blueprintId, offerGuid) {
69
+ await this.request(this.orgUrl("cancel-flow/actions/rebate"), { blueprintId, offerGuid });
70
+ }
68
71
  async createSession(payload) {
69
72
  await this.request(`${this.baseUrl}/api/sessions/sdk`, payload);
70
73
  }
@@ -412,6 +415,16 @@ function transformOfferConfig(o) {
412
415
  url: o.url,
413
416
  label: o.label
414
417
  };
418
+ case "rebate":
419
+ return {
420
+ type: "rebate",
421
+ amountMinor: o.amountMinor,
422
+ currency: o.currency,
423
+ amountPaidMinor: o.amountPaidMinor,
424
+ netAfterRebateMinor: o.netAfterRebateMinor,
425
+ paymentMethodBrand: o.paymentMethodBrand,
426
+ paymentMethodLast4: o.paymentMethodLast4
427
+ };
415
428
  }
416
429
  }
417
430
  function defaultOfferCopy(offer) {
@@ -459,6 +472,13 @@ function defaultOfferCopy(offer) {
459
472
  cta: o.label,
460
473
  declineCta: "No thanks"
461
474
  };
475
+ case "rebate":
476
+ return {
477
+ headline: "Get money back",
478
+ body: "Stay subscribed and we'll refund part of your most recent payment.",
479
+ cta: "Accept refund",
480
+ declineCta: "No thanks"
481
+ };
462
482
  default:
463
483
  return {
464
484
  headline: "Before you go...",
@@ -485,6 +505,8 @@ function handlerFor(offerType, cb) {
485
505
  return cb.handlePlanChange;
486
506
  case "trial_extension":
487
507
  return cb.handleTrialExtension;
508
+ case "rebate":
509
+ return cb.handleRebate;
488
510
  default:
489
511
  return void 0;
490
512
  }
@@ -499,6 +521,8 @@ function listenerFor(offerType, cb) {
499
521
  return cb.onPlanChange;
500
522
  case "trial_extension":
501
523
  return cb.onTrialExtension;
524
+ case "rebate":
525
+ return cb.onRebate;
502
526
  default:
503
527
  return void 0;
504
528
  }
@@ -525,7 +549,8 @@ var OFFER_TYPE_API_MAP = {
525
549
  plan_change: "PLAN_CHANGE",
526
550
  trial_extension: "TRIAL_EXTENSION",
527
551
  contact: "CONTACT",
528
- redirect: "REDIRECT"
552
+ redirect: "REDIRECT",
553
+ rebate: "REBATE"
529
554
  };
530
555
  function toApiStepType(step) {
531
556
  if (step === "success") return null;
@@ -605,6 +630,8 @@ function toAcceptedOfferPayload(rec, result) {
605
630
  return { ...base, trialExtensionDays: o.days };
606
631
  case "redirect":
607
632
  return { ...base, redirectUrl: o.url };
633
+ case "rebate":
634
+ return { ...base, rebateAmount: o.amountMinor };
608
635
  default:
609
636
  return base;
610
637
  }
@@ -735,7 +762,7 @@ var CancelFlowMachine = class {
735
762
  if (handler) {
736
763
  await handler(acceptedOffer, customer);
737
764
  } else if (this.isTokenMode()) {
738
- await this.executeTokenAction(acceptedOffer);
765
+ await this.executeTokenAction(acceptedOffer, offer.decisionId);
739
766
  }
740
767
  const listener = listenerFor(offer.type, this.callbacks);
741
768
  if (listener) await runListener(listener, acceptedOffer, customer);
@@ -889,7 +916,7 @@ var CancelFlowMachine = class {
889
916
  listener();
890
917
  }
891
918
  }
892
- async executeTokenAction(offer) {
919
+ async executeTokenAction(offer, decisionId) {
893
920
  if (!this.apiClient) return;
894
921
  const o = offer;
895
922
  switch (o.type) {
@@ -907,6 +934,9 @@ var CancelFlowMachine = class {
907
934
  case "trial_extension":
908
935
  await this.apiClient.extendTrial(o.days, this.blueprintId ?? void 0);
909
936
  break;
937
+ case "rebate":
938
+ await this.apiClient.applyRebate(this.blueprintId ?? void 0, decisionId);
939
+ break;
910
940
  }
911
941
  }
912
942
  trackStepView(stepType, guid, numChoices) {
@@ -1067,5 +1097,5 @@ exports.AnalyticsClient = AnalyticsClient;
1067
1097
  exports.CancelFlowMachine = CancelFlowMachine;
1068
1098
  exports.ChurnkeyApi = ChurnkeyApi;
1069
1099
  exports.decodeSessionToken = decodeSessionToken;
1070
- //# sourceMappingURL=chunk-2VQNWZWO.cjs.map
1071
- //# sourceMappingURL=chunk-2VQNWZWO.cjs.map
1100
+ //# sourceMappingURL=chunk-SNTKIKHU.cjs.map
1101
+ //# sourceMappingURL=chunk-SNTKIKHU.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/api.ts","../src/core/merge-fields.ts","../src/core/step-graph.ts","../src/core/transform.ts","../src/core/machine.ts","../src/core/token.ts"],"names":["defaultOfferCopy"],"mappings":"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","file":"chunk-SNTKIKHU.cjs","sourcesContent":["import type { SdkConfig } from './api-types'\nimport type { SessionCredentials } from './token'\nimport type { DirectCustomer, DirectSubscription } from './types'\n\nconst DEFAULT_BASE_URL = 'https://api.churnkey.co/v1'\n\n// Wire enums accepted by the API. Literal unions so payload builders fail\n// at compile time if they emit a value outside the accepted set.\nexport type ApiStepType = 'OFFER' | 'SURVEY' | 'CONFIRM' | 'FREEFORM' | 'CUSTOM'\nexport type ApiOfferType =\n | 'DISCOUNT'\n | 'PAUSE'\n | 'PLAN_CHANGE'\n | 'TRIAL_EXTENSION'\n | 'CONTACT'\n | 'REDIRECT'\n | 'REBATE'\n | 'CUSTOM'\nexport type ApiPauseInterval = 'MONTH' | 'WEEK'\nexport type ApiCouponType = 'PERCENT' | 'AMOUNT'\nexport type ApiBillingInterval = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR'\nexport type ApiMode = 'LIVE' | 'TEST'\n\nexport interface StepViewed {\n stepType: ApiStepType\n // Populated iff stepType === 'CUSTOM' — holds the SDK step name.\n customStepType?: string\n guid?: string\n numChoices?: number\n start: string\n end?: string\n duration?: number\n}\n\nexport interface PresentedOffer {\n guid?: string\n offerType?: ApiOfferType\n // Populated iff offerType === 'CUSTOM' — holds the SDK offer name.\n customOfferType?: string\n accepted: boolean\n presentedAt: string\n acceptedAt?: string\n declinedAt?: string\n [key: string]: unknown\n}\n\nexport interface AcceptedOfferPayload {\n guid?: string\n offerType: ApiOfferType\n // Populated iff offerType === 'CUSTOM' — holds the SDK offer name.\n customOfferType?: string\n // Populated iff offerType === 'CUSTOM' — the result arg passed to\n // `onAccept(result)` from the custom offer component.\n customOfferResult?: Record<string, unknown>\n couponId?: string\n couponType?: ApiCouponType\n couponAmount?: number\n couponDuration?: number\n pauseDuration?: number\n pauseInterval?: ApiPauseInterval\n newPlanId?: string\n newPlanPrice?: number\n trialExtensionDays?: number\n redirectUrl?: string\n rebateAmount?: number\n}\n\nexport interface SessionCustomer {\n id: string\n email?: string\n subscriptionId?: string\n planId?: string\n planPrice?: number\n currency?: string\n billingInterval?: ApiBillingInterval\n created?: string\n onTrial?: boolean\n customAttributes?: Record<string, unknown>\n}\n\nexport interface SessionPayload {\n blueprintId?: string\n surveyId?: string\n customer?: SessionCustomer\n canceled?: boolean\n aborted?: boolean\n surveyChoiceId?: string\n surveyChoiceValue?: string\n /** Free-text from a `freeform: true` reason. The reason's static `label` still travels on `surveyChoiceValue`. */\n followupResponse?: string\n feedback?: string\n acceptedOffer?: AcceptedOfferPayload\n presentedOffers?: PresentedOffer[]\n stepsViewed?: StepViewed[]\n customStepResults?: Record<string, unknown>\n mode: ApiMode\n provider?: string\n embedVersion?: string\n // Token-mode session-record fields. Populated automatically when the SDK\n // is configured with a session token; ignored in local/analytics mode.\n clickToCancelEnabled?: boolean\n strictFTCComplianceEnabled?: boolean\n usedClickToCancel?: boolean\n autoOptimizationUsed?: boolean\n autoOptimizationKey?: string\n discountCooldown?: number\n pauseCooldown?: number\n discountCooldownApplied?: boolean\n pauseCooldownApplied?: boolean\n}\n\nexport class ChurnkeyApi {\n private creds: SessionCredentials\n private baseUrl: string\n\n constructor(creds: SessionCredentials, baseUrl?: string) {\n this.creds = creds\n this.baseUrl = baseUrl ?? DEFAULT_BASE_URL\n }\n\n private get headers(): Record<string, string> {\n const h: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-ck-app': this.creds.appId,\n 'x-ck-customer': this.creds.customerId,\n 'x-ck-authorization': this.creds.authHash,\n 'x-ck-mode': this.creds.mode,\n }\n if (this.creds.subscriptionId) {\n h['x-ck-subscription'] = this.creds.subscriptionId\n }\n return h\n }\n\n private orgUrl(path: string): string {\n return `${this.baseUrl}/api/orgs/${this.creds.appId}/${path}`\n }\n\n // Action methods discard the response body, so don't parse JSON here —\n // a server returning an empty 201 would otherwise blow up res.json() and\n // surface as an error even though the action committed.\n private async request(url: string, body?: unknown): Promise<Response> {\n const res = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`Churnkey API error (${res.status}): ${text}`)\n }\n return res\n }\n\n async fetchConfig(): Promise<SdkConfig> {\n const res = await this.request(this.orgUrl('cancel-flow/config'))\n return (await res.json()) as SdkConfig\n }\n\n async applyDiscount(couponId: string, blueprintId?: string): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/discount'), {\n coupon: couponId,\n blueprintId,\n })\n }\n\n async pause(params: { duration: number; interval: string }): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/pause'), {\n duration: params.duration,\n interval: params.interval,\n })\n }\n\n async cancelSubscription(): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/cancel'), { cancelAtPeriodEnd: true })\n }\n\n async changePlan(planId: string): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/change-plan'), { planId })\n }\n\n async extendTrial(days: number, blueprintId?: string): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/extend-trial'), { days, blueprintId })\n }\n\n async applyRebate(blueprintId?: string, offerGuid?: string): Promise<void> {\n await this.request(this.orgUrl('cancel-flow/actions/rebate'), { blueprintId, offerGuid })\n }\n\n async createSession(payload: SessionPayload): Promise<void> {\n await this.request(`${this.baseUrl}/api/sessions/sdk`, payload)\n }\n}\n\nexport class AnalyticsClient {\n private appId: string\n private baseUrl: string\n\n constructor(appId: string, baseUrl?: string) {\n this.appId = appId\n this.baseUrl = baseUrl ?? DEFAULT_BASE_URL\n }\n\n // Fire-and-forget. Non-2xx responses are ignored — analytics failures\n // should never surface into the host app's flow.\n async createSession(payload: SessionPayload): Promise<void> {\n await fetch(`${this.baseUrl}/api/sessions/sdk`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-ck-app': this.appId,\n },\n body: JSON.stringify(payload),\n })\n }\n}\n\nfunction toIsoString(value: Date | string | undefined): string | undefined {\n if (value == null) return undefined\n return value instanceof Date ? value.toISOString() : String(value)\n}\n\nfunction toApiBillingInterval(interval: 'day' | 'week' | 'month' | 'year' | undefined): ApiBillingInterval | undefined {\n if (!interval) return undefined\n return interval.toUpperCase() as ApiBillingInterval\n}\n\nexport function directDataToSessionCustomer(\n customer: DirectCustomer,\n subscriptions?: DirectSubscription[],\n): SessionPayload['customer'] {\n const sub = subscriptions?.[0]\n const price = sub?.items[0]?.price\n\n return {\n id: customer.id,\n email: customer.email,\n subscriptionId: sub?.id,\n planId: price?.id,\n planPrice: price?.amount.value,\n currency: price?.amount.currency ?? customer.currency,\n billingInterval: toApiBillingInterval(price?.duration?.interval),\n created: toIsoString(sub?.start),\n onTrial: sub ? sub.status.name === 'trial' : undefined,\n customAttributes: customer.metadata,\n }\n}\n","// Merge field substitution for dashboard-authored copy. Placeholders look\n// like `{{CUSTOMER_NAME.FIRST|Jane}}` — field name, optional fallback after\n// the pipe. Copy can also arrive wrapped in `<merge-field>` tags (the\n// dashboard editor uses them for its own UI); browsers render unknown tags\n// as their text content, so the wrapper is transparent and only the inner\n// `{{…}}` needs substitution.\n\nimport type {\n DirectCustomer,\n FeedbackStep,\n OfferConfig,\n OfferDecision,\n OfferStep,\n ReasonConfig,\n Step,\n SurveyStep,\n} from './types'\n\nexport type MergeAttrs = Record<string, string>\n\nconst MERGE_FIELD_PATTERN = /{{([a-zA-Z0-9_.]+)\\|([^}]*)}}/g\n\n/**\n * Build the attribute map merge fields are resolved against. Sourced from\n * Direct.Customer fields: name (with `.FIRST`/`.LAST` variants), email, and\n * metadata. Values that aren't strings are coerced — dashboards emit merge\n * fields into HTML, and HTML only speaks strings.\n */\nexport function buildMergeAttrs(customer: DirectCustomer | null | undefined): MergeAttrs {\n if (!customer) return {}\n const attrs: MergeAttrs = {}\n\n // Build full name from Direct.Customer's separate first/last name fields.\n const first = customer.name\n const last = customer.lastName\n const fullName = [first, last].filter(Boolean).join(' ') || undefined\n if (fullName) attrs.CUSTOMER_NAME = fullName\n if (first) attrs['CUSTOMER_NAME.FIRST'] = first\n if (last) attrs['CUSTOMER_NAME.LAST'] = last\n\n if (customer.email) attrs.CUSTOMER_EMAIL = customer.email\n\n for (const [key, value] of Object.entries(customer.metadata ?? {})) {\n if (value != null) attrs[key] = String(value)\n }\n\n return attrs\n}\n\n/**\n * Replace `{{FIELD|fallback}}` placeholders in `text` with values from `attrs`.\n * Missing keys fall back to the `|…}}` segment (which may be empty). The\n * enclosing `<merge-field>` wrapper, if any, is left as-is — browsers ignore\n * unknown tags and render their children, so the visible output is correct.\n */\nexport function applyMergeFields(text: string, attrs: MergeAttrs): string {\n if (!text?.includes('{{')) return text\n return text.replace(MERGE_FIELD_PATTERN, (_match, field: string, fallback: string) => attrs[field] ?? fallback)\n}\n\n/**\n * Substitute merge fields across a Step[] tree. Called once at machine init\n * so the runtime carries already-resolved copy — components stay unaware of\n * merge fields entirely.\n */\nexport function applyMergeFieldsToSteps(steps: Step[], customer: DirectCustomer | null | undefined): Step[] {\n const attrs = buildMergeAttrs(customer)\n return steps.map((step) => mergeStep(step, attrs))\n}\n\nfunction mergeStep(step: Step, attrs: MergeAttrs): Step {\n // CustomStepConfig.type is `string`, so a literal-string switch doesn't\n // narrow it out of the union — each branch needs an explicit cast.\n switch (step.type) {\n case 'survey': {\n const s = step as SurveyStep\n return {\n ...s,\n title: maybeMerge(s.title, attrs),\n description: maybeMerge(s.description, attrs),\n reasons: s.reasons.map((r) => mergeReason(r, attrs)),\n }\n }\n case 'offer': {\n const s = step as OfferStep\n return {\n ...s,\n title: maybeMerge(s.title, attrs),\n description: maybeMerge(s.description, attrs),\n offer: s.offer ? mergeOffer(s.offer, attrs) : undefined,\n }\n }\n case 'feedback': {\n const s = step as FeedbackStep\n return {\n ...s,\n title: maybeMerge(s.title, attrs),\n description: maybeMerge(s.description, attrs),\n placeholder: maybeMerge(s.placeholder, attrs),\n }\n }\n case 'success':\n // savedTitle/cancelledTitle/etc. are picked at render time based on the\n // outcome; merge substitution can be added there if it's ever needed.\n return step\n default: {\n const s = step as { title?: string; description?: string }\n return { ...step, title: maybeMerge(s.title, attrs), description: maybeMerge(s.description, attrs) }\n }\n }\n}\n\nfunction mergeReason(r: ReasonConfig, attrs: MergeAttrs): ReasonConfig {\n return { ...r, label: applyMergeFields(r.label, attrs) }\n}\n\n// Standalone OfferSteps may arrive without copy (the step graph synthesizes\n// defaults later); merging copy is a no-op when there's nothing to merge.\nfunction mergeOffer(o: OfferConfig | OfferDecision, attrs: MergeAttrs): OfferConfig | OfferDecision {\n if (!('copy' in o)) return o\n return {\n ...o,\n copy: {\n headline: applyMergeFields(o.copy.headline, attrs),\n body: applyMergeFields(o.copy.body, attrs),\n cta: applyMergeFields(o.copy.cta, attrs),\n declineCta: applyMergeFields(o.copy.declineCta, attrs),\n },\n }\n}\n\nfunction maybeMerge(text: string | undefined, attrs: MergeAttrs): string | undefined {\n return text ? applyMergeFields(text, attrs) : text\n}\n","// Steps are a graph, not an array. Each step has a guid and two pointer\n// fields — defaultNextStep, defaultPreviousStep — set once at build and\n// never mutated. Survey steps additionally carry offersAttached, a\n// reasonId → synthetic-offer-step-guid map.\n//\n// Survey-choice offers are their own steps rather than a mutable slot, so\n// the current offer is always readable as stepMap[currentStepId].offer —\n// one source of truth for what's on screen.\n//\n// The graph is immutable after build. Local mode builds in the machine\n// constructor; token mode defers until the server config has loaded.\n\nimport type {\n ConfirmStep,\n CustomStepConfig,\n FeedbackStep,\n OfferConfig,\n OfferDecision,\n OfferStep,\n ReasonConfig,\n Step,\n SuccessStep,\n SurveyStep,\n} from './types'\n\nexport interface ResolvedStep {\n guid: string\n type: string\n defaultNextStep?: string\n defaultPreviousStep?: string\n title?: string\n description?: string\n\n // survey\n reasons?: ReasonConfig[]\n offersAttached?: Record<string, string>\n numChoices?: number\n\n // offer\n offer?: OfferDecision\n /** True if this step was synthesized from a survey choice. Used by stepIndex so synthetic offers share the survey's progress slot. */\n surveyOffer?: boolean\n\n // feedback\n placeholder?: string\n required?: boolean\n minLength?: number\n\n // confirm\n losses?: string[]\n lossesLabel?: string\n\n // success\n savedTitle?: string\n savedDescription?: string\n cancelledTitle?: string\n cancelledDescription?: string\n\n // custom\n data?: Record<string, unknown>\n\n classNames?: unknown\n}\n\nexport interface StepGraph {\n stepMap: Record<string, ResolvedStep>\n /** Entry point. */\n firstStepId: string\n /** Developer-declared steps in declaration order. Synthetic offer steps are NOT included — they live in stepMap only. Drives progress UI. */\n orderedStepIds: string[]\n /** Cached for O(1) lookup. Undefined if the flow has no survey step. */\n surveyStepId?: string\n}\n\nconst EMPTY_GRAPH: StepGraph = { stepMap: {}, firstStepId: '', orderedStepIds: [] }\n\nexport function buildStepGraph(\n steps: Step[],\n defaultOfferCopy: (offer: OfferConfig) => OfferDecision['copy'],\n): StepGraph {\n if (steps.length === 0) return EMPTY_GRAPH\n\n const resolved = steps.map((step, i) => normalizeStep(step, i, defaultOfferCopy))\n linkNeighbors(resolved)\n\n const stepMap: Record<string, ResolvedStep> = {}\n for (const step of resolved) stepMap[step.guid] = step\n\n // Only the first survey in the declared order gets its choice offers wired.\n // Multiple surveys per flow is legal but unusual; the second+ behave as\n // plain steps. If this becomes a real pattern, wire them all.\n const surveyStep = resolved.find((s) => s.type === 'survey')\n if (surveyStep?.reasons) {\n surveyStep.offersAttached = {}\n for (const reason of surveyStep.reasons) {\n if (!reason.offer) continue\n const offerGuid = `${surveyStep.guid}:offer:${reason.id}`\n stepMap[offerGuid] = {\n guid: offerGuid,\n type: 'offer',\n surveyOffer: true,\n offer: toDecision(reason.offer, defaultOfferCopy),\n // Decline/next from the synthetic offer skips the survey entirely;\n // back returns to the survey so the user can pick a different reason.\n defaultNextStep: surveyStep.defaultNextStep,\n defaultPreviousStep: surveyStep.guid,\n }\n surveyStep.offersAttached[reason.id] = offerGuid\n }\n }\n\n return {\n stepMap,\n firstStepId: resolved[0].guid,\n orderedStepIds: resolved.map((s) => s.guid),\n surveyStepId: surveyStep?.guid,\n }\n}\n\nfunction normalizeStep(\n step: Step,\n index: number,\n defaultOfferCopy: (offer: OfferConfig) => OfferDecision['copy'],\n): ResolvedStep {\n // Prefer the caller-provided guid; otherwise generate a stable slug. Stable\n // ids matter for analytics and React keys.\n const guid = (step as { guid?: string }).guid ?? `step-${index}-${step.type}`\n const base: ResolvedStep = { guid, type: step.type }\n\n switch (step.type) {\n case 'survey': {\n const s = step as SurveyStep\n return {\n ...base,\n title: s.title,\n description: s.description,\n reasons: s.reasons,\n numChoices: s.reasons.length,\n classNames: s.classNames,\n }\n }\n case 'offer': {\n const s = step as OfferStep\n return {\n ...base,\n title: s.title,\n description: s.description,\n // Standalone offers may arrive without `copy` — toDecision fills it\n // in from defaultOfferCopy. Token-mode offers already carry copy\n // from the server, so toDecision passes them through unchanged.\n offer: s.offer ? toDecision(s.offer, defaultOfferCopy) : undefined,\n classNames: s.classNames,\n }\n }\n case 'feedback': {\n const s = step as FeedbackStep\n return {\n ...base,\n title: s.title,\n description: s.description,\n placeholder: s.placeholder,\n required: s.required,\n minLength: s.minLength,\n classNames: s.classNames,\n }\n }\n case 'confirm': {\n const s = step as ConfirmStep\n return {\n ...base,\n title: s.title,\n description: s.description,\n losses: s.losses,\n lossesLabel: s.lossesLabel,\n classNames: s.classNames,\n }\n }\n case 'success': {\n const s = step as SuccessStep\n return {\n ...base,\n savedTitle: s.savedTitle,\n savedDescription: s.savedDescription,\n cancelledTitle: s.cancelledTitle,\n cancelledDescription: s.cancelledDescription,\n classNames: s.classNames,\n }\n }\n default: {\n const s = step as CustomStepConfig\n return {\n ...base,\n title: s.title,\n description: s.description,\n data: s.data,\n }\n }\n }\n}\n\nfunction linkNeighbors(steps: ResolvedStep[]): void {\n for (let i = 0; i < steps.length; i++) {\n if (i < steps.length - 1) steps[i].defaultNextStep = steps[i + 1].guid\n if (i > 0) steps[i].defaultPreviousStep = steps[i - 1].guid\n }\n}\n\nfunction toDecision(offer: OfferConfig, defaultCopy: (o: OfferConfig) => OfferDecision['copy']): OfferDecision {\n return 'copy' in offer ? (offer as OfferDecision) : { ...offer, copy: defaultCopy(offer) }\n}\n","// Translate the SdkConfig response (token mode) into the runtime Step shape\n// the rest of the SDK works with. Token-mode flows arrive with offers fully\n// resolved — coupon ids hydrated to amounts and durations, plan ids inlined\n// as DirectPrice[], so this layer is a pure shape projection.\n\nimport type { SdkConfig, SdkDiscountOffer, SdkOffer, SdkReason, SdkStep } from './api-types'\nimport type { BuiltInOfferConfig, OfferConfig, OfferCopy, OfferDecision, ReasonConfig, Step } from './types'\n\nexport interface TransformResult {\n steps: Step[]\n blueprintId: string\n metadata: {\n autoOptimizationKey?: string\n }\n}\n\nexport function transformSdkConfig(config: SdkConfig): TransformResult {\n return {\n steps: config.steps.map(transformStep),\n blueprintId: config.blueprintId,\n metadata: {\n autoOptimizationKey: config.autoOptimizationKey,\n },\n }\n}\n\nfunction transformStep(step: SdkStep): Step {\n switch (step.type) {\n case 'survey':\n return {\n type: 'survey',\n guid: step.guid,\n title: step.title,\n description: step.description,\n reasons: step.reasons.map(transformReason),\n }\n case 'offer':\n return {\n type: 'offer',\n guid: step.guid,\n title: step.title,\n description: step.description,\n offer: transformOfferDecision(step.offer),\n }\n case 'feedback':\n return {\n type: 'feedback',\n guid: step.guid,\n title: step.title,\n description: step.description,\n placeholder: step.placeholder,\n required: step.required,\n minLength: step.minLength,\n }\n case 'confirm':\n return {\n type: 'confirm',\n guid: step.guid,\n title: step.title,\n description: step.description,\n }\n }\n}\n\nfunction transformReason(r: SdkReason): ReasonConfig {\n const out: ReasonConfig = {\n id: r.id,\n label: r.label,\n }\n if (r.freeform) out.freeform = true\n if (r.offer) out.offer = transformOfferConfig(r.offer)\n return out\n}\n\nfunction transformOfferDecision(o: SdkOffer): OfferDecision {\n return { ...transformOfferConfig(o), copy: o.copy, decisionId: o.decisionId }\n}\n\nfunction transformOfferConfig(o: SdkOffer): OfferConfig {\n switch (o.type) {\n case 'discount': {\n const d: SdkDiscountOffer = o\n return {\n type: 'discount',\n couponId: d.couponId,\n percentOff: d.percentOff,\n amountOff: d.amountOff,\n currency: d.currency,\n durationInMonths: d.durationInMonths,\n }\n }\n case 'pause':\n return {\n type: 'pause',\n months: o.months,\n interval: o.interval,\n }\n case 'plan_change':\n return {\n type: 'plan_change',\n plans: o.plans,\n }\n case 'trial_extension':\n return {\n type: 'trial_extension',\n days: o.days,\n }\n case 'redirect':\n return {\n type: 'redirect',\n url: o.url,\n label: o.label ?? '',\n }\n case 'contact':\n return {\n type: 'contact',\n url: o.url,\n label: o.label,\n }\n case 'rebate':\n return {\n type: 'rebate',\n amountMinor: o.amountMinor,\n currency: o.currency,\n amountPaidMinor: o.amountPaidMinor,\n netAfterRebateMinor: o.netAfterRebateMinor,\n paymentMethodBrand: o.paymentMethodBrand,\n paymentMethodLast4: o.paymentMethodLast4,\n }\n }\n}\n\n/**\n * Default offer copy used by step-graph.ts when a local-mode offer doesn't\n * include explicit copy. Token-mode offers come with copy already filled in\n * by the server, so this only fires for local mode.\n */\nexport function defaultOfferCopy(offer: OfferConfig): OfferCopy {\n const o = offer as BuiltInOfferConfig\n switch (o.type) {\n case 'discount':\n return {\n headline: o.percentOff != null ? `How about ${o.percentOff}% off?` : 'Special offer',\n body: discountBody(o),\n cta: 'Accept offer',\n declineCta: 'No thanks',\n }\n case 'pause':\n return {\n headline: 'Take a break instead?',\n body: `Pause your subscription for up to ${o.months} month${o.months === 1 ? '' : 's'}.`,\n cta: 'Pause subscription',\n declineCta: 'No thanks',\n }\n case 'plan_change':\n return {\n headline: 'Switch to a different plan?',\n body: 'We have other plans that might be a better fit.',\n cta: 'Switch plan',\n declineCta: 'No thanks',\n }\n case 'trial_extension':\n return {\n headline: 'Need more time?',\n body: `We'll extend your trial by ${o.days} day${o.days === 1 ? '' : 's'}.`,\n cta: 'Extend trial',\n declineCta: 'No thanks',\n }\n case 'contact':\n return {\n headline: 'Talk to us first?',\n body: 'Our team would love to help resolve any issues.',\n cta: o.label ?? 'Contact support',\n declineCta: 'No thanks',\n }\n case 'redirect':\n return {\n headline: 'Before you go...',\n body: 'Check this out — it might change your mind.',\n cta: o.label,\n declineCta: 'No thanks',\n }\n case 'rebate':\n return {\n headline: 'Get money back',\n body: \"Stay subscribed and we'll refund part of your most recent payment.\",\n cta: 'Accept refund',\n declineCta: 'No thanks',\n }\n default:\n return {\n headline: 'Before you go...',\n body: \"We'd like to offer you something.\",\n cta: 'Accept',\n declineCta: 'No thanks',\n }\n }\n}\n\nfunction discountBody(o: { percentOff?: number; durationInMonths?: number }): string {\n if (o.percentOff == null) return \"We'd like to offer you a discount.\"\n const months = o.durationInMonths ?? 1\n return `We'd like to offer you ${o.percentOff}% off for ${months} month${months === 1 ? '' : 's'}.`\n}\n","import type {\n AcceptedOfferPayload,\n ApiOfferType,\n ApiPauseInterval,\n ApiStepType,\n ChurnkeyApi,\n PresentedOffer,\n SessionPayload,\n StepViewed,\n} from './api'\nimport { AnalyticsClient, directDataToSessionCustomer } from './api'\nimport type { SdkConfig } from './api-types'\nimport { applyMergeFieldsToSteps } from './merge-fields'\nimport { buildStepGraph, type ResolvedStep, type StepGraph } from './step-graph'\nimport type { SessionCredentials } from './token'\nimport { defaultOfferCopy, transformSdkConfig } from './transform'\nimport type {\n AcceptedOffer,\n BuiltInOfferConfig,\n BuiltInStepType,\n DirectCustomer,\n DirectSubscription,\n FlowCallbacks,\n FlowConfig,\n FlowState,\n OfferDecision,\n ReasonConfig,\n Step,\n} from './types'\n\ntype OfferCallback = (offer: AcceptedOffer, customer: DirectCustomer | null) => Promise<void> | void\n\nfunction handlerFor(offerType: string, cb: FlowCallbacks): OfferCallback | undefined {\n switch (offerType) {\n case 'discount':\n return cb.handleDiscount\n case 'pause':\n return cb.handlePause\n case 'plan_change':\n return cb.handlePlanChange\n case 'trial_extension':\n return cb.handleTrialExtension\n case 'rebate':\n return cb.handleRebate\n default:\n return undefined\n }\n}\n\nfunction listenerFor(offerType: string, cb: FlowCallbacks): OfferCallback | undefined {\n switch (offerType) {\n case 'discount':\n return cb.onDiscount\n case 'pause':\n return cb.onPause\n case 'plan_change':\n return cb.onPlanChange\n case 'trial_extension':\n return cb.onTrialExtension\n case 'rebate':\n return cb.onRebate\n default:\n return undefined\n }\n}\n\n// Listener errors are swallowed — they're side effects, not part of the\n// success path, and shouldn't flip the flow into an error state.\nfunction runListener(listener: OfferCallback, offer: AcceptedOffer, customer: DirectCustomer | null): Promise<void> {\n return Promise.resolve(listener(offer, customer)).catch((e) => {\n console.error('Error in offer listener:', e)\n })\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (!value || typeof value !== 'object') return false\n const proto = Object.getPrototypeOf(value)\n return proto === null || proto === Object.prototype\n}\n\n// --- Wire translation ---\n//\n// SDK types use lowercase identifiers; the API expects uppercase enums.\n// Both maps are typed as exhaustive Records so adding a new built-in step\n// or offer type fails the build until its wire mapping is set.\nconst STEP_TYPE_API_MAP: Record<Exclude<BuiltInStepType, 'success'>, Exclude<ApiStepType, 'CUSTOM'>> = {\n survey: 'SURVEY',\n offer: 'OFFER',\n feedback: 'FREEFORM',\n confirm: 'CONFIRM',\n}\n\nconst OFFER_TYPE_API_MAP: Record<BuiltInOfferConfig['type'], Exclude<ApiOfferType, 'CUSTOM'>> = {\n discount: 'DISCOUNT',\n pause: 'PAUSE',\n plan_change: 'PLAN_CHANGE',\n trial_extension: 'TRIAL_EXTENSION',\n contact: 'CONTACT',\n redirect: 'REDIRECT',\n rebate: 'REBATE',\n}\n\n// 'success' isn't a stepsViewed entry — the session's outcome/canceled/\n// acceptedOffer already captures the terminal state, and recording it\n// separately would double-count the funnel's last hop.\nfunction toApiStepType(step: string): { stepType: ApiStepType; customStepType?: string } | null {\n if (step === 'success') return null\n const builtIn = STEP_TYPE_API_MAP[step as Exclude<BuiltInStepType, 'success'>]\n if (builtIn) return { stepType: builtIn }\n return { stepType: 'CUSTOM', customStepType: step }\n}\n\nfunction toApiOfferType(type: string): { offerType: ApiOfferType; customOfferType?: string } {\n const builtIn = OFFER_TYPE_API_MAP[type as BuiltInOfferConfig['type']]\n if (builtIn) return { offerType: builtIn }\n return { offerType: 'CUSTOM', customOfferType: type }\n}\n\nfunction toApiPauseInterval(interval: 'month' | 'week' | undefined): ApiPauseInterval {\n return interval === 'week' ? 'WEEK' : 'MONTH'\n}\n\n// --- Offer shape builders ---\n//\n// Sessions record offers two ways: presentedOffers keeps the nested config\n// shape (discountConfig, pauseConfig, …); acceptedOffer flattens the fields.\n// Two builders, one source of truth.\n\nfunction toPresentedOfferConfig(rec: OfferDecision): Partial<PresentedOffer> {\n const base = toApiOfferType(rec.type)\n if (base.offerType === 'CUSTOM') return base\n const o = rec as BuiltInOfferConfig\n switch (o.type) {\n case 'discount':\n return {\n ...base,\n discountConfig: { couponId: o.couponId, customAmount: o.percentOff },\n }\n case 'pause':\n return {\n ...base,\n pauseConfig: {\n maxPauseLength: o.months,\n pauseInterval: toApiPauseInterval(o.interval),\n },\n }\n case 'plan_change':\n return { ...base, planChangeConfig: {} }\n case 'trial_extension':\n return { ...base, trialExtensionConfig: { trialExtensionDays: o.days } }\n case 'redirect':\n return {\n ...base,\n redirectConfig: { redirectUrl: o.url, redirectLabel: o.label },\n }\n case 'contact':\n return { ...base, contactConfig: {} }\n default:\n return base\n }\n}\n\nfunction toAcceptedOfferPayload(rec: OfferDecision, result?: Record<string, unknown>): AcceptedOfferPayload {\n const base: AcceptedOfferPayload = { guid: rec.decisionId, ...toApiOfferType(rec.type) }\n if (base.offerType === 'CUSTOM') {\n return result ? { ...base, customOfferResult: result } : base\n }\n const o = rec as BuiltInOfferConfig\n switch (o.type) {\n case 'discount':\n return {\n ...base,\n couponId: o.couponId,\n couponAmount: o.percentOff,\n couponType: 'PERCENT',\n couponDuration: o.durationInMonths,\n }\n case 'pause':\n return {\n ...base,\n pauseDuration: o.months,\n pauseInterval: toApiPauseInterval(o.interval),\n }\n case 'plan_change':\n return {\n ...base,\n newPlanId: o.plans?.[0]?.id,\n newPlanPrice: o.plans?.[0]?.amount.value,\n }\n case 'trial_extension':\n return { ...base, trialExtensionDays: o.days }\n case 'redirect':\n return { ...base, redirectUrl: o.url }\n case 'rebate':\n return { ...base, rebateAmount: o.amountMinor }\n default:\n return base\n }\n}\n\n// --- Machine ---\n\nexport class CancelFlowMachine {\n private state: FlowState\n private cachedSnapshot: FlowState\n private callbacks: FlowCallbacks\n private graph: StepGraph = { stepMap: {}, firstStepId: '', orderedStepIds: [] }\n private listeners: Set<() => void> = new Set()\n\n private apiClient: ChurnkeyApi | null = null\n private analyticsClient: AnalyticsClient | null = null\n private directCustomer: DirectCustomer | null = null\n private directSubscriptions: DirectSubscription[] | null = null\n private creds: SessionCredentials | null = null\n private config: SdkConfig | null = null\n private blueprintId: string | null = null\n private localSteps: Step[] | null = null\n private stepsViewed: StepViewed[] = []\n private presentedOffers: PresentedOffer[] = []\n private customStepResults: Record<string, unknown> = {}\n private configMode: 'live' | 'test' = 'live'\n private stepEnteredAt: number = Date.now()\n private aborted = false\n // Visited-step stack. `back` pops this so it lands on the actually-seen\n // previous step (including synthetic offers a survey choice spawned),\n // not the previous step in declared graph order.\n private history: string[] = []\n\n constructor(config: FlowConfig) {\n // FlowConfig extends FlowCallbacks; storing the whole config covers\n // every callback by name without a separate copy.\n this.callbacks = config\n if (config.mode) this.configMode = config.mode\n if (config.appId && config.customer) {\n this.analyticsClient = new AnalyticsClient(config.appId, config.apiBaseUrl)\n this.directCustomer = config.customer\n this.directSubscriptions = config.subscriptions ?? null\n }\n\n // Token mode defers graph construction until initializeFromConfig runs\n // with the server-supplied steps; stash any locally-declared steps for\n // merging then.\n if (config.session) {\n if (config.steps) this.localSteps = config.steps\n } else if (config.steps) {\n const merged = applyMergeFieldsToSteps(config.steps, this.directCustomer)\n this.graph = buildStepGraph(merged, defaultOfferCopy)\n }\n\n // Seed state from local props for open-source and analytics modes. Token\n // mode overwrites both fields once initializeFromConfig settles, so these\n // values only matter for the pre-fetch render.\n this.state = this.buildInitialState(this.directCustomer, this.directSubscriptions ?? [])\n this.cachedSnapshot = { ...this.state }\n\n // Defer entry tracking in token mode — firing trackStepEnter before the\n // graph is built would record a stale (empty) guid.\n const first = this.firstStep()\n if (!config.session && first) this.trackStepEnter(first)\n }\n\n // Public methods are arrow-bound so consumers can pass them directly\n // (`<button onClick={flow.next}>`) and so useSyncExternalStore sees\n // stable references between renders.\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n getSnapshot = (): FlowState => {\n return this.cachedSnapshot\n }\n\n get reasons(): ReasonConfig[] {\n return this.surveyStep()?.reasons ?? []\n }\n\n get currentStep(): ResolvedStep | undefined {\n return this.graph.stepMap[this.state.currentStepId]\n }\n\n /** The offer on the current step, or null. Always derived — no separate slot to drift. */\n get currentOffer(): OfferDecision | null {\n return this.currentStep?.offer ?? null\n }\n\n /** Whether `back()` would move anywhere — false on the first step and on success. */\n get canGoBack(): boolean {\n if (this.state.step === 'success') return false\n return this.history.length > 0 || Boolean(this.currentStep?.defaultPreviousStep)\n }\n\n /**\n * First step of a given type. Fine for the common \"one step per type\" case;\n * flows with multiple of a type should key on currentStepId instead.\n */\n getStepConfig(stepType: string): ResolvedStep | undefined {\n return Object.values(this.graph.stepMap).find((s) => s.type === stepType)\n }\n\n /** Progress indicator index. Synthetic offers share their survey's slot. */\n get stepIndex(): number {\n const current = this.currentStep\n if (!current) return 0\n if (current.surveyOffer) {\n const surveyId = current.defaultPreviousStep\n return surveyId ? this.graph.orderedStepIds.indexOf(surveyId) : 0\n }\n return Math.max(0, this.graph.orderedStepIds.indexOf(current.guid))\n }\n\n get totalSteps(): number {\n return this.graph.orderedStepIds.length\n }\n\n selectReason = (id: string): void => {\n if (!this.reasons.find((r) => r.id === id)) return\n // Clear follow-up text on reason change so it doesn't carry across selections.\n this.setState({ selectedReason: id, followupResponse: '' })\n }\n\n setFollowupResponse = (text: string): void => {\n this.setState({ followupResponse: text })\n }\n\n next = (result?: Record<string, unknown>): void => {\n // `onClick={next}` would otherwise pass a SyntheticEvent through as result\n // — has circular refs, breaks JSON.stringify. Only accept plain objects.\n if (isPlainObject(result)) {\n this.customStepResults[this.state.step] = result\n }\n const nextId = this.projectedNextStepId()\n if (!nextId) return\n this.transitionTo(nextId, { recordHistory: true })\n }\n\n back = (): void => {\n const popped = this.history.pop()\n if (popped) {\n this.transitionTo(popped)\n return\n }\n // History is empty when the consumer triggered back without a prior\n // forward navigation (e.g. starting state). Fall back to declared order.\n const prevId = this.currentStep?.defaultPreviousStep\n if (prevId) this.transitionTo(prevId)\n }\n\n accept = async (result?: Record<string, unknown>): Promise<void> => {\n // Capture before any state transition — the 'success' transition may\n // move currentStepId off the offer step, depending on whether a success\n // step is declared in the graph.\n const offer = this.currentOffer\n if (!offer) return\n const safeResult = isPlainObject(result) ? result : undefined\n this.setState({ isProcessing: true, error: null })\n try {\n const acceptedOffer = this.buildAcceptedOffer(offer, safeResult)\n const customer = this.state.customer\n\n // Handler wins over the server-side action. With no handler, token mode\n // hits the server endpoint and local mode is a no-op (relying on\n // onAccept's catch-all if anything).\n const handler = handlerFor(offer.type, this.callbacks)\n if (handler) {\n await handler(acceptedOffer, customer)\n } else if (this.isTokenMode()) {\n await this.executeTokenAction(acceptedOffer, offer.decisionId)\n }\n\n // Listeners fire after the action succeeded, regardless of who ran it.\n // Per-type listener first, then the catch-all onAccept.\n const listener = listenerFor(offer.type, this.callbacks)\n if (listener) await runListener(listener, acceptedOffer, customer)\n await this.callbacks.onAccept?.(acceptedOffer, customer)\n\n this.markCurrentOfferAccepted()\n this.enterSuccessStep('saved')\n this.recordOutcome('saved', offer, safeResult)\n } catch (error) {\n this.setState({ isProcessing: false, error: error as Error })\n }\n }\n\n decline = (): void => {\n this.markCurrentOfferDeclined()\n const nextId = this.currentStep?.defaultNextStep\n if (nextId) this.transitionTo(nextId, { recordHistory: true })\n }\n\n setFeedback = (text: string): void => {\n this.setState({ feedback: text })\n }\n\n cancel = async (): Promise<void> => {\n this.setState({ isProcessing: true, error: null })\n try {\n const customer = this.state.customer\n\n if (this.callbacks.handleCancel) {\n await this.callbacks.handleCancel(customer)\n } else if (this.isTokenMode()) {\n await this.apiClient!.cancelSubscription()\n }\n\n await this.callbacks.onCancel?.(customer)\n this.enterSuccessStep('cancelled')\n this.recordOutcome('cancelled')\n } catch (error) {\n this.setState({ isProcessing: false, error: error as Error })\n }\n }\n\n close = (): void => {\n if (this.state.outcome === null && !this.aborted) {\n this.aborted = true\n this.recordAbort()\n }\n this.callbacks.onClose?.()\n }\n\n destroy(): void {\n this.listeners.clear()\n }\n\n // Callbacks are wired through the constructor; this only takes the\n // server-supplied config so callers can't accidentally clobber them.\n initializeFromConfig(config: SdkConfig, apiClient: ChurnkeyApi, creds: SessionCredentials): void {\n this.apiClient = apiClient\n this.creds = creds\n this.config = config\n\n const result = transformSdkConfig(config)\n this.blueprintId = result.blueprintId\n\n const merged = this.localSteps ? mergeLocalSteps(result.steps, this.localSteps) : result.steps\n const steps = applyMergeFieldsToSteps(merged, config.customer ?? null)\n this.graph = buildStepGraph(steps, defaultOfferCopy)\n\n this.state = this.buildInitialState(config.customer ?? null, config.subscriptions ?? [])\n this.cachedSnapshot = { ...this.state }\n const first = this.firstStep()\n if (first) this.trackStepEnter(first)\n this.notify()\n }\n\n // --- Internal helpers ---\n\n private isTokenMode(): boolean {\n return this.apiClient != null\n }\n\n private firstStep(): ResolvedStep | undefined {\n return this.graph.stepMap[this.graph.firstStepId]\n }\n\n private surveyStep(): ResolvedStep | undefined {\n return this.graph.surveyStepId ? this.graph.stepMap[this.graph.surveyStepId] : undefined\n }\n\n private buildInitialState(customer: DirectCustomer | null, subscriptions: DirectSubscription[]): FlowState {\n const first = this.firstStep()\n return {\n step: first?.type ?? 'survey',\n currentStepId: this.graph.firstStepId,\n selectedReason: null,\n followupResponse: '',\n feedback: '',\n outcome: null,\n isProcessing: false,\n error: null,\n customer,\n subscriptions,\n }\n }\n\n // On a survey step with a selected reason that has an attached offer,\n // jump to that offer's synthetic step; otherwise follow the default\n // forward pointer.\n private projectedNextStepId(): string | undefined {\n const current = this.currentStep\n if (!current) return undefined\n if (current.offersAttached && this.state.selectedReason) {\n const override = current.offersAttached[this.state.selectedReason]\n if (override) return override\n }\n return current.defaultNextStep\n }\n\n // Single entry point for step changes. All navigation flows through here so\n // view-timing and presentation tracking stay in one place. Forward callers\n // pass recordHistory; `back` omits it so popping isn't reversed.\n private transitionTo(stepId: string, opts: { recordHistory?: boolean } = {}): void {\n const step = this.graph.stepMap[stepId]\n if (!step) return\n if (opts.recordHistory && this.state.currentStepId && this.state.currentStepId !== stepId) {\n this.history.push(this.state.currentStepId)\n }\n this.setState({ step: step.type, currentStepId: stepId })\n }\n\n private setState(partial: Partial<FlowState>): void {\n const prevStep = this.state.step\n this.state = { ...this.state, ...partial }\n this.cachedSnapshot = { ...this.state }\n if (partial.step && partial.step !== prevStep) {\n this.finalizeStepView(prevStep)\n // enterSuccessStep can set state.step='success' without moving currentStepId\n // (when no success step is declared). Only feed the new graph node into\n // trackStepEnter when its type actually matches — otherwise the prior\n // step would be re-recorded.\n const step = this.graph.stepMap[this.state.currentStepId]\n if (step?.type === partial.step) this.trackStepEnter(step)\n else this.trackStepView(partial.step)\n this.callbacks.onStepChange?.(partial.step, prevStep)\n }\n this.notify()\n }\n\n private trackStepEnter(step: ResolvedStep): void {\n this.trackStepView(step.type, step.guid, step.numChoices)\n if (step.type === 'offer') this.recordOfferPresented()\n }\n\n private recordOfferPresented(): void {\n const offer = this.currentOffer\n if (!offer) return\n this.presentedOffers.push({\n ...toPresentedOfferConfig(offer),\n guid: offer.decisionId,\n accepted: false,\n presentedAt: new Date().toISOString(),\n })\n }\n\n private markCurrentOfferAccepted(): void {\n const last = this.presentedOffers[this.presentedOffers.length - 1]\n if (!last || last.acceptedAt || last.declinedAt) return\n last.accepted = true\n last.acceptedAt = new Date().toISOString()\n }\n\n private markCurrentOfferDeclined(): void {\n const last = this.presentedOffers[this.presentedOffers.length - 1]\n if (!last || last.acceptedAt || last.declinedAt) return\n last.declinedAt = new Date().toISOString()\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener()\n }\n }\n\n private async executeTokenAction(offer: AcceptedOffer, decisionId?: string): Promise<void> {\n if (!this.apiClient) return\n\n // Only built-in offer types have a server action; custom types route\n // entirely through the consumer's handler/onAccept.\n const o = offer as BuiltInOfferConfig\n switch (o.type) {\n case 'discount':\n if (o.couponId) {\n await this.apiClient.applyDiscount(o.couponId, this.blueprintId ?? undefined)\n }\n break\n case 'pause':\n await this.apiClient.pause({ duration: o.months, interval: o.interval ?? 'month' })\n break\n case 'plan_change':\n await this.apiClient.changePlan(o.plans[0]?.id)\n break\n case 'trial_extension':\n await this.apiClient.extendTrial(o.days, this.blueprintId ?? undefined)\n break\n case 'rebate':\n await this.apiClient.applyRebate(this.blueprintId ?? undefined, decisionId)\n break\n }\n }\n\n private trackStepView(stepType: string, guid?: string, numChoices?: number): void {\n this.stepEnteredAt = Date.now()\n const mapped = toApiStepType(stepType)\n if (!mapped) return\n\n const entry: StepViewed = {\n ...mapped,\n start: new Date().toISOString(),\n }\n if (guid) entry.guid = guid\n if (numChoices != null) entry.numChoices = numChoices\n\n this.stepsViewed.push(entry)\n }\n\n private finalizeStepView(step: string): void {\n const mapped = toApiStepType(step)\n if (!mapped) return\n // Match the most recent entry for this step. Custom steps share\n // stepType='CUSTOM', so disambiguate on customStepType.\n const entry = [...this.stepsViewed]\n .reverse()\n .find((s) => s.stepType === mapped.stepType && s.customStepType === mapped.customStepType)\n if (entry) {\n entry.end = new Date().toISOString()\n entry.duration = Date.now() - this.stepEnteredAt\n }\n }\n\n // Offer passed in so accept() can capture it before enterSuccessStep\n // potentially moves currentStepId off the offer step. copy and decisionId\n // are SDK-internal — strip them from the consumer-facing payload.\n private buildAcceptedOffer(offer: OfferDecision, result?: Record<string, unknown>): AcceptedOffer {\n const { copy: _copy, decisionId: _decisionId, ...offerConfig } = offer\n const accepted: AcceptedOffer = offerConfig\n if (this.state.selectedReason) accepted.reasonId = this.state.selectedReason\n if (result) accepted.result = result\n return accepted\n }\n\n // Terminal transition. Prefer moving currentStepId to a declared success\n // step so the developer's savedTitle / classNames / custom component\n // applies; otherwise stay put and the renderer's defaults cover it.\n private enterSuccessStep(outcome: 'saved' | 'cancelled'): void {\n const success = this.getStepConfig('success')\n const partial: Partial<FlowState> = { step: 'success', outcome, isProcessing: false }\n if (success) partial.currentStepId = success.guid\n this.setState(partial)\n }\n\n private resolveSessionCustomer(): SessionPayload['customer'] {\n const direct = this.directCustomer\n ? directDataToSessionCustomer(this.directCustomer, this.directSubscriptions ?? undefined)\n : undefined\n // Token identifies the customer authoritatively; direct data fills in\n // extras (email, plan, metadata) but never overrides id/subscriptionId.\n if (this.creds) {\n return { ...direct, id: this.creds.customerId, subscriptionId: this.creds.subscriptionId }\n }\n return direct\n }\n\n private buildBasePayload(): SessionPayload {\n const selectedReason = this.reasons.find((r) => r.id === this.state.selectedReason)\n // surveyChoiceValue is always the static label so dashboard groupings\n // by reason stay stable. Typed text from `freeform: true` reasons\n // travels separately on followupResponse, mirroring the embed payload.\n const followupResponse =\n selectedReason?.freeform && this.state.followupResponse ? this.state.followupResponse : undefined\n const payload: SessionPayload = {\n blueprintId: this.blueprintId ?? undefined,\n customer: this.resolveSessionCustomer(),\n canceled: false,\n surveyChoiceId: this.state.selectedReason ?? undefined,\n surveyChoiceValue: selectedReason?.label,\n followupResponse,\n feedback: this.state.feedback || undefined,\n presentedOffers: this.presentedOffers,\n stepsViewed: this.stepsViewed,\n customStepResults: Object.keys(this.customStepResults).length > 0 ? this.customStepResults : undefined,\n // Token's signed mode wins — the client can't override it.\n mode: (this.creds?.mode ?? this.configMode) === 'test' ? 'TEST' : 'LIVE',\n provider: this.isTokenMode() ? undefined : 'sdk-react',\n embedVersion: 'sdk-react',\n }\n\n // Token-mode session-record fields. Required by downstream analytics\n // and compliance reporting on the dashboard.\n if (this.config) {\n const surveyStep = this.config.steps.find((s) => s.type === 'survey')\n payload.surveyId = surveyStep?.guid\n payload.clickToCancelEnabled = this.config.settings.clickToCancelEnabled\n payload.strictFTCComplianceEnabled = this.config.settings.strictFTCComplianceEnabled\n payload.usedClickToCancel = false\n payload.autoOptimizationUsed = !!this.config.autoOptimizationKey\n payload.autoOptimizationKey = this.config.autoOptimizationKey\n payload.discountCooldown = this.config.settings.discountCooldown\n payload.pauseCooldown = this.config.settings.pauseCooldown\n payload.discountCooldownApplied = false\n payload.pauseCooldownApplied = false\n }\n\n return payload\n }\n\n private recordAbort(): void {\n const client = this.apiClient ?? this.analyticsClient\n if (!client) return\n this.finalizeStepView(this.state.step)\n client.createSession({ ...this.buildBasePayload(), aborted: true }).catch(() => {})\n }\n\n // acceptedOffer is a parameter so callers capture it before enterSuccessStep\n // moves currentStepId off the offer step. setState already finalized the\n // step view on the way to 'success', so no extra finalize call here.\n private recordOutcome(\n outcome: 'saved' | 'cancelled',\n acceptedOffer?: OfferDecision,\n result?: Record<string, unknown>,\n ): void {\n const client = this.apiClient ?? this.analyticsClient\n if (!client) return\n\n const payload = this.buildBasePayload()\n payload.canceled = outcome === 'cancelled'\n\n if (outcome === 'saved' && acceptedOffer) {\n payload.acceptedOffer = toAcceptedOfferPayload(acceptedOffer, result)\n }\n\n client.createSession(payload).catch(() => {})\n }\n}\n\n// Local steps override server steps by type. Unmatched local steps append\n// at the end. Server order is preserved so the dashboard stays in charge of\n// flow shape while developers can swap in their own copy / custom steps.\nfunction mergeLocalSteps(serverSteps: Step[], localSteps: Step[]): Step[] {\n const localByType = new Map(localSteps.map((s) => [s.type, s]))\n const merged = serverSteps.map((serverStep) => {\n const local = localByType.get(serverStep.type)\n if (!local) return serverStep\n localByType.delete(serverStep.type)\n return { ...serverStep, ...local } as Step\n })\n for (const [, step] of localByType) merged.push(step)\n return merged\n}\n","export interface SessionCredentials {\n appId: string\n customerId: string\n subscriptionId?: string\n authHash: string\n mode: 'live' | 'test'\n issuedAt: number\n}\n\n/** Decode a session token created by `@churnkey/node`. */\nexport function decodeSessionToken(token: string): SessionCredentials {\n if (!token.startsWith('ck_')) {\n throw new Error('Invalid token: must start with \"ck_\"')\n }\n\n const encoded = token.slice(3)\n\n let json: string\n try {\n // base64url decode: replace URL-safe chars, add padding\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/')\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4)\n json = atob(padded)\n } catch {\n throw new Error('Invalid token: malformed base64')\n }\n\n let payload: Record<string, unknown>\n try {\n payload = JSON.parse(json)\n } catch {\n throw new Error('Invalid token: malformed JSON')\n }\n\n if (typeof payload.a !== 'string' || !payload.a) {\n throw new Error('Invalid token: missing appId')\n }\n if (typeof payload.c !== 'string' || !payload.c) {\n throw new Error('Invalid token: missing customerId')\n }\n if (typeof payload.h !== 'string' || !payload.h) {\n throw new Error('Invalid token: missing authHash')\n }\n\n return {\n appId: payload.a,\n customerId: payload.c,\n subscriptionId: typeof payload.s === 'string' ? payload.s : undefined,\n authHash: payload.h,\n mode: payload.m === 'test' ? 'test' : 'live',\n issuedAt: typeof payload.t === 'number' ? payload.t : 0,\n }\n}\n"]}
package/dist/core.cjs CHANGED
@@ -1,57 +1,57 @@
1
1
  'use strict';
2
2
 
3
- var chunkLVUDBCQ2_cjs = require('./chunk-LVUDBCQ2.cjs');
4
- var chunk2VQNWZWO_cjs = require('./chunk-2VQNWZWO.cjs');
3
+ var chunkBDBZ5OS3_cjs = require('./chunk-BDBZ5OS3.cjs');
4
+ var chunkSNTKIKHU_cjs = require('./chunk-SNTKIKHU.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "BUILT_IN_OFFER_TYPES", {
9
9
  enumerable: true,
10
- get: function () { return chunkLVUDBCQ2_cjs.BUILT_IN_OFFER_TYPES; }
10
+ get: function () { return chunkBDBZ5OS3_cjs.BUILT_IN_OFFER_TYPES; }
11
11
  });
12
12
  Object.defineProperty(exports, "BUILT_IN_STEP_TYPES", {
13
13
  enumerable: true,
14
- get: function () { return chunkLVUDBCQ2_cjs.BUILT_IN_STEP_TYPES; }
14
+ get: function () { return chunkBDBZ5OS3_cjs.BUILT_IN_STEP_TYPES; }
15
15
  });
16
16
  Object.defineProperty(exports, "appearanceToStyle", {
17
17
  enumerable: true,
18
- get: function () { return chunkLVUDBCQ2_cjs.appearanceToStyle; }
18
+ get: function () { return chunkBDBZ5OS3_cjs.appearanceToStyle; }
19
19
  });
20
20
  Object.defineProperty(exports, "calculateDiscountedPrice", {
21
21
  enumerable: true,
22
- get: function () { return chunkLVUDBCQ2_cjs.calculateDiscountedPrice; }
22
+ get: function () { return chunkBDBZ5OS3_cjs.calculateDiscountedPrice; }
23
23
  });
24
24
  Object.defineProperty(exports, "cn", {
25
25
  enumerable: true,
26
- get: function () { return chunkLVUDBCQ2_cjs.cn; }
26
+ get: function () { return chunkBDBZ5OS3_cjs.cn; }
27
27
  });
28
28
  Object.defineProperty(exports, "defaultTitles", {
29
29
  enumerable: true,
30
- get: function () { return chunkLVUDBCQ2_cjs.defaultTitles; }
30
+ get: function () { return chunkBDBZ5OS3_cjs.defaultTitles; }
31
31
  });
32
32
  Object.defineProperty(exports, "formatPeriodEnd", {
33
33
  enumerable: true,
34
- get: function () { return chunkLVUDBCQ2_cjs.formatPeriodEnd; }
34
+ get: function () { return chunkBDBZ5OS3_cjs.formatPeriodEnd; }
35
35
  });
36
36
  Object.defineProperty(exports, "formatPrice", {
37
37
  enumerable: true,
38
- get: function () { return chunkLVUDBCQ2_cjs.formatPrice; }
38
+ get: function () { return chunkBDBZ5OS3_cjs.formatPrice; }
39
39
  });
40
40
  Object.defineProperty(exports, "AnalyticsClient", {
41
41
  enumerable: true,
42
- get: function () { return chunk2VQNWZWO_cjs.AnalyticsClient; }
42
+ get: function () { return chunkSNTKIKHU_cjs.AnalyticsClient; }
43
43
  });
44
44
  Object.defineProperty(exports, "CancelFlowMachine", {
45
45
  enumerable: true,
46
- get: function () { return chunk2VQNWZWO_cjs.CancelFlowMachine; }
46
+ get: function () { return chunkSNTKIKHU_cjs.CancelFlowMachine; }
47
47
  });
48
48
  Object.defineProperty(exports, "ChurnkeyApi", {
49
49
  enumerable: true,
50
- get: function () { return chunk2VQNWZWO_cjs.ChurnkeyApi; }
50
+ get: function () { return chunkSNTKIKHU_cjs.ChurnkeyApi; }
51
51
  });
52
52
  Object.defineProperty(exports, "decodeSessionToken", {
53
53
  enumerable: true,
54
- get: function () { return chunk2VQNWZWO_cjs.decodeSessionToken; }
54
+ get: function () { return chunkSNTKIKHU_cjs.decodeSessionToken; }
55
55
  });
56
56
  //# sourceMappingURL=core.cjs.map
57
57
  //# sourceMappingURL=core.cjs.map
package/dist/core.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { N as PlanOption, s as DirectCustomer, u as DirectSubscription, z as FlowConfig, E as FlowState, Q as ReasonConfig, U as ResolvedStep, J as OfferDecision, d as Appearance } from './step-graph-ChlSCUGk.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, G as OfferClassNames, H as OfferConfig, I as OfferCopy, K as OfferStep, O as OfferStepProps, P as PauseOffer, L as PlanChangeOffer, R as ReasonButtonProps, T as RedirectOffer, V as Step, W as StructuralClassNames, X as SubscriptionStatus, Y as SuccessClassNames, Z as SuccessStep, S as SuccessStepProps, _ as SurveyClassNames, $ as SurveyStep, b as SurveyStepProps, a0 as TrialExtensionOffer } from './step-graph-ChlSCUGk.cjs';
1
+ import { N as PlanOption, s as DirectCustomer, u as DirectSubscription, z as FlowConfig, E as FlowState, Q as ReasonConfig, V as ResolvedStep, J as OfferDecision, d as Appearance } from './step-graph-DKvaV3Dg.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, G as OfferClassNames, H as OfferConfig, I as OfferCopy, K as OfferStep, O as OfferStepProps, P as PauseOffer, L as PlanChangeOffer, R as ReasonButtonProps, T as RebateOffer, U as RedirectOffer, W as Step, X as StructuralClassNames, Y as SubscriptionStatus, Z as SuccessClassNames, _ as SuccessStep, S as SuccessStepProps, $ as SurveyClassNames, a0 as SurveyStep, b as SurveyStepProps, a1 as TrialExtensionOffer } from './step-graph-DKvaV3Dg.cjs';
3
3
  import { CSSProperties } from 'react';
4
4
 
5
5
  interface SdkConfig {
@@ -46,7 +46,7 @@ interface SdkReason {
46
46
  freeform?: boolean;
47
47
  offer?: SdkOffer;
48
48
  }
49
- type SdkOffer = SdkDiscountOffer | SdkPauseOffer | SdkPlanChangeOffer | SdkTrialExtensionOffer | SdkRedirectOffer | SdkContactOffer;
49
+ type SdkOffer = SdkDiscountOffer | SdkPauseOffer | SdkPlanChangeOffer | SdkTrialExtensionOffer | SdkRedirectOffer | SdkContactOffer | SdkRebateOffer;
50
50
  interface SdkOfferBase {
51
51
  /** Per-offer guid — used for analytics joins between presented and accepted offers. */
52
52
  decisionId?: string;
@@ -85,6 +85,18 @@ interface SdkContactOffer extends SdkOfferBase {
85
85
  url?: string;
86
86
  label?: string;
87
87
  }
88
+ interface SdkRebateOffer extends SdkOfferBase {
89
+ type: 'rebate';
90
+ /** Cash refunded to the card, smallest currency unit. */
91
+ amountMinor: number;
92
+ currency: string;
93
+ /** Gross amount paid on the target invoice — the "you paid" row. */
94
+ amountPaidMinor: number;
95
+ /** amountPaidMinor − amountMinor — the "your net" row. */
96
+ netAfterRebateMinor: number;
97
+ paymentMethodBrand?: string;
98
+ paymentMethodLast4?: string;
99
+ }
88
100
  interface SdkOfferCopy {
89
101
  headline: string;
90
102
  body: string;
@@ -104,7 +116,7 @@ interface SessionCredentials {
104
116
  declare function decodeSessionToken(token: string): SessionCredentials;
105
117
 
106
118
  type ApiStepType = 'OFFER' | 'SURVEY' | 'CONFIRM' | 'FREEFORM' | 'CUSTOM';
107
- type ApiOfferType = 'DISCOUNT' | 'PAUSE' | 'PLAN_CHANGE' | 'TRIAL_EXTENSION' | 'CONTACT' | 'REDIRECT' | 'CUSTOM';
119
+ type ApiOfferType = 'DISCOUNT' | 'PAUSE' | 'PLAN_CHANGE' | 'TRIAL_EXTENSION' | 'CONTACT' | 'REDIRECT' | 'REBATE' | 'CUSTOM';
108
120
  type ApiPauseInterval = 'MONTH' | 'WEEK';
109
121
  type ApiCouponType = 'PERCENT' | 'AMOUNT';
110
122
  type ApiBillingInterval = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR';
@@ -143,6 +155,7 @@ interface AcceptedOfferPayload {
143
155
  newPlanPrice?: number;
144
156
  trialExtensionDays?: number;
145
157
  redirectUrl?: string;
158
+ rebateAmount?: number;
146
159
  }
147
160
  interface SessionCustomer {
148
161
  id: string;
@@ -200,6 +213,7 @@ declare class ChurnkeyApi {
200
213
  cancelSubscription(): Promise<void>;
201
214
  changePlan(planId: string): Promise<void>;
202
215
  extendTrial(days: number, blueprintId?: string): Promise<void>;
216
+ applyRebate(blueprintId?: string, offerGuid?: string): Promise<void>;
203
217
  createSession(payload: SessionPayload): Promise<void>;
204
218
  }
205
219
  declare class AnalyticsClient {
package/dist/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { N as PlanOption, s as DirectCustomer, u as DirectSubscription, z as FlowConfig, E as FlowState, Q as ReasonConfig, U as ResolvedStep, J as OfferDecision, d as Appearance } from './step-graph-ChlSCUGk.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, G as OfferClassNames, H as OfferConfig, I as OfferCopy, K as OfferStep, O as OfferStepProps, P as PauseOffer, L as PlanChangeOffer, R as ReasonButtonProps, T as RedirectOffer, V as Step, W as StructuralClassNames, X as SubscriptionStatus, Y as SuccessClassNames, Z as SuccessStep, S as SuccessStepProps, _ as SurveyClassNames, $ as SurveyStep, b as SurveyStepProps, a0 as TrialExtensionOffer } from './step-graph-ChlSCUGk.js';
1
+ import { N as PlanOption, s as DirectCustomer, u as DirectSubscription, z as FlowConfig, E as FlowState, Q as ReasonConfig, V as ResolvedStep, J as OfferDecision, d as Appearance } from './step-graph-DKvaV3Dg.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, G as OfferClassNames, H as OfferConfig, I as OfferCopy, K as OfferStep, O as OfferStepProps, P as PauseOffer, L as PlanChangeOffer, R as ReasonButtonProps, T as RebateOffer, U as RedirectOffer, W as Step, X as StructuralClassNames, Y as SubscriptionStatus, Z as SuccessClassNames, _ as SuccessStep, S as SuccessStepProps, $ as SurveyClassNames, a0 as SurveyStep, b as SurveyStepProps, a1 as TrialExtensionOffer } from './step-graph-DKvaV3Dg.js';
3
3
  import { CSSProperties } from 'react';
4
4
 
5
5
  interface SdkConfig {
@@ -46,7 +46,7 @@ interface SdkReason {
46
46
  freeform?: boolean;
47
47
  offer?: SdkOffer;
48
48
  }
49
- type SdkOffer = SdkDiscountOffer | SdkPauseOffer | SdkPlanChangeOffer | SdkTrialExtensionOffer | SdkRedirectOffer | SdkContactOffer;
49
+ type SdkOffer = SdkDiscountOffer | SdkPauseOffer | SdkPlanChangeOffer | SdkTrialExtensionOffer | SdkRedirectOffer | SdkContactOffer | SdkRebateOffer;
50
50
  interface SdkOfferBase {
51
51
  /** Per-offer guid — used for analytics joins between presented and accepted offers. */
52
52
  decisionId?: string;
@@ -85,6 +85,18 @@ interface SdkContactOffer extends SdkOfferBase {
85
85
  url?: string;
86
86
  label?: string;
87
87
  }
88
+ interface SdkRebateOffer extends SdkOfferBase {
89
+ type: 'rebate';
90
+ /** Cash refunded to the card, smallest currency unit. */
91
+ amountMinor: number;
92
+ currency: string;
93
+ /** Gross amount paid on the target invoice — the "you paid" row. */
94
+ amountPaidMinor: number;
95
+ /** amountPaidMinor − amountMinor — the "your net" row. */
96
+ netAfterRebateMinor: number;
97
+ paymentMethodBrand?: string;
98
+ paymentMethodLast4?: string;
99
+ }
88
100
  interface SdkOfferCopy {
89
101
  headline: string;
90
102
  body: string;
@@ -104,7 +116,7 @@ interface SessionCredentials {
104
116
  declare function decodeSessionToken(token: string): SessionCredentials;
105
117
 
106
118
  type ApiStepType = 'OFFER' | 'SURVEY' | 'CONFIRM' | 'FREEFORM' | 'CUSTOM';
107
- type ApiOfferType = 'DISCOUNT' | 'PAUSE' | 'PLAN_CHANGE' | 'TRIAL_EXTENSION' | 'CONTACT' | 'REDIRECT' | 'CUSTOM';
119
+ type ApiOfferType = 'DISCOUNT' | 'PAUSE' | 'PLAN_CHANGE' | 'TRIAL_EXTENSION' | 'CONTACT' | 'REDIRECT' | 'REBATE' | 'CUSTOM';
108
120
  type ApiPauseInterval = 'MONTH' | 'WEEK';
109
121
  type ApiCouponType = 'PERCENT' | 'AMOUNT';
110
122
  type ApiBillingInterval = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR';
@@ -143,6 +155,7 @@ interface AcceptedOfferPayload {
143
155
  newPlanPrice?: number;
144
156
  trialExtensionDays?: number;
145
157
  redirectUrl?: string;
158
+ rebateAmount?: number;
146
159
  }
147
160
  interface SessionCustomer {
148
161
  id: string;
@@ -200,6 +213,7 @@ declare class ChurnkeyApi {
200
213
  cancelSubscription(): Promise<void>;
201
214
  changePlan(planId: string): Promise<void>;
202
215
  extendTrial(days: number, blueprintId?: string): Promise<void>;
216
+ applyRebate(blueprintId?: string, offerGuid?: string): Promise<void>;
203
217
  createSession(payload: SessionPayload): Promise<void>;
204
218
  }
205
219
  declare class AnalyticsClient {
package/dist/core.js CHANGED
@@ -1,4 +1,4 @@
1
- export { BUILT_IN_OFFER_TYPES, BUILT_IN_STEP_TYPES, appearanceToStyle, calculateDiscountedPrice, cn, defaultTitles, formatPeriodEnd, formatPrice } from './chunk-SQ35G4LA.js';
2
- export { AnalyticsClient, CancelFlowMachine, ChurnkeyApi, decodeSessionToken } from './chunk-UNSSI6KX.js';
1
+ export { BUILT_IN_OFFER_TYPES, BUILT_IN_STEP_TYPES, appearanceToStyle, calculateDiscountedPrice, cn, defaultTitles, formatPeriodEnd, formatPrice } from './chunk-G57YLYM5.js';
2
+ export { AnalyticsClient, CancelFlowMachine, ChurnkeyApi, decodeSessionToken } from './chunk-QYNW3HF3.js';
3
3
  //# sourceMappingURL=core.js.map
4
4
  //# sourceMappingURL=core.js.map
package/dist/headless.cjs CHANGED
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var chunk42SJA62X_cjs = require('./chunk-42SJA62X.cjs');
4
- require('./chunk-2VQNWZWO.cjs');
3
+ var chunk4BMB42WI_cjs = require('./chunk-4BMB42WI.cjs');
4
+ require('./chunk-SNTKIKHU.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "useCancelFlow", {
9
9
  enumerable: true,
10
- get: function () { return chunk42SJA62X_cjs.useCancelFlow; }
10
+ get: function () { return chunk4BMB42WI_cjs.useCancelFlow; }
11
11
  });
12
12
  //# sourceMappingURL=headless.cjs.map
13
13
  //# sourceMappingURL=headless.cjs.map
@@ -1,4 +1,4 @@
1
- import { z as FlowConfig, Q as ReasonConfig, U as ResolvedStep, J as OfferDecision, s as DirectCustomer, u as DirectSubscription } from './step-graph-ChlSCUGk.cjs';
1
+ import { z as FlowConfig, Q as ReasonConfig, V as ResolvedStep, J as OfferDecision, s as DirectCustomer, u as DirectSubscription } from './step-graph-DKvaV3Dg.cjs';
2
2
  import 'react';
3
3
 
4
4
  declare function useCancelFlow(config: FlowConfig): {
@@ -1,4 +1,4 @@
1
- import { z as FlowConfig, Q as ReasonConfig, U as ResolvedStep, J as OfferDecision, s as DirectCustomer, u as DirectSubscription } from './step-graph-ChlSCUGk.js';
1
+ import { z as FlowConfig, Q as ReasonConfig, V as ResolvedStep, J as OfferDecision, s as DirectCustomer, u as DirectSubscription } from './step-graph-DKvaV3Dg.js';
2
2
  import 'react';
3
3
 
4
4
  declare function useCancelFlow(config: FlowConfig): {
package/dist/headless.js CHANGED
@@ -1,4 +1,4 @@
1
- export { useCancelFlow } from './chunk-YZERGV7F.js';
2
- import './chunk-UNSSI6KX.js';
1
+ export { useCancelFlow } from './chunk-F4ESJBOS.js';
2
+ import './chunk-QYNW3HF3.js';
3
3
  //# sourceMappingURL=headless.js.map
4
4
  //# sourceMappingURL=headless.js.map