@funnelsgrove/payments 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +32 -3
  2. package/dist/components/shared/ApplePaySubscribeButton.d.ts +15 -0
  3. package/dist/components/shared/ApplePaySubscribeButton.js +76 -0
  4. package/dist/components/shared/CheckoutBrandAssets.d.ts +12 -0
  5. package/dist/components/shared/CheckoutBrandAssets.js +56 -0
  6. package/dist/components/shared/GooglePaySubscribeButton.d.ts +14 -0
  7. package/dist/components/shared/GooglePaySubscribeButton.js +94 -0
  8. package/dist/components/shared/SharedStripeCheckoutDialog.d.ts +44 -0
  9. package/dist/components/shared/SharedStripeCheckoutDialog.js +717 -0
  10. package/dist/components/shared/SharedStripeCheckoutV2Dialog.d.ts +60 -0
  11. package/dist/components/shared/SharedStripeCheckoutV2Dialog.js +988 -0
  12. package/dist/components/shared/StripeExpressCheckoutButton.d.ts +18 -0
  13. package/dist/components/shared/StripeExpressCheckoutButton.js +164 -0
  14. package/dist/components/shared/StripeExpressCheckoutElement.d.ts +8 -0
  15. package/dist/components/shared/StripeExpressCheckoutElement.js +19 -0
  16. package/dist/components/shared/StripePlanSelector.d.ts +5 -7
  17. package/dist/components/shared/StripePlanSelector.js +16 -57
  18. package/dist/components/shared/walletPlatform.d.ts +11 -0
  19. package/dist/components/shared/walletPlatform.js +39 -0
  20. package/dist/config/billing.config.d.ts +60 -9
  21. package/dist/config/billing.config.js +7 -2
  22. package/dist/hooks/useResolvedPaywallPlans.d.ts +15 -0
  23. package/dist/hooks/useResolvedPaywallPlans.js +68 -0
  24. package/dist/index.d.ts +21 -5
  25. package/dist/index.js +21 -5
  26. package/dist/providers/paymentProvider.types.d.ts +4 -0
  27. package/dist/providers/paymentProvider.types.js +4 -0
  28. package/dist/providers/stripe/ApplePaySubscriptionCheckoutSlot.d.ts +5 -0
  29. package/dist/providers/stripe/ApplePaySubscriptionCheckoutSlot.js +21 -0
  30. package/dist/providers/stripe/GooglePaySubscriptionCheckoutSlot.d.ts +7 -0
  31. package/dist/providers/stripe/GooglePaySubscriptionCheckoutSlot.js +44 -0
  32. package/dist/providers/stripe/WalletSubscriptionCheckoutSlot.d.ts +32 -0
  33. package/dist/providers/stripe/WalletSubscriptionCheckoutSlot.js +69 -0
  34. package/dist/providers/stripe/useStripeSubscriptionCheckoutSession.d.ts +30 -0
  35. package/dist/providers/stripe/useStripeSubscriptionCheckoutSession.js +164 -0
  36. package/dist/services/paywallOffer.service.d.ts +65 -0
  37. package/dist/services/paywallOffer.service.js +312 -0
  38. package/dist/services/planCatalog.service.d.ts +28 -0
  39. package/dist/services/planCatalog.service.js +60 -0
  40. package/dist/services/runtimeBillingPlanCatalog.service.d.ts +6 -0
  41. package/dist/services/runtimeBillingPlanCatalog.service.js +24 -0
  42. package/dist/services/stripe.service.d.ts +66 -6
  43. package/dist/services/stripe.service.js +409 -54
  44. package/package.json +3 -3
