@solvapay/react 1.0.7 → 1.0.8-preview.2

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.ts CHANGED
@@ -1,524 +1,11 @@
1
- import React$1 from 'react';
2
- import * as _stripe_stripe_js from '@stripe/stripe-js';
3
- import { PaymentIntent, Stripe } from '@stripe/stripe-js';
4
- import { ProcessPaymentResult, ActivatePlanResult } from '@solvapay/server';
1
+ import React from 'react';
2
+ import { S as SolvaPayProviderProps, P as PaymentFormProps, a as PrefillCustomer, b as PaymentFormSummary, c as PaymentFormCustomerFields, d as PaymentFormPaymentElement, e as PaymentFormCardElement, f as PaymentFormMandateText, g as PaymentFormTermsCheckbox, h as PaymentFormSubmitButton, i as PaymentFormLoading, j as PaymentFormError, T as TopupFormProps, C as CheckoutResult, k as Plan, A as ActivationResult, l as PurchaseStatus, m as SolvaPayContextValue, U as UsePlansOptions, n as UsePlansReturn, o as UsePlanOptions, p as UsePlanReturn, q as UseProductReturn, r as UseMerchantReturn, s as SolvaPayCopy, t as PurchaseStatusReturn, u as CancelResult, R as ReactivateResult, v as UseTopupOptions, w as UseTopupReturn, B as BalanceStatus, x as UseTopupAmountSelectorOptions, y as UseTopupAmountSelectorReturn, z as PartialSolvaPayCopy, D as PurchaseInfo, E as CheckoutVariant, F as Product } from './CancelPlanButton-f56UlQN-.js';
3
+ export { G as ActivationFlowStep, H as BalanceBadge, I as CancelPlanButton, J as CheckoutSummary, K as CheckoutSummaryProps, L as CustomerPurchaseData, M as MandateContext, N as MandateTemplate, O as MandateText, Q as MandateTextProps, V as Merchant, W as PaymentError, X as PaymentIntentResult, Y as PaymentResult, Z as PlanBadge, _ as ProductBadge, $ as PurchaseGate, a0 as PurchaseStatusValue, a1 as SolvaPayConfig, a2 as TopupPaymentResult, a3 as deriveVariant } from './CancelPlanButton-f56UlQN-.js';
4
+ import { PaymentIntent, Stripe, StripeElements } from '@stripe/stripe-js';
5
+ import { ActivatePlanResult } from '@solvapay/server';
5
6
  export { ActivatePlanResult } from '@solvapay/server';
