@virex-tech/paywallo-sdk 2.2.1 → 2.2.3

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/index.d.mts CHANGED
@@ -346,60 +346,6 @@ interface ConditionalFlagContext {
346
346
  distinctId?: string;
347
347
  }
348
348
 
349
- interface PaywallModalProps {
350
- placement: string;
351
- visible: boolean;
352
- onResult: (result: PaywallResult) => void;
353
- paywallConfig?: {
354
- id: string;
355
- placement: string;
356
- config: Record<string, unknown>;
357
- primaryProductId?: string;
358
- secondaryProductId?: string;
359
- };
360
- preloadedProducts?: Map<string, Product>;
361
- variantKey?: string;
362
- campaignId?: string;
363
- /** UUID de `paywall_variants` (sub-fase 2.14). */
364
- variantId?: string;
365
- }
366
- declare function PaywallModal({ placement, visible, onResult, paywallConfig: preloadedConfig, preloadedProducts, variantKey, campaignId, variantId, }: PaywallModalProps): React__default.ReactElement | null;
367
-
368
- interface PaywallContextValue {
369
- nodes: Record<string, PaywallNode>;
370
- rootId: string;
371
- language: string;
372
- defaultLanguage: string;
373
- products: Map<string, Product>;
374
- selectedProductId: string | null;
375
- primaryProductId: string | null;
376
- secondaryProductId: string | null;
377
- currentNavigationIndex: number;
378
- currentTabIndex: number;
379
- trialEnabled: boolean;
380
- selectedPeriod: string | null;
381
- isPurchasing: boolean;
382
- exitOfferVisible: boolean;
383
- exitOfferTriggeredByBackButton: boolean;
384
- onClose: () => void;
385
- onTryClose: () => void;
386
- onSelectProduct: (productId: string) => void;
387
- onPurchase: (productId: string) => void;
388
- onRestore: () => void;
389
- onNavigate: (target: "next" | "previous" | "first" | "last" | number) => void;
390
- onSetTab: (index: number) => void;
391
- onSetVariable: (name: string, value: string) => void;
392
- onToggleTrial: (enabled: boolean) => void;
393
- onSelectPeriod: (value: string) => void;
394
- onOpenUrl: (url: string, inBrowser?: boolean) => void;
395
- onTapBehavior: (behavior: TapBehavior) => void;
396
- onShowExitOffer: () => void;
397
- onDismissExitOffer: () => void;
398
- onTriggerBackButton: () => void;
399
- }
400
- declare const PaywallContext: React.Context<PaywallContextValue | null>;
401
- declare function usePaywallContext(): PaywallContextValue;
402
-
403
349
  interface PreloadResult {
404
350
  success: boolean;
405
351
  error?: Error;
@@ -427,17 +373,53 @@ interface PaywalloContextValue {
427
373
  }
428
374
  declare const PaywalloContext: React.Context<PaywalloContextValue | null>;
429
375
 
430
- declare class PaywallError extends PaywalloError {
431
- constructor(code: string, message: string);
376
+ /**
377
+ * Shared context resolved once per batch and hoisted out of every individual
378
+ * event in the V2 ingest envelope. The provider is called at flush time so
379
+ * each field reflects the most recent SDK state.
380
+ *
381
+ * The shape mirrors the server-side `/api/v2/ingest/batch` contract (Phase
382
+ * 3.1). Fields declared here are deduplicated across the batch — they exist
383
+ * once on the envelope instead of `N` times on each `events[]` entry.
384
+ */
385
+ interface EventContext {
386
+ distinct_id?: string;
387
+ session_id?: string;
388
+ device_id?: string;
389
+ app_version?: string;
390
+ sdk_version?: string;
391
+ platform?: string;
392
+ os_version?: string;
393
+ device_model?: string;
394
+ timezone?: string;
395
+ locale?: string;
396
+ attribution?: Record<string, unknown>;
397
+ ids?: Record<string, unknown>;
398
+ }
399
+
400
+ /**
401
+ * Event priority controls flush semantics:
402
+ *
403
+ * - `"critical"` → flushed as a batch-of-1 on the next microtask (via
404
+ * `queueMicrotask`). Used for events where loss is unacceptable:
405
+ * `transaction`, `identify`, `lifecycle {type: "install"}`,
406
+ * `subscription_*`, `refund`, `checkout_started`.
407
+ * - `"normal"` → buffered and flushed on a rolling window (whichever fires
408
+ * first): `BATCH_MAX_SIZE` events OR `BATCH_FLUSH_MS`. Used for events
409
+ * where batching amortizes network cost: `paywall`, non-install
410
+ * `lifecycle` (foreground/background/session), `onboarding`,
411
+ * `notification`, `custom`.
412
+ *
413
+ * Both priorities post to `/sdk/ingest/batch` (Phase 3.1 envelope) with
414
+ * automatic fallback to `/sdk/events/batch` when the V2 endpoint is
415
+ * absent (old server) or rejects the request. `OfflineQueue` handles
416
+ * network-failure durability for both queues via the `PostFn` injected by
417
+ * `ApiClient.postWithQueue`.
418
+ */
419
+ type EventPriority = "critical" | "normal";
420
+ interface TrackOptions {
421
+ priority?: EventPriority;
432
422
  }
433
- declare const PAYWALL_ERROR_CODES: {
434
- readonly NOT_INITIALIZED: "PAYWALL_NOT_INITIALIZED";
435
- readonly NOT_FOUND: "PAYWALL_NOT_FOUND";
436
- readonly RENDER_FAILED: "PAYWALL_RENDER_FAILED";
437
- readonly LOAD_FAILED: "PAYWALL_LOAD_FAILED";
438
- readonly DISMISS_FAILED: "PAYWALL_DISMISS_FAILED";
439
- readonly INVALID_CONFIG: "PAYWALL_INVALID_CONFIG";
440
- };
441
423
 
442
424
  interface RetryConfig {
443
425
  maxRetries: number;
@@ -498,54 +480,6 @@ declare class HttpClient {
498
480
  getConfig(): Readonly<HttpClientConfig>;
499
481
  }
500
482
 
501
- /**
502
- * Shared context resolved once per batch and hoisted out of every individual
503
- * event in the V2 ingest envelope. The provider is called at flush time so
504
- * each field reflects the most recent SDK state.
505
- *
506
- * The shape mirrors the server-side `/api/v2/ingest/batch` contract (Phase
507
- * 3.1). Fields declared here are deduplicated across the batch — they exist
508
- * once on the envelope instead of `N` times on each `events[]` entry.
509
- */
510
- interface EventContext {
511
- distinct_id?: string;
512
- session_id?: string;
513
- device_id?: string;
514
- app_version?: string;
515
- sdk_version?: string;
516
- platform?: string;
517
- os_version?: string;
518
- device_model?: string;
519
- timezone?: string;
520
- locale?: string;
521
- attribution?: Record<string, unknown>;
522
- ids?: Record<string, unknown>;
523
- }
524
-
525
- /**
526
- * Event priority controls flush semantics:
527
- *
528
- * - `"critical"` → flushed as a batch-of-1 on the next microtask (via
529
- * `queueMicrotask`). Used for events where loss is unacceptable:
530
- * `transaction`, `identify`, `lifecycle {type: "install"}`,
531
- * `subscription_*`, `refund`, `checkout_started`.
532
- * - `"normal"` → buffered and flushed on a rolling window (whichever fires
533
- * first): `BATCH_MAX_SIZE` events OR `BATCH_FLUSH_MS`. Used for events
534
- * where batching amortizes network cost: `paywall`, non-install
535
- * `lifecycle` (foreground/background/session), `onboarding`,
536
- * `notification`, `custom`.
537
- *
538
- * Both priorities post to `/sdk/ingest/batch` (Phase 3.1 envelope) with
539
- * automatic fallback to `/sdk/events/batch` when the V2 endpoint is
540
- * absent (old server) or rejects the request. `OfflineQueue` handles
541
- * network-failure durability for both queues via the `PostFn` injected by
542
- * `ApiClient.postWithQueue`.
543
- */
544
- type EventPriority = "critical" | "normal";
545
- interface TrackOptions {
546
- priority?: EventPriority;
547
- }
548
-
549
483
  declare class ApiClient {
550
484
  private baseUrl;
551
485
  private webUrl;
@@ -611,129 +545,69 @@ declare class ApiClient {
611
545
  private flagDeps;
612
546
  }
613
547
 
548
+ type NetworkState = "online" | "offline" | "unknown";
549
+ type NetworkListener = (state: NetworkState) => void;
550
+ interface NetworkMonitorConfig {
551
+ debug: boolean;
552
+ checkInterval: number;
553
+ checkUrl: string;
554
+ }
555
+
556
+ declare class NetworkMonitorClass {
557
+ private config;
558
+ private listeners;
559
+ private currentState;
560
+ private appStateSubscription;
561
+ private initialized;
562
+ private checkIntervalId;
563
+ initialize(config?: Partial<NetworkMonitorConfig>): Promise<void>;
564
+ private setupFallbackDetection;
565
+ private setupAppStateListener;
566
+ private checkConnectivity;
567
+ private updateState;
568
+ private notifyListeners;
569
+ isOnline(): boolean;
570
+ getState(): NetworkState;
571
+ isInitialized(): boolean;
572
+ addListener(listener: NetworkListener): () => void;
573
+ removeListener(listener: NetworkListener): void;
574
+ forceCheck(): Promise<NetworkState>;
575
+ dispose(): void;
576
+ private log;
577
+ setDebug(debug: boolean): void;
578
+ }
579
+ declare const networkMonitor: NetworkMonitorClass;
580
+
614
581
  /**
615
- * Event payload emitted by the native module whenever StoreKit 2
616
- * (`Transaction.updates`) or Google Play Billing (`onPurchasesUpdated` +
617
- * refund diff) detects a renewal, refund, or cancellation.
582
+ * Guard usado pelo SessionManager.startSession() aguarda distinctId ficar
583
+ * disponível antes de criar a sessão. Raiz dos 55% users com total_sessions=0
584
+ * era session.startSession rodando em paralelo com identity.initialize() e
585
+ * batendo em distinctId vazio. Agora sessão só inicia depois da identity
586
+ * estar pronta; este guard é uma defesa extra caso alguém chame startSession
587
+ * manualmente antes do init terminar.
618
588
  */
619
- interface NativeTransactionUpdate {
620
- type: "renewed" | "refunded" | "canceled";
621
- transactionId: string;
622
- productId: string;
623
- amount?: number;
624
- currency?: string;
625
- }
626
- type TransactionUpdateListener = (update: NativeTransactionUpdate) => void;
627
- interface TransactionUpdateSubscription {
628
- remove(): void;
589
+ type DistinctIdProvider = () => string;
590
+
591
+ declare class IdentityError extends PaywalloError {
592
+ constructor(code: string, message: string);
629
593
  }
630
- declare function isAvailable(): boolean;
631
- declare const nativeStoreKit: {
632
- isAvailable: typeof isAvailable;
633
- getProducts(productIds: string[]): Promise<Product[]>;
634
- purchase(productId: string): Promise<Purchase | null>;
635
- finishTransaction(transactionId: string): Promise<void>;
636
- getActiveTransactions(): Promise<Purchase[]>;
637
- /**
638
- * Subscribes to native transaction update events (renewals, refunds,
639
- * cancellations) from StoreKit 2 (`Transaction.updates`) on iOS or
640
- * `PurchasesUpdatedListener` + refund diff on Android.
641
- *
642
- * Returns a subscription with a `remove()` method. The caller is
643
- * responsible for cleanup (typically on `Paywallo.reset()`).
644
- *
645
- * Returns `null` when the native module isn't available (non-mobile env,
646
- * native module not linked) — callers should treat null as a no-op.
647
- */
648
- subscribeToTransactionUpdates(listener: TransactionUpdateListener): TransactionUpdateSubscription | null;
594
+ declare const IDENTITY_ERROR_CODES: {
595
+ readonly NOT_INITIALIZED: "IDENTITY_NOT_INITIALIZED";
596
+ readonly DEVICE_ID_UNAVAILABLE: "IDENTITY_DEVICE_ID_UNAVAILABLE";
597
+ readonly STORAGE_READ_FAILED: "IDENTITY_STORAGE_READ_FAILED";
598
+ readonly STORAGE_WRITE_FAILED: "IDENTITY_STORAGE_WRITE_FAILED";
599
+ readonly IDENTIFY_FAILED: "IDENTITY_IDENTIFY_FAILED";
649
600
  };
650
601
 
651
- interface ValidateOptions {
652
- paywallPlacement?: string;
653
- variantKey?: string;
654
- paywallId?: string;
655
- variantId?: string;
656
- }
657
-
658
- declare class IAPService {
659
- private productsCache;
660
- private apiClient;
661
- private purchaseInFlight;
662
- /**
663
- * Idempotency guard against double-finish. Populated with transaction IDs
664
- * that have already been forwarded to `NativeStoreKit.finishTransaction`.
665
- */
666
- private finishedTransactions;
667
- private validator;
668
- private emitter;
669
- constructor(apiClient?: ApiClient);
670
- private get debug();
671
- private getDeviceCountry;
672
- private getApiClient;
673
- isAvailable(): boolean;
674
- loadProducts(productIds: string[]): Promise<Product[]>;
675
- getProduct(productId: string): Product | undefined;
676
- getCachedProducts(): Map<string, Product>;
677
- private finishTransaction;
678
- startTransactionListener(): void;
679
- stopTransactionListener(): void;
680
- emitTransactionUpdate(update: NativeTransactionUpdate): Promise<void>;
681
- purchase(productId: string, options?: ValidateOptions): Promise<PurchaseResult>;
682
- restore(): Promise<Purchase[]>;
683
- reset(): void;
684
- }
685
- declare function getIAPService(): IAPService;
686
-
687
- type PurchaseState = "idle" | "purchasing" | "restoring" | "error";
688
- interface IAPProduct {
689
- productId: string;
690
- price: string;
691
- currency: string;
692
- localizedPrice: string;
693
- title: string;
694
- description: string;
695
- type: "inapp" | "subs";
696
- subscriptionPeriodAndroid?: string;
697
- subscriptionPeriodNumberIOS?: string;
698
- subscriptionPeriodUnitIOS?: string;
699
- introductoryPrice?: string;
700
- introductoryPricePaymentModeIOS?: string;
701
- introductoryPriceNumberOfPeriodsIOS?: string;
702
- introductoryPriceSubscriptionPeriodIOS?: string;
703
- freeTrialPeriodAndroid?: string;
704
- trialDays: number;
705
- }
706
- interface IAPPurchase {
707
- productId: string;
708
- transactionId?: string;
709
- transactionDate: number;
710
- transactionReceipt: string;
711
- purchaseToken?: string;
712
- }
713
- interface PurchaseControllerConfig {
714
- debug?: boolean;
715
- validateOnServer?: boolean;
716
- serverValidationUrl?: string;
717
- }
718
- interface ProductPriceInfo {
719
- price: string;
720
- priceValue: number;
721
- currency: string;
722
- localizedPrice: string;
723
- pricePerMonth?: string;
724
- pricePerWeek?: string;
725
- pricePerDay?: string;
726
- }
727
-
728
- interface IdentityState {
729
- deviceId: string;
730
- email: string | null;
731
- properties: UserProperties;
732
- phone: string | null;
733
- firstName: string | null;
734
- lastName: string | null;
735
- dateOfBirth: string | null;
736
- gender: string | null;
602
+ interface IdentityState {
603
+ deviceId: string;
604
+ email: string | null;
605
+ properties: UserProperties;
606
+ phone: string | null;
607
+ firstName: string | null;
608
+ lastName: string | null;
609
+ dateOfBirth: string | null;
610
+ gender: string | null;
737
611
  }
738
612
  declare class IdentityManager {
739
613
  private deviceId;
@@ -767,29 +641,10 @@ declare class IdentityManager {
767
641
  }
768
642
  declare const identityManager: IdentityManager;
769
643
 
770
- /**
771
- * Guard usado pelo SessionManager.startSession() — aguarda distinctId ficar
772
- * disponível antes de criar a sessão. Raiz dos 55% users com total_sessions=0
773
- * era session.startSession rodando em paralelo com identity.initialize() e
774
- * batendo em distinctId vazio. Agora sessão só inicia depois da identity
775
- * estar pronta; este guard é uma defesa extra caso alguém chame startSession
776
- * manualmente antes do init terminar.
777
- */
778
- type DistinctIdProvider = () => string;
779
-
780
- declare class IdentityError extends PaywalloError {
781
- constructor(code: string, message: string);
782
- }
783
- declare const IDENTITY_ERROR_CODES: {
784
- readonly NOT_INITIALIZED: "IDENTITY_NOT_INITIALIZED";
785
- readonly DEVICE_ID_UNAVAILABLE: "IDENTITY_DEVICE_ID_UNAVAILABLE";
786
- readonly STORAGE_READ_FAILED: "IDENTITY_STORAGE_READ_FAILED";
787
- readonly STORAGE_WRITE_FAILED: "IDENTITY_STORAGE_WRITE_FAILED";
788
- readonly IDENTIFY_FAILED: "IDENTITY_IDENTIFY_FAILED";
789
- };
790
-
791
644
  declare class MetaBridge {
792
645
  private cachedAnonId;
646
+ private debug;
647
+ setDebug(debug: boolean): void;
793
648
  /** Sync read of the cached anonymous ID. Returns null until `getAnonymousID()` resolves once. */
794
649
  getCachedAnonymousID(): string | null;
795
650
  getAnonymousID(): Promise<string | null>;
@@ -800,101 +655,64 @@ declare class MetaBridge {
800
655
  }
801
656
  declare const metaBridge: MetaBridge;
802
657
 
803
- type NetworkState = "online" | "offline" | "unknown";
804
- type NetworkListener = (state: NetworkState) => void;
805
- interface NetworkMonitorConfig {
806
- debug: boolean;
807
- checkInterval: number;
808
- checkUrl: string;
658
+ interface FcmRemoteMessage {
659
+ messageId?: string;
660
+ data?: Record<string, string>;
661
+ notification?: {
662
+ title?: string;
663
+ body?: string;
664
+ };
665
+ sentTime?: number;
809
666
  }
810
-
811
- declare class NetworkMonitorClass {
812
- private config;
813
- private listeners;
814
- private currentState;
815
- private appStateSubscription;
816
- private initialized;
817
- private checkIntervalId;
818
- initialize(config?: Partial<NetworkMonitorConfig>): Promise<void>;
819
- private setupFallbackDetection;
820
- private setupAppStateListener;
821
- private checkConnectivity;
822
- private updateState;
823
- private notifyListeners;
824
- isOnline(): boolean;
825
- getState(): NetworkState;
826
- isInitialized(): boolean;
827
- addListener(listener: NetworkListener): () => void;
828
- removeListener(listener: NetworkListener): void;
829
- forceCheck(): Promise<NetworkState>;
830
- dispose(): void;
831
- private log;
832
- setDebug(debug: boolean): void;
667
+ /**
668
+ * Minimal interface satisfied by NativePushBridge (and any custom bridge).
669
+ * Use this type instead of concrete classes to keep code bridge-agnostic.
670
+ */
671
+ interface IPushBridge {
672
+ getToken(): Promise<string | null>;
673
+ getAPNSToken(): Promise<string | null>;
674
+ requestPermission(options?: {
675
+ provisional?: boolean;
676
+ }): Promise<number>;
677
+ hasPermission(): Promise<number>;
678
+ onTokenRefresh(cb: (token: string) => void): () => void;
679
+ onMessage(cb: (message: FcmRemoteMessage) => Promise<void>): () => void;
680
+ setBackgroundMessageHandler(cb: (message: FcmRemoteMessage) => Promise<void>): void;
681
+ getInitialNotification(): Promise<FcmRemoteMessage | null>;
833
682
  }
834
- declare const networkMonitor: NetworkMonitorClass;
835
683
 
836
- interface PlanProduct {
837
- id: string;
838
- name: string;
839
- description: string | null;
840
- type: string;
841
- appleProductId: string | null;
842
- googleProductId: string | null;
843
- billingPeriod: string | null;
844
- trialDays: number | null;
845
- priceUsd: number | null;
846
- regionalPrices: unknown;
847
- displayOrder: number;
848
- isActive: boolean;
849
- }
850
- interface Plan {
851
- id: string;
852
- identifier: string;
853
- name: string;
854
- description: string | null;
855
- metadata: unknown;
856
- products: PlanProduct[];
857
- }
858
- interface PlansResponse {
859
- plan: Plan | null;
860
- }
861
- interface AllPlansResponse {
862
- plans: Plan[];
863
- currentIdentifier: string | null;
864
- }
865
- interface PlanServiceConfig {
866
- apiClient: ApiClient;
867
- debug: boolean;
868
- }
869
- interface CachedPlans {
870
- data: AllPlansResponse;
871
- cachedAt: number;
872
- isStale: boolean;
684
+ declare class NativePushBridge implements IPushBridge {
685
+ getToken(): Promise<string | null>;
686
+ getAPNSToken(): Promise<string | null>;
687
+ requestPermission(options?: {
688
+ provisional?: boolean;
689
+ }): Promise<number>;
690
+ hasPermission(): Promise<number>;
691
+ onTokenRefresh(cb: (token: string) => void): () => void;
692
+ onMessage(cb: (message: FcmRemoteMessage) => Promise<void>): () => void;
693
+ setBackgroundMessageHandler(_cb: (message: FcmRemoteMessage) => Promise<void>): void;
694
+ getInitialNotification(): Promise<FcmRemoteMessage | null>;
873
695
  }
874
696
 
875
- declare class PlanCache {
876
- private cache;
877
- private ttl;
878
- get(): CachedPlans | null;
879
- set(data: AllPlansResponse): void;
880
- invalidate(): void;
881
- setTTL(ttl: number): void;
697
+ type NotificationsEnvironment = "sandbox" | "production";
698
+ interface NotificationsConfig {
699
+ debug?: boolean;
700
+ environment?: NotificationsEnvironment;
701
+ apiBaseUrl?: string;
882
702
  }
883
- declare const planCache: PlanCache;
884
703
 
885
- declare class PlanService {
886
- private config;
887
- private cache;
888
- init(config: PlanServiceConfig): void;
889
- getCurrentPlan(forceRefresh?: boolean): Promise<Plan | null>;
890
- getAllPlans(forceRefresh?: boolean): Promise<AllPlansResponse>;
891
- invalidateCache(): void;
892
- private getApiClient;
893
- private fetchCurrentPlan;
894
- private fetchAllPlans;
895
- private log;
704
+ declare const NOTIFICATIONS_ERROR_CODES: {
705
+ readonly TOKEN_UNAVAILABLE: "TOKEN_UNAVAILABLE";
706
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
707
+ readonly REGISTRATION_FAILED: "REGISTRATION_FAILED";
708
+ readonly NOT_INITIALIZED: "NOT_INITIALIZED";
709
+ readonly ABORTED: "ABORTED";
710
+ };
711
+ type NotificationsErrorCode = (typeof NOTIFICATIONS_ERROR_CODES)[keyof typeof NOTIFICATIONS_ERROR_CODES];
712
+ declare class NotificationsError extends PaywalloError {
713
+ readonly details?: unknown;
714
+ constructor(code: NotificationsErrorCode, message: string, details?: unknown);
896
715
  }
897
- declare const planService: PlanService;
898
716
 
899
717
  declare class SecureStorage {
900
718
  constructor(_debug?: boolean);
@@ -949,36 +767,10 @@ type NotificationListener = (event: {
949
767
  messageId: string;
950
768
  }) => void;
951
769
 
952
- interface FcmRemoteMessage {
953
- messageId?: string;
954
- data?: Record<string, string>;
955
- notification?: {
956
- title?: string;
957
- body?: string;
958
- };
959
- sentTime?: number;
960
- }
961
770
  /**
962
- * Minimal interface satisfied by NativePushBridge (and any custom bridge).
963
- * Use this type instead of concrete classes to keep code bridge-agnostic.
964
- */
965
- interface IPushBridge {
966
- getToken(): Promise<string | null>;
967
- getAPNSToken(): Promise<string | null>;
968
- requestPermission(options?: {
969
- provisional?: boolean;
970
- }): Promise<number>;
971
- hasPermission(): Promise<number>;
972
- onTokenRefresh(cb: (token: string) => void): () => void;
973
- onMessage(cb: (message: FcmRemoteMessage) => Promise<void>): () => void;
974
- setBackgroundMessageHandler(cb: (message: FcmRemoteMessage) => Promise<void>): void;
975
- getInitialNotification(): Promise<FcmRemoteMessage | null>;
976
- }
977
-
978
- /**
979
- * Minimal surface the facade needs from the SDK's unified event pipeline.
980
- * `PaywalloClient` implements it (forwarding to `ApiClient.trackEvent`
981
- * which ends up in the `EventBatcher`).
771
+ * Minimal surface the facade needs from the SDK's unified event pipeline.
772
+ * `PaywalloClient` implements it (forwarding to `ApiClient.trackEvent`
773
+ * which ends up in the `EventBatcher`).
982
774
  */
983
775
  interface EventBatcherLike {
984
776
  trackEvent(eventName: string, distinctId: string, properties?: Record<string, unknown>, timestamp?: number): Promise<void>;
@@ -1007,13 +799,6 @@ interface RNPlatform {
1007
799
  Version?: number | string;
1008
800
  }
1009
801
 
1010
- type NotificationsEnvironment = "sandbox" | "production";
1011
- interface NotificationsConfig {
1012
- debug?: boolean;
1013
- environment?: NotificationsEnvironment;
1014
- apiBaseUrl?: string;
1015
- }
1016
-
1017
802
  interface HandlersConfig {
1018
803
  eventBatcher: EventBatcherLike;
1019
804
  }
@@ -1096,31 +881,78 @@ declare class NotificationsManager {
1096
881
 
1097
882
  declare const notificationsManager: NotificationsManager;
1098
883
 
1099
- declare class NativePushBridge implements IPushBridge {
1100
- getToken(): Promise<string | null>;
1101
- getAPNSToken(): Promise<string | null>;
1102
- requestPermission(options?: {
1103
- provisional?: boolean;
1104
- }): Promise<number>;
1105
- hasPermission(): Promise<number>;
1106
- onTokenRefresh(cb: (token: string) => void): () => void;
1107
- onMessage(cb: (message: FcmRemoteMessage) => Promise<void>): () => void;
1108
- setBackgroundMessageHandler(_cb: (message: FcmRemoteMessage) => Promise<void>): void;
1109
- getInitialNotification(): Promise<FcmRemoteMessage | null>;
884
+ interface PlanProduct {
885
+ id: string;
886
+ name: string;
887
+ description: string | null;
888
+ type: string;
889
+ appleProductId: string | null;
890
+ googleProductId: string | null;
891
+ billingPeriod: string | null;
892
+ trialDays: number | null;
893
+ priceUsd: number | null;
894
+ regionalPrices: unknown;
895
+ displayOrder: number;
896
+ isActive: boolean;
897
+ }
898
+ interface Plan {
899
+ id: string;
900
+ identifier: string;
901
+ name: string;
902
+ description: string | null;
903
+ metadata: unknown;
904
+ products: PlanProduct[];
905
+ }
906
+ interface PlansResponse {
907
+ plan: Plan | null;
908
+ }
909
+ interface AllPlansResponse {
910
+ plans: Plan[];
911
+ currentIdentifier: string | null;
912
+ }
913
+ interface PlanServiceConfig {
914
+ apiClient: ApiClient;
915
+ debug: boolean;
916
+ }
917
+ interface CachedPlans {
918
+ data: AllPlansResponse;
919
+ cachedAt: number;
920
+ isStale: boolean;
1110
921
  }
1111
922
 
1112
- declare const NOTIFICATIONS_ERROR_CODES: {
1113
- readonly TOKEN_UNAVAILABLE: "TOKEN_UNAVAILABLE";
1114
- readonly PERMISSION_DENIED: "PERMISSION_DENIED";
1115
- readonly REGISTRATION_FAILED: "REGISTRATION_FAILED";
1116
- readonly NOT_INITIALIZED: "NOT_INITIALIZED";
1117
- readonly ABORTED: "ABORTED";
1118
- };
1119
- type NotificationsErrorCode = (typeof NOTIFICATIONS_ERROR_CODES)[keyof typeof NOTIFICATIONS_ERROR_CODES];
1120
- declare class NotificationsError extends PaywalloError {
1121
- readonly details?: unknown;
1122
- constructor(code: NotificationsErrorCode, message: string, details?: unknown);
923
+ declare class PlanCache {
924
+ private cache;
925
+ private ttl;
926
+ get(): CachedPlans | null;
927
+ set(data: AllPlansResponse): void;
928
+ invalidate(): void;
929
+ setTTL(ttl: number): void;
930
+ }
931
+ declare const planCache: PlanCache;
932
+
933
+ declare class PlanService {
934
+ private config;
935
+ private cache;
936
+ init(config: PlanServiceConfig): void;
937
+ getCurrentPlan(forceRefresh?: boolean): Promise<Plan | null>;
938
+ getAllPlans(forceRefresh?: boolean): Promise<AllPlansResponse>;
939
+ invalidateCache(): void;
940
+ private getApiClient;
941
+ private fetchCurrentPlan;
942
+ private fetchAllPlans;
943
+ private log;
944
+ }
945
+ declare const planService: PlanService;
946
+
947
+ declare class SessionError extends PaywalloError {
948
+ constructor(code: string, message: string);
1123
949
  }
950
+ declare const SESSION_ERROR_CODES: {
951
+ readonly NOT_INITIALIZED: "SESSION_NOT_INITIALIZED";
952
+ readonly START_FAILED: "SESSION_START_FAILED";
953
+ readonly END_FAILED: "SESSION_END_FAILED";
954
+ readonly RESTORE_FAILED: "SESSION_RESTORE_FAILED";
955
+ };
1124
956
 
1125
957
  interface SessionState {
1126
958
  sessionId: string | null;
@@ -1174,16 +1006,6 @@ declare class SessionManager {
1174
1006
  }
1175
1007
  declare const sessionManager: SessionManager;
1176
1008
 
1177
- declare class SessionError extends PaywalloError {
1178
- constructor(code: string, message: string);
1179
- }
1180
- declare const SESSION_ERROR_CODES: {
1181
- readonly NOT_INITIALIZED: "SESSION_NOT_INITIALIZED";
1182
- readonly START_FAILED: "SESSION_START_FAILED";
1183
- readonly END_FAILED: "SESSION_END_FAILED";
1184
- readonly RESTORE_FAILED: "SESSION_RESTORE_FAILED";
1185
- };
1186
-
1187
1009
  interface PreloadCampaignResult {
1188
1010
  success: boolean;
1189
1011
  error?: Error;
@@ -1447,156 +1269,299 @@ declare class QueueProcessorClass {
1447
1269
  }
1448
1270
  declare const queueProcessor: QueueProcessorClass;
1449
1271
 
1272
+ interface ValidateOptions {
1273
+ paywallPlacement?: string;
1274
+ variantKey?: string;
1275
+ paywallId?: string;
1276
+ variantId?: string;
1277
+ }
1278
+
1450
1279
  /**
1451
- * Minimal surface the OnboardingManager needs from the unified event pipeline.
1452
- * `PaywalloClient` satisfies this interface (forwarding to
1453
- * `ApiClient.trackEvent` `EventBatcher` `/api/v1/events/batch`).
1280
+ * Event payload emitted by the native module whenever StoreKit 2
1281
+ * (`Transaction.updates`) or Google Play Billing (`onPurchasesUpdated` +
1282
+ * refund diff) detects a renewal, refund, or cancellation.
1454
1283
  */
1455
- interface OnboardingEventPipeline {
1456
- trackEvent(eventName: string, distinctId: string, properties?: Record<string, unknown>, timestamp?: number): Promise<void>;
1457
- getDistinctId(): string;
1284
+ interface NativeTransactionUpdate {
1285
+ type: "renewed" | "refunded" | "canceled";
1286
+ transactionId: string;
1287
+ productId: string;
1288
+ amount?: number;
1289
+ currency?: string;
1458
1290
  }
1459
- interface OnboardingDepsConfig {
1460
- pipeline: OnboardingEventPipeline;
1461
- debug?: boolean;
1291
+ type TransactionUpdateListener = (update: NativeTransactionUpdate) => void;
1292
+ interface TransactionUpdateSubscription {
1293
+ remove(): void;
1462
1294
  }
1463
- declare class OnboardingManager {
1464
- private pipeline;
1465
- private debug;
1466
- private lastStep;
1467
- private finished;
1468
- /**
1469
- * Injects runtime dependencies. Called by PaywalloClient during init.
1470
- */
1471
- injectDeps(config: OnboardingDepsConfig): void;
1295
+ declare function isAvailable(): boolean;
1296
+ declare const nativeStoreKit: {
1297
+ isAvailable: typeof isAvailable;
1298
+ getProducts(productIds: string[]): Promise<Product[]>;
1299
+ purchase(productId: string): Promise<Purchase | null>;
1300
+ finishTransaction(transactionId: string): Promise<void>;
1301
+ getActiveTransactions(): Promise<Purchase[]>;
1472
1302
  /**
1473
- * Tracks an onboarding step view.
1474
- * Saves the step name internally for implicit drop detection on the backend.
1303
+ * Subscribes to native transaction update events (renewals, refunds,
1304
+ * cancellations) from StoreKit 2 (`Transaction.updates`) on iOS or
1305
+ * `PurchasesUpdatedListener` + refund diff on Android.
1475
1306
  *
1476
- * @param stepName - Unique name for this onboarding step.
1477
- */
1478
- step(stepName: string): Promise<void>;
1479
- /**
1480
- * Tracks successful completion of the onboarding flow.
1481
- * Marks the flow as finished.
1482
- */
1483
- complete(): Promise<void>;
1484
- /**
1485
- * Tracks an explicit drop (abandonment) at the given step.
1486
- * Marks the flow as finished.
1307
+ * Returns a subscription with a `remove()` method. The caller is
1308
+ * responsible for cleanup (typically on `Paywallo.reset()`).
1487
1309
  *
1488
- * @param stepName - The step name where the user dropped off.
1310
+ * Returns `null` when the native module isn't available (non-mobile env,
1311
+ * native module not linked) — callers should treat null as a no-op.
1489
1312
  */
1490
- drop(stepName: string): Promise<void>;
1491
- /** Returns the last step name seen, or null if no step was tracked yet. */
1492
- getLastStep(): string | null;
1493
- /** Returns whether the flow has been marked as finished (complete or drop). */
1494
- isFinished(): boolean;
1495
- private emit;
1496
- private assertConfig;
1497
- private validateStepName;
1498
- }
1499
- declare const onboardingManager: OnboardingManager;
1500
-
1501
- declare class OnboardingError extends PaywalloError {
1502
- constructor(code: string, message: string);
1503
- }
1504
- declare const ONBOARDING_ERROR_CODES: {
1505
- readonly NOT_INITIALIZED: "ONBOARDING_NOT_INITIALIZED";
1506
- readonly INVALID_STEP_NAME: "ONBOARDING_INVALID_STEP_NAME";
1313
+ subscribeToTransactionUpdates(listener: TransactionUpdateListener): TransactionUpdateSubscription | null;
1507
1314
  };
1508
1315
 
1509
- /** Payload sent with onboarding.step events. */
1510
- interface OnboardingStepPayload {
1511
- step_name: string;
1512
- }
1513
- /** Payload sent with onboarding.drop events. */
1514
- interface OnboardingDropPayload {
1515
- step_name: string;
1516
- }
1517
-
1518
- interface UseOnboardingResult {
1519
- step: (stepName: string) => Promise<void>;
1520
- complete: () => Promise<void>;
1521
- drop: (stepName: string) => Promise<void>;
1316
+ declare class IAPService {
1317
+ private productsCache;
1318
+ private apiClient;
1319
+ private purchaseInFlight;
1320
+ /**
1321
+ * Idempotency guard against double-finish. Populated with transaction IDs
1322
+ * that have already been forwarded to `NativeStoreKit.finishTransaction`.
1323
+ */
1324
+ private finishedTransactions;
1325
+ private validator;
1326
+ private emitter;
1327
+ constructor(apiClient?: ApiClient);
1328
+ private get debug();
1329
+ private getDeviceCountry;
1330
+ private getApiClient;
1331
+ isAvailable(): boolean;
1332
+ loadProducts(productIds: string[]): Promise<Product[]>;
1333
+ getProduct(productId: string): Product | undefined;
1334
+ getCachedProducts(): Map<string, Product>;
1335
+ private finishTransaction;
1336
+ startTransactionListener(): void;
1337
+ stopTransactionListener(): void;
1338
+ emitTransactionUpdate(update: NativeTransactionUpdate): Promise<void>;
1339
+ purchase(productId: string, options?: ValidateOptions): Promise<PurchaseResult>;
1340
+ restore(): Promise<Purchase[]>;
1341
+ reset(): void;
1522
1342
  }
1523
- /**
1524
- * React hook that exposes bound onboarding tracking methods.
1525
- * Wraps `onboardingManager` with stable `useCallback` references.
1526
- */
1527
- declare function useOnboarding(): UseOnboardingResult;
1343
+ declare function getIAPService(): IAPService;
1528
1344
 
1529
- declare class CampaignError extends PaywalloError {
1530
- constructor(code: string, message: string);
1531
- }
1532
- declare const CAMPAIGN_ERROR_CODES: {
1533
- readonly NOT_INITIALIZED: "CAMPAIGN_NOT_INITIALIZED";
1534
- readonly FETCH_FAILED: "CAMPAIGN_FETCH_FAILED";
1535
- readonly PRELOAD_FAILED: "CAMPAIGN_PRELOAD_FAILED";
1536
- readonly NOT_FOUND: "CAMPAIGN_NOT_FOUND";
1537
- readonly PRESENT_FAILED: "CAMPAIGN_PRESENT_FAILED";
1538
- };
1345
+ type PurchaseState = "idle" | "purchasing" | "restoring" | "error";
1346
+ interface IAPProduct {
1347
+ productId: string;
1348
+ price: string;
1349
+ currency: string;
1350
+ localizedPrice: string;
1351
+ title: string;
1352
+ description: string;
1353
+ type: "inapp" | "subs";
1354
+ subscriptionPeriodAndroid?: string;
1355
+ subscriptionPeriodNumberIOS?: string;
1356
+ subscriptionPeriodUnitIOS?: string;
1357
+ introductoryPrice?: string;
1358
+ introductoryPricePaymentModeIOS?: string;
1359
+ introductoryPriceNumberOfPeriodsIOS?: string;
1360
+ introductoryPriceSubscriptionPeriodIOS?: string;
1361
+ freeTrialPeriodAndroid?: string;
1362
+ trialDays: number;
1363
+ }
1364
+ interface IAPPurchase {
1365
+ productId: string;
1366
+ transactionId?: string;
1367
+ transactionDate: number;
1368
+ transactionReceipt: string;
1369
+ purchaseToken?: string;
1370
+ }
1371
+ interface PurchaseControllerConfig {
1372
+ debug?: boolean;
1373
+ validateOnServer?: boolean;
1374
+ serverValidationUrl?: string;
1375
+ }
1376
+ interface ProductPriceInfo {
1377
+ price: string;
1378
+ priceValue: number;
1379
+ currency: string;
1380
+ localizedPrice: string;
1381
+ pricePerMonth?: string;
1382
+ pricePerWeek?: string;
1383
+ pricePerDay?: string;
1384
+ }
1539
1385
 
1540
- declare function usePaywallo(): PaywalloContextValue;
1386
+ interface OfferingProduct {
1387
+ id: string;
1388
+ name: string;
1389
+ description: string | null;
1390
+ type: string;
1391
+ productId: string;
1392
+ billingPeriod: string | null;
1393
+ trialDays: number | null;
1394
+ priceUsd: number | null;
1395
+ regionalPrices: unknown;
1396
+ isActive: boolean;
1397
+ }
1398
+ interface Offering {
1399
+ id: string;
1400
+ identifier: string;
1401
+ name: string;
1402
+ description: string | null;
1403
+ metadata: unknown;
1404
+ product: OfferingProduct;
1405
+ }
1406
+ interface OfferingServiceConfig {
1407
+ apiClient: ApiClient;
1408
+ debug: boolean;
1409
+ }
1410
+ interface CachedOfferings {
1411
+ data: Offering[];
1412
+ cachedAt: number;
1413
+ isStale: boolean;
1414
+ }
1541
1415
 
1542
- interface UsePlansResult {
1543
- currentPlan: Plan | null;
1544
- allPlans: Plan[];
1545
- isLoading: boolean;
1546
- error: Error | null;
1547
- refresh: () => Promise<void>;
1416
+ declare class OfferingService {
1417
+ private config;
1418
+ private cache;
1419
+ private ttl;
1420
+ init(config: OfferingServiceConfig): void;
1421
+ getOfferings(ids?: string[]): Promise<Offering[]>;
1422
+ invalidateCache(): void;
1423
+ private getMemCache;
1424
+ private setMemCache;
1425
+ private filterByIds;
1426
+ private getApiClient;
1427
+ private fetchOfferings;
1428
+ private log;
1548
1429
  }
1549
- declare function usePlans(): UsePlansResult;
1430
+ declare const offeringService: OfferingService;
1550
1431
 
1551
- interface RestoreResult {
1552
- restoredCount: number;
1553
- productIds: string[];
1432
+ declare class OnboardingError extends PaywalloError {
1433
+ constructor(code: string, message: string);
1554
1434
  }
1555
- interface UsePlanPurchaseResult {
1556
- purchase: (productId: string) => Promise<PurchaseResult | null>;
1557
- restore: () => Promise<RestoreResult | null>;
1558
- isPurchasing: boolean;
1559
- isRestoring: boolean;
1560
- error: Error | null;
1435
+ declare const ONBOARDING_ERROR_CODES: {
1436
+ readonly NOT_INITIALIZED: "ONBOARDING_NOT_INITIALIZED";
1437
+ readonly INVALID_STEP_NAME: "ONBOARDING_INVALID_STEP_NAME";
1438
+ };
1439
+
1440
+ /**
1441
+ * Minimal surface the OnboardingManager needs from the unified event pipeline.
1442
+ * `PaywalloClient` satisfies this interface (forwarding to
1443
+ * `ApiClient.trackEvent` → `EventBatcher` → `/api/v1/events/batch`).
1444
+ */
1445
+ interface OnboardingEventPipeline {
1446
+ trackEvent(eventName: string, distinctId: string, properties?: Record<string, unknown>, timestamp?: number): Promise<void>;
1447
+ getDistinctId(): string;
1561
1448
  }
1562
- declare function usePlanPurchase(): UsePlanPurchaseResult;
1449
+ interface OnboardingDepsConfig {
1450
+ pipeline: OnboardingEventPipeline;
1451
+ debug?: boolean;
1452
+ }
1453
+ declare class OnboardingManager {
1454
+ private pipeline;
1455
+ private debug;
1456
+ private lastStep;
1457
+ private finished;
1458
+ /**
1459
+ * Injects runtime dependencies. Called by PaywalloClient during init.
1460
+ */
1461
+ injectDeps(config: OnboardingDepsConfig): void;
1462
+ /**
1463
+ * Tracks an onboarding step view.
1464
+ * Saves the step name internally for implicit drop detection on the backend.
1465
+ *
1466
+ * @param stepName - Unique name for this onboarding step.
1467
+ */
1468
+ step(stepName: string): Promise<void>;
1469
+ /**
1470
+ * Tracks successful completion of the onboarding flow.
1471
+ * Marks the flow as finished.
1472
+ */
1473
+ complete(): Promise<void>;
1474
+ /**
1475
+ * Tracks an explicit drop (abandonment) at the given step.
1476
+ * Marks the flow as finished.
1477
+ *
1478
+ * @param stepName - The step name where the user dropped off.
1479
+ */
1480
+ drop(stepName: string): Promise<void>;
1481
+ /** Returns the last step name seen, or null if no step was tracked yet. */
1482
+ getLastStep(): string | null;
1483
+ /** Returns whether the flow has been marked as finished (complete or drop). */
1484
+ isFinished(): boolean;
1485
+ private emit;
1486
+ private assertConfig;
1487
+ private validateStepName;
1488
+ }
1489
+ declare const onboardingManager: OnboardingManager;
1563
1490
 
1564
- interface FormattedProduct extends ProductPriceInfo {
1565
- productId: string;
1566
- title: string;
1567
- description: string;
1568
- subscriptionPeriod?: string;
1569
- introductoryPrice?: string;
1570
- freeTrialPeriod?: string;
1571
- trialDays: number;
1491
+ /** Payload sent with onboarding.step events. */
1492
+ interface OnboardingStepPayload {
1493
+ step_name: string;
1494
+ }
1495
+ /** Payload sent with onboarding.drop events. */
1496
+ interface OnboardingDropPayload {
1497
+ step_name: string;
1572
1498
  }
1573
1499
 
1574
- interface UseProductsResult {
1575
- products: IAPProduct[];
1576
- formattedProducts: FormattedProduct[];
1577
- isLoading: boolean;
1578
- error: Error | null;
1579
- loadProducts: (productIds: string[]) => Promise<void>;
1580
- getProduct: (productId: string) => IAPProduct | undefined;
1581
- getFormattedProduct: (productId: string) => FormattedProduct | undefined;
1582
- getPriceInfo: (productId: string) => ProductPriceInfo | undefined;
1500
+ interface PaywallContextValue {
1501
+ nodes: Record<string, PaywallNode>;
1502
+ rootId: string;
1503
+ language: string;
1504
+ defaultLanguage: string;
1505
+ products: Map<string, Product>;
1506
+ selectedProductId: string | null;
1507
+ primaryProductId: string | null;
1508
+ secondaryProductId: string | null;
1509
+ currentNavigationIndex: number;
1510
+ currentTabIndex: number;
1511
+ trialEnabled: boolean;
1512
+ selectedPeriod: string | null;
1513
+ isPurchasing: boolean;
1514
+ exitOfferVisible: boolean;
1515
+ exitOfferTriggeredByBackButton: boolean;
1516
+ onClose: () => void;
1517
+ onTryClose: () => void;
1518
+ onSelectProduct: (productId: string) => void;
1519
+ onPurchase: (productId: string) => void;
1520
+ onRestore: () => void;
1521
+ onNavigate: (target: "next" | "previous" | "first" | "last" | number) => void;
1522
+ onSetTab: (index: number) => void;
1523
+ onSetVariable: (name: string, value: string) => void;
1524
+ onToggleTrial: (enabled: boolean) => void;
1525
+ onSelectPeriod: (value: string) => void;
1526
+ onOpenUrl: (url: string, inBrowser?: boolean) => void;
1527
+ onTapBehavior: (behavior: TapBehavior) => void;
1528
+ onShowExitOffer: () => void;
1529
+ onDismissExitOffer: () => void;
1530
+ onTriggerBackButton: () => void;
1583
1531
  }
1584
- declare function useProducts(initialProductIds?: string[]): UseProductsResult;
1532
+ declare const PaywallContext: React.Context<PaywallContextValue | null>;
1533
+ declare function usePaywallContext(): PaywallContextValue;
1585
1534
 
1586
- interface PurchaseOutcome {
1587
- status: "success" | "cancelled" | "failed";
1588
- purchase?: IAPPurchase;
1589
- error?: PurchaseError;
1535
+ declare class PaywallError extends PaywalloError {
1536
+ constructor(code: string, message: string);
1590
1537
  }
1591
- interface UsePurchaseResult {
1592
- state: PurchaseState;
1593
- purchase: (productId: string) => Promise<PurchaseOutcome>;
1594
- restore: () => Promise<IAPPurchase[]>;
1595
- error: PurchaseError | null;
1596
- isPurchasing: boolean;
1597
- isRestoring: boolean;
1538
+ declare const PAYWALL_ERROR_CODES: {
1539
+ readonly NOT_INITIALIZED: "PAYWALL_NOT_INITIALIZED";
1540
+ readonly NOT_FOUND: "PAYWALL_NOT_FOUND";
1541
+ readonly RENDER_FAILED: "PAYWALL_RENDER_FAILED";
1542
+ readonly LOAD_FAILED: "PAYWALL_LOAD_FAILED";
1543
+ readonly DISMISS_FAILED: "PAYWALL_DISMISS_FAILED";
1544
+ readonly INVALID_CONFIG: "PAYWALL_INVALID_CONFIG";
1545
+ };
1546
+
1547
+ interface PaywallModalProps {
1548
+ placement: string;
1549
+ visible: boolean;
1550
+ onResult: (result: PaywallResult) => void;
1551
+ paywallConfig?: {
1552
+ id: string;
1553
+ placement: string;
1554
+ config: Record<string, unknown>;
1555
+ primaryProductId?: string;
1556
+ secondaryProductId?: string;
1557
+ };
1558
+ preloadedProducts?: Map<string, Product>;
1559
+ variantKey?: string;
1560
+ campaignId?: string;
1561
+ /** UUID de `paywall_variants` (sub-fase 2.14). */
1562
+ variantId?: string;
1598
1563
  }
1599
- declare function usePurchase(): UsePurchaseResult;
1564
+ declare function PaywallModal({ placement, visible, onResult, paywallConfig: preloadedConfig, preloadedProducts, variantKey, campaignId, variantId, }: PaywallModalProps): React__default.ReactElement | null;
1600
1565
 
1601
1566
  type SubscriptionStatus = "active" | "expired" | "grace_period" | "billing_retry" | "canceled" | "paused" | "unknown";
1602
1567
  interface SubscriptionInfo {
@@ -1631,23 +1596,6 @@ interface SubscriptionManagerConfig {
1631
1596
  debug?: boolean;
1632
1597
  }
1633
1598
 
1634
- interface UseSubscriptionResult {
1635
- subscription: SubscriptionInfo | null;
1636
- isActive: boolean;
1637
- isLoading: boolean;
1638
- error: Error | null;
1639
- entitlements: string[];
1640
- refresh: () => Promise<void>;
1641
- restore: () => Promise<void>;
1642
- }
1643
- declare function useSubscription(): UseSubscriptionResult;
1644
-
1645
- interface PaywalloProviderProps {
1646
- children: React__default.ReactNode;
1647
- config: PaywalloConfig;
1648
- }
1649
- declare function PaywalloProvider({ children, config }: PaywalloProviderProps): React__default.ReactElement;
1650
-
1651
1599
  declare class SubscriptionCache {
1652
1600
  private ttl;
1653
1601
  private memoryCache;
@@ -1689,6 +1637,118 @@ declare class SubscriptionManagerClass {
1689
1637
  }
1690
1638
  declare const subscriptionManager: SubscriptionManagerClass;
1691
1639
 
1640
+ declare class CampaignError extends PaywalloError {
1641
+ constructor(code: string, message: string);
1642
+ }
1643
+ declare const CAMPAIGN_ERROR_CODES: {
1644
+ readonly NOT_INITIALIZED: "CAMPAIGN_NOT_INITIALIZED";
1645
+ readonly FETCH_FAILED: "CAMPAIGN_FETCH_FAILED";
1646
+ readonly PRELOAD_FAILED: "CAMPAIGN_PRELOAD_FAILED";
1647
+ readonly NOT_FOUND: "CAMPAIGN_NOT_FOUND";
1648
+ readonly PRESENT_FAILED: "CAMPAIGN_PRESENT_FAILED";
1649
+ };
1650
+
1651
+ interface UseOfferingPurchaseResult {
1652
+ purchase: (productId: string) => Promise<void>;
1653
+ isPurchasing: boolean;
1654
+ }
1655
+ declare function useOfferingPurchase(): UseOfferingPurchaseResult;
1656
+
1657
+ interface UseOfferingsResult {
1658
+ offerings: Offering[];
1659
+ isLoading: boolean;
1660
+ }
1661
+ declare function useOfferings(ids?: string[]): UseOfferingsResult;
1662
+
1663
+ interface UseOnboardingResult {
1664
+ step: (stepName: string) => Promise<void>;
1665
+ complete: () => Promise<void>;
1666
+ drop: (stepName: string) => Promise<void>;
1667
+ }
1668
+ /**
1669
+ * React hook that exposes bound onboarding tracking methods.
1670
+ * Wraps `onboardingManager` with stable `useCallback` references.
1671
+ */
1672
+ declare function useOnboarding(): UseOnboardingResult;
1673
+
1674
+ declare function usePaywallo(): PaywalloContextValue;
1675
+
1676
+ interface RestoreResult {
1677
+ restoredCount: number;
1678
+ productIds: string[];
1679
+ }
1680
+ interface UsePlanPurchaseResult {
1681
+ purchase: (productId: string) => Promise<PurchaseResult | null>;
1682
+ restore: () => Promise<RestoreResult | null>;
1683
+ isPurchasing: boolean;
1684
+ isRestoring: boolean;
1685
+ error: Error | null;
1686
+ }
1687
+ declare function usePlanPurchase(): UsePlanPurchaseResult;
1688
+
1689
+ interface UsePlansResult {
1690
+ currentPlan: Plan | null;
1691
+ allPlans: Plan[];
1692
+ isLoading: boolean;
1693
+ error: Error | null;
1694
+ refresh: () => Promise<void>;
1695
+ }
1696
+ declare function usePlans(): UsePlansResult;
1697
+
1698
+ interface FormattedProduct extends ProductPriceInfo {
1699
+ productId: string;
1700
+ title: string;
1701
+ description: string;
1702
+ subscriptionPeriod?: string;
1703
+ introductoryPrice?: string;
1704
+ freeTrialPeriod?: string;
1705
+ trialDays: number;
1706
+ }
1707
+
1708
+ interface UseProductsResult {
1709
+ products: IAPProduct[];
1710
+ formattedProducts: FormattedProduct[];
1711
+ isLoading: boolean;
1712
+ error: Error | null;
1713
+ loadProducts: (productIds: string[]) => Promise<void>;
1714
+ getProduct: (productId: string) => IAPProduct | undefined;
1715
+ getFormattedProduct: (productId: string) => FormattedProduct | undefined;
1716
+ getPriceInfo: (productId: string) => ProductPriceInfo | undefined;
1717
+ }
1718
+ declare function useProducts(initialProductIds?: string[]): UseProductsResult;
1719
+
1720
+ interface PurchaseOutcome {
1721
+ status: "success" | "cancelled" | "failed";
1722
+ purchase?: IAPPurchase;
1723
+ error?: PurchaseError;
1724
+ }
1725
+ interface UsePurchaseResult {
1726
+ state: PurchaseState;
1727
+ purchase: (productId: string) => Promise<PurchaseOutcome>;
1728
+ restore: () => Promise<IAPPurchase[]>;
1729
+ error: PurchaseError | null;
1730
+ isPurchasing: boolean;
1731
+ isRestoring: boolean;
1732
+ }
1733
+ declare function usePurchase(): UsePurchaseResult;
1734
+
1735
+ interface UseSubscriptionResult {
1736
+ subscription: SubscriptionInfo | null;
1737
+ isActive: boolean;
1738
+ isLoading: boolean;
1739
+ error: Error | null;
1740
+ entitlements: string[];
1741
+ refresh: () => Promise<void>;
1742
+ restore: () => Promise<void>;
1743
+ }
1744
+ declare function useSubscription(): UseSubscriptionResult;
1745
+
1746
+ interface PaywalloProviderProps {
1747
+ children: React__default.ReactNode;
1748
+ config: PaywalloConfig;
1749
+ }
1750
+ declare function PaywalloProvider({ children, config }: PaywalloProviderProps): React__default.ReactElement;
1751
+
1692
1752
  declare function setCurrentLanguage(language: string): void;
1693
1753
  declare function setDefaultLanguage(language: string): void;
1694
1754
  declare function getCurrentLanguage(): string;
@@ -1725,4 +1785,4 @@ declare function hasVariables(text: string): boolean;
1725
1785
 
1726
1786
  declare const Paywallo: IPaywalloClient;
1727
1787
 
1728
- export { type AllPlansResponse, ApiClient, type ApiClientConfig, type BlockType, type BoxSpacing, CAMPAIGN_ERROR_CODES, type CachedPlans, type CachedSubscription, CampaignError, type CampaignPresentOptions, type CampaignResponse, type CampaignResult, type ConditionalFlagContext, type ConditionalFlagResult, type DeviceTokenRegistration, PURCHASE_ERROR_CODES as ERROR_CODES, type EmergencyPaywallResponse, type Environment, type FlagVariant, HttpClient, type HttpClientConfig, type HttpResponse, type IAPProduct, type IAPPurchase, IAPService, IDENTITY_ERROR_CODES, type IPaywalloClient, type IPushBridge, type IdentifyOptions, IdentityError, IdentityManager, type IdentityState, type LocalizedText, MetaBridge, NOTIFICATIONS_ERROR_CODES, NativePushBridge, type NetworkListener, type NetworkMonitorConfig, type NetworkState, type NotificationEventType, type NotificationListener, type NotificationPayload, NotificationsError, NotificationsManager, ONBOARDING_ERROR_CODES, type OfflineQueueConfig, type OnboardingDropPayload, OnboardingError, OnboardingManager, type OnboardingStepPayload, PAYWALL_ERROR_CODES, PURCHASE_ERROR_CODES, type PaywallBlockConfig, type PaywallConfig, PaywallContext, PaywallError, type PaywallErrorStrings$1 as PaywallErrorStrings, PaywallModal, type PaywallNode, type PaywallPresentOptions, type PaywallResult, type PaywallState, Paywallo, PaywalloClient, type PaywalloConfig, PaywalloContext, PaywalloError, type PaywalloInitConfig, PaywalloProvider, type PaywalloProviderProps, type Plan, PlanCache, type PlanProduct, PlanService, type PlanServiceConfig, type PlansResponse, type PrePromptHandle, type PrePromptOptions, type PreloadCampaignResult, type PreloadResult, type Product, type ProductPriceInfo, type Purchase, type PurchaseControllerConfig, PurchaseError, type PurchaseResult, type PurchaseState, type PushPermissionStatus, type PushPlatform, type QueueEvent, type QueueItem, type QueueListener, type QueueProcessorConfig, type RequestOptions, type RestoreResult$1 as RestoreResult, type RetryConfig, SESSION_ERROR_CODES, type SessionConfig, SessionError, SessionManager, type SessionState, type Subscription, SubscriptionCache, type SubscriptionInfo, type SubscriptionManagerConfig, type SubscriptionPlatform, type SubscriptionStatus$1 as SubscriptionStatus, type SubscriptionStatusResponse$1 as SubscriptionStatusResponse, type TapBehavior, type TrackEventOptions, type UserProperties, type ValidatePurchaseResponse, type VariableContext, createPurchaseError, Paywallo as default, detectDeviceLanguage, getCurrentLanguage, getDefaultLanguage, getIAPService, getLocalizedString, hasVariables, identityManager, initLocalization, metaBridge, nativeStoreKit, networkMonitor, notificationsManager, offlineQueue, onboardingManager, parseVariables, planCache, planService, queueProcessor, resolveText, sessionManager, setCurrentLanguage, setDefaultLanguage, subscriptionManager, useOnboarding, usePaywallContext, usePaywallo, usePlanPurchase, usePlans, useProducts, usePurchase, useSubscription };
1788
+ export { type AllPlansResponse, ApiClient, type ApiClientConfig, type BlockType, type BoxSpacing, CAMPAIGN_ERROR_CODES, type CachedOfferings, type CachedPlans, type CachedSubscription, CampaignError, type CampaignPresentOptions, type CampaignResponse, type CampaignResult, type ConditionalFlagContext, type ConditionalFlagResult, type DeviceTokenRegistration, PURCHASE_ERROR_CODES as ERROR_CODES, type EmergencyPaywallResponse, type Environment, type FlagVariant, HttpClient, type HttpClientConfig, type HttpResponse, type IAPProduct, type IAPPurchase, IAPService, IDENTITY_ERROR_CODES, type IPaywalloClient, type IPushBridge, type IdentifyOptions, IdentityError, IdentityManager, type IdentityState, type LocalizedText, MetaBridge, NOTIFICATIONS_ERROR_CODES, NativePushBridge, type NetworkListener, type NetworkMonitorConfig, type NetworkState, type NotificationEventType, type NotificationListener, type NotificationPayload, NotificationsError, NotificationsManager, ONBOARDING_ERROR_CODES, type Offering, type OfferingProduct, OfferingService, type OfferingServiceConfig, type OfflineQueueConfig, type OnboardingDropPayload, OnboardingError, OnboardingManager, type OnboardingStepPayload, PAYWALL_ERROR_CODES, PURCHASE_ERROR_CODES, type PaywallBlockConfig, type PaywallConfig, PaywallContext, PaywallError, type PaywallErrorStrings$1 as PaywallErrorStrings, PaywallModal, type PaywallNode, type PaywallPresentOptions, type PaywallResult, type PaywallState, Paywallo, PaywalloClient, type PaywalloConfig, PaywalloContext, PaywalloError, type PaywalloInitConfig, PaywalloProvider, type PaywalloProviderProps, type Plan, PlanCache, type PlanProduct, PlanService, type PlanServiceConfig, type PlansResponse, type PrePromptHandle, type PrePromptOptions, type PreloadCampaignResult, type PreloadResult, type Product, type ProductPriceInfo, type Purchase, type PurchaseControllerConfig, PurchaseError, type PurchaseResult, type PurchaseState, type PushPermissionStatus, type PushPlatform, type QueueEvent, type QueueItem, type QueueListener, type QueueProcessorConfig, type RequestOptions, type RestoreResult$1 as RestoreResult, type RetryConfig, SESSION_ERROR_CODES, type SessionConfig, SessionError, SessionManager, type SessionState, type Subscription, SubscriptionCache, type SubscriptionInfo, type SubscriptionManagerConfig, type SubscriptionPlatform, type SubscriptionStatus$1 as SubscriptionStatus, type SubscriptionStatusResponse$1 as SubscriptionStatusResponse, type TapBehavior, type TrackEventOptions, type UserProperties, type ValidatePurchaseResponse, type VariableContext, createPurchaseError, Paywallo as default, detectDeviceLanguage, getCurrentLanguage, getDefaultLanguage, getIAPService, getLocalizedString, hasVariables, identityManager, initLocalization, metaBridge, nativeStoreKit, networkMonitor, notificationsManager, offeringService, offlineQueue, onboardingManager, parseVariables, planCache, planService, queueProcessor, resolveText, sessionManager, setCurrentLanguage, setDefaultLanguage, subscriptionManager, useOfferingPurchase, useOfferings, useOnboarding, usePaywallContext, usePaywallo, usePlanPurchase, usePlans, useProducts, usePurchase, useSubscription };