@@ -0,0 +1,717 @@
1
+ 'use client';
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
+ import { useEffect, useMemo, useState, useSyncExternalStore, } from 'react';
15
+ import { CardCvcElement, CardExpiryElement, CardNumberElement, Elements, useElements, useStripe, } from '@stripe/react-stripe-js';
16
+ import { ApplePaySubscribeButton } from './ApplePaySubscribeButton.js';
17
+ import { PaymentBrandMark, SecurityLockIcon, StripeWordmark, } from './CheckoutBrandAssets.js';
18
+ import { StripeExpressCheckoutButton } from './StripeExpressCheckoutButton.js';
19
+ const isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
20
+ const defaultPaymentMethodLabels = ['Visa', 'Mastercard', 'PayPal', 'G Pay', 'Apple Pay'];
21
+ const normalizeBillingName = (input) => {
22
+ var _a, _b, _c;
23
+ const normalizedName = (_a = input.name) === null || _a === void 0 ? void 0 : _a.trim();
24
+ if (normalizedName) {
25
+ return normalizedName;
26
+ }
27
+ const normalizedEmail = (_b = input.email) === null || _b === void 0 ? void 0 : _b.trim();
28
+ if (normalizedEmail) {
29
+ const localPart = (_c = normalizedEmail
30
+ .split('@')[0]) === null || _c === void 0 ? void 0 : _c.replace(/[._-]+/g, ' ').trim();
31
+ if (localPart) {
32
+ return localPart;
33
+ }
34
+ }
35
+ return 'Customer';
36
+ };
37
+ const isSuccessfulIntentStatus = (status) => {
38
+ return status === 'succeeded' || status === 'processing' || status === 'requires_capture';
39
+ };
40
+ const applePayQrFallbackMediaQuery = '(hover: hover) and (pointer: fine)';
41
+ function getApplePayQrFallbackSnapshot() {
42
+ if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
43
+ return false;
44
+ }
45
+ return window.matchMedia('(hover: hover) and (pointer: fine)').matches;
46
+ }
47
+ function subscribeApplePayQrFallback(onStoreChange) {
48
+ if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
49
+ return () => undefined;
50
+ }
51
+ const mediaQuery = window.matchMedia(applePayQrFallbackMediaQuery);
52
+ mediaQuery.addEventListener('change', onStoreChange);
53
+ return () => mediaQuery.removeEventListener('change', onStoreChange);
54
+ }
55
+ export function useApplePayQrFallbackAllowed() {
56
+ return useSyncExternalStore(subscribeApplePayQrFallback, getApplePayQrFallbackSnapshot, () => false);
57
+ }
58
+ function getApplePayExpressCheckoutSnapshot() {
59
+ if (typeof window === 'undefined') {
60
+ return false;
61
+ }
62
+ const applePaySession = window.ApplePaySession;
63
+ return typeof (applePaySession === null || applePaySession === void 0 ? void 0 : applePaySession.canMakePayments) === 'function' &&
64
+ applePaySession.canMakePayments();
65
+ }
66
+ export function useApplePayExpressCheckoutAllowed() {
67
+ return useSyncExternalStore(() => () => undefined, getApplePayExpressCheckoutSnapshot, () => false);
68
+ }
69
+ const stripeCardElementStyle = {
70
+ base: {
71
+ color: '#111827',
72
+ fontFamily: 'Manrope, Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
73
+ fontSize: '16px',
74
+ fontSmoothing: 'antialiased',
75
+ '::placeholder': {
76
+ color: '#9ca3af',
77
+ },
78
+ },
79
+ invalid: {
80
+ color: '#c43737',
81
+ iconColor: '#c43737',
82
+ },
83
+ };
84
+ const cardNumberElementOptions = {
85
+ placeholder: '1234 1234 1234 1234',
86
+ showIcon: false,
87
+ style: stripeCardElementStyle,
88
+ };
89
+ const cardExpiryElementOptions = {
90
+ placeholder: 'MM/YY',
91
+ style: stripeCardElementStyle,
92
+ };
93
+ const cardCvcElementOptions = {
94
+ placeholder: 'CVV',
95
+ style: stripeCardElementStyle,
96
+ };
97
+ function getFriendlyCardErrorMessage(error) {
98
+ return error instanceof Error && error.message
99
+ ? error.message
100
+ : 'Payment failed. Please review your card details and try again.';
101
+ }
102
+ function SharedStripeCheckoutForm({ amountCents, clientSecret, closeAriaLabel, customerEmailEditable = false, customerEmailInvalidMessage = 'Enter a valid email address.', customerEmailLabel = 'Email', customerEmailPlaceholder = 'Enter your email', customerEmail, customerName, legalNotice, onClose, onCustomerEmailChange, onCustomerEmailCommit, onError, onSuccess, paymentMethodLabels = defaultPaymentMethodLabels, poweredByLabel, processingLabel, renewalNotice, returnUrl, secureLabel, submitLabel, summaryLabel, summaryRows, summaryTitle, title, totalLabel, totalValue, walletPlaceholderLabel, summaryNote, }) {
103
+ const stripe = useStripe();
104
+ const elements = useElements();
105
+ const [submitting, setSubmitting] = useState(false);
106
+ const [error, setError] = useState(null);
107
+ const [walletAvailable, setWalletAvailable] = useState(null);
108
+ const [cardNumberError, setCardNumberError] = useState(null);
109
+ const [cardExpiryError, setCardExpiryError] = useState(null);
110
+ const [cardCvcError, setCardCvcError] = useState(null);
111
+ const [cardNumberComplete, setCardNumberComplete] = useState(false);
112
+ const [cardExpiryComplete, setCardExpiryComplete] = useState(false);
113
+ const [cardCvcComplete, setCardCvcComplete] = useState(false);
114
+ const [emailDraft, setEmailDraft] = useState((customerEmail === null || customerEmail === void 0 ? void 0 : customerEmail.trim()) || '');
115
+ const allowApplePayQrFallback = useApplePayQrFallbackAllowed();
116
+ const allowApplePayExpressCheckout = useApplePayExpressCheckoutAllowed();
117
+ const cardFieldBrandLabels = useMemo(() => {
118
+ const labels = paymentMethodLabels.filter((label) => {
119
+ const normalizedLabel = label.trim().toLowerCase();
120
+ return normalizedLabel === 'visa' || normalizedLabel === 'mastercard';
121
+ });
122
+ return labels.length > 0 ? labels.slice(0, 2) : ['Visa', 'Mastercard'];
123
+ }, [paymentMethodLabels]);
124
+ const showsStripeWordmark = /stripe/i.test(poweredByLabel);
125
+ const poweredByText = useMemo(() => {
126
+ if (!showsStripeWordmark) {
127
+ return poweredByLabel;
128
+ }
129
+ return poweredByLabel.replace(/\s*stripe\b/i, '').trim();
130
+ }, [poweredByLabel, showsStripeWordmark]);
131
+ const initialCustomerEmail = (customerEmail === null || customerEmail === void 0 ? void 0 : customerEmail.trim()) || '';
132
+ const resolvedCustomerEmail = customerEmailEditable
133
+ ? emailDraft.trim() || initialCustomerEmail
134
+ : initialCustomerEmail;
135
+ const canSubmit = Boolean(stripe) &&
136
+ Boolean(elements) &&
137
+ cardNumberComplete &&
138
+ cardExpiryComplete &&
139
+ cardCvcComplete &&
140
+ !submitting;
141
+ const walletCheckoutAllowed = allowApplePayExpressCheckout || allowApplePayQrFallback;
142
+ const walletFallbackDisabled = !walletCheckoutAllowed || walletAvailable === false;
143
+ const setSharedError = (message) => {
144
+ setError(message);
145
+ onError === null || onError === void 0 ? void 0 : onError(message);
146
+ };
147
+ const ensureCustomerEmail = async () => {
148
+ const normalizedEmail = resolvedCustomerEmail.trim();
149
+ if (!normalizedEmail || !isValidEmail(normalizedEmail)) {
150
+ setSharedError(customerEmailInvalidMessage);
151
+ return null;
152
+ }
153
+ if (!customerEmailEditable || !onCustomerEmailCommit) {
154
+ return normalizedEmail;
155
+ }
156
+ const committedEmail = await onCustomerEmailCommit(normalizedEmail);
157
+ const nextEmail = typeof committedEmail === 'string' && committedEmail.trim()
158
+ ? committedEmail.trim()
159
+ : normalizedEmail;
160
+ setEmailDraft(nextEmail);
161
+ onCustomerEmailChange === null || onCustomerEmailChange === void 0 ? void 0 : onCustomerEmailChange(nextEmail);
162
+ return nextEmail;
163
+ };
164
+ const handleFieldError = (event, setFieldError, setFieldComplete) => {
165
+ var _a, _b, _c;
166
+ setFieldError((_b = (_a = event.error) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : null);
167
+ setFieldComplete(event.complete);
168
+ if ((_c = event.error) === null || _c === void 0 ? void 0 : _c.message) {
169
+ setSharedError(event.error.message);
170
+ return;
171
+ }
172
+ setSharedError(null);
173
+ };
174
+ const handleSubmit = async (event) => {
175
+ var _a;
176
+ event.preventDefault();
177
+ if (!stripe || !elements || submitting) {
178
+ return;
179
+ }
180
+ const cardNumberElement = elements.getElement(CardNumberElement);
181
+ if (!cardNumberElement) {
182
+ setSharedError('Payment form is not ready yet.');
183
+ return;
184
+ }
185
+ setSubmitting(true);
186
+ setSharedError(null);
187
+ try {
188
+ const syncedEmail = await ensureCustomerEmail();
189
+ if (!syncedEmail) {
190
+ setSubmitting(false);
191
+ return;
192
+ }
193
+ const result = await stripe.confirmCardPayment(clientSecret, {
194
+ payment_method: {
195
+ card: cardNumberElement,
196
+ billing_details: {
197
+ email: syncedEmail || undefined,
198
+ name: normalizeBillingName({
199
+ email: syncedEmail,
200
+ name: customerName,
201
+ }),
202
+ },
203
+ },
204
+ return_url: returnUrl,
205
+ });
206
+ if (result.error) {
207
+ setSharedError(result.error.message || 'Payment failed.');
208
+ setSubmitting(false);
209
+ return;
210
+ }
211
+ if (typeof window !== 'undefined' &&
212
+ isSuccessfulIntentStatus((_a = result.paymentIntent) === null || _a === void 0 ? void 0 : _a.status)) {
213
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess();
214
+ window.location.assign(returnUrl);
215
+ return;
216
+ }
217
+ setSubmitting(false);
218
+ }
219
+ catch (submitError) {
220
+ setSharedError(getFriendlyCardErrorMessage(submitError));
221
+ setSubmitting(false);
222
+ }
223
+ };
224
+ const fieldError = error || cardNumberError || cardExpiryError || cardCvcError;
225
+ return (_jsxs("div", { className: 'shared-stripe-checkout-dialog', "data-node-id": '7368:460', children: [_jsxs("div", { className: 'shared-stripe-checkout-header', children: [_jsxs("div", { className: 'shared-stripe-checkout-heading', children: [_jsx("h2", { id: 'shared-stripe-checkout-title', children: title }), _jsx("p", { children: summaryTitle })] }), _jsx("button", { type: 'button', className: 'shared-stripe-checkout-close', onClick: onClose, "aria-label": closeAriaLabel, children: "\u00D7" })] }), _jsxs("div", { className: 'shared-stripe-checkout-summary', children: [summaryRows.map((row) => (_jsxs("div", { className: 'shared-stripe-checkout-summary-row', children: [_jsx("span", { children: row.label }), _jsx("strong", { className: row.tone === 'positive'
226
+ ? 'is-positive'
227
+ : row.tone === 'negative'
228
+ ? 'is-negative'
229
+ : undefined, children: row.value })] }, row.id))), _jsxs("div", { className: 'shared-stripe-checkout-summary-total', children: [_jsx("span", { children: totalLabel }), _jsx("strong", { children: totalValue })] }), summaryNote ? (_jsx("p", { className: 'shared-stripe-checkout-summary-note', children: summaryNote })) : null] }), _jsxs("form", { className: 'shared-stripe-checkout-form', onSubmit: (event) => void handleSubmit(event), children: [_jsxs("div", { className: 'shared-stripe-checkout-wallet-shell', children: [walletAvailable !== true ? (_jsx(ApplePaySubscribeButton, { className: 'shared-stripe-checkout-wallet-placeholder', disabled: walletFallbackDisabled, label: walletPlaceholderLabel })) : null, walletCheckoutAllowed ? (_jsx(StripeExpressCheckoutButton, { amountCents: amountCents, beforeConfirm: ensureCustomerEmail, summaryLabel: summaryLabel, returnUrl: returnUrl, customerEmail: resolvedCustomerEmail, customerName: customerName, className: 'shared-stripe-checkout-wallet-button', onAvailabilityChange: setWalletAvailable, onError: setSharedError })) : null] }), _jsxs("div", { className: 'shared-stripe-checkout-card-surface', children: [_jsxs("div", { className: 'shared-stripe-checkout-field-group shared-stripe-checkout-field-group--wide', children: [_jsx("p", { className: 'shared-stripe-checkout-field-label', children: customerEmailLabel }), _jsx("div", { className: 'shared-stripe-checkout-field shared-stripe-checkout-field--wide', children: _jsx("input", { type: 'email', inputMode: 'email', autoComplete: 'email', className: [
230
+ 'shared-stripe-checkout-text-input',
231
+ customerEmailEditable ? '' : 'is-readonly',
232
+ ]
233
+ .filter(Boolean)
234
+ .join(' '), value: resolvedCustomerEmail, placeholder: customerEmailPlaceholder, disabled: !customerEmailEditable, onChange: (event) => {
235
+ setEmailDraft(event.target.value);
236
+ onCustomerEmailChange === null || onCustomerEmailChange === void 0 ? void 0 : onCustomerEmailChange(event.target.value);
237
+ setSharedError(null);
238
+ } }) })] }), _jsxs("div", { className: 'shared-stripe-checkout-field-group shared-stripe-checkout-field-group--wide', children: [_jsx("p", { className: 'shared-stripe-checkout-field-label', children: "Card number" }), _jsxs("div", { className: 'shared-stripe-checkout-field shared-stripe-checkout-field--wide shared-stripe-checkout-field--card-number', children: [_jsx(CardNumberElement, { options: cardNumberElementOptions, onChange: (event) => {
239
+ handleFieldError(event, setCardNumberError, setCardNumberComplete);
240
+ } }), _jsx("div", { className: 'shared-stripe-checkout-card-number-brands', "aria-hidden": 'true', children: cardFieldBrandLabels.map((label) => (_jsx(PaymentBrandMark, { label: label, className: 'shared-stripe-checkout-brand shared-stripe-checkout-brand--card' }, label))) })] })] }), _jsxs("div", { className: 'shared-stripe-checkout-field-row', children: [_jsxs("div", { className: 'shared-stripe-checkout-field-group', children: [_jsx("p", { className: 'shared-stripe-checkout-field-label', children: "Expiration date" }), _jsx("div", { className: 'shared-stripe-checkout-field', children: _jsx(CardExpiryElement, { options: cardExpiryElementOptions, onChange: (event) => {
241
+ handleFieldError(event, setCardExpiryError, setCardExpiryComplete);
242
+ } }) })] }), _jsxs("div", { className: 'shared-stripe-checkout-field-group', children: [_jsx("p", { className: 'shared-stripe-checkout-field-label', children: "Security code" }), _jsx("div", { className: 'shared-stripe-checkout-field', children: _jsx(CardCvcElement, { options: cardCvcElementOptions, onChange: (event) => {
243
+ handleFieldError(event, setCardCvcError, setCardCvcComplete);
244
+ } }) })] })] })] }), fieldError ? _jsx("p", { className: 'shared-stripe-checkout-error', children: fieldError }) : null, _jsx("button", { type: 'submit', className: 'shared-stripe-checkout-submit', disabled: !canSubmit, children: submitting ? processingLabel : submitLabel }), _jsxs("div", { className: 'shared-stripe-checkout-trust', children: [_jsxs("p", { className: 'shared-stripe-checkout-secure', children: [_jsx(SecurityLockIcon, { className: 'shared-stripe-checkout-secure-icon' }), _jsx("span", { children: secureLabel })] }), _jsxs("p", { className: 'shared-stripe-checkout-powered', children: [poweredByText ? _jsx("span", { children: poweredByText }) : null, showsStripeWordmark ? (_jsx(StripeWordmark, { className: 'shared-stripe-checkout-powered-mark' })) : null] })] }), paymentMethodLabels.length > 0 ? (_jsx("div", { className: 'shared-stripe-checkout-brands', "aria-hidden": 'true', children: paymentMethodLabels.map((label) => (_jsx(PaymentBrandMark, { label: label, className: 'shared-stripe-checkout-brand' }, label))) })) : null, legalNotice ? (_jsx("div", { className: 'shared-stripe-checkout-legal', children: legalNotice })) : null, renewalNotice ? (_jsx("div", { className: 'shared-stripe-checkout-renewal', children: renewalNotice })) : null] })] }));
245
+ }
246
+ export function SharedStripeCheckoutDialog(_a) {
247
+ var { clientSecret, onClose, stripePromise } = _a, props = __rest(_a, ["clientSecret", "onClose", "stripePromise"]);
248
+ useEffect(() => {
249
+ const handleKeyDown = (event) => {
250
+ if (event.key === 'Escape') {
251
+ onClose();
252
+ }
253
+ };
254
+ window.addEventListener('keydown', handleKeyDown);
255
+ return () => window.removeEventListener('keydown', handleKeyDown);
256
+ }, [onClose]);
257
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: 'shared-stripe-checkout-overlay', role: 'presentation', onClick: onClose, children: _jsx("div", { className: 'shared-stripe-checkout-shell', role: 'dialog', "aria-modal": 'true', "aria-labelledby": 'shared-stripe-checkout-title', onClick: (event) => event.stopPropagation(), children: _jsx(Elements, { stripe: stripePromise, options: {
258
+ clientSecret,
259
+ }, children: _jsx(SharedStripeCheckoutForm, Object.assign({}, props, { clientSecret: clientSecret, onClose: onClose })) }) }) }), _jsx("style", { children: sharedStripeCheckoutDialogStyles })] }));
260
+ }
261
+ const sharedStripeCheckoutDialogStyles = `
262
+ .shared-stripe-checkout-overlay {
263
+ position: fixed;
264
+ inset: 0;
265
+ z-index: 100;
266
+ display: flex;
267
+ align-items: center;
268
+ justify-content: center;
269
+ overflow: hidden;
270
+ padding: 12px;
271
+ background: rgb(17 24 39 / 55%);
272
+ backdrop-filter: blur(4px);
273
+ }
274
+
275
+ .shared-stripe-checkout-shell {
276
+ width: min(100%, 428px);
277
+ max-height: calc(100svh - 24px);
278
+ display: flex;
279
+ }
280
+
281
+ .shared-stripe-checkout-dialog {
282
+ width: 100%;
283
+ max-height: calc(100svh - 24px);
284
+ display: flex;
285
+ flex-direction: column;
286
+ overflow: hidden;
287
+ border-radius: 16px;
288
+ background: #fff;
289
+ padding: 20px 20px 16px;
290
+ color: #111827;
291
+ box-shadow: 0 24px 80px rgb(17 24 39 / 18%);
292
+ }
293
+
294
+ .shared-stripe-checkout-header {
295
+ display: flex;
296
+ align-items: flex-start;
297
+ justify-content: space-between;
298
+ gap: 16px;
299
+ flex: none;
300
+ }
301
+
302
+ .shared-stripe-checkout-heading {
303
+ display: flex;
304
+ flex-direction: column;
305
+ gap: 4px;
306
+ }
307
+
308
+ .shared-stripe-checkout-heading h2 {
309
+ margin: 0;
310
+ color: #111827;
311
+ font-family: Sora, Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
312
+ font-size: 24px;
313
+ font-weight: 700;
314
+ line-height: 1.2;
315
+ }
316
+
317
+ .shared-stripe-checkout-heading p {
318
+ margin: 0;
319
+ color: #6b7280;
320
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
321
+ font-size: 14px;
322
+ font-weight: 600;
323
+ line-height: 1.4;
324
+ }
325
+
326
+ .shared-stripe-checkout-close {
327
+ width: 36px;
328
+ height: 36px;
329
+ border: 0;
330
+ border-radius: 999px;
331
+ background: #f3f4f6;
332
+ color: #6b7280;
333
+ font-size: 24px;
334
+ line-height: 1;
335
+ cursor: pointer;
336
+ }
337
+
338
+ .shared-stripe-checkout-summary {
339
+ margin-top: 16px;
340
+ padding-bottom: 12px;
341
+ border-bottom: 1px solid #e5e7eb;
342
+ display: flex;
343
+ flex-direction: column;
344
+ gap: 10px;
345
+ flex: none;
346
+ }
347
+
348
+ .shared-stripe-checkout-summary-row,
349
+ .shared-stripe-checkout-summary-total {
350
+ display: flex;
351
+ align-items: center;
352
+ justify-content: space-between;
353
+ gap: 12px;
354
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
355
+ font-size: 14px;
356
+ line-height: 1.4;
357
+ }
358
+
359
+ .shared-stripe-checkout-summary-row span,
360
+ .shared-stripe-checkout-summary-total span {
361
+ color: #374151;
362
+ }
363
+
364
+ .shared-stripe-checkout-summary-row strong,
365
+ .shared-stripe-checkout-summary-total strong {
366
+ color: #111827;
367
+ font-weight: 700;
368
+ }
369
+
370
+ .shared-stripe-checkout-summary-row .is-positive {
371
+ color: #10b981;
372
+ }
373
+
374
+ .shared-stripe-checkout-summary-row .is-negative {
375
+ color: #fb7d75;
376
+ }
377
+
378
+ .shared-stripe-checkout-summary-total {
379
+ padding-top: 10px;
380
+ border-top: 1px solid #e5e7eb;
381
+ }
382
+
383
+ .shared-stripe-checkout-summary-note {
384
+ margin: 8px 0 0;
385
+ color: #111827;
386
+ text-align: center;
387
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
388
+ font-size: 12px;
389
+ font-weight: 600;
390
+ line-height: 1.45;
391
+ }
392
+
393
+ .shared-stripe-checkout-form {
394
+ min-height: 0;
395
+ display: flex;
396
+ flex-direction: column;
397
+ gap: 14px;
398
+ margin-top: 14px;
399
+ overflow-y: auto;
400
+ padding-right: 2px;
401
+ scrollbar-width: none;
402
+ }
403
+
404
+ .shared-stripe-checkout-form::-webkit-scrollbar {
405
+ display: none;
406
+ }
407
+
408
+ .shared-stripe-checkout-wallet-shell {
409
+ position: relative;
410
+ min-height: 64px;
411
+ }
412
+
413
+ .shared-stripe-checkout-wallet-button {
414
+ width: 100%;
415
+ }
416
+
417
+ .shared-stripe-checkout-wallet-placeholder {
418
+ min-height: 64px;
419
+ }
420
+
421
+ .shared-stripe-checkout-card-surface {
422
+ display: flex;
423
+ flex-direction: column;
424
+ gap: 14px;
425
+ }
426
+
427
+ .shared-stripe-checkout-field-group {
428
+ display: flex;
429
+ flex-direction: column;
430
+ gap: 7px;
431
+ }
432
+
433
+ .shared-stripe-checkout-field-label {
434
+ margin: 0;
435
+ color: #374151;
436
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
437
+ font-size: 14px;
438
+ font-weight: 600;
439
+ line-height: 1.4;
440
+ }
441
+
442
+ .shared-stripe-checkout-field-row {
443
+ display: grid;
444
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
445
+ gap: 12px;
446
+ }
447
+
448
+ .shared-stripe-checkout-field {
449
+ position: relative;
450
+ min-height: 50px;
451
+ box-sizing: border-box;
452
+ border: 1px solid #d1d5db;
453
+ border-radius: 16px;
454
+ background: #fff;
455
+ padding: 13px 14px;
456
+ }
457
+
458
+ .shared-stripe-checkout-text-input {
459
+ width: 100%;
460
+ border: 0;
461
+ padding: 0;
462
+ background: transparent;
463
+ color: #111827;
464
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
465
+ font-size: 16px;
466
+ font-weight: 500;
467
+ line-height: 1.35;
468
+ outline: none;
469
+ }
470
+
471
+ .shared-stripe-checkout-text-input::placeholder {
472
+ color: #9ca3af;
473
+ }
474
+
475
+ .shared-stripe-checkout-text-input.is-readonly:disabled {
476
+ opacity: 1;
477
+ cursor: default;
478
+ -webkit-text-fill-color: #111827;
479
+ }
480
+
481
+ .shared-stripe-checkout-field--wide {
482
+ min-height: 50px;
483
+ }
484
+
485
+ .shared-stripe-checkout-field--card-number {
486
+ padding-right: 96px;
487
+ }
488
+
489
+ .shared-stripe-checkout-card-number-brands {
490
+ position: absolute;
491
+ top: 50%;
492
+ right: 14px;
493
+ display: flex;
494
+ align-items: center;
495
+ gap: 4px;
496
+ transform: translateY(-50%);
497
+ }
498
+
499
+ .shared-stripe-checkout-error {
500
+ margin: -4px 0 0;
501
+ color: #c43737;
502
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
503
+ font-size: 13px;
504
+ line-height: 1.4;
505
+ }
506
+
507
+ .shared-stripe-checkout-submit {
508
+ min-height: 52px;
509
+ flex: none;
510
+ border: 0;
511
+ border-radius: 16px;
512
+ background: #10b981;
513
+ color: #fff;
514
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
515
+ font-size: 16px;
516
+ font-weight: 800;
517
+ letter-spacing: 0.01em;
518
+ cursor: pointer;
519
+ }
520
+
521
+ .shared-stripe-checkout-submit:disabled {
522
+ cursor: not-allowed;
523
+ opacity: 0.68;
524
+ }
525
+
526
+ .shared-stripe-checkout-trust {
527
+ width: 100%;
528
+ display: flex;
529
+ align-items: center;
530
+ justify-content: space-between;
531
+ gap: 18px;
532
+ flex-wrap: nowrap;
533
+ flex: none;
534
+ }
535
+
536
+ .shared-stripe-checkout-secure,
537
+ .shared-stripe-checkout-powered {
538
+ margin: 0;
539
+ display: inline-flex;
540
+ align-items: center;
541
+ gap: 6px;
542
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
543
+ font-size: 11px;
544
+ line-height: 1.35;
545
+ }
546
+
547
+ .shared-stripe-checkout-secure {
548
+ color: #374151;
549
+ font-weight: 500;
550
+ min-width: 0;
551
+ }
552
+
553
+ .shared-stripe-checkout-secure span {
554
+ text-decoration-line: underline;
555
+ text-decoration-color: #1d9bf0;
556
+ text-decoration-thickness: 2px;
557
+ text-underline-offset: 3px;
558
+ white-space: nowrap;
559
+ }
560
+
561
+ .shared-stripe-checkout-secure-icon {
562
+ width: 14px;
563
+ height: 14px;
564
+ flex: none;
565
+ }
566
+
567
+ .shared-stripe-checkout-powered {
568
+ color: #6b7280;
569
+ font-weight: 500;
570
+ flex: none;
571
+ white-space: nowrap;
572
+ }
573
+
574
+ .shared-stripe-checkout-powered-mark {
575
+ width: 52px;
576
+ height: 20px;
577
+ flex: none;
578
+ }
579
+
580
+ .shared-stripe-checkout-brands {
581
+ display: flex;
582
+ flex-wrap: nowrap;
583
+ justify-content: center;
584
+ gap: 6px;
585
+ overflow: visible;
586
+ padding-bottom: 0;
587
+ flex: none;
588
+ }
589
+
590
+ .shared-stripe-checkout-brand {
591
+ width: 34px;
592
+ height: 16px;
593
+ }
594
+
595
+ .shared-stripe-checkout-brand-mark {
596
+ display: inline-flex;
597
+ align-items: center;
598
+ justify-content: center;
599
+ }
600
+
601
+ .shared-stripe-checkout-brand-mark svg {
602
+ display: block;
603
+ width: auto;
604
+ max-width: 100%;
605
+ height: 100%;
606
+ }
607
+
608
+ .shared-stripe-checkout-brands .shared-stripe-checkout-brand path[stroke='black'] {
609
+ stroke: #e6edf7;
610
+ }
611
+
612
+ .shared-stripe-checkout-brands .shared-stripe-checkout-brand path[fill='white'] {
613
+ fill: #f4f9ff;
614
+ }
615
+
616
+ .shared-stripe-checkout-brands .shared-stripe-checkout-brand:last-child svg path:first-of-type {
617
+ fill: #111;
618
+ }
619
+
620
+ .shared-stripe-checkout-brands .shared-stripe-checkout-brand:last-child svg path:nth-of-type(2) {
621
+ display: none;
622
+ }
623
+
624
+ .shared-stripe-checkout-brands .shared-stripe-checkout-brand:last-child svg path:not(:first-of-type) {
625
+ fill: #fff;
626
+ }
627
+
628
+ .shared-stripe-checkout-brand--card {
629
+ width: 30px;
630
+ height: 18px;
631
+ }
632
+
633
+ .shared-stripe-checkout-brand-fallback {
634
+ display: inline-flex;
635
+ align-items: center;
636
+ justify-content: center;
637
+ height: 100%;
638
+ padding: 0 8px;
639
+ border: 1px solid #d1d5db;
640
+ border-radius: 999px;
641
+ color: #6b7280;
642
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
643
+ font-size: 11px;
644
+ font-weight: 700;
645
+ line-height: 1;
646
+ white-space: nowrap;
647
+ }
648
+
649
+ .shared-stripe-checkout-legal,
650
+ .shared-stripe-checkout-renewal {
651
+ color: #6b7280;
652
+ font-family: Manrope, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
653
+ font-size: 11px;
654
+ line-height: 1.5;
655
+ }
656
+
657
+ .shared-stripe-checkout-legal :is(a) {
658
+ color: #111827;
659
+ font-weight: 700;
660
+ }
661
+
662
+ .shared-stripe-checkout-renewal strong {
663
+ color: #111827;
664
+ }
665
+
666
+ @media (max-width: 429px) {
667
+ .shared-stripe-checkout-overlay {
668
+ padding: 8px;
669
+ }
670
+
671
+ .shared-stripe-checkout-shell,
672
+ .shared-stripe-checkout-dialog {
673
+ max-height: calc(100svh - 16px);
674
+ }
675
+
676
+ .shared-stripe-checkout-dialog {
677
+ padding: 18px 14px 14px;
678
+ }
679
+
680
+ .shared-stripe-checkout-heading h2 {
681
+ font-size: 22px;
682
+ }
683
+
684
+ .shared-stripe-checkout-field-row {
685
+ gap: 8px;
686
+ }
687
+
688
+ .shared-stripe-checkout-trust {
689
+ gap: 8px;
690
+ }
691
+
692
+ .shared-stripe-checkout-secure,
693
+ .shared-stripe-checkout-powered {
694
+ gap: 6px;
695
+ font-size: 10px;
696
+ }
697
+
698
+ .shared-stripe-checkout-secure-icon {
699
+ width: 13px;
700
+ height: 13px;
701
+ }
702
+
703
+ .shared-stripe-checkout-powered-mark {
704
+ width: 48px;
705
+ height: 18px;
706
+ }
707
+
708
+ .shared-stripe-checkout-brands {
709
+ gap: 5px;
710
+ }
711
+
712
+ .shared-stripe-checkout-brand {
713
+ width: 30px;
714
+ height: 14px;
715
+ }
716
+ }
717
+ `;