6
- import { AuthAdapter } from './adapters/auth.js';
7
- export { defaultAuthAdapter } from './adapters/auth.js';
8
- import * as react_jsx_runtime from 'react/jsx-runtime';
9
-
10
- interface PurchaseInfo {
11
- reference: string;
12
- productName: string;
13
- productRef?: string;
14
- status: string;
15
- startDate: string;
16
- endDate?: string;
17
- cancelledAt?: string;
18
- cancellationReason?: string;
19
- amount?: number;
20
- currency?: string;
21
- planType?: string;
22
- isRecurring?: boolean;
23
- nextBillingDate?: string;
24
- billingCycle?: string;
25
- planRef?: string;
26
- planSnapshot?: {
27
- reference?: string;
28
- price?: number;
29
- meterRef?: string;
30
- limit?: number;
31
- freeUnits?: number;
32
- creditsPerUnit?: number;
33
- planType?: string;
34
- billingCycle?: string | null;
35
- features?: Record<string, unknown> | null;
36
- };
37
- usage?: {
38
- used: number;
39
- overageUnits?: number;
40
- overageCost?: number;
41
- periodStart?: string;
42
- periodEnd?: string;
43
- };
44
- }
45
- interface CustomerPurchaseData {
46
- customerRef?: string;
47
- email?: string;
48
- name?: string;
49
- purchases: PurchaseInfo[];
50
- }
51
- interface PaymentIntentResult {
52
- clientSecret: string;
53
- publishableKey: string;
54
- accountId?: string;
55
- customerRef?: string;
56
- }
57
- interface TopupPaymentResult {
58
- clientSecret: string;
59
- publishableKey: string;
60
- accountId?: string;
61
- customerRef?: string;
62
- }
63
- interface UseTopupOptions {
64
- amount: number;
65
- currency?: string;
66
- }
67
- interface UseTopupReturn {
68
- loading: boolean;
69
- error: Error | null;
70
- stripePromise: Promise<_stripe_stripe_js.Stripe | null> | null;
71
- clientSecret: string | null;
72
- startTopup: () => Promise<void>;
73
- reset: () => void;
74
- }
75
- interface TopupFormProps {
76
- amount: number;
77
- currency?: string;
78
- onSuccess?: (paymentIntent: PaymentIntent) => void;
79
- onError?: (error: Error) => void;
80
- returnUrl?: string;
81
- submitButtonText?: string;
82
- className?: string;
83
- buttonClassName?: string;
84
- }
85
- interface PurchaseStatus {
86
- loading: boolean;
87
- /** True when data already exists but a background refetch is in progress */
88
- isRefetching: boolean;
89
- /** Last fetch error, or null if the most recent fetch succeeded */
90
- error: Error | null;
91
- customerRef?: string;
92
- email?: string;
93
- name?: string;
94
- purchases: PurchaseInfo[];
95
- hasProduct: (productName: string) => boolean;
96
- /** @deprecated Use hasProduct instead */
97
- hasPlan: (productName: string) => boolean;
98
- /**
99
- * Primary active purchase (paid or free) - most recent purchase with status === 'active'
100
- * Backend keeps purchases as 'active' until expiration, even when cancelled.
101
- * null if no active purchase exists
102
- */
103
- activePurchase: PurchaseInfo | null;
104
- /**
105
- * Check if user has any active paid purchase (amount > 0)
106
- * Checks purchases with status === 'active'.
107
- * Backend keeps purchases as 'active' until expiration, even when cancelled.
108
- */
109
- hasPaidPurchase: boolean;
110
- /**
111
- * Most recent active paid purchase (sorted by startDate)
112
- * Returns purchase with status === 'active' and amount > 0.
113
- * null if no active paid purchase exists
114
- */
115
- activePaidPurchase: PurchaseInfo | null;
116
- }
117
- /**
118
- * SolvaPay Provider Configuration
119
- * Sensible defaults for minimal code, but fully customizable
120
- */
121
- interface BalanceStatus {
122
- loading: boolean;
123
- credits: number | null;
124
- displayCurrency: string | null;
125
- creditsPerMinorUnit: number | null;
126
- displayExchangeRate: number | null;
127
- refetch: () => Promise<void>;
128
- adjustBalance: (credits: number) => void;
129
- }
130
- interface SolvaPayConfig {
131
- /**
132
- * API route configuration
133
- * Defaults to standard Next.js API routes
134
- */
135
- api?: {
136
- checkPurchase?: string;
137
- createPayment?: string;
138
- processPayment?: string;
139
- createTopupPayment?: string;
140
- customerBalance?: string;
141
- cancelRenewal?: string;
142
- reactivateRenewal?: string;
143
- activatePlan?: string;
144
- listPlans?: string;
145
- };
146
- /**
147
- * Authentication configuration
148
- * Uses adapter pattern for flexible auth provider support
149
- */
150
- auth?: {
151
- /**
152
- * Auth adapter instance
153
- * Default: checks localStorage for 'auth_token' key
154
- *
155
- * @example
156
- * ```tsx
157
- * import { createSupabaseAuthAdapter } from '@solvapay/react-supabase';
158
- *
159
- * <SolvaPayProvider
160
- * config={{
161
- * auth: {
162
- * adapter: createSupabaseAuthAdapter({
163
- * supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL!,
164
- * supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
165
- * })
166
- * }
167
- * }}
168
- * >
169
- * ```
170
- */
171
- adapter?: AuthAdapter;
172
- /**
173
- * @deprecated Use `adapter` instead. Will be removed in a future version.
174
- * Function to get auth token
175
- */
176
- getToken?: () => Promise<string | null>;
177
- /**
178
- * @deprecated Use `adapter` instead. Will be removed in a future version.
179
- * Function to get user ID (for cache key)
180
- */
181
- getUserId?: () => Promise<string | null>;
182
- };
183
- /**
184
- * Custom fetch implementation
185
- * Default: uses global fetch
186
- */
187
- fetch?: typeof fetch;
188
- /**
189
- * Request headers to include in all API calls
190
- * Default: empty
191
- */
192
- headers?: HeadersInit | (() => Promise<HeadersInit>);
193
- /**
194
- * Custom error handler
195
- * Default: logs to console
196
- */
197
- onError?: (error: Error, context: string) => void;
198
- }
199
- interface CancelResult {
200
- reference?: string;
201
- status?: string;
202
- cancelledAt?: string;
203
- [key: string]: unknown;
204
- }
205
- interface ReactivateResult {
206
- reference?: string;
207
- status?: string;
208
- [key: string]: unknown;
209
- }
210
-
211
- interface SolvaPayContextValue {
212
- purchase: PurchaseStatus;
213
- refetchPurchase: () => Promise<void>;
214
- createPayment: (params: {
215
- planRef?: string;
216
- productRef?: string;
217
- }) => Promise<PaymentIntentResult>;
218
- processPayment?: (params: {
219
- paymentIntentId: string;
220
- productRef: string;
221
- planRef?: string;
222
- }) => Promise<ProcessPaymentResult>;
223
- createTopupPayment: (params: {
224
- amount: number;
225
- currency?: string;
226
- }) => Promise<TopupPaymentResult>;
227
- cancelRenewal: (params: {
228
- purchaseRef: string;
229
- reason?: string;
230
- }) => Promise<CancelResult>;
231
- reactivateRenewal: (params: {
232
- purchaseRef: string;
233
- }) => Promise<ReactivateResult>;
234
- activatePlan: (params: {
235
- productRef: string;
236
- planRef: string;
237
- }) => Promise<ActivatePlanResult>;
238
- customerRef?: string;
239
- updateCustomerRef?: (newCustomerRef: string) => void;
240
- balance: BalanceStatus;
241
- /** @internal Provider config — used by SDK hooks, not part of public API */
242
- _config?: SolvaPayConfig;
243
- }
244
- interface SolvaPayProviderProps {
245
- /**
246
- * Configuration object with sensible defaults
247
- * If not provided, uses standard Next.js API routes
248
- */
249
- config?: SolvaPayConfig;
250
- /**
251
- * Custom API functions (override config defaults)
252
- * Use only if you need custom logic beyond standard API routes
253
- */
254
- createPayment?: (params: {
255
- planRef?: string;
256
- productRef?: string;
257
- }) => Promise<PaymentIntentResult>;
258
- checkPurchase?: () => Promise<CustomerPurchaseData>;
259
- processPayment?: (params: {
260
- paymentIntentId: string;
261
- productRef: string;
262
- planRef?: string;
263
- }) => Promise<ProcessPaymentResult>;
264
- createTopupPayment?: (params: {
265
- amount: number;
266
- currency?: string;
267
- }) => Promise<TopupPaymentResult>;
268
- children: React.ReactNode;
269
- }
270
- interface ProductBadgeProps {
271
- children?: (props: {
272
- purchases: PurchaseInfo[];
273
- loading: boolean;
274
- displayPlan: string | null;
275
- shouldShow: boolean;
276
- }) => React.ReactNode;
277
- as?: React.ElementType;
278
- className?: string | ((props: {
279
- purchases: PurchaseInfo[];
280
- }) => string);
281
- }
282
- /** @deprecated Use ProductBadgeProps instead */
283
- type PlanBadgeProps = ProductBadgeProps;
284
- interface PurchaseGateProps {
285
- /** @deprecated Use requireProduct instead */
286
- requirePlan?: string;
287
- requireProduct?: string;
288
- children: (props: {
289
- hasAccess: boolean;
290
- purchases: PurchaseInfo[];
291
- loading: boolean;
292
- }) => React.ReactNode;
293
- }
294
- /**
295
- * Error type for payment operations
296
- */
297
- interface PaymentError extends Error {
298
- code?: string;
299
- type?: string;
300
- }
301
- /**
302
- * Plan returned by the SolvaPay API.
303
- *
304
- * All fields are optional except `reference` so the type stays compatible
305
- * with partial JSON responses from custom fetcher functions.
306
- */
307
- interface Plan {
308
- type?: 'recurring' | 'one-time' | 'usage-based';
309
- reference: string;
310
- name?: string;
311
- description?: string;
312
- price?: number;
313
- currency?: string;
314
- currencySymbol?: string;
315
- freeUnits?: number;
316
- setupFee?: number;
317
- trialDays?: number;
318
- billingCycle?: string;
319
- billingModel?: 'pre-paid' | 'post-paid';
320
- creditsPerUnit?: number;
321
- measures?: string;
322
- limit?: number;
323
- rolloverUnusedUnits?: boolean;
324
- limits?: Record<string, unknown>;
325
- features?: Record<string, unknown> | string[];
326
- requiresPayment?: boolean;
327
- default?: boolean;
328
- isActive?: boolean;
329
- maxActiveUsers?: number;
330
- accessExpiryDays?: number;
331
- status?: string;
332
- createdAt?: string;
333
- updatedAt?: string;
334
- interval?: string;
335
- metadata?: Record<string, unknown>;
336
- }
337
- /**
338
- * Options for usePlans hook
339
- */
340
- interface UsePlansOptions {
341
- /**
342
- * Fetcher function to retrieve plans
343
- */
344
- fetcher: (productRef: string) => Promise<Plan[]>;
345
- /**
346
- * Product reference to fetch plans for
347
- */
348
- productRef?: string;
349
- /**
350
- * Optional filter function to filter plans.
351
- * Receives plan and its index (after sorting, if sortBy is provided).
352
- */
353
- filter?: (plan: Plan, index: number) => boolean;
354
- /**
355
- * Optional sort function to sort plans
356
- */
357
- sortBy?: (a: Plan, b: Plan) => number;
358
- /**
359
- * Auto-select first paid plan on load
360
- */
361
- autoSelectFirstPaid?: boolean;
362
- /**
363
- * Plan reference to select initially when plans load.
364
- * Applied at most once when selectionReady is true.
365
- * Takes priority over autoSelectFirstPaid.
366
- */
367
- initialPlanRef?: string;
368
- /**
369
- * When false, plans still fetch but auto-selection is deferred.
370
- * When it transitions to true, one-shot initial selection fires.
371
- * Defaults to true.
372
- */
373
- selectionReady?: boolean;
374
- }
375
- /**
376
- * Return type for usePlans hook
377
- */
378
- interface UsePlansReturn {
379
- plans: Plan[];
380
- loading: boolean;
381
- error: Error | null;
382
- selectedPlanIndex: number;
383
- selectedPlan: Plan | null;
384
- setSelectedPlanIndex: (index: number) => void;
385
- selectPlan: (planRef: string) => void;
386
- refetch: () => Promise<void>;
387
- /** True after the one-shot initial selection has been applied */
388
- isSelectionReady: boolean;
389
- }
390
- /**
391
- * Props for headless PricingSelector component
392
- */
393
- interface PricingSelectorProps {
394
- /**
395
- * Product reference to fetch plans for
396
- */
397
- productRef?: string;
398
- /**
399
- * Fetcher function to retrieve plans
400
- */
401
- fetcher: (productRef: string) => Promise<Plan[]>;
402
- /**
403
- * Optional filter function
404
- */
405
- filter?: (plan: Plan, index: number) => boolean;
406
- /**
407
- * Optional sort function
408
- */
409
- sortBy?: (a: Plan, b: Plan) => number;
410
- /**
411
- * Auto-select first paid plan on load
412
- */
413
- autoSelectFirstPaid?: boolean;
414
- /**
415
- * Render prop function
416
- */
417
- children: (props: UsePlansReturn & {
418
- purchases: PurchaseInfo[];
419
- isPaidPlan: (planRef: string) => boolean;
420
- isCurrentPlan: (planRef: string) => boolean;
421
- }) => React.ReactNode;
422
- }
423
- /** @deprecated Use PricingSelectorProps instead */
424
- type PlanSelectorProps = PricingSelectorProps;
425
- /**
426
- * Return type for usePurchaseStatus hook
427
- *
428
- * Provides advanced purchase status helpers and utilities.
429
- * Focuses on cancelled purchase logic and date formatting.
430
- * For basic purchase data and paid status, use usePurchase() instead.
431
- */
432
- interface PurchaseStatusReturn {
433
- /**
434
- * Most recent cancelled paid purchase (sorted by startDate)
435
- * null if no cancelled paid purchase exists
436
- */
437
- cancelledPurchase: PurchaseInfo | null;
438
- /**
439
- * Whether to show cancelled purchase notice
440
- * true if cancelledPurchase exists
441
- */
442
- shouldShowCancelledNotice: boolean;
443
- /**
444
- * Format a date string to locale format (e.g., "January 15, 2024")
445
- * Returns null if dateString is not provided
446
- */
447
- formatDate: (dateString?: string) => string | null;
448
- /**
449
- * Calculate days until expiration date
450
- * Returns null if endDate is not provided, otherwise returns days (0 or positive)
451
- */
452
- getDaysUntilExpiration: (endDate?: string) => number | null;
453
- }
454
- /**
455
- * Payment form props - simplified and minimal
456
- */
457
- interface PaymentFormProps {
458
- /**
459
- * Plan reference to checkout. When omitted, the SDK auto-resolves the plan from
460
- * productRef (requires exactly one active plan or a default plan). Pass explicitly
461
- * when the product has multiple plans without a default.
462
- */
463
- planRef?: string;
464
- /**
465
- * Product reference. Required when planRef is omitted (for plan resolution)
466
- * and for processing payment after confirmation.
467
- */
468
- productRef?: string;
469
- /**
470
- * Callback when payment succeeds
471
- */
472
- onSuccess?: (paymentIntent: PaymentIntent) => void;
473
- /**
474
- * Callback when payment fails
475
- */
476
- onError?: (error: Error) => void;
477
- /**
478
- * Return URL after payment completion. Defaults to current page URL if not provided.
479
- */
480
- returnUrl?: string;
481
- /**
482
- * Text for the submit button. Defaults to "Pay Now"
483
- */
484
- submitButtonText?: string;
485
- /**
486
- * Optional className for the form container
487
- */
488
- className?: string;
489
- /**
490
- * Optional className for the submit button
491
- */
492
- buttonClassName?: string;
493
- }
494
- interface BalanceBadgeProps {
495
- className?: string;
496
- numberOnly?: boolean;
497
- children?: (props: {
498
- credits: number | null;
499
- loading: boolean;
500
- displayCurrency: string | null;
501
- creditsPerMinorUnit: number | null;
502
- }) => React.ReactNode;
503
- }
504
- interface UseTopupAmountSelectorOptions {
505
- currency: string;
506
- minAmount?: number;
507
- maxAmount?: number;
508
- }
509
- interface UseTopupAmountSelectorReturn {
510
- quickAmounts: number[];
511
- selectedAmount: number | null;
512
- customAmount: string;
513
- resolvedAmount: number | null;
514
- selectQuickAmount: (amount: number) => void;
515
- setCustomAmount: (value: string) => void;
516
- error: string | null;
517
- validate: () => boolean;
518
- reset: () => void;
519
- currencySymbol: string;
520
- }
521
- type PurchaseStatusValue = 'pending' | 'active' | 'trialing' | 'past_due' | 'cancelled' | 'expired' | 'suspended' | 'refunded';
7
+ export { AuthAdapter, defaultAuthAdapter } from './adapters/auth.js';
8
+ import '@stripe/react-stripe-js';
522
9
 
