@solvapay/react 1.0.8-preview.6 → 1.0.8-preview.8
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/README.md +12 -95
- package/dist/CancelPlanButton-Bb7cvym9.d.cts +1105 -0
- package/dist/CancelPlanButton-CieT9swn.d.cts +1102 -0
- package/dist/CancelPlanButton-Cq117t7h.d.ts +1105 -0
- package/dist/CancelPlanButton-f56UlQN-.d.ts +1102 -0
- package/dist/PaymentForm-B5dw0i1X.d.ts +934 -0
- package/dist/PaymentForm-CesoRQWu.d.cts +934 -0
- package/dist/chunk-C7SKOENW.js +1889 -0
- package/dist/chunk-ISYAH4ZL.js +1889 -0
- package/dist/chunk-MOP3ZBGC.js +4749 -0
- package/dist/chunk-Q7GPX6X4.js +4748 -0
- package/dist/chunk-TP4JPKE2.js +3126 -0
- package/dist/chunk-VTGIXJQU.js +4755 -0
- package/dist/chunk-XMQ4GBWQ.js +4752 -0
- package/dist/index-DLl3UwO3.d.ts +798 -0
- package/dist/index-Sj2lHLl8.d.cts +798 -0
- package/dist/index.cjs +11 -25
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/primitives/index.cjs +4 -21
- package/dist/primitives/index.d.cts +2 -2
- package/dist/primitives/index.d.ts +2 -2
- package/dist/primitives/index.js +1 -1
- package/dist/src/PaymentForm.d.ts +56 -0
- package/dist/src/PaymentForm.d.ts.map +1 -0
- package/dist/src/PaymentForm.js +212 -0
- package/dist/src/PaymentForm.js.map +1 -0
- package/dist/src/SolvaPayProvider.d.ts +84 -0
- package/dist/src/SolvaPayProvider.d.ts.map +1 -0
- package/dist/src/SolvaPayProvider.js +537 -0
- package/dist/src/SolvaPayProvider.js.map +1 -0
- package/dist/src/adapters/auth.d.ts +43 -0
- package/dist/src/adapters/auth.d.ts.map +1 -0
- package/dist/src/adapters/auth.js +38 -0
- package/dist/src/adapters/auth.js.map +1 -0
- package/dist/src/components/PlanBadge.d.ts +31 -0
- package/dist/src/components/PlanBadge.d.ts.map +1 -0
- package/dist/src/components/PlanBadge.js +119 -0
- package/dist/src/components/PlanBadge.js.map +1 -0
- package/dist/src/components/PlanSelector.d.ts +49 -0
- package/dist/src/components/PlanSelector.d.ts.map +1 -0
- package/dist/src/components/PlanSelector.js +82 -0
- package/dist/src/components/PlanSelector.js.map +1 -0
- package/dist/src/components/Spinner.d.ts +10 -0
- package/dist/src/components/Spinner.d.ts.map +1 -0
- package/dist/src/components/Spinner.js +14 -0
- package/dist/src/components/Spinner.js.map +1 -0
- package/dist/src/components/StripePaymentFormWrapper.d.ts +17 -0
- package/dist/src/components/StripePaymentFormWrapper.d.ts.map +1 -0
- package/dist/src/components/StripePaymentFormWrapper.js +158 -0
- package/dist/src/components/StripePaymentFormWrapper.js.map +1 -0
- package/dist/src/components/SubscriptionGate.d.ts +21 -0
- package/dist/src/components/SubscriptionGate.d.ts.map +1 -0
- package/dist/src/components/SubscriptionGate.js +32 -0
- package/dist/src/components/SubscriptionGate.js.map +1 -0
- package/dist/src/hooks/__tests__/useSubscription.test.d.ts +2 -0
- package/dist/src/hooks/__tests__/useSubscription.test.d.ts.map +1 -0
- package/dist/src/hooks/__tests__/useSubscription.test.js +554 -0
- package/dist/src/hooks/__tests__/useSubscription.test.js.map +1 -0
- package/dist/src/hooks/__tests__/useSubscriptionStatus.test.d.ts +2 -0
- package/dist/src/hooks/__tests__/useSubscriptionStatus.test.d.ts.map +1 -0
- package/dist/src/hooks/__tests__/useSubscriptionStatus.test.js +719 -0
- package/dist/src/hooks/__tests__/useSubscriptionStatus.test.js.map +1 -0
- package/dist/src/hooks/useCheckout.d.ts +59 -0
- package/dist/src/hooks/useCheckout.d.ts.map +1 -0
- package/dist/src/hooks/useCheckout.js +138 -0
- package/dist/src/hooks/useCheckout.js.map +1 -0
- package/dist/src/hooks/useCustomer.d.ts +43 -0
- package/dist/src/hooks/useCustomer.d.ts.map +1 -0
- package/dist/src/hooks/useCustomer.js +31 -0
- package/dist/src/hooks/useCustomer.js.map +1 -0
- package/dist/src/hooks/usePlans.d.ts +28 -0
- package/dist/src/hooks/usePlans.d.ts.map +1 -0
- package/dist/src/hooks/usePlans.js +181 -0
- package/dist/src/hooks/usePlans.js.map +1 -0
- package/dist/src/hooks/useSolvaPay.d.ts +44 -0
- package/dist/src/hooks/useSolvaPay.d.ts.map +1 -0
- package/dist/src/hooks/useSolvaPay.js +52 -0
- package/dist/src/hooks/useSolvaPay.js.map +1 -0
- package/dist/src/hooks/useSubscription.d.ts +46 -0
- package/dist/src/hooks/useSubscription.d.ts.map +1 -0
- package/dist/src/hooks/useSubscription.js +50 -0
- package/dist/src/hooks/useSubscription.js.map +1 -0
- package/dist/src/hooks/useSubscriptionStatus.d.ts +19 -0
- package/dist/src/hooks/useSubscriptionStatus.d.ts.map +1 -0
- package/dist/src/hooks/useSubscriptionStatus.js +68 -0
- package/dist/src/hooks/useSubscriptionStatus.js.map +1 -0
- package/dist/src/index.d.ts +24 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +26 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/types/index.d.ts +339 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +5 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/utils/__tests__/subscriptions.test.d.ts +2 -0
- package/dist/src/utils/__tests__/subscriptions.test.d.ts.map +1 -0
- package/dist/src/utils/__tests__/subscriptions.test.js +121 -0
- package/dist/src/utils/__tests__/subscriptions.test.js.map +1 -0
- package/dist/src/utils/subscriptions.d.ts +57 -0
- package/dist/src/utils/subscriptions.d.ts.map +1 -0
- package/dist/src/utils/subscriptions.js +85 -0
- package/dist/src/utils/subscriptions.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,798 @@
|
|
|
1
|
+
import * as _stripe_stripe_js from '@stripe/stripe-js';
|
|
2
|
+
import { PaymentIntent } from '@stripe/stripe-js';
|
|
3
|
+
import { ActivatePlanResult, ProcessPaymentResult } from '@solvapay/server';
|
|
4
|
+
import { AuthAdapter } from './adapters/auth.cjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Typed copy bundle surfaced through `<SolvaPayProvider config={{ copy }} />`.
|
|
8
|
+
*
|
|
9
|
+
* Every user-visible string in `@solvapay/react` routes through this bundle via
|
|
10
|
+
* `useCopy()`. Values are either plain templates with `{placeholder}` tokens or
|
|
11
|
+
* function-form resolvers (currently only used for mandate variants) that
|
|
12
|
+
* receive a `MandateContext` and return the final string.
|
|
13
|
+
*/
|
|
14
|
+
type MandateContext = {
|
|
15
|
+
merchant: {
|
|
16
|
+
legalName: string;
|
|
17
|
+
displayName?: string;
|
|
18
|
+
supportEmail?: string;
|
|
19
|
+
termsUrl?: string;
|
|
20
|
+
privacyUrl?: string;
|
|
21
|
+
};
|
|
22
|
+
plan?: {
|
|
23
|
+
name?: string;
|
|
24
|
+
interval?: string;
|
|
25
|
+
intervalCount?: number;
|
|
26
|
+
trialDays?: number;
|
|
27
|
+
measures?: string;
|
|
28
|
+
billingCycle?: string;
|
|
29
|
+
};
|
|
30
|
+
product?: {
|
|
31
|
+
name?: string;
|
|
32
|
+
};
|
|
33
|
+
amountFormatted: string;
|
|
34
|
+
trialDays?: number;
|
|
35
|
+
};
|
|
36
|
+
type MandateTemplate = string | ((ctx: MandateContext) => string);
|
|
37
|
+
interface SolvaPayCopy {
|
|
38
|
+
mandate: {
|
|
39
|
+
recurring: MandateTemplate;
|
|
40
|
+
oneTime: MandateTemplate;
|
|
41
|
+
topup: MandateTemplate;
|
|
42
|
+
usageMetered: MandateTemplate;
|
|
43
|
+
freeTier: MandateTemplate;
|
|
44
|
+
};
|
|
45
|
+
cta: {
|
|
46
|
+
payNow: string;
|
|
47
|
+
topUp: string;
|
|
48
|
+
subscribe: string;
|
|
49
|
+
trialStart: string;
|
|
50
|
+
payAmount: string;
|
|
51
|
+
addAmount: string;
|
|
52
|
+
startUsing: string;
|
|
53
|
+
processing: string;
|
|
54
|
+
};
|
|
55
|
+
interval: {
|
|
56
|
+
day: string;
|
|
57
|
+
week: string;
|
|
58
|
+
month: string;
|
|
59
|
+
year: string;
|
|
60
|
+
every: string;
|
|
61
|
+
free: string;
|
|
62
|
+
trial: string;
|
|
63
|
+
};
|
|
64
|
+
terms: {
|
|
65
|
+
checkboxLabel: string;
|
|
66
|
+
};
|
|
67
|
+
customer: {
|
|
68
|
+
chargingTo: string;
|
|
69
|
+
emailLabel: string;
|
|
70
|
+
nameLabel: string;
|
|
71
|
+
};
|
|
72
|
+
balance: {
|
|
73
|
+
credits: string;
|
|
74
|
+
currencyEquivalent: string;
|
|
75
|
+
};
|
|
76
|
+
product: {
|
|
77
|
+
currentProductLabel: string;
|
|
78
|
+
};
|
|
79
|
+
topup: {
|
|
80
|
+
selectOrEnterAmount: string;
|
|
81
|
+
minAmount: string;
|
|
82
|
+
maxAmount: string;
|
|
83
|
+
};
|
|
84
|
+
activation: {
|
|
85
|
+
paymentRequired: string;
|
|
86
|
+
invalidConfiguration: string;
|
|
87
|
+
unexpectedResponse: string;
|
|
88
|
+
failed: string;
|
|
89
|
+
};
|
|
90
|
+
planSelector: {
|
|
91
|
+
heading: string;
|
|
92
|
+
currentBadge: string;
|
|
93
|
+
popularBadge: string;
|
|
94
|
+
freeBadge: string;
|
|
95
|
+
perIntervalShort: string;
|
|
96
|
+
continueButton: string;
|
|
97
|
+
backButton: string;
|
|
98
|
+
trialBadge: string;
|
|
99
|
+
};
|
|
100
|
+
amountPicker: {
|
|
101
|
+
selectAmountLabel: string;
|
|
102
|
+
customAmountLabel: string;
|
|
103
|
+
creditEstimateExact: string;
|
|
104
|
+
creditEstimateApprox: string;
|
|
105
|
+
};
|
|
106
|
+
activationFlow: {
|
|
107
|
+
heading: string;
|
|
108
|
+
activateButton: string;
|
|
109
|
+
activatingLabel: string;
|
|
110
|
+
topupHeading: string;
|
|
111
|
+
topupSubheading: string;
|
|
112
|
+
continueToPayment: string;
|
|
113
|
+
changeAmountButton: string;
|
|
114
|
+
retryingHeading: string;
|
|
115
|
+
retryingSubheading: string;
|
|
116
|
+
activatedHeading: string;
|
|
117
|
+
activatedSubheading: string;
|
|
118
|
+
tryAgainButton: string;
|
|
119
|
+
backButton: string;
|
|
120
|
+
};
|
|
121
|
+
cancelPlan: {
|
|
122
|
+
button: string;
|
|
123
|
+
buttonLoading: string;
|
|
124
|
+
confirmRecurring: string;
|
|
125
|
+
confirmUsageBased: string;
|
|
126
|
+
};
|
|
127
|
+
cancelledNotice: {
|
|
128
|
+
heading: string;
|
|
129
|
+
expiresLabel: string;
|
|
130
|
+
daysRemaining: string;
|
|
131
|
+
dayRemaining: string;
|
|
132
|
+
accessUntil: string;
|
|
133
|
+
accessEnded: string;
|
|
134
|
+
cancelledOn: string;
|
|
135
|
+
reactivateButton: string;
|
|
136
|
+
reactivateButtonLoading: string;
|
|
137
|
+
};
|
|
138
|
+
creditGate: {
|
|
139
|
+
lowBalanceHeading: string;
|
|
140
|
+
lowBalanceSubheading: string;
|
|
141
|
+
topUpCta: string;
|
|
142
|
+
};
|
|
143
|
+
errors: {
|
|
144
|
+
paymentInitFailed: string;
|
|
145
|
+
topupInitFailed: string;
|
|
146
|
+
configMissingPlanOrProduct: string;
|
|
147
|
+
configMissingAmount: string;
|
|
148
|
+
unknownError: string;
|
|
149
|
+
stripeUnavailable: string;
|
|
150
|
+
paymentIntentUnavailable: string;
|
|
151
|
+
cardElementMissing: string;
|
|
152
|
+
paymentUnexpected: string;
|
|
153
|
+
paymentProcessingFailed: string;
|
|
154
|
+
paymentRequires3ds: string;
|
|
155
|
+
paymentProcessingTimeout: string;
|
|
156
|
+
paymentStatusPrefix: string;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Deep-partial type for consumer overrides — every nested key is optional so
|
|
161
|
+
* integrators can override only the strings they care about.
|
|
162
|
+
*/
|
|
163
|
+
type PartialSolvaPayCopy = {
|
|
164
|
+
[K in keyof SolvaPayCopy]?: Partial<SolvaPayCopy[K]>;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
interface PurchaseInfo {
|
|
168
|
+
reference: string;
|
|
169
|
+
productName: string;
|
|
170
|
+
productRef?: string;
|
|
171
|
+
status: string;
|
|
172
|
+
startDate: string;
|
|
173
|
+
endDate?: string;
|
|
174
|
+
cancelledAt?: string;
|
|
175
|
+
cancellationReason?: string;
|
|
176
|
+
amount?: number;
|
|
177
|
+
currency?: string;
|
|
178
|
+
planType?: string;
|
|
179
|
+
isRecurring?: boolean;
|
|
180
|
+
nextBillingDate?: string;
|
|
181
|
+
billingCycle?: string;
|
|
182
|
+
planRef?: string;
|
|
183
|
+
planSnapshot?: {
|
|
184
|
+
reference?: string;
|
|
185
|
+
price?: number;
|
|
186
|
+
meterRef?: string;
|
|
187
|
+
limit?: number;
|
|
188
|
+
freeUnits?: number;
|
|
189
|
+
creditsPerUnit?: number;
|
|
190
|
+
planType?: string;
|
|
191
|
+
billingCycle?: string | null;
|
|
192
|
+
features?: Record<string, unknown> | null;
|
|
193
|
+
};
|
|
194
|
+
usage?: {
|
|
195
|
+
used: number;
|
|
196
|
+
overageUnits?: number;
|
|
197
|
+
overageCost?: number;
|
|
198
|
+
periodStart?: string;
|
|
199
|
+
periodEnd?: string;
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
interface CustomerPurchaseData {
|
|
203
|
+
customerRef?: string;
|
|
204
|
+
email?: string;
|
|
205
|
+
name?: string;
|
|
206
|
+
purchases: PurchaseInfo[];
|
|
207
|
+
}
|
|
208
|
+
interface PaymentIntentResult {
|
|
209
|
+
clientSecret: string;
|
|
210
|
+
publishableKey: string;
|
|
211
|
+
accountId?: string;
|
|
212
|
+
customerRef?: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Subset of merchant identity surfaced by `GET /v1/sdk/merchant`.
|
|
216
|
+
* Used by `<MandateText>` and customer-facing trust signals.
|
|
217
|
+
*/
|
|
218
|
+
interface Merchant {
|
|
219
|
+
displayName: string;
|
|
220
|
+
legalName: string;
|
|
221
|
+
supportEmail?: string;
|
|
222
|
+
supportUrl?: string;
|
|
223
|
+
termsUrl?: string;
|
|
224
|
+
privacyUrl?: string;
|
|
225
|
+
country?: string;
|
|
226
|
+
defaultCurrency?: string;
|
|
227
|
+
statementDescriptor?: string;
|
|
228
|
+
logoUrl?: string;
|
|
229
|
+
}
|
|
230
|
+
interface UseMerchantReturn {
|
|
231
|
+
merchant: Merchant | null;
|
|
232
|
+
loading: boolean;
|
|
233
|
+
error: Error | null;
|
|
234
|
+
refetch: () => Promise<void>;
|
|
235
|
+
}
|
|
236
|
+
interface Product {
|
|
237
|
+
reference: string;
|
|
238
|
+
name?: string;
|
|
239
|
+
description?: string;
|
|
240
|
+
status?: string;
|
|
241
|
+
[key: string]: unknown;
|
|
242
|
+
}
|
|
243
|
+
interface UseProductReturn {
|
|
244
|
+
product: Product | null;
|
|
245
|
+
loading: boolean;
|
|
246
|
+
error: Error | null;
|
|
247
|
+
refetch: () => Promise<void>;
|
|
248
|
+
}
|
|
249
|
+
interface UsePlanOptions {
|
|
250
|
+
/** Plan reference (e.g. `'pln_premium'`). */
|
|
251
|
+
planRef?: string;
|
|
252
|
+
/**
|
|
253
|
+
* Optional product reference. When provided, the hook reuses the
|
|
254
|
+
* `usePlans` cache instead of fetching a dedicated plan endpoint.
|
|
255
|
+
*/
|
|
256
|
+
productRef?: string;
|
|
257
|
+
/**
|
|
258
|
+
* Fetcher for plan lookup when `productRef` is not provided. Required in
|
|
259
|
+
* that mode so the hook stays dependency-free.
|
|
260
|
+
*/
|
|
261
|
+
fetcher?: (productRef: string) => Promise<Plan[]>;
|
|
262
|
+
}
|
|
263
|
+
interface UsePlanReturn {
|
|
264
|
+
plan: Plan | null;
|
|
265
|
+
loading: boolean;
|
|
266
|
+
error: Error | null;
|
|
267
|
+
refetch: () => Promise<void>;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Optional customer fields forwarded to payment-intent creation so the
|
|
271
|
+
* backend customer record is authoritative. Read back via `useCustomer()`
|
|
272
|
+
* after the intent is created.
|
|
273
|
+
*/
|
|
274
|
+
interface PrefillCustomer {
|
|
275
|
+
name?: string;
|
|
276
|
+
email?: string;
|
|
277
|
+
}
|
|
278
|
+
interface TopupPaymentResult {
|
|
279
|
+
clientSecret: string;
|
|
280
|
+
publishableKey: string;
|
|
281
|
+
accountId?: string;
|
|
282
|
+
customerRef?: string;
|
|
283
|
+
}
|
|
284
|
+
interface UseTopupOptions {
|
|
285
|
+
amount: number;
|
|
286
|
+
currency?: string;
|
|
287
|
+
}
|
|
288
|
+
interface UseTopupReturn {
|
|
289
|
+
loading: boolean;
|
|
290
|
+
error: Error | null;
|
|
291
|
+
stripePromise: Promise<_stripe_stripe_js.Stripe | null> | null;
|
|
292
|
+
clientSecret: string | null;
|
|
293
|
+
startTopup: () => Promise<void>;
|
|
294
|
+
reset: () => void;
|
|
295
|
+
}
|
|
296
|
+
interface TopupFormProps {
|
|
297
|
+
amount: number;
|
|
298
|
+
currency?: string;
|
|
299
|
+
onSuccess?: (paymentIntent: PaymentIntent) => void;
|
|
300
|
+
onError?: (error: Error) => void;
|
|
301
|
+
returnUrl?: string;
|
|
302
|
+
submitButtonText?: string;
|
|
303
|
+
className?: string;
|
|
304
|
+
buttonClassName?: string;
|
|
305
|
+
}
|
|
306
|
+
interface PurchaseStatus {
|
|
307
|
+
loading: boolean;
|
|
308
|
+
/** True when data already exists but a background refetch is in progress */
|
|
309
|
+
isRefetching: boolean;
|
|
310
|
+
/** Last fetch error, or null if the most recent fetch succeeded */
|
|
311
|
+
error: Error | null;
|
|
312
|
+
customerRef?: string;
|
|
313
|
+
email?: string;
|
|
314
|
+
name?: string;
|
|
315
|
+
purchases: PurchaseInfo[];
|
|
316
|
+
hasProduct: (productName: string) => boolean;
|
|
317
|
+
/** @deprecated Use hasProduct instead */
|
|
318
|
+
hasPlan: (productName: string) => boolean;
|
|
319
|
+
/**
|
|
320
|
+
* Primary active purchase (paid or free) - most recent purchase with status === 'active'
|
|
321
|
+
* Backend keeps purchases as 'active' until expiration, even when cancelled.
|
|
322
|
+
* null if no active purchase exists
|
|
323
|
+
*/
|
|
324
|
+
activePurchase: PurchaseInfo | null;
|
|
325
|
+
/**
|
|
326
|
+
* Check if user has any active paid purchase (amount > 0)
|
|
327
|
+
* Checks purchases with status === 'active'.
|
|
328
|
+
* Backend keeps purchases as 'active' until expiration, even when cancelled.
|
|
329
|
+
*/
|
|
330
|
+
hasPaidPurchase: boolean;
|
|
331
|
+
/**
|
|
332
|
+
* Most recent active paid purchase (sorted by startDate)
|
|
333
|
+
* Returns purchase with status === 'active' and amount > 0.
|
|
334
|
+
* null if no active paid purchase exists
|
|
335
|
+
*/
|
|
336
|
+
activePaidPurchase: PurchaseInfo | null;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* SolvaPay Provider Configuration
|
|
340
|
+
* Sensible defaults for minimal code, but fully customizable
|
|
341
|
+
*/
|
|
342
|
+
interface BalanceStatus {
|
|
343
|
+
loading: boolean;
|
|
344
|
+
credits: number | null;
|
|
345
|
+
displayCurrency: string | null;
|
|
346
|
+
creditsPerMinorUnit: number | null;
|
|
347
|
+
displayExchangeRate: number | null;
|
|
348
|
+
refetch: () => Promise<void>;
|
|
349
|
+
adjustBalance: (credits: number) => void;
|
|
350
|
+
}
|
|
351
|
+
interface SolvaPayConfig {
|
|
352
|
+
/**
|
|
353
|
+
* API route configuration
|
|
354
|
+
* Defaults to standard Next.js API routes
|
|
355
|
+
*/
|
|
356
|
+
api?: {
|
|
357
|
+
checkPurchase?: string;
|
|
358
|
+
createPayment?: string;
|
|
359
|
+
processPayment?: string;
|
|
360
|
+
createTopupPayment?: string;
|
|
361
|
+
customerBalance?: string;
|
|
362
|
+
cancelRenewal?: string;
|
|
363
|
+
reactivateRenewal?: string;
|
|
364
|
+
activatePlan?: string;
|
|
365
|
+
listPlans?: string;
|
|
366
|
+
getMerchant?: string;
|
|
367
|
+
getProduct?: string;
|
|
368
|
+
};
|
|
369
|
+
/**
|
|
370
|
+
* BCP-47 locale tag (e.g. 'en', 'sv-SE'). Threaded through every SDK
|
|
371
|
+
* component, `Intl.NumberFormat`, and Stripe Elements. Defaults to the
|
|
372
|
+
* runtime default (typically 'en').
|
|
373
|
+
*/
|
|
374
|
+
locale?: string;
|
|
375
|
+
/**
|
|
376
|
+
* Partial copy overrides. Keys not supplied fall back to the bundled English
|
|
377
|
+
* defaults — consumers only provide the strings they actually want to change.
|
|
378
|
+
*/
|
|
379
|
+
copy?: PartialSolvaPayCopy;
|
|
380
|
+
/**
|
|
381
|
+
* Authentication configuration
|
|
382
|
+
* Uses adapter pattern for flexible auth provider support
|
|
383
|
+
*/
|
|
384
|
+
auth?: {
|
|
385
|
+
/**
|
|
386
|
+
* Auth adapter instance
|
|
387
|
+
* Default: checks localStorage for 'auth_token' key
|
|
388
|
+
*
|
|
389
|
+
* @example
|
|
390
|
+
* ```tsx
|
|
391
|
+
* import { createSupabaseAuthAdapter } from '@solvapay/react-supabase';
|
|
392
|
+
*
|
|
393
|
+
* <SolvaPayProvider
|
|
394
|
+
* config={{
|
|
395
|
+
* auth: {
|
|
396
|
+
* adapter: createSupabaseAuthAdapter({
|
|
397
|
+
* supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
398
|
+
* supabaseAnonKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
399
|
+
* })
|
|
400
|
+
* }
|
|
401
|
+
* }}
|
|
402
|
+
* >
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
adapter?: AuthAdapter;
|
|
406
|
+
/**
|
|
407
|
+
* @deprecated Use `adapter` instead. Will be removed in a future version.
|
|
408
|
+
* Function to get auth token
|
|
409
|
+
*/
|
|
410
|
+
getToken?: () => Promise<string | null>;
|
|
411
|
+
/**
|
|
412
|
+
* @deprecated Use `adapter` instead. Will be removed in a future version.
|
|
413
|
+
* Function to get user ID (for cache key)
|
|
414
|
+
*/
|
|
415
|
+
getUserId?: () => Promise<string | null>;
|
|
416
|
+
};
|
|
417
|
+
/**
|
|
418
|
+
* Custom fetch implementation
|
|
419
|
+
* Default: uses global fetch
|
|
420
|
+
*/
|
|
421
|
+
fetch?: typeof fetch;
|
|
422
|
+
/**
|
|
423
|
+
* Request headers to include in all API calls
|
|
424
|
+
* Default: empty
|
|
425
|
+
*/
|
|
426
|
+
headers?: HeadersInit | (() => Promise<HeadersInit>);
|
|
427
|
+
/**
|
|
428
|
+
* Custom error handler
|
|
429
|
+
* Default: logs to console
|
|
430
|
+
*/
|
|
431
|
+
onError?: (error: Error, context: string) => void;
|
|
432
|
+
}
|
|
433
|
+
interface CancelResult {
|
|
434
|
+
reference?: string;
|
|
435
|
+
status?: string;
|
|
436
|
+
cancelledAt?: string;
|
|
437
|
+
[key: string]: unknown;
|
|
438
|
+
}
|
|
439
|
+
interface ReactivateResult {
|
|
440
|
+
reference?: string;
|
|
441
|
+
status?: string;
|
|
442
|
+
[key: string]: unknown;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
interface SolvaPayContextValue {
|
|
446
|
+
purchase: PurchaseStatus;
|
|
447
|
+
refetchPurchase: () => Promise<void>;
|
|
448
|
+
createPayment: (params: {
|
|
449
|
+
planRef?: string;
|
|
450
|
+
productRef?: string;
|
|
451
|
+
customer?: PrefillCustomer;
|
|
452
|
+
}) => Promise<PaymentIntentResult>;
|
|
453
|
+
processPayment?: (params: {
|
|
454
|
+
paymentIntentId: string;
|
|
455
|
+
productRef: string;
|
|
456
|
+
planRef?: string;
|
|
457
|
+
}) => Promise<ProcessPaymentResult>;
|
|
458
|
+
createTopupPayment: (params: {
|
|
459
|
+
amount: number;
|
|
460
|
+
currency?: string;
|
|
461
|
+
}) => Promise<TopupPaymentResult>;
|
|
462
|
+
cancelRenewal: (params: {
|
|
463
|
+
purchaseRef: string;
|
|
464
|
+
reason?: string;
|
|
465
|
+
}) => Promise<CancelResult>;
|
|
466
|
+
reactivateRenewal: (params: {
|
|
467
|
+
purchaseRef: string;
|
|
468
|
+
}) => Promise<ReactivateResult>;
|
|
469
|
+
activatePlan: (params: {
|
|
470
|
+
productRef: string;
|
|
471
|
+
planRef: string;
|
|
472
|
+
}) => Promise<ActivatePlanResult>;
|
|
473
|
+
customerRef?: string;
|
|
474
|
+
updateCustomerRef?: (newCustomerRef: string) => void;
|
|
475
|
+
balance: BalanceStatus;
|
|
476
|
+
/** @internal Provider config — used by SDK hooks, not part of public API */
|
|
477
|
+
_config?: SolvaPayConfig;
|
|
478
|
+
}
|
|
479
|
+
interface SolvaPayProviderProps {
|
|
480
|
+
/**
|
|
481
|
+
* Configuration object with sensible defaults
|
|
482
|
+
* If not provided, uses standard Next.js API routes
|
|
483
|
+
*/
|
|
484
|
+
config?: SolvaPayConfig;
|
|
485
|
+
/**
|
|
486
|
+
* Custom API functions (override config defaults)
|
|
487
|
+
* Use only if you need custom logic beyond standard API routes
|
|
488
|
+
*/
|
|
489
|
+
createPayment?: (params: {
|
|
490
|
+
planRef?: string;
|
|
491
|
+
productRef?: string;
|
|
492
|
+
customer?: PrefillCustomer;
|
|
493
|
+
}) => Promise<PaymentIntentResult>;
|
|
494
|
+
checkPurchase?: () => Promise<CustomerPurchaseData>;
|
|
495
|
+
processPayment?: (params: {
|
|
496
|
+
paymentIntentId: string;
|
|
497
|
+
productRef: string;
|
|
498
|
+
planRef?: string;
|
|
499
|
+
}) => Promise<ProcessPaymentResult>;
|
|
500
|
+
createTopupPayment?: (params: {
|
|
501
|
+
amount: number;
|
|
502
|
+
currency?: string;
|
|
503
|
+
}) => Promise<TopupPaymentResult>;
|
|
504
|
+
children: React.ReactNode;
|
|
505
|
+
}
|
|
506
|
+
interface ProductBadgeProps {
|
|
507
|
+
children?: (props: {
|
|
508
|
+
purchases: PurchaseInfo[];
|
|
509
|
+
loading: boolean;
|
|
510
|
+
displayPlan: string | null;
|
|
511
|
+
shouldShow: boolean;
|
|
512
|
+
}) => React.ReactNode;
|
|
513
|
+
as?: React.ElementType;
|
|
514
|
+
className?: string | ((props: {
|
|
515
|
+
purchases: PurchaseInfo[];
|
|
516
|
+
}) => string);
|
|
517
|
+
}
|
|
518
|
+
/** @deprecated Use ProductBadgeProps instead */
|
|
519
|
+
type PlanBadgeProps = ProductBadgeProps;
|
|
520
|
+
interface PurchaseGateProps {
|
|
521
|
+
/** @deprecated Use requireProduct instead */
|
|
522
|
+
requirePlan?: string;
|
|
523
|
+
requireProduct?: string;
|
|
524
|
+
children: (props: {
|
|
525
|
+
hasAccess: boolean;
|
|
526
|
+
purchases: PurchaseInfo[];
|
|
527
|
+
loading: boolean;
|
|
528
|
+
}) => React.ReactNode;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Error type for payment operations
|
|
532
|
+
*/
|
|
533
|
+
interface PaymentError extends Error {
|
|
534
|
+
code?: string;
|
|
535
|
+
type?: string;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Plan returned by the SolvaPay API.
|
|
539
|
+
*
|
|
540
|
+
* All fields are optional except `reference` so the type stays compatible
|
|
541
|
+
* with partial JSON responses from custom fetcher functions.
|
|
542
|
+
*/
|
|
543
|
+
interface Plan {
|
|
544
|
+
type?: 'recurring' | 'one-time' | 'usage-based';
|
|
545
|
+
reference: string;
|
|
546
|
+
name?: string;
|
|
547
|
+
description?: string;
|
|
548
|
+
price?: number;
|
|
549
|
+
currency?: string;
|
|
550
|
+
currencySymbol?: string;
|
|
551
|
+
freeUnits?: number;
|
|
552
|
+
setupFee?: number;
|
|
553
|
+
trialDays?: number;
|
|
554
|
+
billingCycle?: string;
|
|
555
|
+
billingModel?: 'pre-paid' | 'post-paid';
|
|
556
|
+
creditsPerUnit?: number;
|
|
557
|
+
measures?: string;
|
|
558
|
+
limit?: number;
|
|
559
|
+
rolloverUnusedUnits?: boolean;
|
|
560
|
+
limits?: Record<string, unknown>;
|
|
561
|
+
features?: Record<string, unknown> | string[];
|
|
562
|
+
requiresPayment?: boolean;
|
|
563
|
+
default?: boolean;
|
|
564
|
+
isActive?: boolean;
|
|
565
|
+
maxActiveUsers?: number;
|
|
566
|
+
accessExpiryDays?: number;
|
|
567
|
+
status?: string;
|
|
568
|
+
createdAt?: string;
|
|
569
|
+
updatedAt?: string;
|
|
570
|
+
interval?: string;
|
|
571
|
+
metadata?: Record<string, unknown>;
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Options for usePlans hook
|
|
575
|
+
*/
|
|
576
|
+
interface UsePlansOptions {
|
|
577
|
+
/**
|
|
578
|
+
* Fetcher function to retrieve plans
|
|
579
|
+
*/
|
|
580
|
+
fetcher: (productRef: string) => Promise<Plan[]>;
|
|
581
|
+
/**
|
|
582
|
+
* Product reference to fetch plans for
|
|
583
|
+
*/
|
|
584
|
+
productRef?: string;
|
|
585
|
+
/**
|
|
586
|
+
* Optional filter function to filter plans.
|
|
587
|
+
* Receives plan and its index (after sorting, if sortBy is provided).
|
|
588
|
+
*/
|
|
589
|
+
filter?: (plan: Plan, index: number) => boolean;
|
|
590
|
+
/**
|
|
591
|
+
* Optional sort function to sort plans
|
|
592
|
+
*/
|
|
593
|
+
sortBy?: (a: Plan, b: Plan) => number;
|
|
594
|
+
/**
|
|
595
|
+
* Auto-select first paid plan on load
|
|
596
|
+
*/
|
|
597
|
+
autoSelectFirstPaid?: boolean;
|
|
598
|
+
/**
|
|
599
|
+
* Plan reference to select initially when plans load.
|
|
600
|
+
* Applied at most once when selectionReady is true.
|
|
601
|
+
* Takes priority over autoSelectFirstPaid.
|
|
602
|
+
*/
|
|
603
|
+
initialPlanRef?: string;
|
|
604
|
+
/**
|
|
605
|
+
* When false, plans still fetch but auto-selection is deferred.
|
|
606
|
+
* When it transitions to true, one-shot initial selection fires.
|
|
607
|
+
* Defaults to true.
|
|
608
|
+
*/
|
|
609
|
+
selectionReady?: boolean;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Return type for usePlans hook
|
|
613
|
+
*/
|
|
614
|
+
interface UsePlansReturn {
|
|
615
|
+
plans: Plan[];
|
|
616
|
+
loading: boolean;
|
|
617
|
+
error: Error | null;
|
|
618
|
+
selectedPlanIndex: number;
|
|
619
|
+
selectedPlan: Plan | null;
|
|
620
|
+
setSelectedPlanIndex: (index: number) => void;
|
|
621
|
+
selectPlan: (planRef: string) => void;
|
|
622
|
+
refetch: () => Promise<void>;
|
|
623
|
+
/** True after the one-shot initial selection has been applied */
|
|
624
|
+
isSelectionReady: boolean;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Props for headless PricingSelector component
|
|
628
|
+
*/
|
|
629
|
+
interface PricingSelectorProps {
|
|
630
|
+
/**
|
|
631
|
+
* Product reference to fetch plans for
|
|
632
|
+
*/
|
|
633
|
+
productRef?: string;
|
|
634
|
+
/**
|
|
635
|
+
* Fetcher function to retrieve plans
|
|
636
|
+
*/
|
|
637
|
+
fetcher: (productRef: string) => Promise<Plan[]>;
|
|
638
|
+
/**
|
|
639
|
+
* Optional filter function
|
|
640
|
+
*/
|
|
641
|
+
filter?: (plan: Plan, index: number) => boolean;
|
|
642
|
+
/**
|
|
643
|
+
* Optional sort function
|
|
644
|
+
*/
|
|
645
|
+
sortBy?: (a: Plan, b: Plan) => number;
|
|
646
|
+
/**
|
|
647
|
+
* Auto-select first paid plan on load
|
|
648
|
+
*/
|
|
649
|
+
autoSelectFirstPaid?: boolean;
|
|
650
|
+
/**
|
|
651
|
+
* Render prop function
|
|
652
|
+
*/
|
|
653
|
+
children: (props: UsePlansReturn & {
|
|
654
|
+
purchases: PurchaseInfo[];
|
|
655
|
+
isPaidPlan: (planRef: string) => boolean;
|
|
656
|
+
isCurrentPlan: (planRef: string) => boolean;
|
|
657
|
+
}) => React.ReactNode;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Return type for usePurchaseStatus hook
|
|
661
|
+
*
|
|
662
|
+
* Provides advanced purchase status helpers and utilities.
|
|
663
|
+
* Focuses on cancelled purchase logic and date formatting.
|
|
664
|
+
* For basic purchase data and paid status, use usePurchase() instead.
|
|
665
|
+
*/
|
|
666
|
+
interface PurchaseStatusReturn {
|
|
667
|
+
/**
|
|
668
|
+
* Most recent cancelled paid purchase (sorted by startDate)
|
|
669
|
+
* null if no cancelled paid purchase exists
|
|
670
|
+
*/
|
|
671
|
+
cancelledPurchase: PurchaseInfo | null;
|
|
672
|
+
/**
|
|
673
|
+
* Whether to show cancelled purchase notice
|
|
674
|
+
* true if cancelledPurchase exists
|
|
675
|
+
*/
|
|
676
|
+
shouldShowCancelledNotice: boolean;
|
|
677
|
+
/**
|
|
678
|
+
* Format a date string to locale format (e.g., "January 15, 2024")
|
|
679
|
+
* Returns null if dateString is not provided
|
|
680
|
+
*/
|
|
681
|
+
formatDate: (dateString?: string) => string | null;
|
|
682
|
+
/**
|
|
683
|
+
* Calculate days until expiration date
|
|
684
|
+
* Returns null if endDate is not provided, otherwise returns days (0 or positive)
|
|
685
|
+
*/
|
|
686
|
+
getDaysUntilExpiration: (endDate?: string) => number | null;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Payment form props - simplified and minimal
|
|
690
|
+
*/
|
|
691
|
+
/**
|
|
692
|
+
* Discriminated checkout-completion result surfaced by `<PaymentForm>` and
|
|
693
|
+
* `<CheckoutLayout>` via their `onResult` callback. Integrators handling
|
|
694
|
+
* both paid and free plans should use `onResult` to get a single typed
|
|
695
|
+
* callback; paid-only integrators keep using `onSuccess(paymentIntent)`.
|
|
696
|
+
*/
|
|
697
|
+
type PaymentResult = {
|
|
698
|
+
kind: 'paid';
|
|
699
|
+
paymentIntent: PaymentIntent;
|
|
700
|
+
};
|
|
701
|
+
type ActivationResult = {
|
|
702
|
+
kind: 'activated';
|
|
703
|
+
result: ActivatePlanResult;
|
|
704
|
+
};
|
|
705
|
+
type CheckoutResult = PaymentResult | ActivationResult;
|
|
706
|
+
interface PaymentFormProps {
|
|
707
|
+
/**
|
|
708
|
+
* Plan reference to checkout. When omitted, the SDK auto-resolves the plan from
|
|
709
|
+
* productRef (requires exactly one active plan or a default plan). Pass explicitly
|
|
710
|
+
* when the product has multiple plans without a default.
|
|
711
|
+
*/
|
|
712
|
+
planRef?: string;
|
|
713
|
+
/**
|
|
714
|
+
* Product reference. Required when planRef is omitted (for plan resolution)
|
|
715
|
+
* and for processing payment after confirmation.
|
|
716
|
+
*/
|
|
717
|
+
productRef?: string;
|
|
718
|
+
/**
|
|
719
|
+
* Callback when payment succeeds. Fires on paid flows only — preserved
|
|
720
|
+
* exactly for backwards compatibility. Free/activation flows do NOT fire
|
|
721
|
+
* `onSuccess`; use `onResult` to receive both paid and activated results.
|
|
722
|
+
*/
|
|
723
|
+
onSuccess?: (paymentIntent: PaymentIntent) => void;
|
|
724
|
+
/**
|
|
725
|
+
* Unified callback fired on both paid and activated completions with a
|
|
726
|
+
* discriminated result. Safe to provide alongside `onSuccess` — for paid
|
|
727
|
+
* flows both fire (in order: `onSuccess` first, then `onResult`).
|
|
728
|
+
*/
|
|
729
|
+
onResult?: (result: CheckoutResult) => void;
|
|
730
|
+
/**
|
|
731
|
+
* Override the default free-plan activation step. When provided, the form
|
|
732
|
+
* awaits this promise on submit and fires `onResult` when it resolves.
|
|
733
|
+
* When omitted, the default behavior calls `activatePlan` from context.
|
|
734
|
+
*/
|
|
735
|
+
onFreePlan?: (plan: Plan) => Promise<unknown> | void;
|
|
736
|
+
/**
|
|
737
|
+
* Callback when payment fails
|
|
738
|
+
*/
|
|
739
|
+
onError?: (error: Error) => void;
|
|
740
|
+
/**
|
|
741
|
+
* Return URL after payment completion. Defaults to current page URL if not provided.
|
|
742
|
+
*/
|
|
743
|
+
returnUrl?: string;
|
|
744
|
+
/**
|
|
745
|
+
* Text for the submit button. Defaults to "Pay Now"
|
|
746
|
+
*/
|
|
747
|
+
submitButtonText?: string;
|
|
748
|
+
/**
|
|
749
|
+
* Optional className for the form container
|
|
750
|
+
*/
|
|
751
|
+
className?: string;
|
|
752
|
+
/**
|
|
753
|
+
* Optional className for the submit button
|
|
754
|
+
*/
|
|
755
|
+
buttonClassName?: string;
|
|
756
|
+
/**
|
|
757
|
+
* Customer name/email to forward to backend PaymentIntent creation so the
|
|
758
|
+
* server-side customer record is authoritative. Echoed back via
|
|
759
|
+
* `useCustomer()` after the intent is created.
|
|
760
|
+
*/
|
|
761
|
+
prefillCustomer?: PrefillCustomer;
|
|
762
|
+
/**
|
|
763
|
+
* When true, the default tree renders a terms/privacy checkbox and gates
|
|
764
|
+
* the submit button until it is ticked. No-op when custom `children` are
|
|
765
|
+
* passed — compose `<PaymentForm.TermsCheckbox />` yourself.
|
|
766
|
+
*/
|
|
767
|
+
requireTermsAcceptance?: boolean;
|
|
768
|
+
}
|
|
769
|
+
interface BalanceBadgeProps {
|
|
770
|
+
className?: string;
|
|
771
|
+
numberOnly?: boolean;
|
|
772
|
+
children?: (props: {
|
|
773
|
+
credits: number | null;
|
|
774
|
+
loading: boolean;
|
|
775
|
+
displayCurrency: string | null;
|
|
776
|
+
creditsPerMinorUnit: number | null;
|
|
777
|
+
}) => React.ReactNode;
|
|
778
|
+
}
|
|
779
|
+
interface UseTopupAmountSelectorOptions {
|
|
780
|
+
currency: string;
|
|
781
|
+
minAmount?: number;
|
|
782
|
+
maxAmount?: number;
|
|
783
|
+
}
|
|
784
|
+
interface UseTopupAmountSelectorReturn {
|
|
785
|
+
quickAmounts: number[];
|
|
786
|
+
selectedAmount: number | null;
|
|
787
|
+
customAmount: string;
|
|
788
|
+
resolvedAmount: number | null;
|
|
789
|
+
selectQuickAmount: (amount: number) => void;
|
|
790
|
+
setCustomAmount: (value: string) => void;
|
|
791
|
+
error: string | null;
|
|
792
|
+
validate: () => boolean;
|
|
793
|
+
reset: () => void;
|
|
794
|
+
currencySymbol: string;
|
|
795
|
+
}
|
|
796
|
+
type PurchaseStatusValue = 'pending' | 'active' | 'trialing' | 'past_due' | 'cancelled' | 'expired' | 'suspended' | 'refunded';
|
|
797
|
+
|
|
798
|
+
export type { ActivationResult as A, BalanceBadgeProps as B, CheckoutResult as C, PaymentError as D, PaymentIntentResult as E, PaymentResult as F, PlanBadgeProps as G, PurchaseStatusValue as H, SolvaPayConfig as I, TopupPaymentResult as J, MandateContext as M, Plan as P, ReactivateResult as R, SolvaPayProviderProps as S, TopupFormProps as T, UsePlansReturn as U, PaymentFormProps as a, PrefillCustomer as b, ProductBadgeProps as c, PurchaseGateProps as d, PricingSelectorProps as e, UseTopupAmountSelectorReturn as f, PurchaseInfo as g, PurchaseStatus as h, SolvaPayContextValue as i, UsePlansOptions as j, UsePlanOptions as k, UsePlanReturn as l, UseProductReturn as m, UseMerchantReturn as n, SolvaPayCopy as o, PurchaseStatusReturn as p, CancelResult as q, UseTopupOptions as r, UseTopupReturn as s, BalanceStatus as t, UseTopupAmountSelectorOptions as u, PartialSolvaPayCopy as v, Product as w, CustomerPurchaseData as x, MandateTemplate as y, Merchant as z };
|