@solvapay/react 1.0.8-preview.4 → 1.0.8-preview.6
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 +95 -12
- package/dist/{CancelPlanButton-f56UlQN-.d.ts → CancelPlanButton-BKH_yv1d.d.ts} +20 -9
- package/dist/{CancelPlanButton-CieT9swn.d.cts → CancelPlanButton-DQXUTHmF.d.cts} +20 -9
- package/dist/{chunk-MOP3ZBGC.js → chunk-5FZBOPIW.js} +25 -11
- package/dist/index.cjs +25 -11
- 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 +21 -4
- package/dist/primitives/index.d.cts +2 -2
- package/dist/primitives/index.d.ts +2 -2
- package/dist/primitives/index.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -13,6 +13,57 @@ pnpm add @solvapay/react
|
|
|
13
13
|
- `react` ^18.2.0 || ^19.0.0
|
|
14
14
|
- `react-dom` ^18.2.0 || ^19.0.0
|
|
15
15
|
|
|
16
|
+
## Tailwind setup
|
|
17
|
+
|
|
18
|
+
SolvaPay primitives ship plain CSS. They work with Tailwind v3 and v4
|
|
19
|
+
identically. Import `@solvapay/react/styles.css` **after** your Tailwind
|
|
20
|
+
entry so the SolvaPay rules resolve above preflight.
|
|
21
|
+
|
|
22
|
+
### Tailwind v4 (recommended for new projects)
|
|
23
|
+
|
|
24
|
+
`src/index.css`:
|
|
25
|
+
|
|
26
|
+
```css
|
|
27
|
+
@import "tailwindcss";
|
|
28
|
+
@import "@solvapay/react/styles.css";
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
No `tailwind.config.ts` needed. Theme via `@theme` block if desired.
|
|
32
|
+
|
|
33
|
+
### Tailwind v3 (Lovable, older projects)
|
|
34
|
+
|
|
35
|
+
`tailwind.config.ts`:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import type { Config } from 'tailwindcss'
|
|
39
|
+
|
|
40
|
+
export default {
|
|
41
|
+
content: ['./src/**/*.{ts,tsx}'],
|
|
42
|
+
theme: { extend: {} },
|
|
43
|
+
plugins: [],
|
|
44
|
+
} satisfies Config
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`src/index.css`:
|
|
48
|
+
|
|
49
|
+
```css
|
|
50
|
+
@tailwind base;
|
|
51
|
+
@tailwind components;
|
|
52
|
+
@tailwind utilities;
|
|
53
|
+
@import "@solvapay/react/styles.css";
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
No `content[]` entry for `@solvapay/react` is needed — primitives don't ship
|
|
57
|
+
utility classes. `data-[state=*]:` variants work natively in v3.3+.
|
|
58
|
+
|
|
59
|
+
### CSS loading order
|
|
60
|
+
|
|
61
|
+
Always import `@solvapay/react/styles.css` **after** `@tailwind utilities`
|
|
62
|
+
(v3) or `@import "tailwindcss"` (v4). SolvaPay rules are unlayered; they beat
|
|
63
|
+
Tailwind's preflight when loaded last. See
|
|
64
|
+
[`examples/spa-checkout/src/index.css`](../../examples/spa-checkout/src/index.css)
|
|
65
|
+
for the canonical demonstration.
|
|
66
|
+
|
|
16
67
|
## Quick Start
|
|
17
68
|
|
|
18
69
|
### Zero-Config Usage (Recommended)
|
|
@@ -344,23 +395,48 @@ Displays current product subscription with render props or className pattern.
|
|
|
344
395
|
|
|
345
396
|
### PurchaseGate
|
|
346
397
|
|
|
347
|
-
Controls access to content based on purchase status.
|
|
398
|
+
Controls access to content based on purchase status. Uses a compound
|
|
399
|
+
primitive API (`PurchaseGate.Root`, `.Allowed`, `.Blocked`, `.Loading`,
|
|
400
|
+
`.Error`). Matching is by stable reference — `productRef` (`prd_*`) and/or
|
|
401
|
+
`planRef` (`pln_*`) — never by product or plan name.
|
|
348
402
|
|
|
349
|
-
**
|
|
403
|
+
**Root props:**
|
|
350
404
|
|
|
351
|
-
- `
|
|
352
|
-
- `
|
|
405
|
+
- `productRef?: string` - Require an active purchase for this product
|
|
406
|
+
- `planRef?: string` - Require an active purchase for this specific plan
|
|
407
|
+
- `asChild?: boolean` - Merge onto the consumer element via `Slot`
|
|
353
408
|
|
|
354
|
-
|
|
409
|
+
Matching precedence:
|
|
410
|
+
|
|
411
|
+
- If neither is set, any `status === 'active'` purchase allows access
|
|
412
|
+
- If only one is set, that field must match on an active purchase
|
|
413
|
+
- If both are set, both must match on the **same** active purchase (AND)
|
|
414
|
+
|
|
415
|
+
**Example — product-level gating:**
|
|
355
416
|
|
|
356
417
|
```tsx
|
|
357
|
-
<PurchaseGate
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
418
|
+
<PurchaseGate.Root productRef="prd_widget">
|
|
419
|
+
<PurchaseGate.Loading>Loading…</PurchaseGate.Loading>
|
|
420
|
+
<PurchaseGate.Allowed>
|
|
421
|
+
<PremiumContent />
|
|
422
|
+
</PurchaseGate.Allowed>
|
|
423
|
+
<PurchaseGate.Blocked>
|
|
424
|
+
<Paywall />
|
|
425
|
+
</PurchaseGate.Blocked>
|
|
426
|
+
</PurchaseGate.Root>
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**Example — plan-level gating:**
|
|
430
|
+
|
|
431
|
+
```tsx
|
|
432
|
+
<PurchaseGate.Root planRef="pln_premium">
|
|
433
|
+
<PurchaseGate.Allowed>
|
|
434
|
+
<PremiumOnlyFeature />
|
|
435
|
+
</PurchaseGate.Allowed>
|
|
436
|
+
<PurchaseGate.Blocked>
|
|
437
|
+
<UpgradePrompt />
|
|
438
|
+
</PurchaseGate.Blocked>
|
|
439
|
+
</PurchaseGate.Root>
|
|
364
440
|
```
|
|
365
441
|
|
|
366
442
|
## Hooks
|
|
@@ -375,8 +451,15 @@ const {
|
|
|
375
451
|
loading, // Loading state
|
|
376
452
|
hasPaidPurchase, // Boolean: has any paid purchase
|
|
377
453
|
activePurchase, // Most recent active purchase
|
|
454
|
+
hasPurchase, // (criteria?: { productRef?, planRef? }) => boolean — predicate matching the PurchaseGate.Root shape
|
|
378
455
|
refetch, // Function to refetch purchases
|
|
379
456
|
} = usePurchase()
|
|
457
|
+
|
|
458
|
+
// Examples — criteria-based checks:
|
|
459
|
+
hasPurchase() // any active purchase
|
|
460
|
+
hasPurchase({ productRef: 'prd_widget' }) // any active purchase for this product
|
|
461
|
+
hasPurchase({ planRef: 'pln_premium' }) // any active purchase for this specific plan
|
|
462
|
+
hasPurchase({ productRef: 'prd_widget', planRef: 'pln_premium' }) // both must match the same active purchase
|
|
380
463
|
```
|
|
381
464
|
|
|
382
465
|
### usePlans
|
|
@@ -315,9 +315,18 @@ interface PurchaseStatus {
|
|
|
315
315
|
email?: string;
|
|
316
316
|
name?: string;
|
|
317
317
|
purchases: PurchaseInfo[];
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
318
|
+
/**
|
|
319
|
+
* Check if the user has an active purchase matching the given criteria.
|
|
320
|
+
*
|
|
321
|
+
* - No criteria: any active purchase
|
|
322
|
+
* - `productRef` only: any active purchase for that product (any plan)
|
|
323
|
+
* - `planRef` only: any active purchase for that specific plan
|
|
324
|
+
* - Both: both must match on the same active purchase (AND)
|
|
325
|
+
*/
|
|
326
|
+
hasPurchase: (criteria?: {
|
|
327
|
+
productRef?: string;
|
|
328
|
+
planRef?: string;
|
|
329
|
+
}) => boolean;
|
|
321
330
|
/**
|
|
322
331
|
* Primary active purchase (paid or free) - most recent purchase with status === 'active'
|
|
323
332
|
* Backend keeps purchases as 'active' until expiration, even when cancelled.
|
|
@@ -908,9 +917,10 @@ type PurchaseGateContextValue = {
|
|
|
908
917
|
error: Error | null;
|
|
909
918
|
};
|
|
910
919
|
declare const PurchaseGateRoot: React$1.ForwardRefExoticComponent<{
|
|
911
|
-
/**
|
|
912
|
-
|
|
913
|
-
|
|
920
|
+
/** Require an active purchase for this product (e.g. "prd_abc"). */
|
|
921
|
+
productRef?: string;
|
|
922
|
+
/** Require an active purchase for this specific plan (e.g. "pln_premium"). */
|
|
923
|
+
planRef?: string;
|
|
914
924
|
asChild?: boolean;
|
|
915
925
|
children?: React$1.ReactNode;
|
|
916
926
|
} & Omit<React$1.HTMLAttributes<HTMLDivElement>, "children"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
@@ -928,9 +938,10 @@ declare const PurchaseGateError: React$1.ForwardRefExoticComponent<React$1.HTMLA
|
|
|
928
938
|
} & React$1.RefAttributes<HTMLDivElement>>;
|
|
929
939
|
declare const PurchaseGate: {
|
|
930
940
|
readonly Root: React$1.ForwardRefExoticComponent<{
|
|
931
|
-
/**
|
|
932
|
-
|
|
933
|
-
|
|
941
|
+
/** Require an active purchase for this product (e.g. "prd_abc"). */
|
|
942
|
+
productRef?: string;
|
|
943
|
+
/** Require an active purchase for this specific plan (e.g. "pln_premium"). */
|
|
944
|
+
planRef?: string;
|
|
934
945
|
asChild?: boolean;
|
|
935
946
|
children?: React$1.ReactNode;
|
|
936
947
|
} & Omit<React$1.HTMLAttributes<HTMLDivElement>, "children"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
@@ -315,9 +315,18 @@ interface PurchaseStatus {
|
|
|
315
315
|
email?: string;
|
|
316
316
|
name?: string;
|
|
317
317
|
purchases: PurchaseInfo[];
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
318
|
+
/**
|
|
319
|
+
* Check if the user has an active purchase matching the given criteria.
|
|
320
|
+
*
|
|
321
|
+
* - No criteria: any active purchase
|
|
322
|
+
* - `productRef` only: any active purchase for that product (any plan)
|
|
323
|
+
* - `planRef` only: any active purchase for that specific plan
|
|
324
|
+
* - Both: both must match on the same active purchase (AND)
|
|
325
|
+
*/
|
|
326
|
+
hasPurchase: (criteria?: {
|
|
327
|
+
productRef?: string;
|
|
328
|
+
planRef?: string;
|
|
329
|
+
}) => boolean;
|
|
321
330
|
/**
|
|
322
331
|
* Primary active purchase (paid or free) - most recent purchase with status === 'active'
|
|
323
332
|
* Backend keeps purchases as 'active' until expiration, even when cancelled.
|
|
@@ -908,9 +917,10 @@ type PurchaseGateContextValue = {
|
|
|
908
917
|
error: Error | null;
|
|
909
918
|
};
|
|
910
919
|
declare const PurchaseGateRoot: React$1.ForwardRefExoticComponent<{
|
|
911
|
-
/**
|
|
912
|
-
|
|
913
|
-
|
|
920
|
+
/** Require an active purchase for this product (e.g. "prd_abc"). */
|
|
921
|
+
productRef?: string;
|
|
922
|
+
/** Require an active purchase for this specific plan (e.g. "pln_premium"). */
|
|
923
|
+
planRef?: string;
|
|
914
924
|
asChild?: boolean;
|
|
915
925
|
children?: React$1.ReactNode;
|
|
916
926
|
} & Omit<React$1.HTMLAttributes<HTMLDivElement>, "children"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
@@ -928,9 +938,10 @@ declare const PurchaseGateError: React$1.ForwardRefExoticComponent<React$1.HTMLA
|
|
|
928
938
|
} & React$1.RefAttributes<HTMLDivElement>>;
|
|
929
939
|
declare const PurchaseGate: {
|
|
930
940
|
readonly Root: React$1.ForwardRefExoticComponent<{
|
|
931
|
-
/**
|
|
932
|
-
|
|
933
|
-
|
|
941
|
+
/** Require an active purchase for this product (e.g. "prd_abc"). */
|
|
942
|
+
productRef?: string;
|
|
943
|
+
/** Require an active purchase for this specific plan (e.g. "pln_premium"). */
|
|
944
|
+
planRef?: string;
|
|
934
945
|
asChild?: boolean;
|
|
935
946
|
children?: React$1.ReactNode;
|
|
936
947
|
} & Omit<React$1.HTMLAttributes<HTMLDivElement>, "children"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
@@ -748,14 +748,11 @@ var SolvaPayProvider = ({
|
|
|
748
748
|
email: purchaseData.email,
|
|
749
749
|
name: purchaseData.name,
|
|
750
750
|
purchases: purchaseData.purchases,
|
|
751
|
-
|
|
751
|
+
hasPurchase: (criteria) => {
|
|
752
|
+
const productRef = criteria?.productRef;
|
|
753
|
+
const planRef = criteria?.planRef;
|
|
752
754
|
return purchaseData.purchases.some(
|
|
753
|
-
(p) => p.
|
|
754
|
-
);
|
|
755
|
-
},
|
|
756
|
-
hasPlan: (productName) => {
|
|
757
|
-
return purchaseData.purchases.some(
|
|
758
|
-
(p) => p.productName.toLowerCase() === productName.toLowerCase() && p.status === "active"
|
|
755
|
+
(p) => p.status === "active" && (!productRef || p.productRef === productRef) && (!planRef || p.planRef === planRef)
|
|
759
756
|
);
|
|
760
757
|
},
|
|
761
758
|
activePurchase,
|
|
@@ -1969,6 +1966,13 @@ async function confirmPayment(input) {
|
|
|
1969
1966
|
if (!paymentElement) {
|
|
1970
1967
|
return { status: "error", message: copy.errors.cardElementMissing };
|
|
1971
1968
|
}
|
|
1969
|
+
const { error: submitError } = await elements.submit();
|
|
1970
|
+
if (submitError) {
|
|
1971
|
+
return {
|
|
1972
|
+
status: "error",
|
|
1973
|
+
message: submitError.message || copy.errors.paymentUnexpected
|
|
1974
|
+
};
|
|
1975
|
+
}
|
|
1972
1976
|
const { error: error2, paymentIntent: paymentIntent2 } = await stripe.confirmPayment({
|
|
1973
1977
|
elements,
|
|
1974
1978
|
clientSecret,
|
|
@@ -3214,6 +3218,14 @@ var Inner = ({
|
|
|
3214
3218
|
}
|
|
3215
3219
|
setError(null);
|
|
3216
3220
|
setIsProcessing(true);
|
|
3221
|
+
const { error: submitError } = await elements.submit();
|
|
3222
|
+
if (submitError) {
|
|
3223
|
+
const msg = submitError.message || copy.errors.paymentUnexpected;
|
|
3224
|
+
setError(msg);
|
|
3225
|
+
setIsProcessing(false);
|
|
3226
|
+
onError?.(new Error(msg));
|
|
3227
|
+
return;
|
|
3228
|
+
}
|
|
3217
3229
|
const { error: confirmError, paymentIntent } = await stripe.confirmPayment({
|
|
3218
3230
|
elements,
|
|
3219
3231
|
clientSecret,
|
|
@@ -3457,12 +3469,14 @@ function useGateCtx(part) {
|
|
|
3457
3469
|
}
|
|
3458
3470
|
return ctx;
|
|
3459
3471
|
}
|
|
3460
|
-
var Root5 = forwardRef7(function PurchaseGateRoot({
|
|
3472
|
+
var Root5 = forwardRef7(function PurchaseGateRoot({ productRef, planRef, asChild, children, ...rest }, forwardedRef) {
|
|
3461
3473
|
const solva = useContext11(SolvaPayContext);
|
|
3462
3474
|
if (!solva) throw new MissingProviderError("PurchaseGate");
|
|
3463
|
-
const {
|
|
3464
|
-
const
|
|
3465
|
-
|
|
3475
|
+
const { loading, hasPurchase, error } = usePurchase();
|
|
3476
|
+
const hasAccess = useMemo10(
|
|
3477
|
+
() => hasPurchase({ productRef, planRef }),
|
|
3478
|
+
[hasPurchase, productRef, planRef]
|
|
3479
|
+
);
|
|
3466
3480
|
const state = loading ? "loading" : hasAccess ? "allowed" : "blocked";
|
|
3467
3481
|
const ctx = useMemo10(
|
|
3468
3482
|
() => ({ state, loading, hasAccess, error }),
|
package/dist/index.cjs
CHANGED
|
@@ -856,14 +856,11 @@ var SolvaPayProvider = ({
|
|
|
856
856
|
email: purchaseData.email,
|
|
857
857
|
name: purchaseData.name,
|
|
858
858
|
purchases: purchaseData.purchases,
|
|
859
|
-
|
|
859
|
+
hasPurchase: (criteria) => {
|
|
860
|
+
const productRef = criteria?.productRef;
|
|
861
|
+
const planRef = criteria?.planRef;
|
|
860
862
|
return purchaseData.purchases.some(
|
|
861
|
-
(p) => p.
|
|
862
|
-
);
|
|
863
|
-
},
|
|
864
|
-
hasPlan: (productName) => {
|
|
865
|
-
return purchaseData.purchases.some(
|
|
866
|
-
(p) => p.productName.toLowerCase() === productName.toLowerCase() && p.status === "active"
|
|
863
|
+
(p) => p.status === "active" && (!productRef || p.productRef === productRef) && (!planRef || p.planRef === planRef)
|
|
867
864
|
);
|
|
868
865
|
},
|
|
869
866
|
activePurchase,
|
|
@@ -2080,6 +2077,13 @@ async function confirmPayment(input) {
|
|
|
2080
2077
|
if (!paymentElement) {
|
|
2081
2078
|
return { status: "error", message: copy.errors.cardElementMissing };
|
|
2082
2079
|
}
|
|
2080
|
+
const { error: submitError } = await elements.submit();
|
|
2081
|
+
if (submitError) {
|
|
2082
|
+
return {
|
|
2083
|
+
status: "error",
|
|
2084
|
+
message: submitError.message || copy.errors.paymentUnexpected
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2083
2087
|
const { error: error2, paymentIntent: paymentIntent2 } = await stripe.confirmPayment({
|
|
2084
2088
|
elements,
|
|
2085
2089
|
clientSecret,
|
|
@@ -3314,6 +3318,14 @@ var Inner = ({
|
|
|
3314
3318
|
}
|
|
3315
3319
|
setError(null);
|
|
3316
3320
|
setIsProcessing(true);
|
|
3321
|
+
const { error: submitError } = await elements.submit();
|
|
3322
|
+
if (submitError) {
|
|
3323
|
+
const msg = submitError.message || copy.errors.paymentUnexpected;
|
|
3324
|
+
setError(msg);
|
|
3325
|
+
setIsProcessing(false);
|
|
3326
|
+
onError?.(new Error(msg));
|
|
3327
|
+
return;
|
|
3328
|
+
}
|
|
3317
3329
|
const { error: confirmError, paymentIntent } = await stripe.confirmPayment({
|
|
3318
3330
|
elements,
|
|
3319
3331
|
clientSecret,
|
|
@@ -3544,12 +3556,14 @@ function useGateCtx(part) {
|
|
|
3544
3556
|
}
|
|
3545
3557
|
return ctx;
|
|
3546
3558
|
}
|
|
3547
|
-
var Root5 = (0, import_react22.forwardRef)(function PurchaseGateRoot({
|
|
3559
|
+
var Root5 = (0, import_react22.forwardRef)(function PurchaseGateRoot({ productRef, planRef, asChild, children, ...rest }, forwardedRef) {
|
|
3548
3560
|
const solva = (0, import_react22.useContext)(SolvaPayContext);
|
|
3549
3561
|
if (!solva) throw new MissingProviderError("PurchaseGate");
|
|
3550
|
-
const {
|
|
3551
|
-
const
|
|
3552
|
-
|
|
3562
|
+
const { loading, hasPurchase, error } = usePurchase();
|
|
3563
|
+
const hasAccess = (0, import_react22.useMemo)(
|
|
3564
|
+
() => hasPurchase({ productRef, planRef }),
|
|
3565
|
+
[hasPurchase, productRef, planRef]
|
|
3566
|
+
);
|
|
3553
3567
|
const state = loading ? "loading" : hasAccess ? "allowed" : "blocked";
|
|
3554
3568
|
const ctx = (0, import_react22.useMemo)(
|
|
3555
3569
|
() => ({ state, loading, hasAccess, error }),
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
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-
|
|
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-
|
|
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-DQXUTHmF.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-DQXUTHmF.cjs';
|
|
4
4
|
import { PaymentIntent, Stripe, StripeElements } from '@stripe/stripe-js';
|
|
5
5
|
import { ActivatePlanResult } from '@solvapay/server';
|
|
6
6
|
export { ActivatePlanResult } from '@solvapay/server';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
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-
|
|
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-
|
|
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-BKH_yv1d.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-BKH_yv1d.js';
|
|
4
4
|
import { PaymentIntent, Stripe, StripeElements } from '@stripe/stripe-js';
|
|
5
5
|
import { ActivatePlanResult } from '@solvapay/server';
|
|
6
6
|
export { ActivatePlanResult } from '@solvapay/server';
|
package/dist/index.js
CHANGED
|
@@ -1866,6 +1866,13 @@ async function confirmPayment(input) {
|
|
|
1866
1866
|
if (!paymentElement) {
|
|
1867
1867
|
return { status: "error", message: copy.errors.cardElementMissing };
|
|
1868
1868
|
}
|
|
1869
|
+
const { error: submitError } = await elements.submit();
|
|
1870
|
+
if (submitError) {
|
|
1871
|
+
return {
|
|
1872
|
+
status: "error",
|
|
1873
|
+
message: submitError.message || copy.errors.paymentUnexpected
|
|
1874
|
+
};
|
|
1875
|
+
}
|
|
1869
1876
|
const { error: error2, paymentIntent: paymentIntent2 } = await stripe.confirmPayment({
|
|
1870
1877
|
elements,
|
|
1871
1878
|
clientSecret,
|
|
@@ -3746,6 +3753,14 @@ var Inner = ({
|
|
|
3746
3753
|
}
|
|
3747
3754
|
setError(null);
|
|
3748
3755
|
setIsProcessing(true);
|
|
3756
|
+
const { error: submitError } = await elements.submit();
|
|
3757
|
+
if (submitError) {
|
|
3758
|
+
const msg = submitError.message || copy.errors.paymentUnexpected;
|
|
3759
|
+
setError(msg);
|
|
3760
|
+
setIsProcessing(false);
|
|
3761
|
+
onError?.(new Error(msg));
|
|
3762
|
+
return;
|
|
3763
|
+
}
|
|
3749
3764
|
const { error: confirmError, paymentIntent } = await stripe.confirmPayment({
|
|
3750
3765
|
elements,
|
|
3751
3766
|
clientSecret,
|
|
@@ -4055,12 +4070,14 @@ function useGateCtx2(part) {
|
|
|
4055
4070
|
}
|
|
4056
4071
|
return ctx;
|
|
4057
4072
|
}
|
|
4058
|
-
var Root9 = (0, import_react29.forwardRef)(function PurchaseGateRoot({
|
|
4073
|
+
var Root9 = (0, import_react29.forwardRef)(function PurchaseGateRoot({ productRef, planRef, asChild, children, ...rest }, forwardedRef) {
|
|
4059
4074
|
const solva = (0, import_react29.useContext)(SolvaPayContext);
|
|
4060
4075
|
if (!solva) throw new MissingProviderError("PurchaseGate");
|
|
4061
|
-
const {
|
|
4062
|
-
const
|
|
4063
|
-
|
|
4076
|
+
const { loading, hasPurchase, error } = usePurchase();
|
|
4077
|
+
const hasAccess = (0, import_react29.useMemo)(
|
|
4078
|
+
() => hasPurchase({ productRef, planRef }),
|
|
4079
|
+
[hasPurchase, productRef, planRef]
|
|
4080
|
+
);
|
|
4064
4081
|
const state = loading ? "loading" : hasAccess ? "allowed" : "blocked";
|
|
4065
4082
|
const ctx = (0, import_react29.useMemo)(
|
|
4066
4083
|
() => ({ state, loading, hasAccess, error }),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React, { Ref } from 'react';
|
|
3
|
-
import { k as Plan, F as Product, y as UseTopupAmountSelectorReturn, D as PurchaseInfo, T as TopupFormProps } from '../CancelPlanButton-
|
|
4
|
-
export { a4 as ActivationFlow, a5 as ActivationFlowActivateButton, a6 as ActivationFlowActivated, a7 as ActivationFlowAmountPicker, a8 as ActivationFlowContinueButton, a9 as ActivationFlowError, aa as ActivationFlowLoading, ab as ActivationFlowRetrying, ac as ActivationFlowRoot, G as ActivationFlowStep, ad as ActivationFlowSummary, H as BalanceBadge, I as CancelPlanButton, O as MandateText, Q as MandateTextProps, ae as PaymentForm, e as PaymentFormCardElement, c as PaymentFormCustomerFields, j as PaymentFormError, i as PaymentFormLoading, f as PaymentFormMandateText, d as PaymentFormPaymentElement, af as PaymentFormRoot, h as PaymentFormSubmitButton, b as PaymentFormSummary, g as PaymentFormTermsCheckbox, Z as PlanBadge, _ as ProductBadge, $ as PurchaseGate, ag as PurchaseGateAllowed, ah as PurchaseGateBlocked, ai as PurchaseGateError, aj as PurchaseGateLoading, ak as PurchaseGateRoot, al as useActivationFlow, am as usePurchaseGate } from '../CancelPlanButton-
|
|
3
|
+
import { k as Plan, F as Product, y as UseTopupAmountSelectorReturn, D as PurchaseInfo, T as TopupFormProps } from '../CancelPlanButton-DQXUTHmF.cjs';
|
|
4
|
+
export { a4 as ActivationFlow, a5 as ActivationFlowActivateButton, a6 as ActivationFlowActivated, a7 as ActivationFlowAmountPicker, a8 as ActivationFlowContinueButton, a9 as ActivationFlowError, aa as ActivationFlowLoading, ab as ActivationFlowRetrying, ac as ActivationFlowRoot, G as ActivationFlowStep, ad as ActivationFlowSummary, H as BalanceBadge, I as CancelPlanButton, O as MandateText, Q as MandateTextProps, ae as PaymentForm, e as PaymentFormCardElement, c as PaymentFormCustomerFields, j as PaymentFormError, i as PaymentFormLoading, f as PaymentFormMandateText, d as PaymentFormPaymentElement, af as PaymentFormRoot, h as PaymentFormSubmitButton, b as PaymentFormSummary, g as PaymentFormTermsCheckbox, Z as PlanBadge, _ as ProductBadge, $ as PurchaseGate, ag as PurchaseGateAllowed, ah as PurchaseGateBlocked, ai as PurchaseGateError, aj as PurchaseGateLoading, ak as PurchaseGateRoot, al as useActivationFlow, am as usePurchaseGate } from '../CancelPlanButton-DQXUTHmF.cjs';
|
|
5
5
|
import { PaymentElement } from '@stripe/react-stripe-js';
|
|
6
6
|
import { Stripe, StripeElements } from '@stripe/stripe-js';
|
|
7
7
|
import '@solvapay/server';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React, { Ref } from 'react';
|
|
3
|
-
import { k as Plan, F as Product, y as UseTopupAmountSelectorReturn, D as PurchaseInfo, T as TopupFormProps } from '../CancelPlanButton-
|
|
4
|
-
export { a4 as ActivationFlow, a5 as ActivationFlowActivateButton, a6 as ActivationFlowActivated, a7 as ActivationFlowAmountPicker, a8 as ActivationFlowContinueButton, a9 as ActivationFlowError, aa as ActivationFlowLoading, ab as ActivationFlowRetrying, ac as ActivationFlowRoot, G as ActivationFlowStep, ad as ActivationFlowSummary, H as BalanceBadge, I as CancelPlanButton, O as MandateText, Q as MandateTextProps, ae as PaymentForm, e as PaymentFormCardElement, c as PaymentFormCustomerFields, j as PaymentFormError, i as PaymentFormLoading, f as PaymentFormMandateText, d as PaymentFormPaymentElement, af as PaymentFormRoot, h as PaymentFormSubmitButton, b as PaymentFormSummary, g as PaymentFormTermsCheckbox, Z as PlanBadge, _ as ProductBadge, $ as PurchaseGate, ag as PurchaseGateAllowed, ah as PurchaseGateBlocked, ai as PurchaseGateError, aj as PurchaseGateLoading, ak as PurchaseGateRoot, al as useActivationFlow, am as usePurchaseGate } from '../CancelPlanButton-
|
|
3
|
+
import { k as Plan, F as Product, y as UseTopupAmountSelectorReturn, D as PurchaseInfo, T as TopupFormProps } from '../CancelPlanButton-BKH_yv1d.js';
|
|
4
|
+
export { a4 as ActivationFlow, a5 as ActivationFlowActivateButton, a6 as ActivationFlowActivated, a7 as ActivationFlowAmountPicker, a8 as ActivationFlowContinueButton, a9 as ActivationFlowError, aa as ActivationFlowLoading, ab as ActivationFlowRetrying, ac as ActivationFlowRoot, G as ActivationFlowStep, ad as ActivationFlowSummary, H as BalanceBadge, I as CancelPlanButton, O as MandateText, Q as MandateTextProps, ae as PaymentForm, e as PaymentFormCardElement, c as PaymentFormCustomerFields, j as PaymentFormError, i as PaymentFormLoading, f as PaymentFormMandateText, d as PaymentFormPaymentElement, af as PaymentFormRoot, h as PaymentFormSubmitButton, b as PaymentFormSummary, g as PaymentFormTermsCheckbox, Z as PlanBadge, _ as ProductBadge, $ as PurchaseGate, ag as PurchaseGateAllowed, ah as PurchaseGateBlocked, ai as PurchaseGateError, aj as PurchaseGateLoading, ak as PurchaseGateRoot, al as useActivationFlow, am as usePurchaseGate } from '../CancelPlanButton-BKH_yv1d.js';
|
|
5
5
|
import { PaymentElement } from '@stripe/react-stripe-js';
|
|
6
6
|
import { Stripe, StripeElements } from '@stripe/stripe-js';
|
|
7
7
|
import '@solvapay/server';
|
package/dist/primitives/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solvapay/react",
|
|
3
|
-
"version": "1.0.8-preview.
|
|
3
|
+
"version": "1.0.8-preview.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"react-dom": "^19.2.4",
|
|
66
66
|
"typescript": "^5.9.3",
|
|
67
67
|
"vitest": "^4.1.2",
|
|
68
|
-
"@solvapay/
|
|
69
|
-
"@solvapay/
|
|
68
|
+
"@solvapay/server": "1.0.8-preview.6",
|
|
69
|
+
"@solvapay/test-utils": "0.0.0"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsup src/index.tsx src/primitives/index.ts src/adapters/auth.ts --format esm,cjs --dts --tsconfig tsconfig.build.json && cp src/styles.css dist/styles.css",
|