523
10
  /**
524
11
  * SolvaPay Provider - Headless Context Provider for React.
@@ -599,151 +86,56 @@ type PurchaseStatusValue = 'pending' | 'active' | 'trialing' | 'past_due' | 'can
599
86
  * @see {@link useSolvaPay} for accessing provider methods
600
87
  * @since 1.0.0
601
88
  */
602
- declare const SolvaPayProvider: React$1.FC<SolvaPayProviderProps>;
89
+ declare const SolvaPayProvider: React.FC<SolvaPayProviderProps>;
603
90
 
604
91
  /**
605
- * Payment form component for handling Stripe checkout.
606
- *
607
- * This component provides a complete payment form with Stripe integration,
608
- * including card input, plan selection, and payment processing. It handles
609
- * the entire checkout flow including payment intent creation and confirmation.
610
- *
611
- * When `planRef` is omitted but `productRef` is provided, the component
612
- * auto-resolves the plan by fetching the product's plans and selecting the
613
- * single active plan or the one marked as default.
614
- *
615
- * @param props - Payment form configuration
616
- * @param props.planRef - Plan reference (optional if product has single/default plan)
617
- * @param props.productRef - Product reference (required when planRef is omitted)
618
- * @param props.onSuccess - Callback when payment succeeds
619
- * @param props.onError - Callback when payment fails
620
- * @param props.returnUrl - Optional return URL after payment (for redirects)
621
- * @param props.submitButtonText - Custom text for submit button (default: 'Pay Now')
622
- * @param props.className - Custom CSS class for the form container
623
- * @param props.buttonClassName - Custom CSS class for the submit button
92
+ * Default-tree shim over the `PaymentForm` primitive.
624
93
  *
625
- * @example
626
- * ```tsx
627
- * // Explicit plan
628
- * <PaymentForm planRef="pln_premium" productRef="prd_myapi" onSuccess={...} />
94
+ * Consumers who just want a drop-in payment form use this component. It
95
+ * renders the primitive's Root with a golden-path default tree composed of
96
+ * `PaymentForm.Summary`, `CustomerFields`, `PaymentElement`, `MandateText`,
97
+ * an optional `TermsCheckbox`, and `SubmitButton`. Free-plan activation
98
+ * flows through the same composition — `FreeInner` in the primitive swaps
99
+ * the submit handler so the default tree works identically for paid and
100
+ * free plans.
629
101
  *
630
- * // Auto-resolve plan (product must have exactly one plan or a default)
631
- * <PaymentForm productRef="prd_myapi" onSuccess={...} />
632
- * ```
102
+ * Full control (swap PaymentElement for CardElement, reorder, compose with
103
+ * shadcn/Tailwind) is available via the primitives at
104
+ * `@solvapay/react/primitives`.
633
105
  */
