@lockerverse/react 0.2.20 → 0.2.22
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 +10 -72
- package/dist/index.d.ts +44 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +137 -720
- package/package.json +3 -5
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# `@lockerverse/react`
|
|
2
2
|
|
|
3
|
-
React payment UI
|
|
3
|
+
React payment UI powered by Stripe Custom Checkout Sessions. The host owns
|
|
4
|
+
Product selection; this package renders and completes the payment step.
|
|
4
5
|
|
|
5
6
|
## Install
|
|
6
7
|
|
|
@@ -23,11 +24,8 @@ export function Checkout() {
|
|
|
23
24
|
name: "Auburn Community",
|
|
24
25
|
}}
|
|
25
26
|
communitySlug="auburn"
|
|
26
|
-
onPaymentComplete={(
|
|
27
|
-
console.info("
|
|
28
|
-
}}
|
|
29
|
-
onPaymentUncertain={({ paymentReference, reason }) => {
|
|
30
|
-
console.info("Payment needs status recovery", paymentReference, reason);
|
|
27
|
+
onPaymentComplete={(result) => {
|
|
28
|
+
console.info("Checkout complete", result.paymentReference);
|
|
31
29
|
}}
|
|
32
30
|
selection={[{ productSlug: "adult", quantity: 1 }]}
|
|
33
31
|
theme="dark"
|
|
@@ -37,70 +35,10 @@ export function Checkout() {
|
|
|
37
35
|
}
|
|
38
36
|
```
|
|
39
37
|
|
|
40
|
-
For
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<LockerversePayment
|
|
44
|
-
apiBaseUrl="https://portal-dev.lockerverse.com/api"
|
|
45
|
-
communitySlug="luis-c"
|
|
46
|
-
environment="development"
|
|
47
|
-
selection={[{ productSlug: "adult", quantity: 1 }]}
|
|
48
|
-
widgetSlug="new-payment-widget"
|
|
49
|
-
/>
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Styling
|
|
53
|
-
|
|
54
|
-
Use `theme="dark"` or `theme="light"`. Brand the default UI with `branding.accentColor`, or override its CSS variables through `style` or a scoped stylesheet.
|
|
55
|
-
|
|
56
|
-
```tsx
|
|
57
|
-
<LockerversePayment
|
|
58
|
-
// ...checkout props
|
|
59
|
-
style={{
|
|
60
|
-
"--lockerverse-accent": "#ff6b35",
|
|
61
|
-
"--lockerverse-radius": "14px",
|
|
62
|
-
}}
|
|
63
|
-
/>
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
The package keeps React, React DOM, and Stripe's React libraries as peer dependencies so it does not ship duplicate framework code. It does not render product selectors or depend on Lockerverse's Next.js application components.
|
|
67
|
-
|
|
68
|
-
## Payment outcomes
|
|
69
|
-
|
|
70
|
-
`onPaymentComplete` runs only after Lockerverse reports `success`. A successful payment is terminal, even if the host callback throws.
|
|
71
|
-
|
|
72
|
-
If the authoritative total, discount, currency, line items, or connected Stripe account changes, the component displays the new quote before creating a Stripe token. The customer must explicitly submit again.
|
|
73
|
-
|
|
74
|
-
An authoritative `failed` result is retryable and the next submit receives a new payment reference. `pending`, unresolved `action_required`, and failed same-reference recovery stay locked so the customer cannot accidentally create a second payment. The optional `onPaymentUncertain` callback receives the retained `paymentReference` and one of these reasons:
|
|
75
|
-
|
|
76
|
-
- `pending`
|
|
77
|
-
- `action_required`
|
|
78
|
-
- `recovery_failed`
|
|
79
|
-
|
|
80
|
-
To abandon a locked attempt and intentionally start a new checkout, the host must remount `LockerversePayment` with a new React `key` after resolving the payment status through its own workflow.
|
|
81
|
-
|
|
82
|
-
Persist `onPaymentRecoveryChange` synchronously before navigation and pass the saved value back through `resumePayment` after a refresh. The recovery value contains a Lockerverse reference and public connected-account ID, never a Stripe secret.
|
|
83
|
-
|
|
84
|
-
```tsx
|
|
85
|
-
import type { LockerversePaymentRecovery } from "@lockerverse/react";
|
|
86
|
-
|
|
87
|
-
const recoveryKey = "lockerverse:tailgate-party:payment";
|
|
88
|
-
const savedRecovery = sessionStorage.getItem(recoveryKey);
|
|
89
|
-
const recovery = savedRecovery
|
|
90
|
-
? (JSON.parse(savedRecovery) as LockerversePaymentRecovery)
|
|
91
|
-
: null;
|
|
92
|
-
|
|
93
|
-
<LockerversePayment
|
|
94
|
-
// ...checkout props
|
|
95
|
-
resumePayment={recovery}
|
|
96
|
-
onPaymentRecoveryChange={(nextRecovery) => {
|
|
97
|
-
if (nextRecovery) {
|
|
98
|
-
sessionStorage.setItem(recoveryKey, JSON.stringify(nextRecovery));
|
|
99
|
-
} else {
|
|
100
|
-
sessionStorage.removeItem(recoveryKey);
|
|
101
|
-
}
|
|
102
|
-
}}
|
|
103
|
-
/>
|
|
104
|
-
```
|
|
38
|
+
For development, provide both `environment="development"` and `apiBaseUrl`.
|
|
39
|
+
The component supports dark and light themes, an accent color, CSS variables,
|
|
40
|
+
and host CSS. It intentionally does not render Product selection.
|
|
105
41
|
|
|
106
|
-
|
|
42
|
+
The package uses Stripe's React Checkout Elements directly. React, React DOM,
|
|
43
|
+
and Stripe libraries are peer dependencies, so consuming applications do not
|
|
44
|
+
receive duplicate framework copies.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { CreateLockerverseWidgetOptions, LockerverseCatalog, LockerverseCustomFieldAnswer } from "@lockerverse/sdk/checkout";
|
|
2
|
+
import { loadStripe } from "@stripe/stripe-js/pure/index.js";
|
|
3
|
+
import { CSSProperties, ComponentPropsWithoutRef, PropsWithChildren } from "react";
|
|
4
4
|
//#region src/types.d.ts
|
|
5
5
|
type LockerversePaymentSelectionItem = {
|
|
6
6
|
amountCents: number;
|
|
@@ -15,44 +15,64 @@ type LockerversePaymentBranding = {
|
|
|
15
15
|
imageUrl?: string | null;
|
|
16
16
|
name: string;
|
|
17
17
|
};
|
|
18
|
+
type LockerversePaymentCompletion = {
|
|
19
|
+
paymentReference: string;
|
|
20
|
+
sessionId: string;
|
|
21
|
+
};
|
|
18
22
|
type LockerversePaymentStyle = CSSProperties & {
|
|
19
23
|
"--lockerverse-accent"?: string;
|
|
20
24
|
"--lockerverse-accent-contrast"?: string;
|
|
21
25
|
"--lockerverse-bg"?: string;
|
|
22
26
|
"--lockerverse-border"?: string;
|
|
23
27
|
"--lockerverse-control"?: string;
|
|
24
|
-
"--lockerverse-danger"?: string;
|
|
25
|
-
"--lockerverse-danger-border"?: string;
|
|
26
28
|
"--lockerverse-font-family"?: string;
|
|
27
29
|
"--lockerverse-muted"?: string;
|
|
28
|
-
"--lockerverse-placeholder"?: string;
|
|
29
30
|
"--lockerverse-radius"?: string;
|
|
30
|
-
"--lockerverse-subtle"?: string;
|
|
31
31
|
"--lockerverse-text"?: string;
|
|
32
32
|
};
|
|
33
|
-
type LockerversePaymentUncertain = {
|
|
34
|
-
paymentReference: string;
|
|
35
|
-
reason: "action_required" | "pending" | "recovery_failed";
|
|
36
|
-
};
|
|
37
|
-
type LockerversePaymentRecovery = {
|
|
38
|
-
connectedAccountId: string | null;
|
|
39
|
-
paymentReference: string;
|
|
40
|
-
};
|
|
41
|
-
type LockerverseStripeLoader = (...args: Parameters<typeof loadStripe>) => ReturnType<typeof loadStripe>;
|
|
42
33
|
type LockerversePaymentProps = CreateLockerverseWidgetOptions & Omit<ComponentPropsWithoutRef<"section">, "children" | "onError"> & {
|
|
43
34
|
branding?: LockerversePaymentBranding;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
resumePayment?: LockerversePaymentRecovery | null;
|
|
35
|
+
includeServiceFee?: boolean;
|
|
36
|
+
onPaymentComplete?: (result: LockerversePaymentCompletion) => void;
|
|
37
|
+
returnUrl?: string;
|
|
48
38
|
selection: LockerversePaymentSelectionItem[];
|
|
49
|
-
|
|
39
|
+
unstable_stripeLoader?: typeof loadStripe;
|
|
50
40
|
style?: LockerversePaymentStyle;
|
|
51
41
|
theme?: LockerversePaymentTheme;
|
|
42
|
+
tipCents?: number;
|
|
52
43
|
};
|
|
53
44
|
//#endregion
|
|
54
|
-
//#region src/
|
|
55
|
-
|
|
45
|
+
//#region src/checkout-session-payment.d.ts
|
|
46
|
+
type CheckoutSessionStripeLoader = typeof loadStripe;
|
|
47
|
+
type LockerverseCheckoutSessionProviderProps = CreateLockerverseWidgetOptions & PropsWithChildren<{
|
|
48
|
+
accentColor?: string;
|
|
49
|
+
email?: string;
|
|
50
|
+
includeServiceFee?: boolean;
|
|
51
|
+
returnUrl: string;
|
|
52
|
+
selection: LockerversePaymentSelectionItem[];
|
|
53
|
+
unstable_stripeLoader?: CheckoutSessionStripeLoader;
|
|
54
|
+
theme?: "dark" | "light";
|
|
55
|
+
tipCents?: number;
|
|
56
|
+
}>;
|
|
57
|
+
type CheckoutContextValue = {
|
|
58
|
+
applyPromoCode: (promoCode: string) => Promise<string | null>;
|
|
59
|
+
catalog: LockerverseCatalog;
|
|
60
|
+
confirm: (contact: {
|
|
61
|
+
customFieldAnswers?: LockerverseCustomFieldAnswer[];
|
|
62
|
+
email: string;
|
|
63
|
+
memberId?: string;
|
|
64
|
+
merchSize?: "XS" | "S" | "M" | "L" | "XL" | "XXL" | "XXXL";
|
|
65
|
+
phone?: string;
|
|
66
|
+
}) => Promise<LockerversePaymentCompletion>;
|
|
67
|
+
paymentReference: string;
|
|
68
|
+
totalCents: number;
|
|
69
|
+
};
|
|
70
|
+
declare function LockerverseCheckoutSessionProvider(props: LockerverseCheckoutSessionProviderProps): import("react").JSX.Element;
|
|
71
|
+
declare function useLockerverseCheckoutSession(): CheckoutContextValue;
|
|
72
|
+
declare function LockerverseCheckoutSessionPaymentForm({ onComplete }: {
|
|
73
|
+
onComplete?: (result: LockerversePaymentCompletion) => void;
|
|
74
|
+
}): import("react").JSX.Element;
|
|
75
|
+
declare function LockerversePayment(props: LockerversePaymentProps): import("react").JSX.Element;
|
|
56
76
|
//#endregion
|
|
57
|
-
export { LockerversePayment, type LockerversePaymentBranding, type
|
|
77
|
+
export { LockerverseCheckoutSessionPaymentForm, LockerverseCheckoutSessionProvider, type LockerverseCheckoutSessionProviderProps, LockerversePayment, type LockerversePaymentBranding, type LockerversePaymentCompletion, type LockerversePaymentProps, type LockerversePaymentSelectionItem, type LockerversePaymentStyle, type LockerversePaymentTheme, useLockerverseCheckoutSession };
|
|
58
78
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/checkout-session-payment.tsx"],"mappings":";;;;KAIY;EACN;EAAqB;;EACrB;EAAqB;;KAEf;KAEA;EACV;EACA;EACA;;KAGU;EACV;EACA;;KAGU,0BAA0B;EACpC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,0BAA0B,iCACpC,KAAK;EACH,WAAW;EACX;EACA,qBAAqB,QAAQ;EAC7B;EACA,WAAW;EACX,+BAA+B;EAC/B,QAAQ;EACR,QAAQ;EACR;;;;KCRC,qCAAqC;KAE9B,0CACV,iCACE;EACE;EACA;EACA;EACA;EACA,WAAW;EACX,wBAAwB;EACxB;EACA;;KAUD;EACH,iBAAiB,sBAAsB;EACvC,SAAS;EACT,UAAU;IACR,qBAAqB;IACrB;IACA;IACA;IACA;QACI,QAAQ;EACd;EACA;;iBAqHc,mCACd,OAAO,0DAAuC,IAAA;iBA8KhC,iCAA6B;iBAyI7B,wCACd;EAEA,cAAc,QAAQ;oBACvB,IAAA;iBAiMe,mBAAmB,OAAO,0CAAuB,IAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{AddressElement as e,Elements as t,PaymentElement as n,useElements as r,useStripe as i}from"@stripe/react-stripe-js";import{loadStripe as a}from"@stripe/stripe-js/pure/index.js";import{createContext as o,useContext as s,useEffect as c,useId as l,useMemo as u,useReducer as d,useRef as f,useState as p}from"react";import{Select as m}from"@base-ui/react/select";import{Fragment as h,jsx as g,jsxs as _}from"react/jsx-runtime";import{LockerverseSdkError as v,createLockerverseCheckoutClient as y}from"@lockerverse/sdk/checkout";import{array as b,email as x,minLength as S,minValue as C,nonEmpty as w,number as T,object as E,pipe as D,regex as O,safeInteger as k,safeParse as A,strictObject as j,string as M,trim as N,union as ee}from"valibot";const P=/^#([\da-f]{3}|[\da-f]{6})$/i;function F(e){let t=P.exec(e.trim());if(!t)return;let[,n]=t;if(!n)return;let r=n.length===3?Array.from(n,e=>`${e}${e}`).join(``):n;return[0,2,4].map(e=>Number.parseInt(r.slice(e,e+2),16))}function I([e,t,n]){let[r=0,i=0,a=0]=[e,t,n].map((e=0)=>{let t=e/255;return t<=.04045?t/12.92:((t+.055)/1.055)**2.4});return .2126*r+.7152*i+.0722*a}function te(e){let t=F(e);if(!t)return;let n=I(t);return(n+.05)/.05>=1.05/(n+.05)?`#000`:`#fff`}const L=o(void 0);function ne({children:e,container:t}){return g(L.Provider,{value:t,children:e})}function re(){return g(`svg`,{"aria-hidden":`true`,fill:`none`,viewBox:`0 0 16 16`,children:g(`path`,{d:`m4 6 4 4 4-4`})})}function R(){return g(`svg`,{"aria-hidden":`true`,fill:`none`,viewBox:`0 0 16 16`,children:g(`path`,{d:`m3 8 3 3 7-7`})})}function z({ariaDescribedBy:e,ariaLabel:t,ariaLabelledBy:n,className:r,id:i,invalid:a=!1,name:o,onValueChange:c,options:l,value:u}){let d=s(L),f=[`lockerverse-payment__select`,r].filter(Boolean).join(` `);return g(`div`,{className:f,children:_(m.Root,{id:i,items:l,name:o,onValueChange:e=>{e!==null&&c(e)},value:u,children:[_(m.Trigger,{"aria-describedby":e,"aria-invalid":a||void 0,"aria-label":t,"aria-labelledby":n,className:`lockerverse-payment__select-trigger`,children:[g(m.Value,{}),g(m.Icon,{"aria-hidden":`true`,className:`lockerverse-payment__select-icon`,children:g(re,{})})]}),g(m.Portal,{container:d,children:g(m.Positioner,{alignItemWithTrigger:!1,className:`lockerverse-payment__select-positioner`,sideOffset:6,children:g(m.Popup,{className:`lockerverse-payment__select-popup`,children:g(m.List,{className:`lockerverse-payment__select-list`,children:l.map(e=>_(m.Item,{className:`lockerverse-payment__select-item`,value:e.value,children:[g(m.ItemText,{children:e.label}),g(m.ItemIndicator,{"aria-hidden":`true`,className:`lockerverse-payment__select-item-indicator`,children:g(R,{})})]},e.value))})})})})]})})}const B=[`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`],ie=[`15`,`12`,`10`,`5`],V=[...ie,`custom`];function ae({enabled:e,error:t,errorId:n,onChange:r,values:i}){if(!e)return null;let a=e=>r({...i,...e}),o=(e,t)=>{let n=V.indexOf(t),r;switch(e.key){case`ArrowDown`:case`ArrowRight`:r=(n+1)%V.length;break;case`ArrowLeft`:case`ArrowUp`:r=(n-1+V.length)%V.length;break;case`Home`:r=0;break;case`End`:r=V.length-1;break;default:return}e.preventDefault();let i=V[r];i&&((e.currentTarget.closest(`[role="radiogroup"]`)?.querySelectorAll(`input[type="radio"]`))?.[r]?.focus(),a({tipPercent:i}))};return _(`div`,{className:`lockerverse-payment__tip-box`,children:[g(`p`,{children:`Add a tip to support the Lockerverse platform`}),_(`div`,{"aria-label":`Tip amount`,role:`radiogroup`,children:[ie.map(e=>_(`label`,{className:`lockerverse-payment__tip-choice`,children:[g(`input`,{checked:i.tipPercent===e,name:`tipPercent`,onChange:()=>a({tipPercent:e}),onKeyDown:t=>o(t,e),tabIndex:i.tipPercent===e?0:-1,type:`radio`,value:e}),_(`span`,{children:[e,`%`]})]},e)),_(`label`,{className:`lockerverse-payment__tip-choice`,children:[g(`input`,{checked:i.tipPercent===`custom`,name:`tipPercent`,onChange:()=>a({tipPercent:`custom`}),onKeyDown:e=>o(e,`custom`),tabIndex:i.tipPercent===`custom`?0:-1,type:`radio`,value:`custom`}),g(`span`,{children:`Other`})]})]}),i.tipPercent===`custom`?_(`label`,{children:[g(`span`,{children:`Custom tip`}),_(`span`,{className:`lockerverse-payment__money-input`,children:[g(`span`,{"aria-hidden":`true`,children:`$`}),g(`input`,{"aria-describedby":t?n:void 0,"aria-invalid":t?`true`:void 0,inputMode:`decimal`,name:`tip`,onChange:e=>a({customTip:e.currentTarget.value}),placeholder:`0.00`,value:i.customTip})]}),t?g(`span`,{className:`lockerverse-payment__field-message`,id:n,children:t}):null]}):g(`input`,{name:`tip`,type:`hidden`,value:i.tipPercent})]})}function oe({checked:e,children:t,name:n,onChange:r}){return _(`label`,{className:`lockerverse-payment__check-row`,children:[g(`input`,{checked:e,name:n,onChange:e=>r(e.currentTarget.checked),type:`checkbox`}),g(`span`,{children:t})]})}function se({customFields:e,errors:t,fields:n,idPrefix:r,onChange:i,values:a}){let o=e=>i({...a,...e});return _(`div`,{className:`lockerverse-payment__additional-fields`,children:[n.memberId?_(`label`,{children:[g(`span`,{children:`Member ID`}),g(`input`,{name:`memberId`,onChange:e=>o({memberId:e.currentTarget.value}),placeholder:`Optional`,value:a.memberId})]}):null,n.merchSize?_(`div`,{className:`lockerverse-payment__field`,children:[g(`span`,{id:`${r}-merch-size-label`,children:`Size`}),g(z,{ariaLabelledBy:`${r}-merch-size-label`,name:`merchSize`,onValueChange:e=>o({merchSize:e}),options:B.map(e=>({label:e,value:e})),value:a.merchSize})]}):null,n.promoCode?_(`label`,{children:[g(`span`,{children:`Promo code`}),g(`input`,{name:`promoCode`,onChange:e=>o({promoCode:e.currentTarget.value}),placeholder:`Optional`,value:a.promoCode})]}):null,e.map(e=>g(le,{error:t[e.id],field:e,idPrefix:r,onChange:t=>o({customFields:{...a.customFields,[e.id]:t}}),value:a.customFields[e.id]},e.id))]})}function ce({amountCents:e,enabled:t,onChange:n,values:r}){return t?_(oe,{checked:r.includeServiceFee,name:`includeServiceFee`,onChange:e=>n({...r,includeServiceFee:e}),children:[`Add `,W(e),` to help cover processing fees`]}):null}function le({error:e,field:t,idPrefix:n,onChange:r,value:i}){let a=`custom:${t.id}`,o=`${n}-custom-${t.id}`,s=`${o}-error`;switch(t.type){case`text`:case`textarea`:return g(ue,{controlId:o,error:e,errorId:s,field:t,name:a,onChange:r,value:i});case`select`:case`multi_select`:return g(U,{controlId:o,error:e,errorId:s,field:t,name:a,onChange:r,value:i});case`radio`:case`checkboxes`:return g(de,{controlId:o,error:e,errorId:s,field:t,name:a,onChange:r,value:i});default:return null}}function H({error:e,id:t}){return e?g(`p`,{className:`lockerverse-payment__field-message`,id:t,children:e}):null}function ue({controlId:e,error:t,errorId:n,field:r,name:i,onChange:a,value:o}){let s={"aria-describedby":t?n:void 0,"aria-invalid":t?`true`:void 0,id:e,name:i,onChange:e=>a(e.currentTarget.value),required:r.required,value:typeof o==`string`?o:``};return _(`label`,{htmlFor:e,children:[g(`span`,{children:r.label}),r.type===`textarea`?g(`textarea`,{...s}):g(`input`,{...s}),g(H,{error:t,id:n})]})}function U({controlId:e,error:t,errorId:n,field:r,name:i,onChange:a,value:o}){return _(`label`,{htmlFor:e,children:[g(`span`,{children:r.label}),_(`select`,{"aria-describedby":t?n:void 0,"aria-invalid":t?`true`:void 0,id:e,multiple:r.type===`multi_select`,name:i,onChange:e=>a(r.type===`multi_select`?[...e.currentTarget.selectedOptions].map(e=>e.value):e.currentTarget.value),required:r.required,value:o??(r.type===`multi_select`?[]:``),children:[r.type===`select`?g(`option`,{value:``,children:`Select…`}):null,r.options.map(e=>g(`option`,{value:e.id,children:e.label},e.id))]}),g(H,{error:t,id:n})]})}function de({controlId:e,error:t,errorId:n,field:r,name:i,onChange:a,value:o}){return _(`fieldset`,{"aria-describedby":t?n:void 0,"aria-invalid":t?`true`:void 0,children:[g(`legend`,{children:r.label}),r.options.map((t,n)=>{let s=Array.isArray(o)?o.includes(t.id):o===t.id;return _(`label`,{className:`lockerverse-payment__check-row`,children:[g(`input`,{checked:s,id:`${e}-${n}`,name:i,onChange:e=>{if(r.type===`radio`){a(t.id);return}let n=Array.isArray(o)?o:[];a(e.currentTarget.checked?[...n,t.id]:n.filter(e=>e!==t.id))},required:r.required,type:r.type===`radio`?`radio`:`checkbox`,value:t.id}),g(`span`,{children:t.label})]},t.id)}),g(H,{error:t,id:n})]})}function W(e){return new Intl.NumberFormat(`en-US`,{currency:`USD`,style:`currency`}).format(e/100)}const G=[`amountCents`,`discountableSubtotalCents`,`discountCents`,`serviceFeeCents`,`subtotalCents`,`tipCents`,`totalCents`];function K(e,t){return G.some(n=>e[n]!==t[n])||e.payment.connectedAccountId!==t.payment.connectedAccountId||e.payment.currency!==t.payment.currency||JSON.stringify(e.appliedDiscount)!==JSON.stringify(t.appliedDiscount)||JSON.stringify(e.lineItems)!==JSON.stringify(t.lineItems)}function q(e){return e.checkoutStatus===`success`?{kind:`success`,payment:e}:e.checkoutStatus===`failed`?{kind:`failed`,payment:e}:{kind:`unresolved`,paymentReference:e.paymentReference,reason:e.checkoutStatus===`action_required`?`action_required`:`pending`}}async function fe(e,t,n){if(t.checkoutStatus!==`action_required`)return q(t);if(t.clientSecret)try{await n.handleNextAction({clientSecret:t.clientSecret})}catch{}try{return q(await e.getPaymentStatus(t.paymentReference))}catch{return{kind:`unresolved`,paymentReference:t.paymentReference,reason:`action_required`}}}async function pe(e,t,n){let r;try{r=await e.submitPayment(t)}catch(n){if(!(n instanceof v&&n.recoveryRecommended))throw n;try{r=await e.getPaymentStatus(t.checkout.paymentReference)}catch{return{kind:`unresolved`,paymentReference:t.checkout.paymentReference,reason:`recovery_failed`}}}return fe(e,r,n)}async function me(e,t,n){try{return fe(e,await e.getPaymentStatus(t),n)}catch{return{kind:`unresolved`,paymentReference:t,reason:`recovery_failed`}}}const he=D(M(),N(),w()),ge=D(T(),k(),C(1)),J=D(b(ee([j({amountCents:ge,productSlug:he}),j({productSlug:he,quantity:ge})])),S(1)),Y=D(M(),N(),O(/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/,`Enter a valid tip amount.`));function X(e){let t=A(Y,e);if(!t.success)return{message:t.issues[0]?.message??`Enter a valid tip amount.`,success:!1};let[n=`0`,r=``]=t.output.split(`.`),i=BigInt(n)*100n+BigInt(r.padEnd(2,`0`));return i>BigInt(2**53-1)?{message:`Enter a valid tip amount.`,success:!1}:{cents:Number(i),success:!0}}function _e(e){let t=A(J,e);return t.success?{success:!0,value:t.output}:{message:`Lockerverse payment configuration is invalid.`,success:!1}}const ve=D(M(),N(),w(`Email is required.`),x(`Enter a valid email address.`)),ye=D(M(),N(),w(`Phone is required.`),O(/^\+[1-9]\d{6,14}$/,`Enter a valid phone number.`));function Z(e){return e.trim().replace(/[().\s-]/g,``)}function be(e,t){let n=t?{...e,phone:Z(e.phone)}:e,r=E(t?{email:ve,phone:ye}:{email:ve}),i=A(r,n);if(i.success)return{errors:{},value:i.output};let a={};for(let e of i.issues){let t=e.path?.[0]?.key;(t===`email`||t===`phone`)&&!a[t]&&(a[t]=e.message)}return{errors:a,value:null}}function xe(e,t){let n={};for(let r of e){if(!r.required)continue;let e=`${r.label} is required.`,i=t[r.id],a=r.type===`checkboxes`||r.type===`multi_select`?A(D(b(M()),S(1,e)),i??[]):A(D(M(),N(),w(e)),typeof i==`string`?i:``);a.success||(n[r.id]=a.issues[0]?.message??e)}return n}function Se(e,t){switch(t.type){case`loading`:return{configuration:t.configuration,phase:`loading`,revision:e.revision,selectionKey:t.selectionKey};case`ready`:return{catalog:t.catalog,checkoutItems:t.checkoutItems,client:t.client,configuration:t.configuration,phase:`ready`,preparedCheckout:t.preparedCheckout,revision:e.revision+1,selectionKey:t.selectionKey};case`error`:return{configuration:t.configuration,failure:t.failure,phase:`error`,revision:e.revision,selectionKey:t.selectionKey};case`checkout`:return e.phase===`ready`?{...e,preparedCheckout:t.preparedCheckout}:e;case`retry`:return{phase:`idle`,revision:e.revision+1};default:return e}}function Ce(e,t){if(`amountCents`in t){if(e.pricingMode!==`custom`)throw TypeError(`Fixed-price Products do not accept custom amounts.`);if(e.minimumAmountCents!==null&&t.amountCents<e.minimumAmountCents)throw TypeError(`Product amount must be at least ${e.minimumAmountCents} cents.`);return{amountCents:t.amountCents,productId:e.id}}if(e.pricingMode!==`fixed`)throw TypeError(`Custom-amount Products do not accept quantities.`);if(e.minimumQuantity!==null&&t.quantity<e.minimumQuantity)throw TypeError(`Product quantity must be at least ${e.minimumQuantity}.`);if(e.maximumQuantity!==null&&t.quantity>e.maximumQuantity)throw TypeError(`Product quantity must not exceed ${e.maximumQuantity}.`);if(e.inventoryQuantity!==null&&t.quantity>e.inventoryQuantity)throw TypeError(`Requested Product quantity is unavailable.`);return{productId:e.id,quantity:t.quantity}}function we(e,t){if(t.length===0)throw TypeError(`Lockerverse payment requires at least one Product.`);return t.map(t=>{let n=e.products.find(e=>e.slug===t.productSlug);if(!n)throw TypeError(`Product ${t.productSlug} is not available.`);return Ce(n,t)})}function Te(e,t){let{apiBaseUrl:n,communitySlug:r,environment:i,fetch:a,requestTimeoutMs:o,sentryDsn:s,widgetSlug:c}=e,l={communitySlug:r,widgetSlug:c,...a?{fetch:a}:{},...t?{onError:t}:{},...o===void 0?{}:{requestTimeoutMs:o},...s===void 0?{}:{sentryDsn:s}};if(n===void 0){if(i===`development`)throw TypeError(`Lockerverse development checkout requires an API base URL.`);return{...l,...i===`production`?{environment:i}:{}}}if(!i)throw TypeError(`Lockerverse development checkout requires an environment.`);return{...l,apiBaseUrl:n,environment:i}}function Ee(e,t,n){return e?.configuration===t&&e.selectionKey===n}function De({apiBaseUrl:e,communitySlug:t,environment:n,fetch:r,onError:i,paymentState:a,requestTimeoutMs:o,selection:s,sentryDsn:l,widgetSlug:p}){let m=u(()=>({apiBaseUrl:e,communitySlug:t,environment:n,fetch:r,requestTimeoutMs:o,sentryDsn:l,widgetSlug:p}),[e,t,n,r,o,l,p]),h=_e(s),g=h.success?JSON.stringify(h.value):`invalid-selection`,_=u(()=>h.success?JSON.parse(g):[],[h.success,g]),[v,b]=d(Se,{phase:`idle`,revision:0}),x=f(void 0),S=f(void 0),C=f(i);return C.current=i,c(()=>{if(!h.success||a===`submitting`||a===`success`||a===`unresolved`||Ee(S.current,m,g)||Ee(x.current,m,g))return;let e=!0,t={configuration:m,selectionKey:g};x.current=t,b({configuration:m,selectionKey:g,type:`loading`});async function n(){try{let n=y(Te(m,e=>C.current?.(e))),r=await n.load(),i=we(r,_),a=await n.calculateTotal({...r.widget.fields.serviceFee?{includeServiceFee:!0}:{},items:i});e&&(x.current=void 0,S.current=t,b({catalog:r,checkoutItems:i,client:n,configuration:m,preparedCheckout:a,selectionKey:g,type:`ready`}))}catch(n){e&&(x.current=void 0,S.current=t,b({configuration:m,failure:n instanceof Error?n.message:`Lockerverse payment could not load.`,selectionKey:g,type:`error`}))}}return n(),()=>{e=!1,Ee(x.current,m,g)&&(x.current=void 0)}},[m,h.success,a,g,v.revision,_]),{retryCheckout:()=>{x.current=void 0,S.current=void 0,b({type:`retry`})},selectionError:h.success?void 0:h.message,session:v,updateCheckout:e=>b({preparedCheckout:e,type:`checkout`})}}function Q(e){return new Intl.NumberFormat(`en-US`,{currency:`USD`,style:`currency`}).format(e/100)}function Oe(e,t){return t.tipPercent===`custom`?X(t.customTip):{cents:Math.round(e*Number(t.tipPercent)/100),success:!0}}const ke=[{callingCode:`+1`,label:`🇺🇸 +1`,value:`US`},{callingCode:`+52`,label:`🇲🇽 +52`,value:`MX`},{callingCode:`+380`,label:`🇺🇦 +380`,value:`UA`},{callingCode:`+48`,label:`🇵🇱 +48`,value:`PL`},{callingCode:`+1`,label:`🇨🇦 +1`,value:`CA`},{callingCode:`+49`,label:`🇩🇪 +49`,value:`DE`},{callingCode:`+44`,label:`🇬🇧 +44`,value:`GB`},{callingCode:`+46`,label:`🇸🇪 +46`,value:`SE`},{callingCode:`+358`,label:`🇫🇮 +358`,value:`FI`},{callingCode:`+1`,label:`🇵🇷 +1`,value:`PR`}];function Ae(e,t){return e.trim().startsWith(`+`)?e:`${ke.find(e=>e.value===t)?.callingCode??`+1`}${e}`}function je(e,t){return e.map(e=>{let n=t[e.id];return e.type===`checkboxes`||e.type===`multi_select`?{fieldId:e.id,value:Array.isArray(n)?n:[]}:{fieldId:e.id,value:typeof n==`string`?n:``}})}function Me(e,t,n,r){return{email:n,...e.widget.fields.serviceFee?{includeServiceFee:t.includeServiceFee}:{},...e.widget.fields.promoCode&&t.promoCode.trim()?{promoCode:t.promoCode.trim()}:{},...e.widget.fields.tipping?{tipCents:r}:{}}}async function Ne(e,t){let n=e.getElement(`address`,{mode:t}),r=t===`billing`?`Billing`:`Shipping`;if(!n)throw Error(`${r} address is still loading.`);let i=await n.getValue();if(!i.complete)throw Error(`${r} address is required.`);return i.value}function Pe(e,t,n,r){if(e.widget.fields.shipping)return n.shippingMatchesBilling?r:Ne(t,`shipping`)}function Fe({billingAddress:e,catalog:t,email:n,phone:r,shippingAddress:i}){return{payment_method_data:{billing_details:{address:e.address,email:n,name:e.name,...t.widget.fields.phone?{phone:r}:{}}},...i?{shipping:{address:i.address,name:i.name,phone:t.widget.fields.phone?r:i.phone??null}}:{}}}function Ie({catalog:e,confirmationToken:t,email:n,fieldValues:r,phone:i}){return{confirmationToken:t,customFieldAnswers:je(e.widget.customFields,r.customFields),email:n,...e.widget.fields.memberId&&r.memberId.trim()?{memberId:r.memberId.trim()}:{},...e.widget.fields.merchSize?{merchSize:r.merchSize}:{},...e.widget.fields.phone?{phone:i}:{}}}async function Le({catalog:e,checkoutItems:t,client:n,elements:r,email:i,fieldValues:a,onPaymentRecoveryChange:o,phone:s,quote:c,stripe:l}){let u=i.trim().toLowerCase(),d=Z(s),f=Oe(c.subtotalCents,a);if(!f.success)throw Error(f.message);let p=Me(e,a,u,f.cents),m=await n.calculateTotal({...p,items:t});if(await r.update({amount:m.totalCents}),K(c,m))return{kind:`quote_changed`,quote:m};let h=await r.submit();if(h.error)throw Error(h.error.message);let g=await Ne(r,`billing`),_=await Pe(e,r,a,g),v=await l.createConfirmationToken({elements:r,params:Fe({billingAddress:g,catalog:e,email:u,phone:d,shippingAddress:_})});if(v.error)throw Error(v.error.message);$(o,{connectedAccountId:m.payment.connectedAccountId,paymentReference:m.paymentReference});let y=await pe(n,{checkout:m,submission:Ie({catalog:e,confirmationToken:v.confirmationToken.id,email:u,fieldValues:a,phone:d})},l);return y.kind===`failed`?{kind:`payment_failed`,message:`Payment was declined. Check your payment details and try again.`}:y.kind===`unresolved`?{kind:`payment_unresolved`,paymentReference:y.paymentReference,reason:y.reason}:{kind:`payment`,payment:y.payment,quote:m}}function Re({accentColor:e,catalog:n,checkoutItems:r,client:i,fontFamily:a,onPaymentComplete:o,onPaymentRecoveryChange:s,onPaymentUncertain:c,onQuoteChange:l,quote:d,resumePayment:f,onStateChange:p,stripeLoader:m,theme:h,visualStyle:_}){let v=f?f.connectedAccountId:d.payment.connectedAccountId,y=u(()=>m(n.payment.publishableKey,v?{stripeAccount:v}:void 0),[n.payment.publishableKey,v,m]);return g(t,{options:{amount:d.totalCents,appearance:{rules:{".Input:focus":{borderColor:e,boxShadow:`0 0 0 1px ${e}`,outline:`none`}},theme:h===`light`?`stripe`:`night`,variables:{borderRadius:_?.[`--lockerverse-radius`]??`10px`,colorBackground:_?.[`--lockerverse-control`]??(h===`light`?`#f5f6f7`:`#121212`),colorDanger:_?.[`--lockerverse-danger`]??(h===`light`?`#c52b3e`:`#f08a98`),colorPrimary:e,colorText:_?.[`--lockerverse-text`]??(h===`light`?`#121416`:`#ffffff`),colorTextPlaceholder:_?.[`--lockerverse-placeholder`]??(h===`light`?`#72767d`:`#6b6b6b`),colorTextSecondary:_?.[`--lockerverse-muted`]??(h===`light`?`#62666d`:`#a1a1aa`),focusBoxShadow:`none`,focusOutline:`none`,fontFamily:a,fontSizeBase:`16px`}},currency:d.payment.currency,excludedPaymentMethodTypes:[`us_bank_account`],mode:`payment`,syncAddressCheckbox:`none`},stripe:y,children:g(Ke,{catalog:n,checkoutItems:r,client:i,onPaymentComplete:o,onPaymentRecoveryChange:s,onPaymentUncertain:c,onQuoteChange:l,onStateChange:p,quote:d,resumePayment:f})},`${n.payment.publishableKey}:${v??`platform`}`)}function ze({label:e}){return _(`div`,{className:`lockerverse-payment__stripe-loader`,role:`status`,children:[g(`p`,{children:e}),_(`div`,{"aria-hidden":`true`,children:[g(`span`,{}),g(`span`,{}),g(`span`,{})]})]})}function Be({onError:e,onReady:t,ready:r}){return _(`div`,{className:`lockerverse-payment__stripe-element`,"data-ready":r,children:[r?null:g(ze,{label:`Loading payment form...`}),g(`div`,{className:`lockerverse-payment__stripe-mount`,children:g(n,{onLoadError:({error:t})=>e(t.message??`Payment form failed to load.`),onReady:t,options:{business:{name:`Lockerverse`},fields:{billingDetails:{address:`never`,email:`never`,name:`never`,phone:`never`}},layout:`tabs`,terms:{applePay:`auto`,auBecsDebit:`never`,bancontact:`never`,card:`always`,cashapp:`never`,googlePay:`never`,ideal:`never`,paypal:`auto`,sepaDebit:`never`,sofort:`never`,usBankAccount:`never`},wallets:{applePay:`auto`,googlePay:`never`}}})})]})}function Ve({label:t,mode:n,onError:r,onReady:i,ready:a}){return _(`div`,{className:`lockerverse-payment__address`,children:[g(`h2`,{children:t}),_(`div`,{className:`lockerverse-payment__stripe-element lockerverse-payment__stripe-element--address`,"data-ready":a,children:[a?null:g(ze,{label:`Loading ${t.toLowerCase()}...`}),g(`div`,{className:`lockerverse-payment__stripe-mount`,children:g(e,{onLoadError:({error:e})=>r(e.message??`${t} failed to load.`),onReady:i,options:{autocomplete:{mode:`automatic`},mode:n}})})]})]})}function He({message:e}){return e?g(`p`,{className:`lockerverse-payment__field-message`,role:`alert`,children:e}):null}function $(e,t){try{e?.(t)}catch{}}function Ue({customFieldErrors:e,emailRef:t,form:n,parsedTipSuccess:r,phoneRef:i,validationErrors:a}){if(a.email){t.current?.focus();return}if(a.phone){i.current?.focus();return}if(!r){n.querySelector(`[name="tip"]`)?.focus();return}let[o]=Object.keys(e);o&&n.querySelector(`[name="custom:${o}"]`)?.focus()}function We({onPaymentComplete:e,onPaymentRecoveryChange:t,onPaymentUncertain:n,onQuoteChange:r,onStateChange:i,result:a,setDisplayedTotalCents:o,setPaymentError:s,setTerminalState:c}){if(a.kind===`quote_changed`){let e=`The total changed to ${Q(a.quote.totalCents)}. Review it and pay again.`;r(a.quote,e),o(a.quote.totalCents),i(`idle`);return}if(a.kind===`payment_failed`){$(t,null),s(a.message),i(`error`);return}if(a.kind===`payment_unresolved`){c({kind:`unresolved`,message:`Payment is still processing. Do not submit it again.`}),i(`unresolved`);try{n?.({paymentReference:a.paymentReference,reason:a.reason})}catch{}return}r(a.quote),$(t,null),c({kind:`success`,message:`Payment completed successfully.`}),i(`success`);try{e?.(a.payment)}catch{}}function Ge({email:e,emailErrorId:t,emailId:n,emailRef:r,errors:i,onEmailChange:a,onPhoneChange:o,onPhoneCountryChange:s,phone:c,phoneCountry:l,phoneEnabled:u,phoneErrorId:d,phoneId:f,phoneRef:p}){return _(`div`,{className:`lockerverse-payment__contact`,children:[g(`label`,{htmlFor:n,children:`Email`}),g(`input`,{"aria-describedby":i.email?t:void 0,"aria-invalid":i.email?`true`:void 0,autoComplete:`email`,id:n,name:`email`,onChange:e=>a(e.currentTarget.value),placeholder:`name@example.com`,ref:r,type:`email`,value:e}),i.email?g(`p`,{className:`lockerverse-payment__field-message`,id:t,children:i.email}):null,u?_(h,{children:[g(`label`,{htmlFor:f,children:`Phone`}),_(`div`,{className:`lockerverse-payment__phone-control`,children:[g(z,{ariaLabel:`Phone number country`,className:`lockerverse-payment__select--phone-country`,name:`phoneCountry`,onValueChange:s,options:ke,value:l}),g(`input`,{"aria-describedby":i.phone?d:void 0,"aria-invalid":i.phone?`true`:void 0,autoComplete:`tel`,id:f,inputMode:`tel`,name:`phone`,onChange:e=>o(e.currentTarget.value),placeholder:`(201) 555-0123`,ref:p,type:`tel`,value:c})]}),i.phone?g(`p`,{className:`lockerverse-payment__field-message`,id:d,children:i.phone}):null]}):null]})}function Ke({catalog:e,checkoutItems:t,client:n,onPaymentComplete:a,onPaymentRecoveryChange:o,onPaymentUncertain:s,onQuoteChange:u,onStateChange:d,quote:m,resumePayment:h}){let[v,y]=p(``),[b,x]=p(``),[S,C]=p(`US`),[w,T]=p({}),[E,D]=p(),[O,k]=p({}),[A,j]=p(),[M,N]=p(!1),[ee,P]=p(!!h),[F,I]=p(),[te,L]=p(!1),[ne,re]=p(!1),[R,z]=p(!1),[B,ie]=p({customFields:{},customTip:``,includeServiceFee:e.widget.fields.serviceFee,memberId:``,merchSize:`M`,promoCode:``,shippingMatchesBilling:!0,tipPercent:`10`}),[V,le]=p(m.totalCents),H=f(null),ue=f(null),U=f(null),de=f(!1),W=r(),G=i(),K=`lockerverse-${l()}`,q=`${K}-email`,fe=`${q}-error`,pe=`${K}-phone`,he=`${pe}-error`,ge=`${K}-tip-error`,J=e.widget.fields.tipping?Oe(m.subtotalCents,B):{cents:0,success:!0},Y=J.success?J.cents:null,X=Y??0,_e=V-X,ve=!e.widget.fields.shipping||B.shippingMatchesBilling||R;c(()=>{if(Y===null)return;let t=e.widget.fields.serviceFee&&B.includeServiceFee?m.serviceFeeCents||Math.round(m.subtotalCents*e.pricingPolicy.serviceFeeRateBasisPoints/1e4):0,n=m.totalCents-m.serviceFeeCents-m.tipCents+t+Y;le(n),W?.update({amount:n})},[e.widget.fields.serviceFee,e.widget.fields.tipping,W,B.includeServiceFee,B.tipPercent,B.customTip,Y,m.serviceFeeCents,m.tipCents,m.totalCents]),c(()=>{M&&U.current?.focus()},[M]),c(()=>{!(h&&G)||de.current||(de.current=!0,d(`submitting`),me(n,h.paymentReference,G).then(e=>{if(e.kind===`failed`){$(o,null),D(`The previous payment failed. Check your details and try again.`),P(!1),d(`error`);return}if(e.kind===`unresolved`){I({kind:`unresolved`,message:`Payment is still processing. Do not submit it again.`}),d(`unresolved`);try{s?.({paymentReference:e.paymentReference,reason:e.reason})}catch{}return}$(o,null),I({kind:`success`,message:`Payment completed successfully.`}),d(`success`);try{a?.(e.payment)}catch{}}))},[n,a,o,s,d,h,G]);function ye(e){T(t=>{let n={...t};return delete n[e],n})}function Z(e){ie(e),k({}),j(void 0)}function Se(e){D(e),d(`error`)}async function Ce(r){r.preventDefault();let i=be({email:v,phone:Ae(b,S)},e.widget.fields.phone),c=xe(e.widget.customFields,B.customFields);if(!(i.value&&J.success)||Object.keys(c).length>0){T(i.errors),k(c),j(J.success?void 0:J.message),d(`invalid`);let e=r.currentTarget;queueMicrotask(()=>{Ue({customFieldErrors:c,emailRef:H,form:e,parsedTipSuccess:J.success,phoneRef:ue,validationErrors:i.errors})});return}if(T({}),k({}),!(W&&G)){D(`Payment form is still loading.`),d(`error`);return}D(void 0),N(!0),d(`submitting`);try{We({onPaymentComplete:a,onPaymentRecoveryChange:o,onPaymentUncertain:s,onQuoteChange:u,onStateChange:d,result:await Le({catalog:e,checkoutItems:t,client:n,elements:W,email:v,fieldValues:B,onPaymentRecoveryChange:o,phone:Ae(b,S),quote:m,stripe:G}),setDisplayedTotalCents:le,setPaymentError:D,setTerminalState:I})}catch(e){$(o,null),D(e instanceof Error?e.message:`Payment could not be completed.`),d(`error`)}finally{N(!1)}}return F?g(`p`,{className:`lockerverse-payment__payment-status`,ref:U,role:`status`,tabIndex:-1,children:F.message}):ee?g(`p`,{className:`lockerverse-payment__payment-status`,role:`status`,children:`Recovering payment…`}):_(`form`,{"aria-busy":M,className:`lockerverse-payment__form`,noValidate:!0,onSubmit:Ce,children:[g(`div`,{"data-lockerverse-input-region":``,inert:M?!0:void 0,children:_(`fieldset`,{className:`lockerverse-payment__input-fieldset`,disabled:M,children:[g(ae,{enabled:e.widget.fields.tipping,error:A,errorId:ge,onChange:Z,values:B}),g(Ge,{email:v,emailErrorId:fe,emailId:q,emailRef:H,errors:w,onEmailChange:e=>{y(e),ye(`email`)},onPhoneChange:e=>{x(e),ye(`phone`)},onPhoneCountryChange:C,phone:b,phoneCountry:S,phoneEnabled:e.widget.fields.phone,phoneErrorId:he,phoneId:pe,phoneRef:ue}),g(Be,{onError:Se,onReady:()=>L(!0),ready:te}),g(Ve,{label:`Billing address`,mode:`billing`,onError:Se,onReady:()=>re(!0),ready:ne}),e.widget.fields.shipping?_(`div`,{className:`lockerverse-payment__shipping`,children:[g(oe,{checked:B.shippingMatchesBilling,name:`shippingMatchesBilling`,onChange:e=>{Z({...B,shippingMatchesBilling:e}),e||z(!1)},children:`Shipping is same as billing information`}),B.shippingMatchesBilling?null:g(Ve,{label:`Shipping address`,mode:`shipping`,onError:Se,onReady:()=>z(!0),ready:R})]}):null,g(se,{customFields:e.widget.customFields,errors:O,fields:e.widget.fields,idPrefix:K,onChange:Z,values:B}),_(`div`,{className:`lockerverse-payment__actions`,children:[g(ce,{amountCents:m.serviceFeeCents||Math.round(m.subtotalCents*e.pricingPolicy.serviceFeeRateBasisPoints/1e4),enabled:e.widget.fields.serviceFee,onChange:Z,values:B}),g(`button`,{"aria-busy":M,"aria-label":`Process payment for ${Q(V)} total`,disabled:M||!(te&&ne&&ve),type:`submit`,children:M?`Processing…`:`Process Payment (${Q(_e)})${X>0?` + ${Q(X)} tip`:``}`})]})]})}),M?g(`p`,{className:`lockerverse-payment__payment-status`,ref:U,role:`status`,tabIndex:-1,children:`Processing payment…`}):null,g(He,{message:E})]})}function qe(){return _(`div`,{className:`lockerverse-payment__skeleton-loader-block`,children:[g(`span`,{className:`lockerverse-payment__skeleton-loader-label`}),_(`div`,{className:`lockerverse-payment__skeleton-loader-content`,children:[g(`span`,{className:`lockerverse-payment__skeleton-loader-full`}),_(`div`,{className:`lockerverse-payment__skeleton-loader-grid`,children:[g(`span`,{className:`lockerverse-payment__skeleton-loader-half`}),g(`span`,{className:`lockerverse-payment__skeleton-loader-half`})]})]})]})}function Je(){return _(`div`,{className:`lockerverse-payment__loading`,children:[g(`span`,{"aria-live":`polite`,className:`lockerverse-payment__sr-only`,role:`status`,children:`Loading payment…`}),_(`div`,{"aria-hidden":`true`,className:`lockerverse-payment__skeleton`,children:[_(`div`,{className:`lockerverse-payment__skeleton-branding`,children:[g(`span`,{className:`lockerverse-payment__skeleton-avatar`}),g(`span`,{className:`lockerverse-payment__skeleton-community`})]}),_(`div`,{className:`lockerverse-payment__skeleton-contact`,children:[_(`div`,{className:`lockerverse-payment__skeleton-field`,children:[g(`span`,{className:`lockerverse-payment__skeleton-label`}),g(`span`,{className:`lockerverse-payment__skeleton-input`})]}),_(`div`,{className:`lockerverse-payment__skeleton-field`,children:[g(`span`,{className:`lockerverse-payment__skeleton-label`}),g(`span`,{className:`lockerverse-payment__skeleton-input`})]})]}),g(qe,{}),g(qe,{}),_(`div`,{className:`lockerverse-payment__skeleton-actions`,children:[g(`span`,{className:`lockerverse-payment__skeleton-check-line`}),g(`span`,{className:`lockerverse-payment__skeleton-button`})]})]})]})}function Ye({apiBaseUrl:e,branding:t,className:n,communitySlug:r,environment:i,fetch:o,onError:s,onPaymentComplete:l,onPaymentRecoveryChange:u,onPaymentUncertain:d,requestTimeoutMs:m,resumePayment:h,selection:v,sentryDsn:y,style:b,stripeLoader:x=a,theme:S=`dark`,widgetSlug:C,...w}){let T=f(h).current,E=f(null),[D,O]=p(),[k,A]=p(`idle`),{retryCheckout:j,selectionError:M,session:N,updateCheckout:ee}=De({apiBaseUrl:e,communitySlug:r,environment:i,fetch:o,onError:s,paymentState:k,requestTimeoutMs:m,selection:v,sentryDsn:y,widgetSlug:C});c(()=>{N.phase===`loading`&&O(void 0)},[N.phase]),c(()=>{N.phase===`ready`&&A(e=>e===`success`||e===`unresolved`?e:`idle`)},[N.phase,N.revision]);let P=[`lockerverse-payment`,n].filter(Boolean).join(` `),F=te(b?.[`--lockerverse-accent`]??t?.accentColor??`#38d77a`),I={...b,...t?.accentColor&&b?.[`--lockerverse-accent`]===void 0?{"--lockerverse-accent":t.accentColor}:{},...F&&b?.[`--lockerverse-accent-contrast`]===void 0?{"--lockerverse-accent-contrast":F}:{}};if(M)return g(`section`,{...w,className:P,"data-lockerverse-theme":S,role:`alert`,style:I,children:M});if(N.phase===`error`)return _(`section`,{...w,className:P,"data-lockerverse-theme":S,style:I,children:[g(`p`,{role:`alert`,children:N.failure}),g(`button`,{onClick:j,type:`button`,children:`Retry`})]});if(N.phase!==`ready`)return g(`section`,{...w,"aria-busy":`true`,"aria-label":`Payment`,className:P,"data-lockerverse-theme":S,style:I,children:g(Je,{})});let{catalog:L,checkoutItems:re,client:R,preparedCheckout:z}=N;return _(`section`,{...w,"aria-label":`Payment`,className:P,"data-lockerverse-theme":S,"data-payment-state":k,ref:E,style:I,children:[_(`header`,{children:[L.widget.showCommunityBranding&&t?_(`div`,{className:`lockerverse-payment__branding`,children:[t.imageUrl?g(`img`,{alt:t.name,height:`48`,src:t.imageUrl,width:`48`}):null,g(`strong`,{children:t.name})]}):null,g(`h1`,{children:L.widget.title??L.widget.name}),L.widget.description?g(`p`,{children:L.widget.description}):null]}),D?g(`p`,{className:`lockerverse-payment__payment-status`,role:`status`,children:D}):null,g(ne,{container:E,children:g(Re,{accentColor:b?.[`--lockerverse-accent`]??t?.accentColor??`#38d77a`,catalog:L,checkoutItems:re,client:R,fontFamily:b?.[`--lockerverse-font-family`]??`ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,onPaymentComplete:l,onPaymentRecoveryChange:u,onPaymentUncertain:d,onQuoteChange:(e,t)=>{O(t),ee(e)},onStateChange:A,quote:z,resumePayment:T,stripeLoader:x,theme:S,visualStyle:I})})]})}export{Ye as LockerversePayment};
|
|
1
|
+
import{createLockerverseCheckoutClient as e}from"@lockerverse/sdk/checkout";import{BillingAddressElement as t,CheckoutElementsProvider as n,PaymentElement as r,ShippingAddressElement as i,useCheckoutElements as a}from"@stripe/react-stripe-js/checkout";import{loadStripe as o}from"@stripe/stripe-js/pure/index.js";import{createContext as s,useContext as c,useEffect as l,useMemo as u,useRef as d,useState as f}from"react";import{jsx as p,jsxs as m}from"react/jsx-runtime";const h=s(null);function g(e,t){if(!t.length)throw Error(`Select at least one Product before opening checkout.`);return t.map(t=>{let n=e.products.find(e=>e.slug===t.productSlug);if(!n)throw Error(`Product ${t.productSlug} is unavailable.`);return`amountCents`in t?{amountCents:t.amountCents,productId:n.id}:{productId:n.id,quantity:t.quantity}})}function _(e){let t={communitySlug:e.communitySlug,...e.fetch?{fetch:e.fetch}:{},...e.onError?{onError:e.onError}:{},...e.requestTimeoutMs===void 0?{}:{requestTimeoutMs:e.requestTimeoutMs},...e.sentryDsn===void 0?{}:{sentryDsn:e.sentryDsn},widgetSlug:e.widgetSlug};return e.apiBaseUrl?{...t,apiBaseUrl:e.apiBaseUrl,environment:e.environment}:{...t,environment:`production`}}function v({children:e,loaded:t}){let n=a();if(n.type===`loading`)return p(`div`,{role:`status`,children:`Loading secure payment form…`});if(n.type===`error`)return p(`div`,{role:`alert`,children:n.error.message});let{checkout:r}=n,i={async applyPromoCode(e){let n=await r.runServerUpdate(()=>t.client.updateSessionDiscount({paymentReference:t.session.paymentReference,...e.trim()?{promoCode:e.trim()}:{}}));return n.type===`error`?n.error.message:null},catalog:t.catalog,async confirm(e){let n=await r.runServerUpdate(()=>t.client.updateSessionDetails({...e.customFieldAnswers?{customFieldAnswers:e.customFieldAnswers}:{},email:e.email,...e.memberId?{memberId:e.memberId}:{},...e.merchSize?{merchSize:e.merchSize}:{},paymentReference:t.session.paymentReference,...e.phone?{phone:e.phone}:{}}));if(n.type===`error`)throw Error(n.error.message);let i=await x(r,e.email,e.phone??``);if(`error`in i)throw Error(i.error);let a=await r.confirm({email:i.email,...i.phone?{phoneNumber:i.phone}:{},redirect:`if_required`});if(a.type===`error`)throw Error(a.error.message);return{paymentReference:t.session.paymentReference,sessionId:t.session.sessionId}},paymentReference:t.session.paymentReference,totalCents:r.total.total.minorUnitsAmount};return p(h.Provider,{value:i,children:e})}function y(t){let[r,i]=f(null),[a,s]=f(null),[c,h]=f(0),y=d(null),b=JSON.stringify({email:t.email,includeServiceFee:t.includeServiceFee,returnUrl:t.returnUrl,selection:t.selection,tipCents:t.tipCents}),x=d({email:t.email,includeServiceFee:t.includeServiceFee,key:b,requestKey:globalThis.crypto.randomUUID(),returnUrl:t.returnUrl,selection:t.selection,tipCents:t.tipCents}),S=u(()=>_(t),[t.apiBaseUrl,t.communitySlug,t.environment,t.fetch,t.onError,t.requestTimeoutMs,t.sentryDsn,t.widgetSlug]);l(()=>{let t=!0;if(y.current?.clientOptions!==S||c>0){let t=e(S),n=x.current;y.current={clientOptions:S,promise:(async()=>{let e=await t.load(),r=g(e,n.selection),i=n.includeServiceFee??e.widget.fields.serviceFee,a=await t.createSession({...n.email?{email:n.email}:{},...e.widget.fields.serviceFee?{includeServiceFee:i}:{},items:r,requestKey:n.requestKey,returnUrl:n.returnUrl,...n.tipCents===void 0?{}:{tipCents:n.tipCents}});return{catalog:e,client:t,returnUrl:n.returnUrl,session:a}})()}}return i(null),s(null),y.current.promise.then(e=>{t&&i(e)}).catch(e=>{t&&s(e instanceof Error?e.message:`Unable to load checkout.`)}),()=>{t=!1}},[S,c]);let C=u(()=>r?(t.unstable_stripeLoader??o)(r.catalog.payment.publishableKey,{betas:[`custom_checkout_server_updates_1`],...r.session.connectedAccountId?{stripeAccount:r.session.connectedAccountId}:{}}):null,[r,t.unstable_stripeLoader]),w=u(()=>r?{clientSecret:r.session.clientSecret,elementsOptions:{appearance:{theme:t.theme===`light`?`stripe`:`night`,variables:{colorBackground:`transparent`,colorPrimary:t.accentColor??`#38d77a`}}}}:null,[r,t.accentColor,t.theme]);return b===x.current.key?a?m(`div`,{className:`lockerverse-payment__payment-status`,role:`alert`,children:[p(`p`,{children:a}),p(`button`,{onClick:()=>h(e=>e+1),type:`button`,children:`Try again`})]}):r&&w?p(n,{options:w,stripe:C,children:p(v,{loaded:r,children:t.children})}):m(`div`,{className:`lockerverse-payment__loading`,children:[p(`span`,{className:`lockerverse-payment__sr-only`,role:`status`,children:`Preparing secure checkout…`}),m(`div`,{"aria-hidden":`true`,className:`lockerverse-payment__skeleton`,children:[p(`div`,{className:`lockerverse-payment__skeleton-contact`,children:m(`div`,{className:`lockerverse-payment__skeleton-field`,children:[p(`span`,{className:`lockerverse-payment__skeleton-label`}),p(`span`,{className:`lockerverse-payment__skeleton-input`})]})}),m(`div`,{className:`lockerverse-payment__skeleton-loader-block`,children:[p(`span`,{className:`lockerverse-payment__skeleton-loader-label`}),p(`span`,{className:`lockerverse-payment__skeleton-loader-full`})]}),p(`div`,{className:`lockerverse-payment__skeleton-actions`,children:p(`span`,{className:`lockerverse-payment__skeleton-button`})})]})]}):p(`div`,{className:`lockerverse-payment__payment-status`,role:`alert`,children:`Checkout selection changed. Remount this payment component for the new selection.`})}function b(){let e=c(h);if(!e)throw Error(`useLockerverseCheckoutSession must be used inside LockerverseCheckoutSessionProvider.`);return e}async function x(e,t,n){let r=t.trim().toLowerCase();if(!r)return{error:`Email is required.`};let i=await e.updateEmail(r);if(i.type===`error`)return{error:i.error.message};let a=n.trim();if(a&&(await e.updatePhoneNumber(a)).type===`error`)return{error:`Phone number is invalid.`};let o=await e.validateElements();return o.type===`error`?{error:o.error.message}:{email:r,phone:a}}function S({fields:e,onChange:t,values:n}){return e.map(e=>{let r=n[e.id]??(e.type.includes(`multi`)||e.type===`checkboxes`?[]:``);if(e.type===`textarea`)return m(`label`,{children:[p(`span`,{children:e.label}),p(`textarea`,{name:e.id,onChange:n=>t(e.id,n.currentTarget.value),required:e.required,value:String(r)})]},e.id);if(e.type===`select`)return m(`label`,{children:[p(`span`,{children:e.label}),m(`select`,{name:e.id,onChange:n=>t(e.id,n.currentTarget.value),required:e.required,value:String(r),children:[p(`option`,{value:``,children:`Select…`}),e.options.map(e=>p(`option`,{value:e.id,children:e.label},e.id))]})]},e.id);if(e.type===`radio`||e.type===`checkboxes`||e.type===`multi_select`){let n=Array.isArray(r)?r:[r];return m(`fieldset`,{children:[p(`legend`,{children:e.label}),e.options.map(r=>{let i=n.includes(r.id);return m(`label`,{className:`lockerverse-payment__choice`,children:[p(`input`,{checked:i,name:e.id,onChange:()=>{if(e.type===`radio`){t(e.id,r.id);return}t(e.id,i?n.filter(e=>e!==r.id):[...n,r.id])},required:e.required&&n.length===0,type:e.type===`radio`?`radio`:`checkbox`,value:r.id}),p(`span`,{children:r.label})]},r.id)})]},e.id)}return m(`label`,{children:[p(`span`,{children:e.label}),p(`input`,{name:e.id,onChange:n=>t(e.id,n.currentTarget.value),required:e.required,type:`text`,value:String(r)})]},e.id)})}function C({onComplete:e}){let{applyPromoCode:n,catalog:a,confirm:o,totalCents:s}=b(),[c,l]=f(``),[u,d]=f(``),[h,g]=f(``),[_,v]=f(``),[y,x]=f({}),[C,w]=f(``),[T,E]=f(null),[D,O]=f(!1);async function k(){O(!0),E(null);try{E(await n(C))}catch(e){E(e instanceof Error?e.message:`Unable to update checkout.`)}finally{O(!1)}}async function A(t){t.preventDefault(),O(!0),E(null);try{e?.(await o({customFieldAnswers:a.widget.customFields.map(e=>({fieldId:e.id,value:y[e.id]??null})),email:c,...h?{memberId:h}:{},..._?{merchSize:_}:{},...u?{phone:u}:{}}))}catch(e){E(e instanceof Error?e.message:`Unable to complete checkout.`)}finally{O(!1)}}return m(`form`,{className:`lockerverse-payment__form`,onSubmit:A,children:[m(`header`,{children:[p(`h1`,{children:a.widget.title??a.widget.name}),a.widget.description?p(`p`,{children:a.widget.description}):null]}),m(`div`,{className:`lockerverse-payment__contact`,children:[m(`label`,{children:[p(`span`,{children:`Email`}),p(`input`,{autoComplete:`email`,inputMode:`email`,name:`email`,onChange:e=>l(e.currentTarget.value),placeholder:`you@example.com`,required:!0,type:`email`,value:c})]}),a.widget.fields.phone?m(`label`,{children:[p(`span`,{children:`Phone`}),p(`input`,{autoComplete:`tel`,inputMode:`tel`,name:`phone`,onChange:e=>d(e.currentTarget.value),placeholder:`+1 555 555 5555`,required:!0,type:`tel`,value:u})]}):null,a.widget.fields.memberId?m(`label`,{children:[p(`span`,{children:`Member ID`}),p(`input`,{name:`memberId`,onChange:e=>g(e.currentTarget.value),required:!0,type:`text`,value:h})]}):null,a.widget.fields.merchSize?m(`label`,{children:[p(`span`,{children:`Merch size`}),m(`select`,{name:`merchSize`,onChange:e=>v(e.currentTarget.value),required:!0,value:_,children:[p(`option`,{value:``,children:`Select…`}),[`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`].map(e=>p(`option`,{value:e,children:e},e))]})]}):null]}),m(`div`,{className:`lockerverse-payment__address`,children:[p(`h2`,{children:`Billing information`}),p(t,{})]}),a.widget.fields.shipping?m(`div`,{className:`lockerverse-payment__shipping`,children:[p(`h2`,{children:`Shipping information`}),p(i,{})]}):null,m(`div`,{className:`lockerverse-payment__stripe-element`,hidden:s===0,children:[p(`h2`,{children:`Payment details`}),p(r,{})]}),a.widget.fields.promoCode?m(`div`,{className:`lockerverse-payment__additional-fields`,children:[m(`label`,{children:[p(`span`,{children:`Promo code`}),p(`input`,{name:`promoCode`,onChange:e=>w(e.currentTarget.value),placeholder:`Optional`,value:C})]}),p(`button`,{disabled:D,onClick:k,type:`button`,children:C.trim()?`Apply code`:`Remove code`})]}):null,a.widget.customFields.length?p(`div`,{className:`lockerverse-payment__custom-fields`,children:p(S,{fields:a.widget.customFields,onChange:(e,t)=>x(n=>({...n,[e]:t})),values:y})}):null,T?p(`div`,{role:`alert`,children:T}):null,p(`div`,{className:`lockerverse-payment__actions`,children:p(`button`,{disabled:D,type:`submit`,children:s===0?`Complete free order`:`Pay $${(s/100).toFixed(2)}`})})]})}function w(e){let{apiBaseUrl:t,branding:n,className:r,communitySlug:i,environment:a,fetch:o,includeServiceFee:s,onError:c,onPaymentComplete:l,requestTimeoutMs:u,returnUrl:d,selection:f,sentryDsn:h,unstable_stripeLoader:g,style:_,theme:v=`dark`,tipCents:b,widgetSlug:x,...S}=e,w=d??(globalThis.location===void 0?`https://lockerverse.com`:globalThis.location.href),T=[`lockerverse-payment`,r].filter(Boolean).join(` `),E=t?{apiBaseUrl:t,communitySlug:i,environment:a,widgetSlug:x}:{communitySlug:i,environment:`production`,widgetSlug:x},D=n?.accentColor?{..._,"--lockerverse-accent":n.accentColor}:_;return m(`section`,{...S,className:T,"data-lockerverse-theme":v,style:D,children:[n?m(`div`,{className:`lockerverse-payment__branding`,children:[n.imageUrl?p(`img`,{alt:``,height:`48`,src:n.imageUrl,width:`48`}):null,p(`strong`,{children:n.name})]}):null,p(y,{...E,...n?.accentColor?{accentColor:n.accentColor}:{},...o?{fetch:o}:{},...s===void 0?{}:{includeServiceFee:s},...c?{onError:c}:{},...u===void 0?{}:{requestTimeoutMs:u},returnUrl:w,selection:f,...h===void 0?{}:{sentryDsn:h},...g?{unstable_stripeLoader:g}:{},theme:v,...b===void 0?{}:{tipCents:b},children:p(C,{...l?{onComplete:l}:{}})})]})}export{C as LockerverseCheckoutSessionPaymentForm,y as LockerverseCheckoutSessionProvider,w as LockerversePayment,b as useLockerverseCheckoutSession};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|