@omnikit-js/ui 0.9.45 → 0.9.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-LIZKLYHH.js +2205 -0
- package/dist/chunk-LIZKLYHH.js.map +1 -0
- package/dist/{chunk-3AQCVPQI.js → chunk-SRPYYSJZ.js} +694 -34
- package/dist/chunk-SRPYYSJZ.js.map +1 -0
- package/dist/components/client/index.d.ts +61 -7
- package/dist/components/client/index.js +23 -35
- package/dist/components/client/index.js.map +1 -1
- package/dist/components/server/index.d.ts +2 -2
- package/dist/components/server/index.js +2 -2
- package/dist/index-Bp2ZenHB.d.ts +376 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/{types-CnhWTSXv.d.ts → types-DAbudCAC.d.ts} +5 -3
- package/package.json +1 -1
- package/dist/chunk-3AQCVPQI.js.map +0 -1
- package/dist/chunk-FNZCGWVE.js +0 -531
- package/dist/chunk-FNZCGWVE.js.map +0 -1
- package/dist/index-DKuejSvz.d.ts +0 -83
|
@@ -7,14 +7,24 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
7
7
|
import { useRouter } from 'next/navigation';
|
|
8
8
|
|
|
9
9
|
// src/components/client/AddPaymentMethodForm/index.tsx
|
|
10
|
-
function PaymentForm({
|
|
10
|
+
function PaymentForm({
|
|
11
|
+
customerId,
|
|
12
|
+
businessName,
|
|
13
|
+
onSuccess,
|
|
14
|
+
onCancel,
|
|
15
|
+
onSubmit,
|
|
16
|
+
onGuestCheckout,
|
|
17
|
+
isGuestMode = false,
|
|
18
|
+
submitButtonText,
|
|
19
|
+
isProcessing: externalIsProcessing = false
|
|
20
|
+
}) {
|
|
11
21
|
const stripe = useStripe();
|
|
12
22
|
const elements = useElements();
|
|
13
23
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
14
24
|
const [errorMessage, setErrorMessage] = useState(null);
|
|
15
|
-
const [setAsDefault, setSetAsDefault] = useState(
|
|
16
|
-
const
|
|
17
|
-
|
|
25
|
+
const [setAsDefault, setSetAsDefault] = useState(true);
|
|
26
|
+
const processing = externalIsProcessing || isProcessing;
|
|
27
|
+
const handleSubmit = async () => {
|
|
18
28
|
if (!stripe || !elements) {
|
|
19
29
|
return;
|
|
20
30
|
}
|
|
@@ -35,6 +45,13 @@ function PaymentForm({ customerId, businessName, onSuccess, onCancel, onSubmit }
|
|
|
35
45
|
setIsProcessing(false);
|
|
36
46
|
return;
|
|
37
47
|
}
|
|
48
|
+
if (isGuestMode && onGuestCheckout) {
|
|
49
|
+
const result2 = await onGuestCheckout(paymentMethod.id);
|
|
50
|
+
if (!result2.success) {
|
|
51
|
+
throw new Error(result2.error || "Payment failed");
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
38
55
|
const result = await onSubmit(paymentMethod.id, setAsDefault);
|
|
39
56
|
if (!result.success) {
|
|
40
57
|
throw new Error(result.error || "Failed to add payment method");
|
|
@@ -50,10 +67,11 @@ function PaymentForm({ customerId, businessName, onSuccess, onCancel, onSubmit }
|
|
|
50
67
|
business: { name: businessName }
|
|
51
68
|
}
|
|
52
69
|
}), [businessName]);
|
|
53
|
-
|
|
70
|
+
const buttonText = submitButtonText || (isGuestMode ? "Pay Now" : "Add Payment Method");
|
|
71
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
54
72
|
/* @__PURE__ */ jsx(PaymentElement, { options: paymentElementOptions }),
|
|
55
73
|
errorMessage && /* @__PURE__ */ jsx("div", { className: "text-red-600 dark:text-red-400 text-sm", children: errorMessage }),
|
|
56
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-2", children: [
|
|
74
|
+
!isGuestMode && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-2", children: [
|
|
57
75
|
/* @__PURE__ */ jsx(
|
|
58
76
|
"input",
|
|
59
77
|
{
|
|
@@ -73,19 +91,33 @@ function PaymentForm({ customerId, businessName, onSuccess, onCancel, onSubmit }
|
|
|
73
91
|
}
|
|
74
92
|
)
|
|
75
93
|
] }),
|
|
76
|
-
/* @__PURE__ */
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
isGuestMode ? /* @__PURE__ */ jsx(
|
|
95
|
+
Button,
|
|
96
|
+
{
|
|
97
|
+
type: "button",
|
|
98
|
+
variant: "primary",
|
|
99
|
+
className: "w-full",
|
|
100
|
+
size: "lg",
|
|
101
|
+
disabled: !stripe || processing,
|
|
102
|
+
onClick: handleSubmit,
|
|
103
|
+
children: processing ? "Processing..." : buttonText
|
|
104
|
+
}
|
|
105
|
+
) : (
|
|
106
|
+
/* Regular mode: cancel + add buttons */
|
|
107
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-3 justify-end mt-6 pt-4 border-t border-gray-200 dark:border-gray-700", children: [
|
|
108
|
+
onCancel && /* @__PURE__ */ jsx(
|
|
109
|
+
Button,
|
|
110
|
+
{
|
|
111
|
+
type: "button",
|
|
112
|
+
variant: "secondary",
|
|
113
|
+
onClick: onCancel,
|
|
114
|
+
disabled: processing,
|
|
115
|
+
children: "Cancel"
|
|
116
|
+
}
|
|
117
|
+
),
|
|
118
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "primary", disabled: !stripe || processing, onClick: handleSubmit, children: processing ? "Processing..." : buttonText })
|
|
119
|
+
] })
|
|
120
|
+
)
|
|
89
121
|
] });
|
|
90
122
|
}
|
|
91
123
|
function AddPaymentMethodForm({
|
|
@@ -94,7 +126,12 @@ function AddPaymentMethodForm({
|
|
|
94
126
|
businessName,
|
|
95
127
|
onSuccess,
|
|
96
128
|
onCancel,
|
|
97
|
-
onSubmit
|
|
129
|
+
onSubmit,
|
|
130
|
+
onGuestCheckout,
|
|
131
|
+
isGuestMode = false,
|
|
132
|
+
guestEmail,
|
|
133
|
+
submitButtonText,
|
|
134
|
+
isProcessing
|
|
98
135
|
}) {
|
|
99
136
|
const [stripePromise, setStripePromise] = useState(null);
|
|
100
137
|
const [theme, setTheme] = useState("light");
|
|
@@ -171,7 +208,11 @@ function AddPaymentMethodForm({
|
|
|
171
208
|
businessName,
|
|
172
209
|
onSuccess,
|
|
173
210
|
onCancel,
|
|
174
|
-
onSubmit
|
|
211
|
+
onSubmit,
|
|
212
|
+
onGuestCheckout,
|
|
213
|
+
isGuestMode,
|
|
214
|
+
submitButtonText,
|
|
215
|
+
isProcessing
|
|
175
216
|
}
|
|
176
217
|
) });
|
|
177
218
|
}
|
|
@@ -637,32 +678,47 @@ function BillingContent({
|
|
|
637
678
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-4", children: "Current Usage" }),
|
|
638
679
|
/* @__PURE__ */ jsx("div", { className: "space-y-4", children: Object.values(featureUsage).sort((a, b) => {
|
|
639
680
|
const getPriority = (usage) => {
|
|
640
|
-
if (usage.
|
|
641
|
-
if (usage.limit > 0) return 1;
|
|
642
|
-
if (usage.
|
|
643
|
-
return 3;
|
|
681
|
+
if (usage.display_mode === "balance_based") return 0;
|
|
682
|
+
if ((usage.limit ?? 0) > 0 && (usage.current_usage ?? 0) > 0) return 1;
|
|
683
|
+
if ((usage.limit ?? 0) > 0) return 2;
|
|
684
|
+
if (usage.feature_type === "string") return 3;
|
|
685
|
+
return 4;
|
|
644
686
|
};
|
|
645
687
|
return getPriority(a) - getPriority(b);
|
|
646
688
|
}).map((usage) => {
|
|
647
689
|
const featureName = usage.feature_name || usage.feature_key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
648
|
-
if (usage.
|
|
649
|
-
const
|
|
690
|
+
if (usage.display_mode === "balance_based") {
|
|
691
|
+
const unit = usage.unit ? ` ${usage.unit}` : "";
|
|
692
|
+
const isLow = usage.remaining < 1e3;
|
|
693
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center text-sm", children: [
|
|
694
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-700 dark:text-neutral-300", children: featureName }),
|
|
695
|
+
/* @__PURE__ */ jsxs("span", { className: `font-medium ${isLow ? "text-amber-600 dark:text-amber-400" : "text-gray-900 dark:text-gray-100"}`, children: [
|
|
696
|
+
usage.remaining.toLocaleString(),
|
|
697
|
+
unit,
|
|
698
|
+
" remaining"
|
|
699
|
+
] })
|
|
700
|
+
] }, usage.feature_key);
|
|
701
|
+
}
|
|
702
|
+
if ((usage.limit ?? 0) > 0) {
|
|
703
|
+
const limit = usage.limit ?? 0;
|
|
704
|
+
const currentUsage = usage.current_usage ?? 0;
|
|
705
|
+
const percentage = currentUsage / limit * 100;
|
|
650
706
|
const unit = usage.unit ? ` ${usage.unit}` : "";
|
|
651
707
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
652
708
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
|
|
653
709
|
/* @__PURE__ */ jsx("span", { className: "text-gray-700 dark:text-neutral-300", children: featureName }),
|
|
654
710
|
/* @__PURE__ */ jsxs("span", { className: "text-gray-600 dark:text-gray-400", children: [
|
|
655
|
-
|
|
711
|
+
currentUsage.toLocaleString(),
|
|
656
712
|
" / ",
|
|
657
|
-
|
|
713
|
+
limit.toLocaleString(),
|
|
658
714
|
unit
|
|
659
715
|
] })
|
|
660
716
|
] }),
|
|
661
717
|
/* @__PURE__ */ jsx(
|
|
662
718
|
ProgressBar,
|
|
663
719
|
{
|
|
664
|
-
value:
|
|
665
|
-
max:
|
|
720
|
+
value: currentUsage,
|
|
721
|
+
max: limit,
|
|
666
722
|
variant: percentage > 80 ? "warning" : "default"
|
|
667
723
|
}
|
|
668
724
|
)
|
|
@@ -1313,7 +1369,611 @@ function BillingContent({
|
|
|
1313
1369
|
)
|
|
1314
1370
|
] });
|
|
1315
1371
|
}
|
|
1372
|
+
var STORAGE_KEY = "omnikit_customer";
|
|
1373
|
+
function getStoredCustomer(projectId) {
|
|
1374
|
+
if (typeof window === "undefined") return null;
|
|
1375
|
+
try {
|
|
1376
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
1377
|
+
if (!stored) return null;
|
|
1378
|
+
const customer = JSON.parse(stored);
|
|
1379
|
+
if (customer.projectId === projectId) {
|
|
1380
|
+
return customer;
|
|
1381
|
+
}
|
|
1382
|
+
return null;
|
|
1383
|
+
} catch {
|
|
1384
|
+
return null;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
function storeCustomer(customer) {
|
|
1388
|
+
if (typeof window === "undefined") return;
|
|
1389
|
+
try {
|
|
1390
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(customer));
|
|
1391
|
+
} catch {
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
function clearStoredCustomer() {
|
|
1395
|
+
if (typeof window === "undefined") return;
|
|
1396
|
+
try {
|
|
1397
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
1398
|
+
} catch {
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
function PaymentForm2({
|
|
1402
|
+
products,
|
|
1403
|
+
customerId: initialCustomerId,
|
|
1404
|
+
paymentMethods: initialPaymentMethods = [],
|
|
1405
|
+
stripePublishableKey,
|
|
1406
|
+
actionConfig,
|
|
1407
|
+
quantity = 1,
|
|
1408
|
+
currencySymbol = "$",
|
|
1409
|
+
successUrl = "/success",
|
|
1410
|
+
cancelUrl,
|
|
1411
|
+
allowPromoCode = true,
|
|
1412
|
+
termsUrl,
|
|
1413
|
+
privacyUrl,
|
|
1414
|
+
onSuccess,
|
|
1415
|
+
onError,
|
|
1416
|
+
onCustomerCreated
|
|
1417
|
+
}) {
|
|
1418
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
1419
|
+
const [isLoadingCustomer, setIsLoadingCustomer] = useState(false);
|
|
1420
|
+
const [error, setError] = useState(null);
|
|
1421
|
+
const [email, setEmail] = useState("");
|
|
1422
|
+
const [customerId, setCustomerId] = useState(initialCustomerId ?? null);
|
|
1423
|
+
const [paymentMethods, setPaymentMethods] = useState(initialPaymentMethods);
|
|
1424
|
+
const [selectedPaymentMethodId, setSelectedPaymentMethodId] = useState(null);
|
|
1425
|
+
const [showNewCardForm, setShowNewCardForm] = useState(false);
|
|
1426
|
+
const [promoCode, setPromoCode] = useState("");
|
|
1427
|
+
const [showPromoInput, setShowPromoInput] = useState(false);
|
|
1428
|
+
const [customerEmail, setCustomerEmail] = useState(null);
|
|
1429
|
+
useEffect(() => {
|
|
1430
|
+
if (initialCustomerId) {
|
|
1431
|
+
setCustomerId(initialCustomerId);
|
|
1432
|
+
return;
|
|
1433
|
+
}
|
|
1434
|
+
const stored = getStoredCustomer(actionConfig.projectId || 0);
|
|
1435
|
+
if (stored) {
|
|
1436
|
+
setCustomerId(stored.id);
|
|
1437
|
+
setCustomerEmail(stored.email);
|
|
1438
|
+
setEmail(stored.email);
|
|
1439
|
+
fetchPaymentMethods(stored.id);
|
|
1440
|
+
}
|
|
1441
|
+
}, [initialCustomerId, actionConfig.projectId]);
|
|
1442
|
+
useEffect(() => {
|
|
1443
|
+
if (initialPaymentMethods.length > 0) {
|
|
1444
|
+
setPaymentMethods(initialPaymentMethods);
|
|
1445
|
+
}
|
|
1446
|
+
}, [initialPaymentMethods]);
|
|
1447
|
+
useEffect(() => {
|
|
1448
|
+
if (paymentMethods.length > 0 && !selectedPaymentMethodId) {
|
|
1449
|
+
const defaultMethod = paymentMethods.find((pm) => pm.is_default);
|
|
1450
|
+
setSelectedPaymentMethodId(defaultMethod?.id || paymentMethods[0].id);
|
|
1451
|
+
setShowNewCardForm(false);
|
|
1452
|
+
} else if (paymentMethods.length === 0 && customerId) {
|
|
1453
|
+
setShowNewCardForm(true);
|
|
1454
|
+
}
|
|
1455
|
+
}, [paymentMethods, selectedPaymentMethodId, customerId]);
|
|
1456
|
+
const subtotal = products.reduce((sum, p) => sum + p.price * quantity, 0);
|
|
1457
|
+
const total = subtotal;
|
|
1458
|
+
const isMultiProduct = products.length > 1;
|
|
1459
|
+
const primaryProduct = products[0];
|
|
1460
|
+
const isSubscription = primaryProduct?.type === "subscription";
|
|
1461
|
+
const buttonText = isSubscription && !isMultiProduct ? `Subscribe ${currencySymbol}${primaryProduct.price.toFixed(2)}/${primaryProduct.interval}` : `Pay ${currencySymbol}${total.toFixed(2)}`;
|
|
1462
|
+
const fetchPaymentMethods = async (custId) => {
|
|
1463
|
+
try {
|
|
1464
|
+
const response = await fetch(
|
|
1465
|
+
`${actionConfig.baseUrl}/billing/customers/${custId}/payment-methods?project_id=${actionConfig.projectId}&status=active`,
|
|
1466
|
+
{
|
|
1467
|
+
headers: {
|
|
1468
|
+
"Content-Type": "application/json",
|
|
1469
|
+
...actionConfig.apiKey && { "X-API-Key": actionConfig.apiKey },
|
|
1470
|
+
...actionConfig.accessToken && { "Authorization": `Bearer ${actionConfig.accessToken}` }
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
);
|
|
1474
|
+
const result = await response.json();
|
|
1475
|
+
if (result.success && result.data) {
|
|
1476
|
+
setPaymentMethods(result.data);
|
|
1477
|
+
}
|
|
1478
|
+
} catch (err) {
|
|
1479
|
+
console.error("Failed to fetch payment methods:", err);
|
|
1480
|
+
}
|
|
1481
|
+
};
|
|
1482
|
+
const getOrCreateCustomer = async (emailAddress) => {
|
|
1483
|
+
setIsLoadingCustomer(true);
|
|
1484
|
+
setError(null);
|
|
1485
|
+
try {
|
|
1486
|
+
const filter = JSON.stringify({
|
|
1487
|
+
email: emailAddress,
|
|
1488
|
+
project_id: actionConfig.projectId
|
|
1489
|
+
});
|
|
1490
|
+
const searchResponse = await fetch(
|
|
1491
|
+
`${actionConfig.baseUrl}/data/customers?filter=${encodeURIComponent(filter)}&limit=1`,
|
|
1492
|
+
{
|
|
1493
|
+
headers: {
|
|
1494
|
+
"Content-Type": "application/json",
|
|
1495
|
+
...actionConfig.apiKey && { "X-API-Key": actionConfig.apiKey },
|
|
1496
|
+
...actionConfig.accessToken && { "Authorization": `Bearer ${actionConfig.accessToken}` }
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
);
|
|
1500
|
+
if (searchResponse.ok) {
|
|
1501
|
+
const searchResult = await searchResponse.json();
|
|
1502
|
+
if (searchResult.success && searchResult.data && searchResult.data.length > 0) {
|
|
1503
|
+
const customer = searchResult.data[0];
|
|
1504
|
+
return { id: customer.id, email: customer.email };
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
const createResponse = await fetch(`${actionConfig.baseUrl}/billing/customers`, {
|
|
1508
|
+
method: "POST",
|
|
1509
|
+
headers: {
|
|
1510
|
+
"Content-Type": "application/json",
|
|
1511
|
+
...actionConfig.apiKey && { "X-API-Key": actionConfig.apiKey },
|
|
1512
|
+
...actionConfig.accessToken && { "Authorization": `Bearer ${actionConfig.accessToken}` }
|
|
1513
|
+
},
|
|
1514
|
+
body: JSON.stringify({
|
|
1515
|
+
project_id: actionConfig.projectId,
|
|
1516
|
+
email: emailAddress,
|
|
1517
|
+
sync_to_stripe: true,
|
|
1518
|
+
test_mode: true
|
|
1519
|
+
})
|
|
1520
|
+
});
|
|
1521
|
+
const createResult = await createResponse.json();
|
|
1522
|
+
if (createResult.success && createResult.data) {
|
|
1523
|
+
return { id: createResult.data.id, email: createResult.data.email };
|
|
1524
|
+
}
|
|
1525
|
+
throw new Error(createResult.error || "Failed to create customer");
|
|
1526
|
+
} catch (err) {
|
|
1527
|
+
const message = err instanceof Error ? err.message : "Failed to create customer";
|
|
1528
|
+
setError(message);
|
|
1529
|
+
return null;
|
|
1530
|
+
} finally {
|
|
1531
|
+
setIsLoadingCustomer(false);
|
|
1532
|
+
}
|
|
1533
|
+
};
|
|
1534
|
+
const handleEmailSubmit = async () => {
|
|
1535
|
+
if (!email || !email.includes("@")) {
|
|
1536
|
+
setError("Please enter a valid email address");
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
const customer = await getOrCreateCustomer(email);
|
|
1540
|
+
if (customer) {
|
|
1541
|
+
setCustomerId(customer.id);
|
|
1542
|
+
setCustomerEmail(customer.email);
|
|
1543
|
+
storeCustomer({
|
|
1544
|
+
id: customer.id,
|
|
1545
|
+
email: customer.email,
|
|
1546
|
+
projectId: actionConfig.projectId || 0
|
|
1547
|
+
});
|
|
1548
|
+
await fetchPaymentMethods(customer.id);
|
|
1549
|
+
onCustomerCreated?.(customer.id, customer.email);
|
|
1550
|
+
}
|
|
1551
|
+
};
|
|
1552
|
+
const handleChangeEmail = () => {
|
|
1553
|
+
clearStoredCustomer();
|
|
1554
|
+
setCustomerId(null);
|
|
1555
|
+
setCustomerEmail(null);
|
|
1556
|
+
setPaymentMethods([]);
|
|
1557
|
+
setSelectedPaymentMethodId(null);
|
|
1558
|
+
setShowNewCardForm(false);
|
|
1559
|
+
};
|
|
1560
|
+
const processPayment = async (custId, paymentMethodId) => {
|
|
1561
|
+
const response = await fetch(`${actionConfig.baseUrl}/billing/payments/intents`, {
|
|
1562
|
+
method: "POST",
|
|
1563
|
+
headers: {
|
|
1564
|
+
"Content-Type": "application/json",
|
|
1565
|
+
...actionConfig.apiKey && { "X-API-Key": actionConfig.apiKey },
|
|
1566
|
+
...actionConfig.accessToken && { "Authorization": `Bearer ${actionConfig.accessToken}` }
|
|
1567
|
+
},
|
|
1568
|
+
body: JSON.stringify({
|
|
1569
|
+
project_id: actionConfig.projectId,
|
|
1570
|
+
customer_id: custId,
|
|
1571
|
+
amount: total,
|
|
1572
|
+
currency: "usd",
|
|
1573
|
+
payment_method_id: paymentMethodId,
|
|
1574
|
+
description: isMultiProduct ? `Purchase of ${products.length} products` : `Purchase of ${primaryProduct.name}`,
|
|
1575
|
+
metadata: {
|
|
1576
|
+
product_ids: products.map((p) => p.id)
|
|
1577
|
+
},
|
|
1578
|
+
confirm: true,
|
|
1579
|
+
sync_to_stripe: true,
|
|
1580
|
+
test_mode: true
|
|
1581
|
+
})
|
|
1582
|
+
});
|
|
1583
|
+
const result = await response.json();
|
|
1584
|
+
if (!result.success) {
|
|
1585
|
+
throw new Error(result.error || "Payment failed");
|
|
1586
|
+
}
|
|
1587
|
+
return result;
|
|
1588
|
+
};
|
|
1589
|
+
const handleSubmit = async (e) => {
|
|
1590
|
+
e.preventDefault();
|
|
1591
|
+
if (customerId && selectedPaymentMethodId && !showNewCardForm) {
|
|
1592
|
+
setIsLoading(true);
|
|
1593
|
+
setError(null);
|
|
1594
|
+
try {
|
|
1595
|
+
await processPayment(customerId, selectedPaymentMethodId);
|
|
1596
|
+
onSuccess?.();
|
|
1597
|
+
window.location.href = successUrl;
|
|
1598
|
+
} catch (err) {
|
|
1599
|
+
const errorMessage = err instanceof Error ? err.message : "Payment failed";
|
|
1600
|
+
setError(errorMessage);
|
|
1601
|
+
onError?.(errorMessage);
|
|
1602
|
+
} finally {
|
|
1603
|
+
setIsLoading(false);
|
|
1604
|
+
}
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
if (!customerId && !selectedPaymentMethodId) {
|
|
1608
|
+
if (!email || !email.includes("@")) {
|
|
1609
|
+
setError("Please enter a valid email address");
|
|
1610
|
+
return;
|
|
1611
|
+
}
|
|
1612
|
+
setError('Please enter your card details and click "Add Card & Pay"');
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
if (showNewCardForm) {
|
|
1616
|
+
setError("Please add a payment method first");
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
};
|
|
1620
|
+
const handleGuestCheckout = async (stripePaymentMethodId) => {
|
|
1621
|
+
if (!email || !email.includes("@")) {
|
|
1622
|
+
return { success: false, error: "Please enter a valid email address" };
|
|
1623
|
+
}
|
|
1624
|
+
setIsLoading(true);
|
|
1625
|
+
setError(null);
|
|
1626
|
+
try {
|
|
1627
|
+
const customer = await getOrCreateCustomer(email);
|
|
1628
|
+
if (!customer) {
|
|
1629
|
+
throw new Error("Failed to create customer");
|
|
1630
|
+
}
|
|
1631
|
+
storeCustomer({
|
|
1632
|
+
id: customer.id,
|
|
1633
|
+
email: customer.email,
|
|
1634
|
+
projectId: actionConfig.projectId || 0
|
|
1635
|
+
});
|
|
1636
|
+
const pmResponse = await fetch(`${actionConfig.baseUrl}/billing/customers/${customer.id}/payment-methods`, {
|
|
1637
|
+
method: "POST",
|
|
1638
|
+
headers: {
|
|
1639
|
+
"Content-Type": "application/json",
|
|
1640
|
+
...actionConfig.apiKey && { "X-API-Key": actionConfig.apiKey },
|
|
1641
|
+
...actionConfig.accessToken && { "Authorization": `Bearer ${actionConfig.accessToken}` }
|
|
1642
|
+
},
|
|
1643
|
+
body: JSON.stringify({
|
|
1644
|
+
project_id: actionConfig.projectId,
|
|
1645
|
+
type: "card",
|
|
1646
|
+
stripe_payment_method_id: stripePaymentMethodId,
|
|
1647
|
+
set_as_default: true
|
|
1648
|
+
})
|
|
1649
|
+
});
|
|
1650
|
+
const pmResult = await pmResponse.json();
|
|
1651
|
+
if (!pmResult.success || !pmResult.data) {
|
|
1652
|
+
throw new Error(pmResult.error || "Failed to add payment method");
|
|
1653
|
+
}
|
|
1654
|
+
await processPayment(customer.id, pmResult.data.id);
|
|
1655
|
+
onCustomerCreated?.(customer.id, customer.email);
|
|
1656
|
+
onSuccess?.();
|
|
1657
|
+
window.location.href = successUrl;
|
|
1658
|
+
return { success: true };
|
|
1659
|
+
} catch (err) {
|
|
1660
|
+
const errorMessage = err instanceof Error ? err.message : "Payment failed";
|
|
1661
|
+
setError(errorMessage);
|
|
1662
|
+
onError?.(errorMessage);
|
|
1663
|
+
return { success: false, error: errorMessage };
|
|
1664
|
+
} finally {
|
|
1665
|
+
setIsLoading(false);
|
|
1666
|
+
}
|
|
1667
|
+
};
|
|
1668
|
+
const handleAddPaymentMethod = async (stripePaymentMethodId, setAsDefault) => {
|
|
1669
|
+
if (!customerId) {
|
|
1670
|
+
return { success: false, error: "Customer not found" };
|
|
1671
|
+
}
|
|
1672
|
+
try {
|
|
1673
|
+
const response = await fetch(`${actionConfig.baseUrl}/billing/customers/${customerId}/payment-methods`, {
|
|
1674
|
+
method: "POST",
|
|
1675
|
+
headers: {
|
|
1676
|
+
"Content-Type": "application/json",
|
|
1677
|
+
...actionConfig.apiKey && { "X-API-Key": actionConfig.apiKey },
|
|
1678
|
+
...actionConfig.accessToken && { "Authorization": `Bearer ${actionConfig.accessToken}` }
|
|
1679
|
+
},
|
|
1680
|
+
body: JSON.stringify({
|
|
1681
|
+
project_id: actionConfig.projectId,
|
|
1682
|
+
type: "card",
|
|
1683
|
+
stripe_payment_method_id: stripePaymentMethodId,
|
|
1684
|
+
set_as_default: setAsDefault
|
|
1685
|
+
})
|
|
1686
|
+
});
|
|
1687
|
+
const result = await response.json();
|
|
1688
|
+
return result;
|
|
1689
|
+
} catch (err) {
|
|
1690
|
+
return { success: false, error: err instanceof Error ? err.message : "Failed to add payment method" };
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
const handlePaymentMethodAdded = async () => {
|
|
1694
|
+
setShowNewCardForm(false);
|
|
1695
|
+
if (customerId) {
|
|
1696
|
+
await fetchPaymentMethods(customerId);
|
|
1697
|
+
}
|
|
1698
|
+
};
|
|
1699
|
+
const needsEmail = !customerId && !initialCustomerId;
|
|
1700
|
+
const isGuestMode = needsEmail && stripePublishableKey;
|
|
1701
|
+
return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
1702
|
+
isGuestMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1703
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1704
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "email", className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: "Email" }),
|
|
1705
|
+
/* @__PURE__ */ jsx(
|
|
1706
|
+
TextInput,
|
|
1707
|
+
{
|
|
1708
|
+
id: "email",
|
|
1709
|
+
type: "email",
|
|
1710
|
+
value: email,
|
|
1711
|
+
onChange: (e) => setEmail(e.target.value),
|
|
1712
|
+
placeholder: "you@example.com",
|
|
1713
|
+
required: true,
|
|
1714
|
+
disabled: isLoading
|
|
1715
|
+
}
|
|
1716
|
+
)
|
|
1717
|
+
] }),
|
|
1718
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1719
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Card Information" }),
|
|
1720
|
+
/* @__PURE__ */ jsx(
|
|
1721
|
+
AddPaymentMethodForm,
|
|
1722
|
+
{
|
|
1723
|
+
customerId: 0,
|
|
1724
|
+
stripePublishableKey,
|
|
1725
|
+
onSuccess: () => {
|
|
1726
|
+
},
|
|
1727
|
+
onSubmit: async () => ({ success: false, error: "Use guest checkout" }),
|
|
1728
|
+
onGuestCheckout: handleGuestCheckout,
|
|
1729
|
+
isGuestMode: true,
|
|
1730
|
+
guestEmail: email,
|
|
1731
|
+
submitButtonText: `Pay ${currencySymbol}${total.toFixed(2)}`,
|
|
1732
|
+
isProcessing: isLoading
|
|
1733
|
+
}
|
|
1734
|
+
)
|
|
1735
|
+
] }),
|
|
1736
|
+
(isMultiProduct || quantity > 1) && /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t border-gray-200 dark:border-neutral-700 space-y-2", children: [
|
|
1737
|
+
products.map((product) => /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
|
|
1738
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-600 dark:text-gray-400", children: [
|
|
1739
|
+
product.name,
|
|
1740
|
+
" ",
|
|
1741
|
+
quantity > 1 && `x ${quantity}`
|
|
1742
|
+
] }),
|
|
1743
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-900 dark:text-white", children: [
|
|
1744
|
+
currencySymbol,
|
|
1745
|
+
(product.price * quantity).toFixed(2)
|
|
1746
|
+
] })
|
|
1747
|
+
] }, product.id)),
|
|
1748
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between font-semibold pt-2 border-t border-gray-200 dark:border-neutral-700", children: [
|
|
1749
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-900 dark:text-white", children: "Total" }),
|
|
1750
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-900 dark:text-white", children: [
|
|
1751
|
+
currencySymbol,
|
|
1752
|
+
total.toFixed(2)
|
|
1753
|
+
] })
|
|
1754
|
+
] })
|
|
1755
|
+
] }),
|
|
1756
|
+
error && /* @__PURE__ */ jsx(Alert, { variant: "error", children: error }),
|
|
1757
|
+
(termsUrl || privacyUrl) && /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400 text-center", children: [
|
|
1758
|
+
"By confirming, you agree to our",
|
|
1759
|
+
" ",
|
|
1760
|
+
termsUrl && /* @__PURE__ */ jsx("a", { href: termsUrl, className: "text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300", children: "Terms of Service" }),
|
|
1761
|
+
termsUrl && privacyUrl && " and ",
|
|
1762
|
+
privacyUrl && /* @__PURE__ */ jsx("a", { href: privacyUrl, className: "text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300", children: "Privacy Policy" }),
|
|
1763
|
+
"."
|
|
1764
|
+
] }),
|
|
1765
|
+
cancelUrl && /* @__PURE__ */ jsx("div", { className: "text-center", children: /* @__PURE__ */ jsx("a", { href: cancelUrl, className: "text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300", children: "Cancel" }) })
|
|
1766
|
+
] }) : needsEmail && !stripePublishableKey ? (
|
|
1767
|
+
/* No Stripe key - show email only with continue button */
|
|
1768
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1769
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "email", className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Email" }),
|
|
1770
|
+
/* @__PURE__ */ jsx(
|
|
1771
|
+
TextInput,
|
|
1772
|
+
{
|
|
1773
|
+
id: "email",
|
|
1774
|
+
type: "email",
|
|
1775
|
+
value: email,
|
|
1776
|
+
onChange: (e) => setEmail(e.target.value),
|
|
1777
|
+
placeholder: "you@example.com",
|
|
1778
|
+
required: true,
|
|
1779
|
+
disabled: isLoadingCustomer
|
|
1780
|
+
}
|
|
1781
|
+
),
|
|
1782
|
+
/* @__PURE__ */ jsx(
|
|
1783
|
+
Button,
|
|
1784
|
+
{
|
|
1785
|
+
type: "button",
|
|
1786
|
+
onClick: handleEmailSubmit,
|
|
1787
|
+
disabled: isLoadingCustomer || !email,
|
|
1788
|
+
className: "w-full",
|
|
1789
|
+
children: isLoadingCustomer ? "Loading..." : "Continue"
|
|
1790
|
+
}
|
|
1791
|
+
)
|
|
1792
|
+
] })
|
|
1793
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1794
|
+
customerEmail && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-3 bg-gray-50 dark:bg-neutral-800 rounded-lg", children: [
|
|
1795
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1796
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Email" }),
|
|
1797
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 dark:text-white", children: customerEmail })
|
|
1798
|
+
] }),
|
|
1799
|
+
/* @__PURE__ */ jsx(
|
|
1800
|
+
"button",
|
|
1801
|
+
{
|
|
1802
|
+
type: "button",
|
|
1803
|
+
onClick: handleChangeEmail,
|
|
1804
|
+
className: "text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300",
|
|
1805
|
+
children: "Change"
|
|
1806
|
+
}
|
|
1807
|
+
)
|
|
1808
|
+
] }),
|
|
1809
|
+
paymentMethods.length > 0 && !showNewCardForm && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1810
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Payment Method" }),
|
|
1811
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: paymentMethods.map((method) => /* @__PURE__ */ jsxs(
|
|
1812
|
+
"label",
|
|
1813
|
+
{
|
|
1814
|
+
className: `flex items-center gap-3 p-3 border-2 rounded-lg cursor-pointer transition-all ${selectedPaymentMethodId === method.id ? "border-blue-500 bg-blue-50 dark:bg-blue-900/30" : "border-gray-200 dark:border-neutral-700 hover:border-gray-300 dark:hover:border-neutral-600"}`,
|
|
1815
|
+
children: [
|
|
1816
|
+
/* @__PURE__ */ jsx(
|
|
1817
|
+
"input",
|
|
1818
|
+
{
|
|
1819
|
+
type: "radio",
|
|
1820
|
+
name: "paymentMethod",
|
|
1821
|
+
value: method.id,
|
|
1822
|
+
checked: selectedPaymentMethodId === method.id,
|
|
1823
|
+
onChange: () => setSelectedPaymentMethodId(method.id),
|
|
1824
|
+
className: "w-4 h-4 text-blue-600"
|
|
1825
|
+
}
|
|
1826
|
+
),
|
|
1827
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
1828
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1829
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900 dark:text-white text-sm", children: method.card_brand ? method.card_brand.charAt(0).toUpperCase() + method.card_brand.slice(1) : "Card" }),
|
|
1830
|
+
method.is_default && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full bg-blue-100 dark:bg-blue-900 px-2 py-0.5 text-xs font-medium text-blue-800 dark:text-blue-200", children: "Default" })
|
|
1831
|
+
] }),
|
|
1832
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-600 dark:text-gray-400", children: [
|
|
1833
|
+
"**** ",
|
|
1834
|
+
method.card_last4 || "XXXX",
|
|
1835
|
+
method.card_exp_month && method.card_exp_year && /* @__PURE__ */ jsxs("span", { className: "ml-2", children: [
|
|
1836
|
+
"Exp ",
|
|
1837
|
+
method.card_exp_month,
|
|
1838
|
+
"/",
|
|
1839
|
+
method.card_exp_year
|
|
1840
|
+
] })
|
|
1841
|
+
] })
|
|
1842
|
+
] })
|
|
1843
|
+
]
|
|
1844
|
+
},
|
|
1845
|
+
method.id
|
|
1846
|
+
)) }),
|
|
1847
|
+
/* @__PURE__ */ jsx(
|
|
1848
|
+
"button",
|
|
1849
|
+
{
|
|
1850
|
+
type: "button",
|
|
1851
|
+
onClick: () => setShowNewCardForm(true),
|
|
1852
|
+
className: "text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300",
|
|
1853
|
+
children: "+ Add new card"
|
|
1854
|
+
}
|
|
1855
|
+
)
|
|
1856
|
+
] }),
|
|
1857
|
+
showNewCardForm && stripePublishableKey && customerId && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1858
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Card Information" }),
|
|
1859
|
+
/* @__PURE__ */ jsx(
|
|
1860
|
+
AddPaymentMethodForm,
|
|
1861
|
+
{
|
|
1862
|
+
customerId,
|
|
1863
|
+
stripePublishableKey,
|
|
1864
|
+
onSuccess: handlePaymentMethodAdded,
|
|
1865
|
+
onCancel: paymentMethods.length > 0 ? () => setShowNewCardForm(false) : void 0,
|
|
1866
|
+
onSubmit: handleAddPaymentMethod
|
|
1867
|
+
}
|
|
1868
|
+
)
|
|
1869
|
+
] }),
|
|
1870
|
+
showNewCardForm && !stripePublishableKey && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1871
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Card Information" }),
|
|
1872
|
+
/* @__PURE__ */ jsx(
|
|
1873
|
+
TextInput,
|
|
1874
|
+
{
|
|
1875
|
+
type: "text",
|
|
1876
|
+
name: "card_number",
|
|
1877
|
+
placeholder: "1234 1234 1234 1234",
|
|
1878
|
+
required: true
|
|
1879
|
+
}
|
|
1880
|
+
),
|
|
1881
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
1882
|
+
/* @__PURE__ */ jsx(
|
|
1883
|
+
TextInput,
|
|
1884
|
+
{
|
|
1885
|
+
type: "text",
|
|
1886
|
+
name: "card_expiry",
|
|
1887
|
+
placeholder: "MM / YY",
|
|
1888
|
+
required: true
|
|
1889
|
+
}
|
|
1890
|
+
),
|
|
1891
|
+
/* @__PURE__ */ jsx(
|
|
1892
|
+
TextInput,
|
|
1893
|
+
{
|
|
1894
|
+
type: "text",
|
|
1895
|
+
name: "card_cvc",
|
|
1896
|
+
placeholder: "CVC",
|
|
1897
|
+
required: true
|
|
1898
|
+
}
|
|
1899
|
+
)
|
|
1900
|
+
] }),
|
|
1901
|
+
/* @__PURE__ */ jsx(
|
|
1902
|
+
TextInput,
|
|
1903
|
+
{
|
|
1904
|
+
type: "text",
|
|
1905
|
+
name: "cardholder_name",
|
|
1906
|
+
placeholder: "Name on card",
|
|
1907
|
+
required: true
|
|
1908
|
+
}
|
|
1909
|
+
)
|
|
1910
|
+
] }),
|
|
1911
|
+
allowPromoCode && /* @__PURE__ */ jsx("div", { children: !showPromoInput ? /* @__PURE__ */ jsx(
|
|
1912
|
+
"button",
|
|
1913
|
+
{
|
|
1914
|
+
type: "button",
|
|
1915
|
+
onClick: () => setShowPromoInput(true),
|
|
1916
|
+
className: "text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300",
|
|
1917
|
+
children: "Add promotion code"
|
|
1918
|
+
}
|
|
1919
|
+
) : /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
1920
|
+
/* @__PURE__ */ jsx(
|
|
1921
|
+
TextInput,
|
|
1922
|
+
{
|
|
1923
|
+
type: "text",
|
|
1924
|
+
value: promoCode,
|
|
1925
|
+
onChange: (e) => setPromoCode(e.target.value),
|
|
1926
|
+
placeholder: "Enter promo code",
|
|
1927
|
+
className: "flex-1"
|
|
1928
|
+
}
|
|
1929
|
+
),
|
|
1930
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", children: "Apply" })
|
|
1931
|
+
] }) }),
|
|
1932
|
+
(isMultiProduct || quantity > 1) && /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t border-gray-200 dark:border-neutral-700 space-y-2", children: [
|
|
1933
|
+
products.map((product) => /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
|
|
1934
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-600 dark:text-gray-400", children: [
|
|
1935
|
+
product.name,
|
|
1936
|
+
" ",
|
|
1937
|
+
quantity > 1 && `x ${quantity}`
|
|
1938
|
+
] }),
|
|
1939
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-900 dark:text-white", children: [
|
|
1940
|
+
currencySymbol,
|
|
1941
|
+
(product.price * quantity).toFixed(2)
|
|
1942
|
+
] })
|
|
1943
|
+
] }, product.id)),
|
|
1944
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between font-semibold pt-2 border-t border-gray-200 dark:border-neutral-700", children: [
|
|
1945
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-900 dark:text-white", children: "Total" }),
|
|
1946
|
+
/* @__PURE__ */ jsxs("span", { className: "text-gray-900 dark:text-white", children: [
|
|
1947
|
+
currencySymbol,
|
|
1948
|
+
total.toFixed(2)
|
|
1949
|
+
] })
|
|
1950
|
+
] })
|
|
1951
|
+
] }),
|
|
1952
|
+
error && /* @__PURE__ */ jsx(Alert, { variant: "error", children: error }),
|
|
1953
|
+
/* @__PURE__ */ jsx(
|
|
1954
|
+
Button,
|
|
1955
|
+
{
|
|
1956
|
+
type: "submit",
|
|
1957
|
+
className: "w-full",
|
|
1958
|
+
size: "lg",
|
|
1959
|
+
disabled: isLoading || showNewCardForm && !!stripePublishableKey,
|
|
1960
|
+
children: isLoading ? "Processing..." : buttonText
|
|
1961
|
+
}
|
|
1962
|
+
),
|
|
1963
|
+
(termsUrl || privacyUrl) && /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400 text-center", children: [
|
|
1964
|
+
"By confirming, you agree to our",
|
|
1965
|
+
" ",
|
|
1966
|
+
termsUrl && /* @__PURE__ */ jsx("a", { href: termsUrl, className: "text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300", children: "Terms of Service" }),
|
|
1967
|
+
termsUrl && privacyUrl && " and ",
|
|
1968
|
+
privacyUrl && /* @__PURE__ */ jsx("a", { href: privacyUrl, className: "text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300", children: "Privacy Policy" }),
|
|
1969
|
+
"."
|
|
1970
|
+
] }),
|
|
1971
|
+
cancelUrl && /* @__PURE__ */ jsx("div", { className: "text-center", children: /* @__PURE__ */ jsx("a", { href: cancelUrl, className: "text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300", children: "Cancel" }) })
|
|
1972
|
+
] }),
|
|
1973
|
+
needsEmail && !stripePublishableKey && error && /* @__PURE__ */ jsx(Alert, { variant: "error", children: error })
|
|
1974
|
+
] });
|
|
1975
|
+
}
|
|
1316
1976
|
|
|
1317
|
-
export { AddPaymentMethodForm, BillingContent };
|
|
1318
|
-
//# sourceMappingURL=chunk-
|
|
1319
|
-
//# sourceMappingURL=chunk-
|
|
1977
|
+
export { AddPaymentMethodForm, BillingContent, PaymentForm2 as PaymentForm };
|
|
1978
|
+
//# sourceMappingURL=chunk-SRPYYSJZ.js.map
|
|
1979
|
+
//# sourceMappingURL=chunk-SRPYYSJZ.js.map
|