634
- declare const PaymentForm: React$1.FC<PaymentFormProps>;
635
106
 
636
- /**
637
- * Credit top-up form with Stripe Elements.
638
- *
639
- * Unlike `PaymentForm`, this component does **not** call `processPayment`
640
- * after Stripe confirmation. Credits are recorded via the backend webhook
641
- * handler (`CreditService.recordCredit`), so `onSuccess` is called
642
- * immediately after `stripe.confirmCardPayment` succeeds.
643
- */
644
- declare const TopupForm: React$1.FC<TopupFormProps>;
107
+ type PaymentFormRootProps = PaymentFormProps & {
108
+ prefillCustomer?: PrefillCustomer;
109
+ requireTermsAcceptance?: boolean;
110
+ children?: React.ReactNode;
111
+ };
112
+ declare const PaymentForm: React.FC<PaymentFormRootProps> & {
113
+ Summary: typeof PaymentFormSummary;
114
+ CustomerFields: typeof PaymentFormCustomerFields;
115
+ PaymentElement: typeof PaymentFormPaymentElement;
116
+ CardElement: typeof PaymentFormCardElement;
117
+ MandateText: typeof PaymentFormMandateText;
118
+ TermsCheckbox: typeof PaymentFormTermsCheckbox;
119
+ SubmitButton: typeof PaymentFormSubmitButton;
120
+ Loading: typeof PaymentFormLoading;
121
+ Error: typeof PaymentFormError;
122
+ };
645
123
 
