@solvapay/react 1.0.6 → 1.0.8-preview.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +117 -0
- package/README.md +234 -1
- package/dist/CancelPlanButton-CieT9swn.d.cts +1102 -0
- package/dist/CancelPlanButton-f56UlQN-.d.ts +1102 -0
- package/dist/chunk-MOP3ZBGC.js +4749 -0
- package/dist/index.cjs +4645 -624
- package/dist/index.d.cts +503 -577
- package/dist/index.d.ts +503 -577
- package/dist/index.js +604 -1042
- package/dist/primitives/index.cjs +4254 -0
- package/dist/primitives/index.d.cts +533 -0
- package/dist/primitives/index.d.ts +533 -0
- package/dist/primitives/index.js +187 -0
- package/dist/styles.css +869 -0
- package/package.json +20 -5
package/dist/index.d.cts
CHANGED
|
@@ -1,375 +1,11 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
interface PurchaseInfo {
|
|
12
|
-
reference: string;
|
|
13
|
-
productName: string;
|
|
14
|
-
productReference?: string;
|
|
15
|
-
status: string;
|
|
16
|
-
startDate: string;
|
|
17
|
-
endDate?: string;
|
|
18
|
-
cancelledAt?: string;
|
|
19
|
-
cancellationReason?: string;
|
|
20
|
-
amount?: number;
|
|
21
|
-
currency?: string;
|
|
22
|
-
planType?: string;
|
|
23
|
-
isRecurring?: boolean;
|
|
24
|
-
nextBillingDate?: string;
|
|
25
|
-
billingCycle?: string;
|
|
26
|
-
transactionId?: string;
|
|
27
|
-
planSnapshot?: {
|
|
28
|
-
reference?: string;
|
|
29
|
-
meterId?: string;
|
|
30
|
-
limit?: number;
|
|
31
|
-
freeUnits?: number;
|
|
32
|
-
pricePerUnit?: 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 PurchaseStatus {
|
|
58
|
-
loading: boolean;
|
|
59
|
-
customerRef?: string;
|
|
60
|
-
email?: string;
|
|
61
|
-
name?: string;
|
|
62
|
-
purchases: PurchaseInfo[];
|
|
63
|
-
hasProduct: (productName: string) => boolean;
|
|
64
|
-
/** @deprecated Use hasProduct instead */
|
|
65
|
-
hasPlan: (productName: string) => boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Primary active purchase (paid or free) - most recent purchase with status === 'active'
|
|
68
|
-
* Backend keeps purchases as 'active' until expiration, even when cancelled.
|
|
69
|
-
* null if no active purchase exists
|
|
70
|
-
*/
|
|
71
|
-
activePurchase: PurchaseInfo | null;
|
|
72
|
-
/**
|
|
73
|
-
* Check if user has any active paid purchase (amount > 0)
|
|
74
|
-
* Checks purchases with status === 'active'.
|
|
75
|
-
* Backend keeps purchases as 'active' until expiration, even when cancelled.
|
|
76
|
-
*/
|
|
77
|
-
hasPaidPurchase: boolean;
|
|
78
|
-
/**
|
|
79
|
-
* Most recent active paid purchase (sorted by startDate)
|
|
80
|
-
* Returns purchase with status === 'active' and amount > 0.
|
|
81
|
-
* null if no active paid purchase exists
|
|
82
|
-
*/
|
|
83
|
-
activePaidPurchase: PurchaseInfo | null;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* SolvaPay Provider Configuration
|
|
87
|
-
* Sensible defaults for minimal code, but fully customizable
|
|
88
|
-
*/
|
|
89
|
-
interface SolvaPayConfig {
|
|
90
|
-
/**
|
|
91
|
-
* API route configuration
|
|
92
|
-
* Defaults to standard Next.js API routes
|
|
93
|
-
*/
|
|
94
|
-
api?: {
|
|
95
|
-
checkPurchase?: string;
|
|
96
|
-
createPayment?: string;
|
|
97
|
-
processPayment?: string;
|
|
98
|
-
};
|
|
99
|
-
/**
|
|
100
|
-
* Authentication configuration
|
|
101
|
-
* Uses adapter pattern for flexible auth provider support
|
|
102
|
-
*/
|
|
103
|
-
auth?: {
|
|
104
|
-
/**
|
|
105
|
-
* Auth adapter instance
|
|
106
|
-
* Default: checks localStorage for 'auth_token' key
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* ```tsx
|
|
110
|
-
* import { createSupabaseAuthAdapter } from '@solvapay/react-supabase';
|
|
111
|
-
*
|
|
112
|
-
* <SolvaPayProvider
|
|
113
|
-
* config={{
|
|
114
|
-
* auth: {
|
|
115
|
-
* adapter: createSupabaseAuthAdapter({
|
|
116
|
-
* supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
117
|
-
* supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
118
|
-
* })
|
|
119
|
-
* }
|
|
120
|
-
* }}
|
|
121
|
-
* >
|
|
122
|
-
* ```
|
|
123
|
-
*/
|
|
124
|
-
adapter?: AuthAdapter;
|
|
125
|
-
/**
|
|
126
|
-
* @deprecated Use `adapter` instead. Will be removed in a future version.
|
|
127
|
-
* Function to get auth token
|
|
128
|
-
*/
|
|
129
|
-
getToken?: () => Promise<string | null>;
|
|
130
|
-
/**
|
|
131
|
-
* @deprecated Use `adapter` instead. Will be removed in a future version.
|
|
132
|
-
* Function to get user ID (for cache key)
|
|
133
|
-
*/
|
|
134
|
-
getUserId?: () => Promise<string | null>;
|
|
135
|
-
};
|
|
136
|
-
/**
|
|
137
|
-
* Custom fetch implementation
|
|
138
|
-
* Default: uses global fetch
|
|
139
|
-
*/
|
|
140
|
-
fetch?: typeof fetch;
|
|
141
|
-
/**
|
|
142
|
-
* Request headers to include in all API calls
|
|
143
|
-
* Default: empty
|
|
144
|
-
*/
|
|
145
|
-
headers?: HeadersInit | (() => Promise<HeadersInit>);
|
|
146
|
-
/**
|
|
147
|
-
* Custom error handler
|
|
148
|
-
* Default: logs to console
|
|
149
|
-
*/
|
|
150
|
-
onError?: (error: Error, context: string) => void;
|
|
151
|
-
}
|
|
152
|
-
interface SolvaPayContextValue {
|
|
153
|
-
purchase: PurchaseStatus;
|
|
154
|
-
refetchPurchase: () => Promise<void>;
|
|
155
|
-
createPayment: (params: {
|
|
156
|
-
planRef: string;
|
|
157
|
-
productRef?: string;
|
|
158
|
-
}) => Promise<PaymentIntentResult>;
|
|
159
|
-
processPayment?: (params: {
|
|
160
|
-
paymentIntentId: string;
|
|
161
|
-
productRef: string;
|
|
162
|
-
planRef?: string;
|
|
163
|
-
}) => Promise<ProcessPaymentResult>;
|
|
164
|
-
customerRef?: string;
|
|
165
|
-
updateCustomerRef?: (newCustomerRef: string) => void;
|
|
166
|
-
}
|
|
167
|
-
interface SolvaPayProviderProps {
|
|
168
|
-
/**
|
|
169
|
-
* Configuration object with sensible defaults
|
|
170
|
-
* If not provided, uses standard Next.js API routes
|
|
171
|
-
*/
|
|
172
|
-
config?: SolvaPayConfig;
|
|
173
|
-
/**
|
|
174
|
-
* Custom API functions (override config defaults)
|
|
175
|
-
* Use only if you need custom logic beyond standard API routes
|
|
176
|
-
*/
|
|
177
|
-
createPayment?: (params: {
|
|
178
|
-
planRef: string;
|
|
179
|
-
productRef?: string;
|
|
180
|
-
}) => Promise<PaymentIntentResult>;
|
|
181
|
-
checkPurchase?: () => Promise<CustomerPurchaseData>;
|
|
182
|
-
processPayment?: (params: {
|
|
183
|
-
paymentIntentId: string;
|
|
184
|
-
productRef: string;
|
|
185
|
-
planRef?: string;
|
|
186
|
-
}) => Promise<ProcessPaymentResult>;
|
|
187
|
-
children: React.ReactNode;
|
|
188
|
-
}
|
|
189
|
-
interface ProductBadgeProps {
|
|
190
|
-
children?: (props: {
|
|
191
|
-
purchases: PurchaseInfo[];
|
|
192
|
-
loading: boolean;
|
|
193
|
-
displayPlan: string | null;
|
|
194
|
-
shouldShow: boolean;
|
|
195
|
-
}) => React.ReactNode;
|
|
196
|
-
as?: React.ElementType;
|
|
197
|
-
className?: string | ((props: {
|
|
198
|
-
purchases: PurchaseInfo[];
|
|
199
|
-
}) => string);
|
|
200
|
-
}
|
|
201
|
-
/** @deprecated Use ProductBadgeProps instead */
|
|
202
|
-
type PlanBadgeProps = ProductBadgeProps;
|
|
203
|
-
interface PurchaseGateProps {
|
|
204
|
-
/** @deprecated Use requireProduct instead */
|
|
205
|
-
requirePlan?: string;
|
|
206
|
-
requireProduct?: string;
|
|
207
|
-
children: (props: {
|
|
208
|
-
hasAccess: boolean;
|
|
209
|
-
purchases: PurchaseInfo[];
|
|
210
|
-
loading: boolean;
|
|
211
|
-
}) => React.ReactNode;
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Error type for payment operations
|
|
215
|
-
*/
|
|
216
|
-
interface PaymentError extends Error {
|
|
217
|
-
code?: string;
|
|
218
|
-
type?: string;
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Plan interface for plans
|
|
222
|
-
*/
|
|
223
|
-
interface Plan {
|
|
224
|
-
reference: string;
|
|
225
|
-
price?: number;
|
|
226
|
-
currency?: string;
|
|
227
|
-
interval?: string;
|
|
228
|
-
features?: string[];
|
|
229
|
-
isFreeTier?: boolean;
|
|
230
|
-
metadata?: Record<string, unknown>;
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Options for usePlans hook
|
|
234
|
-
*/
|
|
235
|
-
interface UsePlansOptions {
|
|
236
|
-
/**
|
|
237
|
-
* Fetcher function to retrieve plans
|
|
238
|
-
*/
|
|
239
|
-
fetcher: (productRef: string) => Promise<Plan[]>;
|
|
240
|
-
/**
|
|
241
|
-
* Product reference to fetch plans for
|
|
242
|
-
*/
|
|
243
|
-
productRef?: string;
|
|
244
|
-
/**
|
|
245
|
-
* Optional filter function to filter plans
|
|
246
|
-
*/
|
|
247
|
-
filter?: (plan: Plan) => boolean;
|
|
248
|
-
/**
|
|
249
|
-
* Optional sort function to sort plans
|
|
250
|
-
*/
|
|
251
|
-
sortBy?: (a: Plan, b: Plan) => number;
|
|
252
|
-
/**
|
|
253
|
-
* Auto-select first paid plan on load
|
|
254
|
-
*/
|
|
255
|
-
autoSelectFirstPaid?: boolean;
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Return type for usePlans hook
|
|
259
|
-
*/
|
|
260
|
-
interface UsePlansReturn {
|
|
261
|
-
plans: Plan[];
|
|
262
|
-
loading: boolean;
|
|
263
|
-
error: Error | null;
|
|
264
|
-
selectedPlanIndex: number;
|
|
265
|
-
selectedPlan: Plan | null;
|
|
266
|
-
setSelectedPlanIndex: (index: number) => void;
|
|
267
|
-
selectPlan: (planRef: string) => void;
|
|
268
|
-
refetch: () => Promise<void>;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Props for headless PricingSelector component
|
|
272
|
-
*/
|
|
273
|
-
interface PricingSelectorProps {
|
|
274
|
-
/**
|
|
275
|
-
* Product reference to fetch plans for
|
|
276
|
-
*/
|
|
277
|
-
productRef?: string;
|
|
278
|
-
/**
|
|
279
|
-
* Fetcher function to retrieve plans
|
|
280
|
-
*/
|
|
281
|
-
fetcher: (productRef: string) => Promise<Plan[]>;
|
|
282
|
-
/**
|
|
283
|
-
* Optional filter function
|
|
284
|
-
*/
|
|
285
|
-
filter?: (plan: Plan) => boolean;
|
|
286
|
-
/**
|
|
287
|
-
* Optional sort function
|
|
288
|
-
*/
|
|
289
|
-
sortBy?: (a: Plan, b: Plan) => number;
|
|
290
|
-
/**
|
|
291
|
-
* Auto-select first paid plan on load
|
|
292
|
-
*/
|
|
293
|
-
autoSelectFirstPaid?: boolean;
|
|
294
|
-
/**
|
|
295
|
-
* Render prop function
|
|
296
|
-
*/
|
|
297
|
-
children: (props: UsePlansReturn & {
|
|
298
|
-
purchases: PurchaseInfo[];
|
|
299
|
-
isPaidPlan: (planRef: string) => boolean;
|
|
300
|
-
isCurrentPlan: (planRef: string) => boolean;
|
|
301
|
-
}) => React.ReactNode;
|
|
302
|
-
}
|
|
303
|
-
/** @deprecated Use PricingSelectorProps instead */
|
|
304
|
-
type PlanSelectorProps = PricingSelectorProps;
|
|
305
|
-
/**
|
|
306
|
-
* Return type for usePurchaseStatus hook
|
|
307
|
-
*
|
|
308
|
-
* Provides advanced purchase status helpers and utilities.
|
|
309
|
-
* Focuses on cancelled purchase logic and date formatting.
|
|
310
|
-
* For basic purchase data and paid status, use usePurchase() instead.
|
|
311
|
-
*/
|
|
312
|
-
interface PurchaseStatusReturn {
|
|
313
|
-
/**
|
|
314
|
-
* Most recent cancelled paid purchase (sorted by startDate)
|
|
315
|
-
* null if no cancelled paid purchase exists
|
|
316
|
-
*/
|
|
317
|
-
cancelledPurchase: PurchaseInfo | null;
|
|
318
|
-
/**
|
|
319
|
-
* Whether to show cancelled purchase notice
|
|
320
|
-
* true if cancelledPurchase exists
|
|
321
|
-
*/
|
|
322
|
-
shouldShowCancelledNotice: boolean;
|
|
323
|
-
/**
|
|
324
|
-
* Format a date string to locale format (e.g., "January 15, 2024")
|
|
325
|
-
* Returns null if dateString is not provided
|
|
326
|
-
*/
|
|
327
|
-
formatDate: (dateString?: string) => string | null;
|
|
328
|
-
/**
|
|
329
|
-
* Calculate days until expiration date
|
|
330
|
-
* Returns null if endDate is not provided, otherwise returns days (0 or positive)
|
|
331
|
-
*/
|
|
332
|
-
getDaysUntilExpiration: (endDate?: string) => number | null;
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Payment form props - simplified and minimal
|
|
336
|
-
*/
|
|
337
|
-
interface PaymentFormProps {
|
|
338
|
-
/**
|
|
339
|
-
* Plan reference to checkout. PaymentForm handles the entire checkout flow internally
|
|
340
|
-
* including Stripe initialization and payment intent creation.
|
|
341
|
-
*/
|
|
342
|
-
planRef: string;
|
|
343
|
-
/**
|
|
344
|
-
* Product reference. Required for processing payment after confirmation.
|
|
345
|
-
*/
|
|
346
|
-
productRef?: string;
|
|
347
|
-
/**
|
|
348
|
-
* Callback when payment succeeds
|
|
349
|
-
*/
|
|
350
|
-
onSuccess?: (paymentIntent: PaymentIntent) => void;
|
|
351
|
-
/**
|
|
352
|
-
* Callback when payment fails
|
|
353
|
-
*/
|
|
354
|
-
onError?: (error: Error) => void;
|
|
355
|
-
/**
|
|
356
|
-
* Return URL after payment completion. Defaults to current page URL if not provided.
|
|
357
|
-
*/
|
|
358
|
-
returnUrl?: string;
|
|
359
|
-
/**
|
|
360
|
-
* Text for the submit button. Defaults to "Pay Now"
|
|
361
|
-
*/
|
|
362
|
-
submitButtonText?: string;
|
|
363
|
-
/**
|
|
364
|
-
* Optional className for the form container
|
|
365
|
-
*/
|
|
366
|
-
className?: string;
|
|
367
|
-
/**
|
|
368
|
-
* Optional className for the submit button
|
|
369
|
-
*/
|
|
370
|
-
buttonClassName?: string;
|
|
371
|
-
}
|
|
372
|
-
type PurchaseStatusValue = 'pending' | 'active' | 'trialing' | 'past_due' | 'cancelled' | 'expired' | 'suspended' | 'refunded';
|
|
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-CieT9swn.cjs';
|
|
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-CieT9swn.cjs';
|
|
4
|
+
import { PaymentIntent, Stripe, StripeElements } from '@stripe/stripe-js';
|
|
5
|
+
import { ActivatePlanResult } from '@solvapay/server';
|
|
6
|
+
export { ActivatePlanResult } from '@solvapay/server';
|
|
7
|
+
export { AuthAdapter, defaultAuthAdapter } from './adapters/auth.cjs';
|
|
8
|
+
import '@stripe/react-stripe-js';
|
|
373
9
|
|
|
374
10
|
/**
|
|
375
11
|
* SolvaPay Provider - Headless Context Provider for React.
|
|
@@ -450,163 +86,56 @@ type PurchaseStatusValue = 'pending' | 'active' | 'trialing' | 'past_due' | 'can
|
|
|
450
86
|
* @see {@link useSolvaPay} for accessing provider methods
|
|
451
87
|
* @since 1.0.0
|
|
452
88
|
*/
|
|
453
|
-
declare const SolvaPayProvider: React
|
|
89
|
+
declare const SolvaPayProvider: React.FC<SolvaPayProviderProps>;
|
|
454
90
|
|
|
455
91
|
/**
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
* @param props - Payment form configuration
|
|
470
|
-
* @param props.planRef - Plan reference to purchase (required)
|
|
471
|
-
* @param props.productRef - Product reference for usage tracking
|
|
472
|
-
* @param props.onSuccess - Callback when payment succeeds
|
|
473
|
-
* @param props.onError - Callback when payment fails
|
|
474
|
-
* @param props.returnUrl - Optional return URL after payment (for redirects)
|
|
475
|
-
* @param props.submitButtonText - Custom text for submit button (default: 'Pay Now')
|
|
476
|
-
* @param props.className - Custom CSS class for the form container
|
|
477
|
-
* @param props.buttonClassName - Custom CSS class for the submit button
|
|
478
|
-
*
|
|
479
|
-
* @example
|
|
480
|
-
* ```tsx
|
|
481
|
-
* import { PaymentForm } from '@solvapay/react';
|
|
482
|
-
* import { useRouter } from 'next/navigation';
|
|
483
|
-
*
|
|
484
|
-
* function CheckoutPage() {
|
|
485
|
-
* const router = useRouter();
|
|
486
|
-
*
|
|
487
|
-
* return (
|
|
488
|
-
* <PaymentForm
|
|
489
|
-
* planRef="pln_premium"
|
|
490
|
-
* productRef="prd_myapi"
|
|
491
|
-
* onSuccess={() => {
|
|
492
|
-
* console.log('Payment successful!');
|
|
493
|
-
* router.push('/dashboard');
|
|
494
|
-
* }}
|
|
495
|
-
* onError={(error) => {
|
|
496
|
-
* console.error('Payment failed:', error);
|
|
497
|
-
* }}
|
|
498
|
-
* />
|
|
499
|
-
* );
|
|
500
|
-
* }
|
|
501
|
-
* ```
|
|
502
|
-
*
|
|
503
|
-
* @see {@link useCheckout} for programmatic checkout handling
|
|
504
|
-
* @see {@link SolvaPayProvider} for required context provider
|
|
505
|
-
* @since 1.0.0
|
|
92
|
+
* Default-tree shim over the `PaymentForm` primitive.
|
|
93
|
+
*
|
|
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.
|
|
101
|
+
*
|
|
102
|
+
* Full control (swap PaymentElement for CardElement, reorder, compose with
|
|
103
|
+
* shadcn/Tailwind) is available via the primitives at
|
|
104
|
+
* `@solvapay/react/primitives`.
|
|
506
105
|
*/
|
|
507
|
-
declare const PaymentForm: React$1.FC<PaymentFormProps>;
|
|
508
106
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
* ) : null
|
|
526
|
-
* )}
|
|
527
|
-
* </ProductBadge>
|
|
528
|
-
*
|
|
529
|
-
* // ClassName pattern
|
|
530
|
-
* <ProductBadge className="badge badge-primary" />
|
|
531
|
-
* ```
|
|
532
|
-
*/
|
|
533
|
-
declare const ProductBadge: React$1.FC<ProductBadgeProps>;
|
|
534
|
-
/** @deprecated Use ProductBadge instead */
|
|
535
|
-
declare const PlanBadge: React$1.FC<ProductBadgeProps>;
|
|
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
|
+
};
|
|
536
123
|
|
|
537
124
|
/**
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
* Controls access to content based on purchase status.
|
|
541
|
-
* Uses render props to give developers full control over locked/unlocked states.
|
|
125
|
+
* Default-tree shim over the `TopupForm` primitive.
|
|
542
126
|
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
* {({ hasAccess, loading }) => {
|
|
547
|
-
* if (loading) return <Skeleton />;
|
|
548
|
-
* if (!hasAccess) return <Paywall />;
|
|
549
|
-
* return <PremiumContent />;
|
|
550
|
-
* }}
|
|
551
|
-
* </PurchaseGate>
|
|
552
|
-
* ```
|
|
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`.
|
|
553
130
|
*/
|
|
554
|
-
declare const PurchaseGate: React$1.FC<PurchaseGateProps>;
|
|
555
131
|
|
|
556
|
-
|
|
557
|
-
* Headless Pricing Selector Component
|
|
558
|
-
*
|
|
559
|
-
* Provides pricing selection logic with complete styling control via render props.
|
|
560
|
-
* Integrates plan fetching, purchase status, and selection state management.
|
|
561
|
-
*
|
|
562
|
-
* Features:
|
|
563
|
-
* - Fetches and manages pricing options
|
|
564
|
-
* - Tracks selected option
|
|
565
|
-
* - Provides helpers for checking if option is current/paid
|
|
566
|
-
* - Integrates with purchase context
|
|
567
|
-
*
|
|
568
|
-
* @example
|
|
569
|
-
* ```tsx
|
|
570
|
-
* <PricingSelector
|
|
571
|
-
* productRef="prd_123"
|
|
572
|
-
* fetcher={async (productRef) => {
|
|
573
|
-
* const res = await fetch(`/api/list-plans?productRef=${productRef}`);
|
|
574
|
-
* const data = await res.json();
|
|
575
|
-
* return data.plans;
|
|
576
|
-
* }}
|
|
577
|
-
* sortBy={(a, b) => (a.price || 0) - (b.price || 0)}
|
|
578
|
-
* autoSelectFirstPaid
|
|
579
|
-
* >
|
|
580
|
-
* {({ plans, selectedPlan, setSelectedPlanIndex, loading, isPaidPlan, isCurrentPlan }) => (
|
|
581
|
-
* <div>
|
|
582
|
-
* {loading ? (
|
|
583
|
-
* <div>Loading...</div>
|
|
584
|
-
* ) : (
|
|
585
|
-
* plans.map((plan, index) => (
|
|
586
|
-
* <button
|
|
587
|
-
* key={plan.reference}
|
|
588
|
-
* onClick={() => setSelectedPlanIndex(index)}
|
|
589
|
-
* disabled={!isPaidPlan(plan.reference)}
|
|
590
|
-
* >
|
|
591
|
-
* ${plan.price}/{plan.interval}
|
|
592
|
-
* {isCurrentPlan(plan.reference) && ' (Current)'}
|
|
593
|
-
* </button>
|
|
594
|
-
* ))
|
|
595
|
-
* )}
|
|
596
|
-
* </div>
|
|
597
|
-
* )}
|
|
598
|
-
* </PricingSelector>
|
|
599
|
-
* ```
|
|
600
|
-
*/
|
|
601
|
-
declare const PricingSelector: React$1.FC<PricingSelectorProps>;
|
|
602
|
-
/** @deprecated Use PricingSelector instead */
|
|
603
|
-
declare const PlanSelector: React$1.FC<PricingSelectorProps>;
|
|
132
|
+
declare const TopupForm: React.FC<TopupFormProps>;
|
|
604
133
|
|
|
605
134
|
/**
|
|
606
135
|
* SVG-based spinner component using CSS animations
|
|
607
136
|
* Uses the same spinner design as the rest of the site
|
|
608
137
|
*/
|
|
609
|
-
declare const Spinner: React
|
|
138
|
+
declare const Spinner: React.FC<{
|
|
610
139
|
className?: string;
|
|
611
140
|
size?: 'sm' | 'md' | 'lg';
|
|
612
141
|
}>;
|
|
@@ -624,7 +153,193 @@ interface StripePaymentFormWrapperProps {
|
|
|
624
153
|
* Renders inside Stripe Elements context and handles the payment flow
|
|
625
154
|
* All hooks are called unconditionally to comply with React Rules of Hooks
|
|
626
155
|
*/
|
|
627
|
-
declare const StripePaymentFormWrapper: React
|
|
156
|
+
declare const StripePaymentFormWrapper: React.FC<StripePaymentFormWrapperProps>;
|
|
157
|
+
|
|
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
|
+
}>;
|
|
628
343
|
|
|
629
344
|
/**
|
|
630
345
|
* Hook to get current purchase status and information.
|
|
@@ -719,61 +434,35 @@ interface UseCheckoutReturn {
|
|
|
719
434
|
error: Error | null;
|
|
720
435
|
stripePromise: Promise<Stripe | null> | null;
|
|
721
436
|
clientSecret: string | null;
|
|
437
|
+
resolvedPlanRef: string | null;
|
|
722
438
|
startCheckout: () => Promise<void>;
|
|
723
439
|
reset: () => void;
|
|
724
440
|
}
|
|
725
441
|
/**
|
|
726
442
|
* Hook to manage checkout flow for payment processing.
|
|
727
443
|
*
|
|
728
|
-
* Handles payment intent creation and Stripe initialization.
|
|
729
|
-
*
|
|
730
|
-
*
|
|
444
|
+
* Handles payment intent creation and Stripe initialization. When `planRef`
|
|
445
|
+
* is omitted but `productRef` is provided, the hook auto-resolves the plan
|
|
446
|
+
* by fetching the product's plans and selecting the single/default one.
|
|
731
447
|
*
|
|
732
448
|
* @param options - Checkout options
|
|
733
|
-
* @param options.planRef - Plan reference
|
|
734
|
-
* @param options.productRef -
|
|
449
|
+
* @param options.planRef - Plan reference (optional if product has single/default plan)
|
|
450
|
+
* @param options.productRef - Product reference (required when planRef is omitted)
|
|
735
451
|
* @returns Checkout state and methods
|
|
736
|
-
* @returns loading - Whether checkout is in progress
|
|
737
|
-
* @returns error - Error state if checkout fails
|
|
738
|
-
* @returns stripePromise - Promise resolving to Stripe instance
|
|
739
|
-
* @returns clientSecret - Stripe payment intent client secret
|
|
740
|
-
* @returns startCheckout - Function to start the checkout process
|
|
741
|
-
* @returns reset - Function to reset checkout state
|
|
742
452
|
*
|
|
743
453
|
* @example
|
|
744
454
|
* ```tsx
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
* function CustomCheckout() {
|
|
749
|
-
* const { loading, error, stripePromise, clientSecret, startCheckout } = useCheckout({
|
|
750
|
-
* planRef: 'pln_premium',
|
|
751
|
-
* productRef: 'prd_myapi',
|
|
752
|
-
* });
|
|
455
|
+
* // Explicit planRef (no resolution needed)
|
|
456
|
+
* const checkout = useCheckout({ planRef: 'pln_premium', productRef: 'prd_myapi' })
|
|
753
457
|
*
|
|
754
|
-
*
|
|
755
|
-
*
|
|
756
|
-
* }, []);
|
|
757
|
-
*
|
|
758
|
-
* if (loading) return <Spinner />;
|
|
759
|
-
* if (error) return <div>Error: {error.message}</div>;
|
|
760
|
-
* if (!clientSecret || !stripePromise) return null;
|
|
761
|
-
*
|
|
762
|
-
* return (
|
|
763
|
-
* <Elements stripe={await stripePromise} options={{ clientSecret }}>
|
|
764
|
-
* <PaymentElement />
|
|
765
|
-
* </Elements>
|
|
766
|
-
* );
|
|
767
|
-
* }
|
|
458
|
+
* // Auto-resolve plan from product (single plan or default plan)
|
|
459
|
+
* const checkout = useCheckout({ productRef: 'prd_myapi' })
|
|
768
460
|
* ```
|
|
769
|
-
*
|
|
770
|
-
* @see {@link PaymentForm} for a complete payment form component
|
|
771
|
-
* @see {@link SolvaPayProvider} for required context provider
|
|
772
|
-
* @since 1.0.0
|
|
773
461
|
*/
|
|
774
462
|
declare function useCheckout(options: {
|
|
775
|
-
planRef
|
|
463
|
+
planRef?: string;
|
|
776
464
|
productRef?: string;
|
|
465
|
+
customer?: PrefillCustomer;
|
|
777
466
|
}): UseCheckoutReturn;
|
|
778
467
|
|
|
779
468
|
/**
|
|
@@ -820,32 +509,53 @@ declare function useCheckout(options: {
|
|
|
820
509
|
declare function useSolvaPay(): SolvaPayContextValue;
|
|
821
510
|
|
|
822
511
|
/**
|
|
823
|
-
* Hook to manage plan fetching and selection
|
|
824
|
-
*
|
|
825
|
-
* Provides a reusable way to fetch, filter, sort and select plans.
|
|
826
|
-
* Handles loading and error states automatically.
|
|
827
|
-
* Uses a global cache to prevent duplicate fetches when multiple components use the same productRef.
|
|
512
|
+
* Hook to manage plan fetching and selection.
|
|
828
513
|
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
*
|
|
833
|
-
*
|
|
834
|
-
* const res = await fetch(`/api/list-plans?productRef=${productRef}`);
|
|
835
|
-
* const data = await res.json();
|
|
836
|
-
* return data.plans;
|
|
837
|
-
* },
|
|
838
|
-
* sortBy: (a, b) => (a.price || 0) - (b.price || 0),
|
|
839
|
-
* autoSelectFirstPaid: true,
|
|
840
|
-
* });
|
|
841
|
-
*
|
|
842
|
-
* // Use in component
|
|
843
|
-
* if (plans.loading) return <div>Loading...</div>;
|
|
844
|
-
* if (plans.error) return <div>Error: {plans.error.message}</div>;
|
|
845
|
-
* ```
|
|
514
|
+
* Selection lifecycle:
|
|
515
|
+
* 1. While `selectionReady` is false, plans fetch but no auto-selection fires.
|
|
516
|
+
* 2. When `selectionReady` becomes true AND plans are loaded, one-shot initial
|
|
517
|
+
* selection is applied (initialPlanRef > autoSelectFirstPaid > index 0).
|
|
518
|
+
* 3. After initial selection, user picks always win — the hook never overrides.
|
|
846
519
|
*/
|
|
847
520
|
declare function usePlans(options: UsePlansOptions): UsePlansReturn;
|
|
848
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
|
+
|
|
849
559
|
/**
|
|
850
560
|
* Hook providing advanced status and helper functions for purchase management
|
|
851
561
|
*
|
|
@@ -864,6 +574,144 @@ declare function usePlans(options: UsePlansOptions): UsePlansReturn;
|
|
|
864
574
|
*/
|
|
865
575
|
declare function usePurchaseStatus(): PurchaseStatusReturn;
|
|
866
576
|
|
|
577
|
+
interface PurchaseActions {
|
|
578
|
+
cancelRenewal: (params: {
|
|
579
|
+
purchaseRef: string;
|
|
580
|
+
reason?: string;
|
|
581
|
+
}) => Promise<CancelResult>;
|
|
582
|
+
reactivateRenewal: (params: {
|
|
583
|
+
purchaseRef: string;
|
|
584
|
+
}) => Promise<ReactivateResult>;
|
|
585
|
+
activatePlan: (params: {
|
|
586
|
+
productRef: string;
|
|
587
|
+
planRef: string;
|
|
588
|
+
}) => Promise<ActivatePlanResult>;
|
|
589
|
+
isCancelling: boolean;
|
|
590
|
+
isReactivating: boolean;
|
|
591
|
+
isActivating: boolean;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Hook for purchase lifecycle mutations: cancel, reactivate, and activate.
|
|
595
|
+
*
|
|
596
|
+
* Wraps the context methods with per-operation loading states.
|
|
597
|
+
* Auto-refetches purchase data on success (handled by the context methods).
|
|
598
|
+
*
|
|
599
|
+
* @example
|
|
600
|
+
* ```tsx
|
|
601
|
+
* const { cancelRenewal, reactivateRenewal, isCancelling } = usePurchaseActions()
|
|
602
|
+
*
|
|
603
|
+
* await cancelRenewal({ purchaseRef: purchase.reference, reason: 'User requested' })
|
|
604
|
+
* ```
|
|
605
|
+
*/
|
|
606
|
+
declare function usePurchaseActions(): PurchaseActions;
|
|
607
|
+
|
|
608
|
+
type ActivationState = 'idle' | 'activating' | 'activated' | 'topup_required' | 'payment_required' | 'error';
|
|
609
|
+
interface UseActivationReturn {
|
|
610
|
+
activate: (params: {
|
|
611
|
+
productRef: string;
|
|
612
|
+
planRef: string;
|
|
613
|
+
}) => Promise<void>;
|
|
614
|
+
state: ActivationState;
|
|
615
|
+
error: string | null;
|
|
616
|
+
result: ActivatePlanResult | null;
|
|
617
|
+
reset: () => void;
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* State-machine hook for the plan activation flow.
|
|
621
|
+
*
|
|
622
|
+
* Wraps `activatePlan` from context and maps API response statuses
|
|
623
|
+
* to discrete UI states: idle → activating → activated | topup_required | payment_required | error.
|
|
624
|
+
*
|
|
625
|
+
* Auto-refetches purchase data on successful activation (handled by context).
|
|
626
|
+
*
|
|
627
|
+
* @example
|
|
628
|
+
* ```tsx
|
|
629
|
+
* const { activate, state, error, reset } = useActivation()
|
|
630
|
+
*
|
|
631
|
+
* if (state === 'topup_required') return <TopupPrompt />
|
|
632
|
+
* if (state === 'activated') return <SuccessMessage />
|
|
633
|
+
*
|
|
634
|
+
* <button onClick={() => activate({ productRef, planRef })} disabled={state === 'activating'}>
|
|
635
|
+
* Activate
|
|
636
|
+
* </button>
|
|
637
|
+
* ```
|
|
638
|
+
*/
|
|
639
|
+
declare function useActivation(): UseActivationReturn;
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Hook to manage credit top-up flow.
|
|
643
|
+
*
|
|
644
|
+
* Handles payment intent creation (with `purpose: 'credit_topup'`) and
|
|
645
|
+
* Stripe initialization. Unlike `useCheckout`, there is no plan resolution
|
|
646
|
+
* and no `processPayment` step — credits are recorded via webhook.
|
|
647
|
+
*
|
|
648
|
+
* @param options.amount - Amount in smallest currency unit (e.g. cents)
|
|
649
|
+
* @param options.currency - ISO 4217 currency code (default: 'usd')
|
|
650
|
+
*/
|
|
651
|
+
declare function useTopup(options: UseTopupOptions): UseTopupReturn;
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Hook to get the current customer's credits.
|
|
655
|
+
*
|
|
656
|
+
* Automatically fetches on mount and re-fetches when
|
|
657
|
+
* authentication state changes (ensures credits load
|
|
658
|
+
* even when auth resolves after initial render).
|
|
659
|
+
*
|
|
660
|
+
* @example
|
|
661
|
+
* ```tsx
|
|
662
|
+
* const { credits, displayCurrency, loading, refetch } = useBalance()
|
|
663
|
+
* ```
|
|
664
|
+
*/
|
|
665
|
+
declare function useBalance(): BalanceStatus;
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Headless hook for top-up amount selection.
|
|
669
|
+
*
|
|
670
|
+
* Manages quick-pick presets, custom input, mutual exclusivity, and validation.
|
|
671
|
+
* Currency-aware: presets and symbol adjust based on the ISO 4217 code.
|
|
672
|
+
*
|
|
673
|
+
* @example
|
|
674
|
+
* ```tsx
|
|
675
|
+
* const {
|
|
676
|
+
* quickAmounts, selectedAmount, customAmount,
|
|
677
|
+
* resolvedAmount, selectQuickAmount, setCustomAmount,
|
|
678
|
+
* error, validate, reset, currencySymbol,
|
|
679
|
+
* } = useTopupAmountSelector({ currency: 'usd' })
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
declare function useTopupAmountSelector(options: UseTopupAmountSelectorOptions): UseTopupAmountSelectorReturn;
|
|
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
|
+
|
|
867
715
|
/**
|
|
868
716
|
* Purchase utility functions
|
|
869
717
|
*
|
|
@@ -921,4 +769,82 @@ declare function getPrimaryPurchase(purchases: PurchaseInfo[]): PurchaseInfo | n
|
|
|
921
769
|
*/
|
|
922
770
|
declare function isPaidPurchase(purchase: PurchaseInfo): boolean;
|
|
923
771
|
|
|
924
|
-
|
|
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 };
|