646
124
  /**
647
- * Headless Product Badge Component
648
- *
649
- * Displays purchase status with complete styling control.
650
- * Supports render props, custom components, or className patterns.
651
- *
652
- * Hidden before initial data load or when no active purchase exists.
653
- * Remains visible during background refetches to avoid flickering.
125
+ * Default-tree shim over the `TopupForm` primitive.
654
126
  *
655
- * @example
656
- * ```tsx
657
- * // Render prop pattern
658
- * <ProductBadge>
659
- * {({ purchases, loading, displayPlan, shouldShow }) => (
660
- * shouldShow ? (
661
- * <div>{displayPlan}</div>
662
- * ) : null
663
- * )}
664
- * </ProductBadge>
665
- *
666
- * // ClassName pattern
667
- * <ProductBadge className="badge badge-primary" />
668
- * ```
127
+ * Drops in a golden-path credit top-up form: Stripe `PaymentElement` +
128
+ * submit button + loading/error states. Full control is available by
129
+ * composing the primitive at `@solvapay/react/primitives`.
669
130
  */
670
- declare const ProductBadge: React$1.FC<ProductBadgeProps>;
671
- /** @deprecated Use ProductBadge instead */
672
- declare const PlanBadge: React$1.FC<ProductBadgeProps>;
673
131
 
674
- /**
675
- * Headless Purchase Gate Component
676
- *
677
- * Controls access to content based on purchase status.
678
- * Uses render props to give developers full control over locked/unlocked states.
679
- *
680
- * @example
681
- * ```tsx
682
- * <PurchaseGate requireProduct="Pro Plan">
683
- * {({ hasAccess, loading }) => {
684
- * if (loading) return <Skeleton />;
685
- * if (!hasAccess) return <Paywall />;
686
- * return <PremiumContent />;
687
- * }}
688
- * </PurchaseGate>
689
- * ```
690
- */
691
- declare const PurchaseGate: React$1.FC<PurchaseGateProps>;
692
-
693
- /**
694
- * Headless Pricing Selector Component
695
- *
696
- * Provides pricing selection logic with complete styling control via render props.
697
- * Integrates plan fetching, purchase status, and selection state management.
698
- *
699
- * Features:
700
- * - Fetches and manages pricing options
701
- * - Tracks selected option
702
- * - Provides helpers for checking if option is current/paid
703
- * - Integrates with purchase context
704
- *
705
- * @example
706
- * ```tsx
707
- * <PricingSelector
708
- * productRef="prd_123"
709
- * fetcher={async (productRef) => {
710
- * const res = await fetch(`/api/list-plans?productRef=${productRef}`);
711
- * const data = await res.json();
712
- * return data.plans;
713
- * }}
714
- * sortBy={(a, b) => (a.price || 0) - (b.price || 0)}
715
- * autoSelectFirstPaid
716
- * >
717
- * {({ plans, selectedPlan, setSelectedPlanIndex, loading, isPaidPlan, isCurrentPlan }) => (
718
- * <div>
719
- * {loading ? (
720
- * <div>Loading...</div>
721
- * ) : (
722
- * plans.map((plan, index) => (
723
- * <button
724
- * key={plan.reference}
725
- * onClick={() => setSelectedPlanIndex(index)}
726
- * disabled={!isPaidPlan(plan.reference)}
727
- * >
728
- * ${plan.price}/{plan.interval}
729
- * {isCurrentPlan(plan.reference) && ' (Current)'}
730
- * </button>
731
- * ))
732
- * )}
733
- * </div>
734
- * )}
735
- * </PricingSelector>
736
- * ```
737
- */
738
- declare const PricingSelector: React$1.FC<PricingSelectorProps>;
739
- /** @deprecated Use PricingSelector instead */
740
- declare const PlanSelector: React$1.FC<PricingSelectorProps>;
132
+ declare const TopupForm: React.FC<TopupFormProps>;
741
133
 
742
134
  /**
743
135
  * SVG-based spinner component using CSS animations
744
136
  * Uses the same spinner design as the rest of the site
745
137
  */
746
- declare const Spinner: React$1.FC<{
138
+ declare const Spinner: React.FC<{
747
139
  className?: string;
748
140
  size?: 'sm' | 'md' | 'lg';
749
141
  }>;
@@ -761,9 +153,193 @@ interface StripePaymentFormWrapperProps {
761
153
  * Renders inside Stripe Elements context and handles the payment flow
762
154
  * All hooks are called unconditionally to comply with React Rules of Hooks
763
155
  */
764
- declare const StripePaymentFormWrapper: React$1.FC<StripePaymentFormWrapperProps>;
156
+ declare const StripePaymentFormWrapper: React.FC<StripePaymentFormWrapperProps>;
765
157
 
766
- declare function BalanceBadge({ className, numberOnly, children }: BalanceBadgeProps): react_jsx_runtime.JSX.Element | null;
158
+ /**
159
+ * Opinionated one-line drop-in checkout built on top of `PlanSelector`,
160
+ * `PaymentForm`, and `ActivationFlow`. Renders the select → pay | activate
161
+ * machine internally, and auto-skips the select step when a product has a
162
+ * single selectable plan.
163
+ *
164
+ * Styling is done entirely via the `solvapay-*` class names documented in
165
+ * PR 5's `styles.css`. No inline styles. Full control (custom layouts,
166
+ * alternate CTAs, multi-step wizards) is available by composing the
167
+ * primitives at `@solvapay/react/primitives` directly.
168
+ */
169
+
170
+ type CheckoutLayoutSize = 'chat' | 'mobile' | 'desktop' | 'auto';
171
+ type CheckoutLayoutPlanSelectorOptions = {
172
+ filter?: (plan: Plan, index: number) => boolean;
173
+ sortBy?: (a: Plan, b: Plan) => number;
174
+ popularPlanRef?: string;
175
+ };
176
+ type CheckoutLayoutProps = {
177
+ /**
178
+ * Plan reference. When passed, skips plan selection and goes directly to
179
+ * payment or activation (routed based on plan type). Backwards compatible
180
+ * with today's payment-only behavior for non-usage-based plans.
181
+ */
182
+ planRef?: string;
183
+ productRef?: string;
184
+ prefillCustomer?: PrefillCustomer;
185
+ size?: CheckoutLayoutSize;
186
+ requireTermsAcceptance?: boolean;
187
+ /**
188
+ * Fires on paid completions only — preserved for backwards compatibility.
189
+ * For a unified callback across paid + activated flows, use `onResult`.
190
+ */
191
+ onSuccess?: (paymentIntent: PaymentIntent) => void;
192
+ /** Unified completion callback (paid + activated). */
193
+ onResult?: (result: CheckoutResult) => void;
194
+ /** Override the default free-plan activation step. Forwarded to PaymentForm. */
195
+ onFreePlan?: (plan: Plan) => Promise<unknown> | void;
196
+ onError?: (error: Error) => void;
197
+ /** Initial selection when rendering the selector step. */
198
+ initialPlanRef?: string;
199
+ /** Callback when the user picks a plan from the selector. */
200
+ onPlanSelect?: (planRef: string, plan: Plan) => void;
201
+ /** Controls for the internal `<PlanSelector>`. */
202
+ planSelector?: CheckoutLayoutPlanSelectorOptions;
203
+ /** Hide the "← Back to plans" affordance on the pay step. Defaults to true. */
204
+ showBackButton?: boolean;
205
+ submitButtonText?: string;
206
+ returnUrl?: string;
207
+ };
208
+ declare const CheckoutLayout: React.FC<CheckoutLayoutProps>;
209
+
210
+ /**
211
+ * Default-tree shim over the `PlanSelector` primitive.
212
+ *
213
+ * Consumers who want a drop-in grid of plan cards use this component.
214
+ * Consumers who want full control compose `@solvapay/react/primitives`
215
+ * directly.
216
+ */
217
+
218
+ interface PlanSelectorProps {
219
+ productRef: string;
220
+ fetcher?: (productRef: string) => Promise<Plan[]>;
221
+ filter?: (plan: Plan, index: number) => boolean;
222
+ sortBy?: (a: Plan, b: Plan) => number;
223
+ autoSelectFirstPaid?: boolean;
224
+ initialPlanRef?: string;
225
+ currentPlanRef?: string | null;
226
+ popularPlanRef?: string;
227
+ onSelect?: (planRef: string, plan: Plan) => void;
228
+ className?: string;
229
+ children?: React.ReactNode;
230
+ }
231
+ declare const PlanSelector: React.FC<PlanSelectorProps>;
232
+
233
+ /**
234
+ * Default-tree shim over the `AmountPicker` primitive.
235
+ *
236
+ * Renders the golden-path pills + custom input combo consumers expect in
237
+ * drop-in usage. For full control (alternate layouts, custom confirm
238
+ * affordance, Tailwind variants), compose
239
+ * `@solvapay/react/primitives` directly.
240
+ */
241
+
242
+ interface AmountPickerProps {
243
+ currency: string;
244
+ minAmount?: number;
245
+ maxAmount?: number;
246
+ showCreditEstimate?: boolean;
247
+ onChange?: (amount: number | null) => void;
248
+ className?: string;
249
+ }
250
+ declare const AmountPicker: React.FC<AmountPickerProps>;
251
+
252
+ /**
253
+ * Default-tree shim over the `ActivationFlow` primitive.
254
+ *
255
+ * Renders the full usage-based activation state machine (summary →
256
+ * activating → selectAmount → topupPayment → retrying → activated | error)
257
+ * with the golden-path copy, the embedded `<CheckoutSummary>` + `<TopupForm>`,
258
+ * and an optional back button. Full control is available by composing the
259
+ * primitive at `@solvapay/react/primitives`.
260
+ */
261
+
262
+ interface ActivationFlowProps {
263
+ productRef: string;
264
+ planRef?: string;
265
+ onSuccess?: (result: ActivationResult) => void;
266
+ onError?: (error: Error) => void;
267
+ onBack?: () => void;
268
+ retryDelayMs?: number;
269
+ retryBackoffMs?: number;
270
+ className?: string;
271
+ }
272
+ declare const ActivationFlow: React.FC<ActivationFlowProps>;
273
+
274
+ /**
275
+ * Default-tree shim over the `CancelledPlanNotice` primitive.
276
+ *
277
+ * Renders the full cancellation banner (heading, expiry, days remaining,
278
+ * access-until, cancellation date, reason, reactivate CTA) when the
279
+ * customer has a cancelled-but-still-active purchase. Renders `null`
280
+ * otherwise.
281
+ */
282
+
283
+ interface CancelledPlanNoticeProps {
284
+ onReactivated?: () => void;
285
+ onError?: (error: Error) => void;
286
+ className?: string;
287
+ }
288
+ declare const CancelledPlanNotice: React.FC<CancelledPlanNoticeProps>;
289
+
290
+ /**
291
+ * Default-tree shim over the `CreditGate` primitive.
292
+ *
293
+ * Renders `children` when the customer has enough credits, otherwise renders
294
+ * a default top-up prompt (Heading + Subheading + Topup) or a user-provided
295
+ * `fallback`. Full control is available via
296
+ * `@solvapay/react/primitives` — compose `CreditGate.Root` with your own
297
+ * subcomponent arrangement.
298
+ */
299
+
300
+ interface CreditGateProps {
301
+ minCredits?: number;
302
+ productRef?: string;
303
+ topupAmount?: number;
304
+ topupCurrency?: string;
305
+ fallback?: React.ReactNode;
306
+ className?: string;
307
+ children?: React.ReactNode;
308
+ }
309
+ declare const CreditGate: React.FC<CreditGateProps>;
310
+
311
+ type PaymentElementKind = 'payment-element' | 'card-element' | null;
312
+ interface PaymentFormContextValue {
313
+ planRef?: string;
314
+ productRef?: string;
315
+ prefillCustomer?: PrefillCustomer;
316
+ resolvedPlanRef: string | null;
317
+ plan: Plan | null;
318
+ clientSecret: string | null;
319
+ stripe: Stripe | null;
320
+ elements: StripeElements | null;
321
+ isProcessing: boolean;
322
+ isReady: boolean;
323
+ paymentInputComplete: boolean;
324
+ termsAccepted: boolean;
325
+ requireTermsAcceptance: boolean;
326
+ canSubmit: boolean;
327
+ error: string | null;
328
+ elementKind: PaymentElementKind;
329
+ returnUrl: string;
330
+ submitButtonText?: string;
331
+ buttonClassName?: string;
332
+ setElementKind: (k: PaymentElementKind) => void;
333
+ setPaymentInputComplete: (complete: boolean) => void;
334
+ setTermsAccepted: (accepted: boolean) => void;
335
+ submit: () => Promise<void>;
336
+ }
337
+ declare const PaymentFormContext: React.Context<PaymentFormContextValue | null>;
338
+ declare function usePaymentForm(): PaymentFormContextValue;
339
+ declare const PaymentFormProvider: React.FC<{
340
+ value: PaymentFormContextValue;
341
+ children: React.ReactNode;
342
+ }>;
767
343
 
768
344
  /**
769
345
  * Hook to get current purchase status and information.
@@ -886,6 +462,7 @@ interface UseCheckoutReturn {
886
462
  declare function useCheckout(options: {
887
463
  planRef?: string;
888
464
  productRef?: string;
465
+ customer?: PrefillCustomer;
889
466
  }): UseCheckoutReturn;
890
467
 
891
468
  /**
@@ -942,6 +519,43 @@ declare function useSolvaPay(): SolvaPayContextValue;
942
519
  */
943
520
  declare function usePlans(options: UsePlansOptions): UsePlansReturn;
944
521
 
522
+ /**
523
+ * Hook to load a single plan by reference.
524
+ *
525
+ * When `productRef` is known, piggybacks on the `usePlans` cache so there's
526
+ * no extra fetch. Otherwise fetches the full plan list and filters.
527
+ */
528
+ declare function usePlan(options: UsePlanOptions): UsePlanReturn;
529
+
530
+ /**
531
+ * Hook to load a single product by reference. Uses a module-level
532
+ * single-flight cache keyed by `productRef` so concurrent consumers share the
533
+ * same in-flight request.
534
+ */
535
+ declare function useProduct(productRef: string | undefined): UseProductReturn;
536
+
537
+ /**
538
+ * Hook to load merchant identity (legal name, support email, terms/privacy
539
+ * URLs, ...) for rendering mandate copy and trust signals.
540
+ *
541
+ * Uses a module-level single-flight cache keyed by the configured route so
542
+ * concurrent consumers share one in-flight request and response.
543
+ */
544
+ declare function useMerchant(): UseMerchantReturn;
545
+
546
+ /**
547
+ * Read the merged copy bundle from context. Used by every SDK component that
548
+ * renders user-visible strings; consumers rarely call it directly but it's
549
+ * exported as an escape hatch for custom UIs.
550
+ */
551
+ declare function useCopy(): SolvaPayCopy;
552
+ /**
553
+ * Current locale string (e.g. `'en'`, `'sv-SE'`). Used to thread the locale
554
+ * through `Intl.NumberFormat`, `Intl.DateTimeFormat`, and Stripe Elements.
555
+ * `undefined` means "runtime default".
556
+ */
557
+ declare function useLocale(): string | undefined;
558
+
945
559
  /**
946
560
  * Hook providing advanced status and helper functions for purchase management
947
561
  *
@@ -1067,6 +681,37 @@ declare function useBalance(): BalanceStatus;
1067
681
  */
1068
682
  declare function useTopupAmountSelector(options: UseTopupAmountSelectorOptions): UseTopupAmountSelectorReturn;
1069
683
 
684
+ type CopyContextValue = {
685
+ locale?: string;
686
+ copy: SolvaPayCopy;
687
+ };
688
+ declare const CopyContext: React.Context<CopyContextValue>;
689
+ type CopyProviderProps = {
690
+ locale?: string;
691
+ copy?: PartialSolvaPayCopy;
692
+ children: React.ReactNode;
693
+ };
694
+ declare const CopyProvider: React.FC<CopyProviderProps>;
695
+
696
+ /**
697
+ * Canonical English copy. Preserves the exact copy shipped before the i18n
698
+ * refactor so no visible behavior changes for English consumers.
699
+ */
700
+ declare const enCopy: SolvaPayCopy;
701
+
702
+ /**
703
+ * Tiny templating helper: replaces `{name}` tokens in `template` with values
704
+ * from `vars`. Missing keys are left as-is so integrators can spot typos.
705
+ */
706
+ declare function interpolate(template: string, vars: Record<string, string | number | undefined>): string;
707
+
708
+ /**
709
+ * Shallow-per-section merge over the default English bundle. Each top-level
710
+ * section of `SolvaPayCopy` is itself a flat record, so a two-level spread is
711
+ * sufficient — no recursive walk needed.
712
+ */
713
+ declare function mergeCopy(defaults: SolvaPayCopy, overrides?: PartialSolvaPayCopy): SolvaPayCopy;
714
+
1070
715
  /**
1071
716
  * Purchase utility functions
1072
717
  *
@@ -1124,4 +769,82 @@ declare function getPrimaryPurchase(purchases: PurchaseInfo[]): PurchaseInfo | n
1124
769
  */
1125
770
  declare function isPaidPurchase(purchase: PurchaseInfo): boolean;
1126
771
 
1127
- export { type ActivationState, AuthAdapter, BalanceBadge, type BalanceBadgeProps, type BalanceStatus, type CancelResult, type CustomerInfo, type CustomerPurchaseData, type PaymentError, PaymentForm, type PaymentFormProps, type PaymentIntentResult, type Plan, PlanBadge, type PlanBadgeProps, PlanSelector, type PlanSelectorProps, PricingSelector, type PricingSelectorProps, ProductBadge, type ProductBadgeProps, type PurchaseActions, PurchaseGate, type PurchaseGateProps, type PurchaseInfo, type PurchaseStatus, type PurchaseStatusReturn, type PurchaseStatusValue, type ReactivateResult, type SolvaPayConfig, type SolvaPayContextValue, SolvaPayProvider, type SolvaPayProviderProps, Spinner, StripePaymentFormWrapper, TopupForm, type TopupFormProps, type TopupPaymentResult, type UseActivationReturn, type UsePlansOptions, type UsePlansReturn, type UseTopupAmountSelectorOptions, type UseTopupAmountSelectorReturn, type UseTopupOptions, type UseTopupReturn, filterPurchases, getActivePurchases, getCancelledPurchasesWithEndDate, getMostRecentPurchase, getPrimaryPurchase, isPaidPurchase, useActivation, useBalance, useCheckout, useCustomer, usePlans, usePurchase, usePurchaseActions, usePurchaseStatus, useSolvaPay, useTopup, useTopupAmountSelector };
772
+ /**
773
+ * Currency + interval price formatting utilities.
774
+ *
775
+ * `formatPrice` renders a minor-unit amount with `Intl.NumberFormat`, handling
776
+ * locale, symbol placement, zero-decimal currencies (JPY, KRW, ...), and an
777
+ * optional trailing interval suffix ("/ month", "/ 3 months").
778
+ */
779
+ type FormatPriceOptions = {
780
+ /** BCP-47 locale tag. Falls back to the runtime default. */
781
+ locale?: string;
782
+ /** Recurring interval unit in English. Localize via the copy bundle if needed. */
783
+ interval?: string;
784
+ /** How many of `interval` per billing cycle. Defaults to 1. */
785
+ intervalCount?: number;
786
+ /**
787
+ * Copy used when `amountMinor` is 0. Defaults to `'Free'`.
788
+ * Pass `''` to disable the zero-check and always render the numeric zero.
789
+ */
790
+ free?: string;
791
+ };
792
+ declare function formatPrice(amountMinor: number, currency: string, opts?: FormatPriceOptions): string;
793
+
794
+ type ResolveCtaInput = {
795
+ variant: CheckoutVariant;
796
+ plan?: Plan | null;
797
+ product?: Product | null;
798
+ amountFormatted: string;
799
+ copy: SolvaPayCopy;
800
+ /** Caller-provided override; short-circuits derivation. */
801
+ override?: string;
802
+ };
803
+ /**
804
+ * Build the submit-button label. Keeps the mapping between plan type and CTA
805
+ * in one place so the button, the aria-label, and `<MandateText>` agree.
806
+ */
807
+ declare function resolveCta(input: ResolveCtaInput): string;
808
+
809
+ type ConfirmPaymentMode = 'payment-element' | 'card-element';
810
+ type ConfirmPaymentInput = {
811
+ stripe: Stripe;
812
+ elements: StripeElements;
813
+ clientSecret: string;
814
+ mode: ConfirmPaymentMode;
815
+ returnUrl: string;
816
+ /** Billing details from `useCustomer()` (echoed from backend). */
817
+ billingDetails?: {
818
+ email?: string;
819
+ name?: string;
820
+ };
821
+ /**
822
+ * When true, skip the browser redirect during PaymentElement confirmation
823
+ * and resolve only if the intent finishes synchronously. This is what
824
+ * SolvaPay's inline forms want so `onSuccess` fires in the same tab.
825
+ */
826
+ redirectIfRequired?: boolean;
827
+ /** Copy bundle for human-readable status messages. */
828
+ copy: SolvaPayCopy;
829
+ };
830
+ type ConfirmPaymentResult = {
831
+ status: 'succeeded';
832
+ paymentIntent: PaymentIntent;
833
+ } | {
834
+ status: 'requires_action';
835
+ message: string;
836
+ } | {
837
+ status: 'other';
838
+ message: string;
839
+ paymentIntent?: PaymentIntent;
840
+ } | {
841
+ status: 'error';
842
+ message: string;
843
+ };
844
+ /**
845
+ * Wrap Stripe confirmation so callers don't have to branch between
846
+ * `confirmPayment` (PaymentElement) and `confirmCardPayment` (CardElement).
847
+ */
848
+ declare function confirmPayment(input: ConfirmPaymentInput): Promise<ConfirmPaymentResult>;
849
+
850
+ export { ActivationFlow, type ActivationFlowProps, ActivationResult, type ActivationState, AmountPicker, type AmountPickerProps, BalanceStatus, CancelResult, CancelledPlanNotice, type CancelledPlanNoticeProps, CheckoutLayout, type CheckoutLayoutPlanSelectorOptions, type CheckoutLayoutProps, type CheckoutLayoutSize, CheckoutResult, CheckoutVariant, type ConfirmPaymentInput, type ConfirmPaymentMode, type ConfirmPaymentResult, CopyContext, CopyProvider, CreditGate, type CreditGateProps, type CustomerInfo, type FormatPriceOptions, PartialSolvaPayCopy, type PaymentElementKind, PaymentForm, PaymentFormContext, type PaymentFormContextValue, PaymentFormProps, PaymentFormProvider, Plan, PlanSelector, type PlanSelectorProps, PrefillCustomer, Product, type PurchaseActions, PurchaseInfo, PurchaseStatus, PurchaseStatusReturn, ReactivateResult, SolvaPayContextValue, SolvaPayCopy, SolvaPayProvider, SolvaPayProviderProps, Spinner, StripePaymentFormWrapper, TopupForm, TopupFormProps, type UseActivationReturn, UseMerchantReturn, UsePlanOptions, UsePlanReturn, UsePlansOptions, UsePlansReturn, UseProductReturn, UseTopupAmountSelectorOptions, UseTopupAmountSelectorReturn, UseTopupOptions, UseTopupReturn, confirmPayment, enCopy, filterPurchases, formatPrice, getActivePurchases, getCancelledPurchasesWithEndDate, getMostRecentPurchase, getPrimaryPurchase, interpolate, isPaidPurchase, mergeCopy, resolveCta, useActivation, useBalance, useCheckout, useCopy, useCustomer, useLocale, useMerchant, usePaymentForm, usePlan, usePlans, useProduct, usePurchase, usePurchaseActions, usePurchaseStatus, useSolvaPay, useTopup, useTopupAmountSelector };