@lockerverse/react 0.2.56 → 0.2.58
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lockerverse-payment.js","names":["formatMoney","normalizeContactPhone"],"sources":["../src/select-control.tsx","../src/checkout-fields.tsx","../src/payment-attempt.ts","../src/payment-input.ts","../src/payment-validation.ts","../src/payment-workflow.ts","../src/use-payment-checkout.ts","../src/lockerverse-payment.tsx"],"sourcesContent":["import { Select } from \"@base-ui/react/select\";\nimport {\n createContext,\n type ReactNode,\n type RefObject,\n useContext,\n} from \"react\";\n\nexport type LockerverseSelectOption = {\n label: string;\n value: string;\n};\n\nconst SelectPortalContext = createContext<\n RefObject<HTMLElement | null> | undefined\n>(undefined);\n\nexport function SelectPortalProvider({\n children,\n container,\n}: {\n children: ReactNode;\n container: RefObject<HTMLElement | null>;\n}) {\n return (\n <SelectPortalContext.Provider value={container}>\n {children}\n </SelectPortalContext.Provider>\n );\n}\n\nfunction SelectIcon() {\n return (\n <svg aria-hidden=\"true\" fill=\"none\" viewBox=\"0 0 16 16\">\n <path d=\"m4 6 4 4 4-4\" />\n </svg>\n );\n}\n\nfunction SelectedIcon() {\n return (\n <svg aria-hidden=\"true\" fill=\"none\" viewBox=\"0 0 16 16\">\n <path d=\"m3 8 3 3 7-7\" />\n </svg>\n );\n}\n\nexport function LockerverseSelect({\n ariaDescribedBy,\n ariaLabel,\n ariaLabelledBy,\n className,\n id,\n invalid = false,\n name,\n onValueChange,\n options,\n value,\n}: {\n ariaDescribedBy?: string;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n className?: string;\n id?: string;\n invalid?: boolean;\n name: string;\n onValueChange: (value: string) => void;\n options: readonly LockerverseSelectOption[];\n value: string;\n}) {\n const portalContainer = useContext(SelectPortalContext);\n const rootClassName = [\"lockerverse-payment__select\", className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={rootClassName}>\n <Select.Root\n id={id}\n items={options}\n name={name}\n onValueChange={(nextValue) => {\n if (nextValue !== null) {\n onValueChange(nextValue);\n }\n }}\n value={value}\n >\n <Select.Trigger\n aria-describedby={ariaDescribedBy}\n aria-invalid={invalid || undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className=\"lockerverse-payment__select-trigger\"\n >\n <Select.Value />\n <Select.Icon\n aria-hidden=\"true\"\n className=\"lockerverse-payment__select-icon\"\n >\n <SelectIcon />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal container={portalContainer}>\n <Select.Positioner\n alignItemWithTrigger={false}\n className=\"lockerverse-payment__select-positioner\"\n sideOffset={6}\n >\n <Select.Popup className=\"lockerverse-payment__select-popup\">\n <Select.List className=\"lockerverse-payment__select-list\">\n {options.map((option) => (\n <Select.Item\n className=\"lockerverse-payment__select-item\"\n key={option.value}\n value={option.value}\n >\n <Select.ItemText>{option.label}</Select.ItemText>\n <Select.ItemIndicator\n aria-hidden=\"true\"\n className=\"lockerverse-payment__select-item-indicator\"\n >\n <SelectedIcon />\n </Select.ItemIndicator>\n </Select.Item>\n ))}\n </Select.List>\n </Select.Popup>\n </Select.Positioner>\n </Select.Portal>\n </Select.Root>\n </div>\n );\n}\n","import type {\n LockerverseCustomField,\n LockerverseWidgetFields,\n} from \"@lockerverse/sdk/checkout\";\nimport { CustomFields } from \"./custom-fields.tsx\";\nimport { LockerverseSelect } from \"./select-control.tsx\";\n\nexport const MERCH_SIZES = [\"XS\", \"S\", \"M\", \"L\", \"XL\", \"XXL\", \"XXXL\"] as const;\n\nexport type CheckoutFieldValues = {\n customTip: string;\n customFields: Record<string, string | string[]>;\n includeServiceFee: boolean;\n memberId: string;\n merchSize: (typeof MERCH_SIZES)[number];\n promoCode: string;\n shippingMatchesBilling: boolean;\n tipPercent: \"5\" | \"10\" | \"12\" | \"15\" | \"custom\";\n};\n\nconst TIP_OPTIONS = [\"15\", \"12\", \"10\", \"5\"] as const;\nconst TIP_VALUES = [...TIP_OPTIONS, \"custom\"] as const;\n\nexport function TipField({\n enabled,\n error,\n errorId,\n onChange,\n values,\n}: {\n enabled: boolean;\n error: string | undefined;\n errorId: string;\n onChange: (values: CheckoutFieldValues) => void;\n values: CheckoutFieldValues;\n}) {\n if (!enabled) {\n return null;\n }\n const update = (next: Partial<CheckoutFieldValues>) =>\n onChange({ ...values, ...next });\n const handleKeyDown = (\n event: React.KeyboardEvent<HTMLInputElement>,\n currentValue: CheckoutFieldValues[\"tipPercent\"]\n ) => {\n const currentIndex = TIP_VALUES.indexOf(currentValue);\n let nextIndex: number | undefined;\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowRight\":\n nextIndex = (currentIndex + 1) % TIP_VALUES.length;\n break;\n case \"ArrowLeft\":\n case \"ArrowUp\":\n nextIndex = (currentIndex - 1 + TIP_VALUES.length) % TIP_VALUES.length;\n break;\n case \"Home\":\n nextIndex = 0;\n break;\n case \"End\":\n nextIndex = TIP_VALUES.length - 1;\n break;\n default:\n return;\n }\n event.preventDefault();\n const nextValue = TIP_VALUES[nextIndex];\n if (!nextValue) {\n return;\n }\n const radios = event.currentTarget\n .closest('[role=\"radiogroup\"]')\n ?.querySelectorAll<HTMLElement>('input[type=\"radio\"]');\n radios?.[nextIndex]?.focus();\n update({ tipPercent: nextValue });\n };\n return (\n <div className=\"lockerverse-payment__tip-box\">\n <p>Add a tip to support the Lockerverse platform</p>\n <div aria-label=\"Tip amount\" role=\"radiogroup\">\n {TIP_OPTIONS.map((tip) => (\n <label className=\"lockerverse-payment__tip-choice\" key={tip}>\n <input\n checked={values.tipPercent === tip}\n name=\"tipPercent\"\n onChange={() => update({ tipPercent: tip })}\n onKeyDown={(event) => handleKeyDown(event, tip)}\n tabIndex={values.tipPercent === tip ? 0 : -1}\n type=\"radio\"\n value={tip}\n />\n <span>{tip}%</span>\n </label>\n ))}\n <label className=\"lockerverse-payment__tip-choice\">\n <input\n checked={values.tipPercent === \"custom\"}\n name=\"tipPercent\"\n onChange={() => update({ tipPercent: \"custom\" })}\n onKeyDown={(event) => handleKeyDown(event, \"custom\")}\n tabIndex={values.tipPercent === \"custom\" ? 0 : -1}\n type=\"radio\"\n value=\"custom\"\n />\n <span>Other</span>\n </label>\n </div>\n {values.tipPercent === \"custom\" ? (\n <label>\n <span>Custom tip</span>\n <span className=\"lockerverse-payment__money-input\">\n <span aria-hidden=\"true\">$</span>\n <input\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? \"true\" : undefined}\n inputMode=\"decimal\"\n name=\"tip\"\n onChange={(event) =>\n update({ customTip: event.currentTarget.value })\n }\n placeholder=\"0.00\"\n value={values.customTip}\n />\n </span>\n {error ? (\n <span className=\"lockerverse-payment__field-message\" id={errorId}>\n {error}\n </span>\n ) : null}\n </label>\n ) : (\n <input name=\"tip\" type=\"hidden\" value={values.tipPercent} />\n )}\n </div>\n );\n}\n\nexport function CheckoutToggle({\n checked,\n children,\n name,\n onChange,\n}: {\n checked: boolean;\n children: React.ReactNode;\n name: string;\n onChange: (checked: boolean) => void;\n}) {\n return (\n <label className=\"lockerverse-payment__check-row\">\n <input\n checked={checked}\n name={name}\n onChange={(event) => onChange(event.currentTarget.checked)}\n type=\"checkbox\"\n />\n <span>{children}</span>\n </label>\n );\n}\n\nexport function AdditionalCheckoutFields({\n customFields,\n errors,\n fields,\n idPrefix,\n isPromoApplying,\n onChange,\n onApplyPromo,\n promoError,\n values,\n}: {\n customFields: LockerverseCustomField[];\n errors: Record<string, string>;\n fields: LockerverseWidgetFields;\n idPrefix: string;\n isPromoApplying: boolean;\n onChange: (values: CheckoutFieldValues) => void;\n onApplyPromo: () => void;\n promoError: string | undefined;\n values: CheckoutFieldValues;\n}) {\n const update = (next: Partial<CheckoutFieldValues>) =>\n onChange({ ...values, ...next });\n\n return (\n <div className=\"lockerverse-payment__additional-fields\">\n {fields.memberId ? (\n <label>\n <span>Member ID</span>\n <input\n name=\"memberId\"\n onChange={(event) =>\n update({ memberId: event.currentTarget.value })\n }\n placeholder=\"Optional\"\n value={values.memberId}\n />\n </label>\n ) : null}\n {fields.merchSize ? (\n <div className=\"lockerverse-payment__field\">\n <span id={`${idPrefix}-merch-size-label`}>Size</span>\n <LockerverseSelect\n ariaLabelledBy={`${idPrefix}-merch-size-label`}\n name=\"merchSize\"\n onValueChange={(merchSize) =>\n update({\n merchSize: merchSize as CheckoutFieldValues[\"merchSize\"],\n })\n }\n options={MERCH_SIZES.map((size) => ({\n label: size,\n value: size,\n }))}\n value={values.merchSize}\n />\n </div>\n ) : null}\n {fields.promoCode ? (\n <div className=\"lockerverse-payment__field\">\n <span id={`${idPrefix}-promo-code-label`}>Promo code</span>\n <div className=\"lockerverse-payment__promo-control\">\n <input\n aria-describedby={\n promoError ? `${idPrefix}-promo-code-error` : undefined\n }\n aria-invalid={promoError ? \"true\" : undefined}\n aria-labelledby={`${idPrefix}-promo-code-label`}\n name=\"promoCode\"\n onChange={(event) =>\n update({ promoCode: event.currentTarget.value })\n }\n placeholder=\"Optional\"\n value={values.promoCode}\n />\n <button\n disabled={!values.promoCode.trim() || isPromoApplying}\n onClick={onApplyPromo}\n type=\"button\"\n >\n {isPromoApplying ? \"Applying…\" : \"Apply\"}\n </button>\n </div>\n {promoError ? (\n <p\n className=\"lockerverse-payment__field-message\"\n id={`${idPrefix}-promo-code-error`}\n role=\"alert\"\n >\n {promoError}\n </p>\n ) : null}\n </div>\n ) : null}\n <CustomFields\n choiceClassName=\"lockerverse-payment__check-row\"\n errorClassName=\"lockerverse-payment__field-message\"\n errors={errors}\n fields={customFields}\n idPrefix={idPrefix}\n onChange={(nextCustomFields) =>\n update({ customFields: nextCustomFields })\n }\n values={values.customFields}\n />\n </div>\n );\n}\n\nexport function ServiceFeeField({\n amountCents,\n enabled,\n onChange,\n values,\n}: {\n amountCents: number;\n enabled: boolean;\n onChange: (values: CheckoutFieldValues) => void;\n values: CheckoutFieldValues;\n}) {\n if (!enabled) {\n return null;\n }\n return (\n <CheckoutToggle\n checked={values.includeServiceFee}\n name=\"includeServiceFee\"\n onChange={(includeServiceFee) =>\n onChange({ ...values, includeServiceFee })\n }\n >\n Add {formatMoney(amountCents)} to help cover processing fees\n </CheckoutToggle>\n );\n}\n\nfunction formatMoney(amountCents: number) {\n return new Intl.NumberFormat(\"en-US\", {\n currency: \"USD\",\n style: \"currency\",\n }).format(amountCents / 100);\n}\n","import type {\n LockerverseCheckoutClient,\n LockerverseCheckoutQuote,\n LockerversePaymentResult,\n LockerverseSubmitPaymentInput,\n} from \"@lockerverse/sdk/checkout\";\nimport { LockerverseSdkError } from \"@lockerverse/sdk/checkout\";\nimport type { Stripe } from \"@stripe/stripe-js\";\n\nconst AMOUNT_KEYS = [\n \"amountCents\",\n \"discountableSubtotalCents\",\n \"discountCents\",\n \"serviceFeeCents\",\n \"subtotalCents\",\n \"tipCents\",\n \"totalCents\",\n] as const satisfies readonly (keyof LockerverseCheckoutQuote)[];\n\nconst SERVER_CONTROLLED_AMOUNT_KEYS = [\n \"discountableSubtotalCents\",\n \"discountCents\",\n \"subtotalCents\",\n] as const satisfies readonly (keyof LockerverseCheckoutQuote)[];\n\nexport function hasMaterialQuoteChange(\n displayed: LockerverseCheckoutQuote,\n current: LockerverseCheckoutQuote,\n locallyPreviewedTotalCents?: number\n) {\n const amountKeys =\n locallyPreviewedTotalCents === current.totalCents\n ? SERVER_CONTROLLED_AMOUNT_KEYS\n : AMOUNT_KEYS;\n return (\n amountKeys.some((key) => displayed[key] !== current[key]) ||\n displayed.payment.connectedAccountId !==\n current.payment.connectedAccountId ||\n displayed.payment.currency !== current.payment.currency ||\n JSON.stringify(displayed.appliedDiscount) !==\n JSON.stringify(current.appliedDiscount) ||\n JSON.stringify(displayed.lineItems) !== JSON.stringify(current.lineItems)\n );\n}\n\nexport type PaymentAttemptOutcome =\n | { kind: \"failed\"; payment: LockerversePaymentResult }\n | { kind: \"success\"; payment: LockerversePaymentResult }\n | {\n kind: \"unresolved\";\n paymentReference: string;\n reason: \"action_required\" | \"pending\" | \"recovery_failed\";\n };\n\nfunction classifyPayment(\n payment: LockerversePaymentResult\n): PaymentAttemptOutcome {\n if (payment.checkoutStatus === \"success\") {\n return { kind: \"success\", payment };\n }\n if (payment.checkoutStatus === \"failed\") {\n return { kind: \"failed\", payment };\n }\n return {\n kind: \"unresolved\",\n paymentReference: payment.paymentReference,\n reason:\n payment.checkoutStatus === \"action_required\"\n ? \"action_required\"\n : \"pending\",\n };\n}\n\nasync function settleRequiredAction(\n client: LockerverseCheckoutClient,\n payment: LockerversePaymentResult,\n stripe: Stripe | null | undefined\n): Promise<PaymentAttemptOutcome> {\n if (payment.checkoutStatus !== \"action_required\") {\n return classifyPayment(payment);\n }\n if (!stripe) {\n return {\n kind: \"unresolved\",\n paymentReference: payment.paymentReference,\n reason: \"action_required\",\n };\n }\n if (payment.clientSecret) {\n try {\n await stripe.handleNextAction({ clientSecret: payment.clientSecret });\n } catch {\n // Status recovery below is authoritative even when Stripe UI fails.\n }\n }\n try {\n const recovered = await client.getPaymentStatus(payment.paymentReference);\n return classifyPayment(recovered);\n } catch {\n return {\n kind: \"unresolved\",\n paymentReference: payment.paymentReference,\n reason: \"action_required\",\n };\n }\n}\n\nexport async function submitPaymentAttempt(\n client: LockerverseCheckoutClient,\n input: LockerverseSubmitPaymentInput,\n stripe?: Stripe | null\n): Promise<PaymentAttemptOutcome> {\n let payment: LockerversePaymentResult;\n try {\n payment = await client.submitPayment(input);\n } catch (error) {\n if (!(error instanceof LockerverseSdkError && error.recoveryRecommended)) {\n throw error;\n }\n try {\n payment = await client.getPaymentStatus(input.checkout.paymentReference);\n } catch {\n return {\n kind: \"unresolved\",\n paymentReference: input.checkout.paymentReference,\n reason: \"recovery_failed\",\n };\n }\n }\n return settleRequiredAction(client, payment, stripe);\n}\n\nexport async function recoverPaymentAttempt(\n client: LockerverseCheckoutClient,\n paymentReference: string,\n stripe: Stripe\n): Promise<PaymentAttemptOutcome> {\n try {\n const payment = await client.getPaymentStatus(paymentReference);\n return settleRequiredAction(client, payment, stripe);\n } catch {\n return {\n kind: \"unresolved\",\n paymentReference,\n reason: \"recovery_failed\",\n };\n }\n}\n","import {\n array,\n minLength,\n minValue,\n nonEmpty,\n number,\n pipe,\n regex,\n safeInteger,\n safeParse,\n strictObject,\n string,\n trim,\n union,\n} from \"valibot\";\n\nconst productSlugSchema = pipe(string(), trim(), nonEmpty());\nconst positiveSafeIntegerSchema = pipe(number(), safeInteger(), minValue(1));\n\nconst paymentSelectionSchema = pipe(\n array(\n union([\n strictObject({\n amountCents: positiveSafeIntegerSchema,\n productSlug: productSlugSchema,\n }),\n strictObject({\n productSlug: productSlugSchema,\n quantity: positiveSafeIntegerSchema,\n }),\n ])\n ),\n minLength(1)\n);\n\nconst customTipSchema = pipe(\n string(),\n trim(),\n regex(/^(?:0|[1-9]\\d*)(?:\\.\\d{1,2})?$/, \"Enter a valid tip amount.\")\n);\n\nexport function parseCustomTipCents(input: string) {\n const result = safeParse(customTipSchema, input);\n if (!result.success) {\n return {\n message: result.issues[0]?.message ?? \"Enter a valid tip amount.\",\n success: false,\n } as const;\n }\n const [dollars = \"0\", fraction = \"\"] = result.output.split(\".\");\n const cents = BigInt(dollars) * 100n + BigInt(fraction.padEnd(2, \"0\"));\n if (cents > BigInt(Number.MAX_SAFE_INTEGER)) {\n return { message: \"Enter a valid tip amount.\", success: false } as const;\n }\n return { cents: Number(cents), success: true } as const;\n}\n\nexport function parsePaymentSelection(input: unknown) {\n const result = safeParse(paymentSelectionSchema, input);\n return result.success\n ? ({ success: true, value: result.output } as const)\n : ({\n message: \"Lockerverse payment configuration is invalid.\",\n success: false,\n } as const);\n}\n","import { object, safeParse } from \"valibot\";\nimport {\n normalizePhone as normalizeContactPhone,\n requiredEmailSchema,\n requiredPhoneSchema,\n} from \"./contact-validation.ts\";\n\nexport function normalizePhone(input: string) {\n return normalizeContactPhone(input);\n}\n\nexport type ContactErrors = {\n email?: string;\n phone?: string;\n};\n\nexport function validateContact(\n input: { email: string; phone: string },\n requiresPhone: boolean\n) {\n const normalizedInput = requiresPhone\n ? { ...input, phone: normalizePhone(input.phone) }\n : input;\n const schema = requiresPhone\n ? object({ email: requiredEmailSchema, phone: requiredPhoneSchema })\n : object({ email: requiredEmailSchema });\n const result = safeParse(schema, normalizedInput);\n\n if (result.success) {\n return { errors: {} as ContactErrors, value: result.output } as const;\n }\n\n const errors: ContactErrors = {};\n for (const issue of result.issues) {\n const field = issue.path?.[0]?.key;\n if ((field === \"email\" || field === \"phone\") && !errors[field]) {\n errors[field] = issue.message;\n }\n }\n return { errors, value: null } as const;\n}\n","import type {\n LockerversePaymentProps,\n LockerversePaymentUncertain,\n} from \"./types.ts\";\n\ntype EditablePaymentWorkflowState = {\n error?: string;\n phase: \"editing\" | \"invalid\";\n};\n\nexport type PaymentWorkflowState =\n | EditablePaymentWorkflowState\n | {\n phase: \"refreshing_quote\";\n previousError?: string;\n validatePromo: boolean;\n }\n | { phase: \"submitting\" }\n | { phase: \"recovering\" }\n | { message: string; phase: \"succeeded\" }\n | {\n message: string;\n paymentReference: string;\n phase: \"unresolved\";\n reason: LockerversePaymentUncertain[\"reason\"];\n };\n\nexport type PaymentWorkflowEvent =\n | { type: \"field_changed\" }\n | { type: \"validation_failed\" }\n | { type: \"quote_refresh_started\"; validatePromo: boolean }\n | { type: \"quote_refresh_succeeded\" }\n | { error?: string; type: \"quote_refresh_failed\" }\n | { type: \"submission_started\" }\n | { type: \"quote_changed\" }\n | { error: string; type: \"retryable_failure\" }\n | { error: string; type: \"recovery_failed\" }\n | { message: string; type: \"succeeded\" }\n | {\n message: string;\n paymentReference: string;\n reason: LockerversePaymentUncertain[\"reason\"];\n type: \"unresolved\";\n };\n\nexport type PaymentWorkflowUiState =\n | \"error\"\n | \"idle\"\n | \"invalid\"\n | \"submitting\"\n | \"success\"\n | \"unresolved\";\n\nfunction assertNever(value: never): never {\n throw new Error(`Unexpected payment workflow value: ${String(value)}`);\n}\n\nfunction createEditableState(\n phase: EditablePaymentWorkflowState[\"phase\"],\n error?: string\n): EditablePaymentWorkflowState {\n return error === undefined ? { phase } : { error, phase };\n}\n\nexport function createPaymentWorkflowState(\n resumePayment: LockerversePaymentProps[\"resumePayment\"]\n): PaymentWorkflowState {\n return resumePayment ? { phase: \"recovering\" } : { phase: \"editing\" };\n}\n\nexport function getPaymentError(state: PaymentWorkflowState) {\n if (state.phase === \"editing\" || state.phase === \"invalid\") {\n return state.error;\n }\n return state.phase === \"refreshing_quote\" ? state.previousError : undefined;\n}\n\nexport function getPaymentUiState(\n state: PaymentWorkflowState\n): PaymentWorkflowUiState {\n if (state.phase === \"succeeded\") {\n return \"success\";\n }\n if (state.phase === \"unresolved\") {\n return \"unresolved\";\n }\n if (state.phase === \"submitting\" || state.phase === \"recovering\") {\n return \"submitting\";\n }\n if (state.phase === \"invalid\") {\n return \"invalid\";\n }\n return getPaymentError(state) ? \"error\" : \"idle\";\n}\n\nexport function isPaymentBusy(state: PaymentWorkflowState) {\n return state.phase === \"submitting\";\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Explicit cases keep payment transitions auditable.\nexport function paymentWorkflowReducer(\n state: PaymentWorkflowState,\n event: PaymentWorkflowEvent\n): PaymentWorkflowState {\n if (state.phase === \"succeeded\" || state.phase === \"unresolved\") {\n return state;\n }\n\n switch (event.type) {\n case \"field_changed\":\n return state.phase === \"invalid\"\n ? createEditableState(\"editing\", state.error)\n : state;\n case \"validation_failed\":\n return state.phase === \"submitting\" || state.phase === \"recovering\"\n ? state\n : createEditableState(\"invalid\", getPaymentError(state));\n case \"quote_refresh_started\": {\n if (state.phase === \"submitting\" || state.phase === \"recovering\") {\n return state;\n }\n const previousError = getPaymentError(state);\n return {\n ...(previousError === undefined ? {} : { previousError }),\n phase: \"refreshing_quote\",\n validatePromo: event.validatePromo,\n };\n }\n case \"quote_refresh_succeeded\":\n return state.phase === \"refreshing_quote\" ? { phase: \"editing\" } : state;\n case \"quote_refresh_failed\":\n return state.phase === \"refreshing_quote\"\n ? createEditableState(\"editing\", event.error ?? state.previousError)\n : state;\n case \"submission_started\":\n return state.phase === \"recovering\" ? state : { phase: \"submitting\" };\n case \"quote_changed\":\n return state.phase === \"submitting\" ? { phase: \"editing\" } : state;\n case \"retryable_failure\":\n return createEditableState(\"editing\", event.error);\n case \"recovery_failed\":\n return state.phase === \"recovering\"\n ? createEditableState(\"editing\", event.error)\n : state;\n case \"succeeded\":\n return state.phase === \"submitting\" || state.phase === \"recovering\"\n ? { message: event.message, phase: \"succeeded\" }\n : state;\n case \"unresolved\":\n return state.phase === \"submitting\" || state.phase === \"recovering\"\n ? {\n message: event.message,\n paymentReference: event.paymentReference,\n phase: \"unresolved\",\n reason: event.reason,\n }\n : state;\n default:\n return assertNever(event);\n }\n}\n","import type {\n CreateLockerverseWidgetOptions,\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutItem,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport { createLockerverseCheckoutClient } from \"@lockerverse/sdk/checkout\";\nimport { useEffect, useMemo, useReducer, useRef } from \"react\";\nimport { parsePaymentSelection } from \"./payment-input.ts\";\nimport type {\n LockerversePaymentProps,\n LockerversePaymentSelectionItem,\n} from \"./types.ts\";\n\nexport type CheckoutPaymentState =\n | \"error\"\n | \"idle\"\n | \"invalid\"\n | \"submitting\"\n | \"success\"\n | \"unresolved\";\n\ntype CheckoutConfiguration = {\n apiBaseUrl: LockerversePaymentProps[\"apiBaseUrl\"] | undefined;\n communitySlug: string;\n environment: LockerversePaymentProps[\"environment\"] | undefined;\n fetch: LockerversePaymentProps[\"fetch\"] | undefined;\n requestTimeoutMs: number | undefined;\n sentryDsn: string | null | undefined;\n widgetSlug: string;\n};\n\ntype SessionState =\n | { phase: \"idle\"; revision: number }\n | {\n configuration: CheckoutConfiguration;\n phase: \"loading\";\n revision: number;\n selectionKey: string;\n }\n | {\n configuration: CheckoutConfiguration;\n failure: string;\n phase: \"error\";\n revision: number;\n selectionKey: string;\n }\n | {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n configuration: CheckoutConfiguration;\n phase: \"ready\";\n preparedCheckout: LockerversePreparedCheckout;\n revision: number;\n selectionKey: string;\n };\n\ntype SessionAction =\n | {\n configuration: CheckoutConfiguration;\n selectionKey: string;\n type: \"loading\";\n }\n | {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n configuration: CheckoutConfiguration;\n preparedCheckout: LockerversePreparedCheckout;\n selectionKey: string;\n type: \"ready\";\n }\n | {\n configuration: CheckoutConfiguration;\n failure: string;\n selectionKey: string;\n type: \"error\";\n }\n | { preparedCheckout: LockerversePreparedCheckout; type: \"checkout\" }\n | { type: \"retry\" };\n\ntype LoadIdentity = {\n configuration: CheckoutConfiguration;\n selectionKey: string;\n};\n\nfunction sessionReducer(\n state: SessionState,\n action: SessionAction\n): SessionState {\n switch (action.type) {\n case \"loading\":\n return {\n configuration: action.configuration,\n phase: \"loading\",\n revision: state.revision,\n selectionKey: action.selectionKey,\n };\n case \"ready\":\n return {\n catalog: action.catalog,\n checkoutItems: action.checkoutItems,\n client: action.client,\n configuration: action.configuration,\n phase: \"ready\",\n preparedCheckout: action.preparedCheckout,\n revision: state.revision + 1,\n selectionKey: action.selectionKey,\n };\n case \"error\":\n return {\n configuration: action.configuration,\n failure: action.failure,\n phase: \"error\",\n revision: state.revision,\n selectionKey: action.selectionKey,\n };\n case \"checkout\":\n return state.phase === \"ready\"\n ? { ...state, preparedCheckout: action.preparedCheckout }\n : state;\n case \"retry\":\n return { phase: \"idle\", revision: state.revision + 1 };\n default:\n return state;\n }\n}\n\nfunction createCheckoutOptions(\n configuration: CheckoutConfiguration,\n onError: LockerversePaymentProps[\"onError\"]\n): CreateLockerverseWidgetOptions {\n const {\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n requestTimeoutMs,\n sentryDsn,\n widgetSlug,\n } = configuration;\n const common = {\n communitySlug,\n widgetSlug,\n ...(fetch ? { fetch } : {}),\n ...(onError ? { onError } : {}),\n ...(requestTimeoutMs === undefined ? {} : { requestTimeoutMs }),\n ...(sentryDsn === undefined ? {} : { sentryDsn }),\n };\n if (apiBaseUrl === undefined) {\n if (environment === \"development\") {\n throw new TypeError(\n \"Lockerverse development checkout requires an API base URL.\"\n );\n }\n return {\n ...common,\n ...(environment === \"production\" ? { environment } : {}),\n };\n }\n return {\n ...common,\n apiBaseUrl,\n ...(environment === undefined ? {} : { environment }),\n };\n}\n\nfunction isSameLoad(\n identity: LoadIdentity | undefined,\n configuration: CheckoutConfiguration,\n selectionKey: string\n) {\n return (\n identity?.configuration === configuration &&\n identity.selectionKey === selectionKey\n );\n}\n\nexport function usePaymentCheckout({\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n onError,\n paymentState,\n requestTimeoutMs,\n selection,\n sentryDsn,\n widgetSlug,\n}: CheckoutConfiguration & {\n onError: LockerversePaymentProps[\"onError\"];\n paymentState: CheckoutPaymentState;\n selection: LockerversePaymentProps[\"selection\"];\n}) {\n const configuration = useMemo<CheckoutConfiguration>(\n () => ({\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n requestTimeoutMs,\n sentryDsn,\n widgetSlug,\n }),\n [\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n requestTimeoutMs,\n sentryDsn,\n widgetSlug,\n ]\n );\n const parsedSelection = parsePaymentSelection(selection);\n const selectionKey = parsedSelection.success\n ? JSON.stringify(parsedSelection.value)\n : \"invalid-selection\";\n const stableSelection = useMemo(\n () =>\n parsedSelection.success\n ? (JSON.parse(selectionKey) as LockerversePaymentSelectionItem[])\n : [],\n [parsedSelection.success, selectionKey]\n );\n const [session, dispatch] = useReducer(sessionReducer, {\n phase: \"idle\",\n revision: 0,\n });\n const loadingRef = useRef<LoadIdentity | undefined>(undefined);\n const settledRef = useRef<LoadIdentity | undefined>(undefined);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n useEffect(() => {\n if (!parsedSelection.success) {\n return;\n }\n if (\n paymentState === \"submitting\" ||\n paymentState === \"success\" ||\n paymentState === \"unresolved\" ||\n isSameLoad(settledRef.current, configuration, selectionKey) ||\n isSameLoad(loadingRef.current, configuration, selectionKey)\n ) {\n return;\n }\n\n let active = true;\n const identity = { configuration, selectionKey };\n loadingRef.current = identity;\n dispatch({ configuration, selectionKey, type: \"loading\" });\n\n async function loadPayment() {\n try {\n const client = createLockerverseCheckoutClient(\n createCheckoutOptions(configuration, (error) =>\n onErrorRef.current?.(error)\n )\n );\n const { catalog, checkout: preparedCheckout } =\n await client.bootstrapCheckout({ items: stableSelection });\n const checkoutItems = [...preparedCheckout.items];\n if (active) {\n loadingRef.current = undefined;\n settledRef.current = identity;\n dispatch({\n catalog,\n checkoutItems,\n client,\n configuration,\n preparedCheckout,\n selectionKey,\n type: \"ready\",\n });\n }\n } catch (error) {\n if (active) {\n loadingRef.current = undefined;\n settledRef.current = identity;\n dispatch({\n configuration,\n failure:\n error instanceof Error\n ? error.message\n : \"Lockerverse payment could not load.\",\n selectionKey,\n type: \"error\",\n });\n }\n }\n }\n\n loadPayment();\n return () => {\n active = false;\n if (isSameLoad(loadingRef.current, configuration, selectionKey)) {\n loadingRef.current = undefined;\n }\n };\n }, [\n configuration,\n parsedSelection.success,\n paymentState,\n selectionKey,\n session.revision,\n stableSelection,\n ]);\n\n return {\n retryCheckout: () => {\n loadingRef.current = undefined;\n settledRef.current = undefined;\n dispatch({ type: \"retry\" });\n },\n selectionError: parsedSelection.success\n ? undefined\n : parsedSelection.message,\n session,\n updateCheckout: (preparedCheckout: LockerversePreparedCheckout) =>\n dispatch({ preparedCheckout, type: \"checkout\" }),\n };\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutItem,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport {\n AddressElement,\n Elements,\n PaymentElement,\n useElements,\n useStripe,\n} from \"@stripe/react-stripe-js\";\nimport type {\n Stripe,\n StripeAddressElementChangeEvent,\n StripeElements,\n} from \"@stripe/stripe-js\";\nimport { loadStripe } from \"@stripe/stripe-js\";\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useReducer,\n useRef,\n useState,\n} from \"react\";\nimport { getAccentContrast } from \"./accent-contrast.ts\";\nimport {\n AdditionalCheckoutFields,\n type CheckoutFieldValues,\n CheckoutToggle,\n ServiceFeeField,\n TipField,\n} from \"./checkout-fields.tsx\";\nimport {\n buildCustomFieldAnswers,\n createCustomFieldValues,\n validateCustomFields,\n} from \"./custom-fields.tsx\";\nimport {\n hasMaterialQuoteChange,\n recoverPaymentAttempt,\n submitPaymentAttempt,\n} from \"./payment-attempt.ts\";\nimport { parseCustomTipCents } from \"./payment-input.ts\";\nimport { normalizePhone, validateContact } from \"./payment-validation.ts\";\nimport {\n createPaymentWorkflowState,\n getPaymentError,\n getPaymentUiState,\n isPaymentBusy,\n type PaymentWorkflowEvent,\n type PaymentWorkflowUiState,\n paymentWorkflowReducer,\n} from \"./payment-workflow.ts\";\nimport { LockerverseSelect, SelectPortalProvider } from \"./select-control.tsx\";\nimport type { LockerversePaymentProps } from \"./types.ts\";\nimport {\n type CheckoutPaymentState,\n usePaymentCheckout,\n} from \"./use-payment-checkout.ts\";\n\nfunction formatMoney(amountCents: number) {\n return new Intl.NumberFormat(\"en-US\", {\n currency: \"USD\",\n style: \"currency\",\n }).format(amountCents / 100);\n}\n\nfunction getTipCents(\n subtotalCents: number,\n values: Pick<CheckoutFieldValues, \"customTip\" | \"tipPercent\">\n) {\n if (values.tipPercent === \"custom\") {\n if (!values.customTip.trim()) {\n return { cents: 0, success: true } as const;\n }\n return parseCustomTipCents(values.customTip);\n }\n return {\n cents: Math.round((subtotalCents * Number(values.tipPercent)) / 100),\n success: true,\n } as const;\n}\n\nconst PHONE_COUNTRIES = [\n { callingCode: \"+1\", label: \"🇺🇸 +1\", value: \"US\" },\n { callingCode: \"+52\", label: \"🇲🇽 +52\", value: \"MX\" },\n { callingCode: \"+380\", label: \"🇺🇦 +380\", value: \"UA\" },\n { callingCode: \"+48\", label: \"🇵🇱 +48\", value: \"PL\" },\n { callingCode: \"+1\", label: \"🇨🇦 +1\", value: \"CA\" },\n { callingCode: \"+49\", label: \"🇩🇪 +49\", value: \"DE\" },\n { callingCode: \"+44\", label: \"🇬🇧 +44\", value: \"GB\" },\n { callingCode: \"+46\", label: \"🇸🇪 +46\", value: \"SE\" },\n { callingCode: \"+358\", label: \"🇫🇮 +358\", value: \"FI\" },\n { callingCode: \"+1\", label: \"🇵🇷 +1\", value: \"PR\" },\n] as const;\n\nconst DEFAULT_FONT_FAMILY =\n 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif';\n\ntype CheckoutAddresses = Record<\n \"billing\" | \"shipping\",\n StripeAddressElementChangeEvent | null\n>;\n\nfunction getInternationalPhone(phone: string, country: string) {\n if (phone.trim().startsWith(\"+\")) {\n return phone;\n }\n const callingCode =\n PHONE_COUNTRIES.find((option) => option.value === country)?.callingCode ??\n \"+1\";\n return `${callingCode}${phone}`;\n}\n\nfunction buildQuoteRequest(\n catalog: LockerverseCatalog,\n fieldValues: CheckoutFieldValues,\n email: string,\n tipCents: number\n) {\n return {\n ...(email ? { email } : {}),\n ...(catalog.widget.fields.serviceFee\n ? { includeServiceFee: fieldValues.includeServiceFee }\n : {}),\n ...(catalog.widget.fields.promoCode && fieldValues.promoCode.trim()\n ? { promoCode: fieldValues.promoCode.trim() }\n : {}),\n ...(catalog.widget.fields.tipping ? { tipCents } : {}),\n };\n}\n\nfunction getCompleteAddress(\n address: StripeAddressElementChangeEvent | null,\n label: \"Billing\" | \"Shipping\"\n) {\n if (!address?.complete) {\n throw new Error(`${label} address is required.`);\n }\n return address.value;\n}\n\nfunction getShippingAddress(\n catalog: LockerverseCatalog,\n fieldValues: CheckoutFieldValues,\n billingAddress: ReturnType<typeof getCompleteAddress>,\n addresses: CheckoutAddresses\n) {\n if (!catalog.widget.fields.shipping) {\n return;\n }\n return fieldValues.shippingMatchesBilling\n ? billingAddress\n : getCompleteAddress(addresses.shipping, \"Shipping\");\n}\n\nfunction buildConfirmationParams({\n billingAddress,\n catalog,\n email,\n phone,\n shippingAddress,\n}: {\n billingAddress: ReturnType<typeof getCompleteAddress>;\n catalog: LockerverseCatalog;\n email: string;\n phone: string;\n shippingAddress: Awaited<ReturnType<typeof getCompleteAddress>> | undefined;\n}) {\n return {\n payment_method_data: {\n billing_details: {\n address: billingAddress.address,\n email,\n name: billingAddress.name,\n ...(catalog.widget.fields.phone ? { phone } : {}),\n },\n },\n ...(shippingAddress\n ? {\n shipping: {\n address: shippingAddress.address,\n name: shippingAddress.name,\n phone: catalog.widget.fields.phone\n ? phone\n : (shippingAddress.phone ?? null),\n },\n }\n : {}),\n };\n}\n\nfunction buildPaymentRequest({\n catalog,\n confirmationToken,\n email,\n fieldValues,\n metadata,\n phone,\n shippingAddress,\n}: {\n catalog: LockerverseCatalog;\n confirmationToken?: string;\n email: string;\n fieldValues: CheckoutFieldValues;\n metadata: Record<string, string> | undefined;\n phone: string;\n shippingAddress?: Awaited<ReturnType<typeof getCompleteAddress>>;\n}) {\n return {\n ...(confirmationToken ? { confirmationToken } : {}),\n customFieldAnswers: buildCustomFieldAnswers(\n catalog.widget.customFields,\n fieldValues.customFields\n ),\n email,\n ...(metadata ? { metadata } : {}),\n ...(catalog.widget.fields.memberId && fieldValues.memberId.trim()\n ? { memberId: fieldValues.memberId.trim() }\n : {}),\n ...(catalog.widget.fields.merchSize\n ? { merchSize: fieldValues.merchSize }\n : {}),\n ...(catalog.widget.fields.phone ? { phone } : {}),\n ...(shippingAddress\n ? {\n shipping: {\n address: {\n city: shippingAddress.address.city ?? \"\",\n country: shippingAddress.address.country,\n line1: shippingAddress.address.line1 ?? \"\",\n ...(shippingAddress.address.line2\n ? { line2: shippingAddress.address.line2 }\n : {}),\n postal_code: shippingAddress.address.postal_code ?? \"\",\n state: shippingAddress.address.state ?? \"\",\n },\n name: shippingAddress.name,\n },\n }\n : {}),\n };\n}\n\nfunction assertPaymentAttemptActive(isAttemptActive: () => boolean) {\n if (!isAttemptActive()) {\n throw new Error(\"Payment component is no longer active.\");\n }\n}\n\nasync function completePayment({\n addresses,\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n isAttemptActive,\n locallyPreviewedTotalCents,\n metadata,\n onPaymentRecoveryChange,\n phone,\n quote,\n stripe,\n}: {\n addresses: CheckoutAddresses;\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n elements?: StripeElements | null;\n email: string;\n fieldValues: CheckoutFieldValues;\n isAttemptActive: () => boolean;\n locallyPreviewedTotalCents: number;\n metadata: Record<string, string> | undefined;\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n phone: string;\n quote: LockerversePreparedCheckout;\n stripe?: Stripe | null;\n}) {\n const normalizedEmail = email.trim().toLowerCase();\n const normalizedPhone = normalizePhone(phone);\n const parsedTip = getTipCents(quote.subtotalCents, fieldValues);\n if (!parsedTip.success) {\n throw new Error(parsedTip.message);\n }\n const pricing = buildQuoteRequest(\n catalog,\n fieldValues,\n normalizedEmail,\n parsedTip.cents\n );\n const currentQuote = await client.calculateTotal({\n ...pricing,\n items: checkoutItems,\n });\n assertPaymentAttemptActive(isAttemptActive);\n if (\n currentQuote.totalCents > 0 &&\n hasMaterialQuoteChange(quote, currentQuote, locallyPreviewedTotalCents)\n ) {\n return { kind: \"quote_changed\" as const, quote: currentQuote };\n }\n\n if (currentQuote.totalCents === 0) {\n let completeShippingAddress:\n | ReturnType<typeof getCompleteAddress>\n | undefined;\n if (catalog.widget.fields.shipping) {\n const completeBillingAddress = getCompleteAddress(\n addresses.billing,\n \"Billing\"\n );\n completeShippingAddress = getShippingAddress(\n catalog,\n fieldValues,\n completeBillingAddress,\n addresses\n );\n }\n assertPaymentAttemptActive(isAttemptActive);\n notifyPaymentRecovery(onPaymentRecoveryChange, {\n connectedAccountId: currentQuote.payment.connectedAccountId,\n paymentReference: currentQuote.paymentReference,\n });\n const outcome = await submitPaymentAttempt(\n client,\n {\n checkout: currentQuote,\n submission: buildPaymentRequest({\n catalog,\n email: normalizedEmail,\n fieldValues,\n metadata,\n phone: normalizedPhone,\n ...(completeShippingAddress\n ? { shippingAddress: completeShippingAddress }\n : {}),\n }),\n },\n stripe\n );\n assertPaymentAttemptActive(isAttemptActive);\n if (outcome.kind === \"failed\") {\n return {\n kind: \"payment_failed\" as const,\n message:\n \"Order could not be completed. Review the details and try again.\",\n };\n }\n if (outcome.kind === \"unresolved\") {\n return {\n kind: \"payment_unresolved\" as const,\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n };\n }\n return {\n kind: \"payment\" as const,\n payment: outcome.payment,\n quote: currentQuote,\n };\n }\n\n if (!(elements && stripe)) {\n throw new Error(\"Payment form is still loading.\");\n }\n\n await elements.update({ amount: currentQuote.totalCents });\n assertPaymentAttemptActive(isAttemptActive);\n\n const elementSubmission = await elements.submit();\n assertPaymentAttemptActive(isAttemptActive);\n if (elementSubmission.error) {\n throw new Error(elementSubmission.error.message);\n }\n\n const completeBillingAddress = getCompleteAddress(\n addresses.billing,\n \"Billing\"\n );\n const completeShippingAddress = getShippingAddress(\n catalog,\n fieldValues,\n completeBillingAddress,\n addresses\n );\n\n const tokenResult = await stripe.createConfirmationToken({\n elements,\n params: buildConfirmationParams({\n billingAddress: completeBillingAddress,\n catalog,\n email: normalizedEmail,\n phone: normalizedPhone,\n shippingAddress: completeShippingAddress,\n }),\n });\n assertPaymentAttemptActive(isAttemptActive);\n if (tokenResult.error) {\n throw new Error(tokenResult.error.message);\n }\n\n notifyPaymentRecovery(onPaymentRecoveryChange, {\n connectedAccountId: currentQuote.payment.connectedAccountId,\n paymentReference: currentQuote.paymentReference,\n });\n\n const outcome = await submitPaymentAttempt(\n client,\n {\n checkout: currentQuote,\n submission: buildPaymentRequest({\n catalog,\n confirmationToken: tokenResult.confirmationToken.id,\n email: normalizedEmail,\n fieldValues,\n metadata,\n phone: normalizedPhone,\n ...(completeShippingAddress\n ? { shippingAddress: completeShippingAddress }\n : {}),\n }),\n },\n stripe\n );\n assertPaymentAttemptActive(isAttemptActive);\n if (outcome.kind === \"failed\") {\n return {\n kind: \"payment_failed\" as const,\n message:\n \"Payment was declined. Check your payment details and try again.\",\n };\n }\n if (outcome.kind === \"unresolved\") {\n return {\n kind: \"payment_unresolved\" as const,\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n };\n }\n return {\n kind: \"payment\" as const,\n payment: outcome.payment,\n quote: currentQuote,\n };\n}\n\nfunction ReadyPayment({\n accentColor,\n catalog,\n checkoutItems,\n client,\n fontFamily,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n quote,\n resumePayment,\n onStateChange,\n stripeLoader,\n theme,\n visualStyle,\n}: {\n accentColor: string;\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n fontFamily: string;\n metadata: Record<string, string> | undefined;\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n quote: LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n onStateChange: (\n state:\n | \"error\"\n | \"idle\"\n | \"invalid\"\n | \"submitting\"\n | \"success\"\n | \"unresolved\"\n ) => void;\n stripeLoader: NonNullable<LockerversePaymentProps[\"stripeLoader\"]>;\n theme: LockerversePaymentProps[\"theme\"];\n visualStyle: LockerversePaymentProps[\"style\"];\n}) {\n const connectedAccountId = resumePayment\n ? resumePayment.connectedAccountId\n : quote.payment.connectedAccountId;\n const stripe = useMemo(\n () =>\n stripeLoader(\n catalog.payment.publishableKey,\n connectedAccountId ? { stripeAccount: connectedAccountId } : undefined\n ).catch(() => null),\n [catalog.payment.publishableKey, connectedAccountId, stripeLoader]\n );\n\n return (\n <Elements\n key={`${catalog.payment.publishableKey}:${connectedAccountId ?? \"platform\"}`}\n options={{\n amount: Math.max(quote.totalCents, 100),\n appearance: {\n rules: {\n \".Input:focus\": {\n borderColor: accentColor,\n boxShadow: `0 0 0 1px ${accentColor}`,\n outline: \"none\",\n },\n },\n theme: theme === \"light\" ? \"stripe\" : \"night\",\n variables: {\n borderRadius: visualStyle?.[\"--lockerverse-radius\"] ?? \"10px\",\n colorBackground:\n visualStyle?.[\"--lockerverse-control\"] ??\n (theme === \"light\" ? \"#f5f6f7\" : \"#121212\"),\n colorDanger:\n visualStyle?.[\"--lockerverse-danger\"] ??\n (theme === \"light\" ? \"#c52b3e\" : \"#f08a98\"),\n colorPrimary: accentColor,\n colorText:\n visualStyle?.[\"--lockerverse-text\"] ??\n (theme === \"light\" ? \"#121416\" : \"#ffffff\"),\n colorTextPlaceholder:\n visualStyle?.[\"--lockerverse-placeholder\"] ??\n (theme === \"light\" ? \"#72767d\" : \"#6b6b6b\"),\n colorTextSecondary:\n visualStyle?.[\"--lockerverse-muted\"] ??\n (theme === \"light\" ? \"#62666d\" : \"#a1a1aa\"),\n focusBoxShadow: \"none\",\n focusOutline: \"none\",\n fontFamily,\n fontSizeBase: \"16px\",\n },\n },\n currency: quote.payment.currency,\n excludedPaymentMethodTypes: [\"us_bank_account\"],\n mode: \"payment\",\n syncAddressCheckbox: \"none\",\n }}\n stripe={stripe}\n >\n <PaymentForm\n catalog={catalog}\n checkoutItems={checkoutItems}\n client={client}\n metadata={metadata}\n onPaymentComplete={onPaymentComplete}\n onPaymentRecoveryChange={onPaymentRecoveryChange}\n onPaymentUncertain={onPaymentUncertain}\n onQuoteChange={onQuoteChange}\n onStateChange={onStateChange}\n quote={quote}\n resumePayment={resumePayment}\n />\n </Elements>\n );\n}\n\nfunction StripeElementLoader({ label }: { label: string }) {\n return (\n <div className=\"lockerverse-payment__stripe-loader\" role=\"status\">\n <p>{label}</p>\n <div aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </div>\n </div>\n );\n}\n\nfunction StripePaymentField({\n onError,\n onReady,\n ready,\n}: {\n onError: (message: string) => void;\n onReady: () => void;\n ready: boolean;\n}) {\n return (\n <div className=\"lockerverse-payment__stripe-element\" data-ready={ready}>\n {ready ? null : <StripeElementLoader label=\"Loading payment form...\" />}\n <div className=\"lockerverse-payment__stripe-mount\">\n <PaymentElement\n onLoadError={({ error }) =>\n onError(error.message ?? \"Payment form failed to load.\")\n }\n onReady={onReady}\n options={{\n business: { name: \"Lockerverse\" },\n fields: {\n billingDetails: {\n address: \"never\",\n email: \"never\",\n name: \"never\",\n phone: \"never\",\n },\n },\n layout: \"tabs\",\n terms: {\n applePay: \"auto\",\n auBecsDebit: \"never\",\n bancontact: \"never\",\n card: \"always\",\n cashapp: \"never\",\n googlePay: \"never\",\n ideal: \"never\",\n paypal: \"auto\",\n sepaDebit: \"never\",\n sofort: \"never\",\n usBankAccount: \"never\",\n },\n wallets: { applePay: \"auto\", googlePay: \"never\" },\n }}\n />\n </div>\n </div>\n );\n}\n\nfunction StripeAddressField({\n label,\n mode,\n onChange,\n onError,\n onReady,\n ready,\n}: {\n label: string;\n mode: \"billing\" | \"shipping\";\n onChange: (address: StripeAddressElementChangeEvent) => void;\n onError: (message: string) => void;\n onReady: () => void;\n ready: boolean;\n}) {\n return (\n <div className=\"lockerverse-payment__address\">\n <h2>{label}</h2>\n <div\n className=\"lockerverse-payment__stripe-element lockerverse-payment__stripe-element--address\"\n data-ready={ready}\n >\n {ready ? null : (\n <StripeElementLoader label={`Loading ${label.toLowerCase()}...`} />\n )}\n <div className=\"lockerverse-payment__stripe-mount\">\n <AddressElement\n onChange={onChange}\n onLoadError={({ error }) =>\n onError(error.message ?? `${label} failed to load.`)\n }\n onReady={onReady}\n options={{ autocomplete: { mode: \"automatic\" }, mode }}\n />\n </div>\n </div>\n </div>\n );\n}\n\nfunction PaymentErrorMessage({ message }: { message: string | undefined }) {\n if (!message) {\n return null;\n }\n return (\n <p className=\"lockerverse-payment__field-message\" role=\"alert\">\n {message}\n </p>\n );\n}\n\nfunction StripeCheckoutFields({\n catalog,\n displayedTotalCents,\n fieldValues,\n isBillingAddressReady,\n isPaymentReady,\n isShippingAddressReady,\n onAddressChange,\n onFieldValuesChange,\n onStripeLoadError,\n setIsBillingAddressReady,\n setIsPaymentReady,\n setIsShippingAddressReady,\n}: {\n catalog: LockerverseCatalog;\n displayedTotalCents: number;\n fieldValues: CheckoutFieldValues;\n isBillingAddressReady: boolean;\n isPaymentReady: boolean;\n isShippingAddressReady: boolean;\n onAddressChange: (\n mode: \"billing\" | \"shipping\",\n address: StripeAddressElementChangeEvent | null\n ) => void;\n onFieldValuesChange: (values: CheckoutFieldValues) => void;\n onStripeLoadError: (message: string) => void;\n setIsBillingAddressReady: (ready: boolean) => void;\n setIsPaymentReady: (ready: boolean) => void;\n setIsShippingAddressReady: (ready: boolean) => void;\n}) {\n const requiresPayment = displayedTotalCents > 0;\n\n return (\n <>\n {requiresPayment ? (\n <StripePaymentField\n onError={onStripeLoadError}\n onReady={() => setIsPaymentReady(true)}\n ready={isPaymentReady}\n />\n ) : null}\n {requiresPayment || catalog.widget.fields.shipping ? (\n <StripeAddressField\n label={requiresPayment ? \"Billing address\" : \"Shipping address\"}\n mode=\"billing\"\n onChange={(address) => onAddressChange(\"billing\", address)}\n onError={onStripeLoadError}\n onReady={() => setIsBillingAddressReady(true)}\n ready={isBillingAddressReady}\n />\n ) : null}\n {catalog.widget.fields.shipping ? (\n <div className=\"lockerverse-payment__shipping\">\n <CheckoutToggle\n checked={fieldValues.shippingMatchesBilling}\n name=\"shippingMatchesBilling\"\n onChange={(shippingMatchesBilling) => {\n onFieldValuesChange({\n ...fieldValues,\n shippingMatchesBilling,\n });\n if (shippingMatchesBilling) {\n onAddressChange(\"shipping\", null);\n } else {\n setIsShippingAddressReady(false);\n }\n }}\n >\n Shipping is same as billing information\n </CheckoutToggle>\n {fieldValues.shippingMatchesBilling ? null : (\n <StripeAddressField\n label=\"Shipping address\"\n mode=\"shipping\"\n onChange={(address) => onAddressChange(\"shipping\", address)}\n onError={onStripeLoadError}\n onReady={() => setIsShippingAddressReady(true)}\n ready={isShippingAddressReady}\n />\n )}\n </div>\n ) : null}\n </>\n );\n}\n\nfunction PaymentSummary({\n displayedBaseCents,\n displayedTipCents,\n displayedTotalCents,\n quote,\n}: {\n displayedBaseCents: number;\n displayedTipCents: number;\n displayedTotalCents: number;\n quote: LockerversePreparedCheckout;\n}) {\n const displayedServiceFeeCents = Math.max(\n 0,\n displayedBaseCents - quote.subtotalCents + quote.discountCents\n );\n return (\n <section\n aria-label=\"Payment summary\"\n className=\"lockerverse-payment__payment-summary\"\n >\n <h2>Order summary</h2>\n <div className=\"lockerverse-payment__payment-summary-items\">\n {quote.lineItems.map((item) => (\n <div\n className=\"lockerverse-payment__payment-summary-row\"\n key={item.listingId}\n >\n <span>\n {item.productName}\n {item.quantity > 1 ? (\n <>\n {\" \"}\n <small>× {item.quantity}</small>\n </>\n ) : null}\n </span>\n <strong>{formatMoney(item.subtotalCents)}</strong>\n </div>\n ))}\n </div>\n <div className=\"lockerverse-payment__payment-summary-totals\">\n {displayedServiceFeeCents > 0 ? (\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-detail\">\n <span>Service fee</span>\n <strong>{formatMoney(displayedServiceFeeCents)}</strong>\n </div>\n ) : null}\n {quote.discountCents > 0 && quote.appliedDiscount ? (\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-discount\">\n <span>\n {quote.appliedDiscount.source === \"email_list\"\n ? \"Email discount\"\n : \"Promo code discount\"}{\" \"}\n ({quote.appliedDiscount.percentageOff}% off)\n </span>\n <strong>-{formatMoney(quote.discountCents)}</strong>\n </div>\n ) : null}\n {displayedTipCents > 0 ? (\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-detail lockerverse-payment__payment-summary-tip\">\n <span>Tip</span>\n <strong>{formatMoney(displayedTipCents)}</strong>\n </div>\n ) : null}\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-total\">\n <span>Total</span>\n <strong>{formatMoney(displayedTotalCents)}</strong>\n </div>\n </div>\n </section>\n );\n}\n\nfunction PaymentAction({\n catalog,\n displayedTotalCents,\n fieldValues,\n isBillingAddressReady,\n isPaymentReady,\n isRequiredShippingReady,\n isSubmitting,\n onFieldValuesChange,\n quote,\n}: {\n catalog: LockerverseCatalog;\n displayedTotalCents: number;\n fieldValues: CheckoutFieldValues;\n isBillingAddressReady: boolean;\n isPaymentReady: boolean;\n isRequiredShippingReady: boolean;\n isSubmitting: boolean;\n onFieldValuesChange: (values: CheckoutFieldValues) => void;\n quote: LockerversePreparedCheckout;\n}) {\n const isFree = displayedTotalCents === 0;\n const isReady = isFree\n ? !catalog.widget.fields.shipping ||\n (isBillingAddressReady && isRequiredShippingReady)\n : isPaymentReady && isBillingAddressReady && isRequiredShippingReady;\n let label = isFree\n ? \"Complete order\"\n : `Pay ${formatMoney(displayedTotalCents)}`;\n if (isSubmitting) {\n label = isFree ? \"Completing…\" : \"Processing…\";\n }\n return (\n <div className=\"lockerverse-payment__actions\">\n <ServiceFeeField\n amountCents={\n quote.serviceFeeCents ||\n Math.round(\n (quote.subtotalCents *\n catalog.pricingPolicy.serviceFeeRateBasisPoints) /\n 10_000\n )\n }\n enabled={catalog.widget.fields.serviceFee}\n onChange={onFieldValuesChange}\n values={fieldValues}\n />\n <button\n aria-busy={isSubmitting}\n aria-label={\n isFree\n ? \"Complete order\"\n : `Process payment for ${formatMoney(displayedTotalCents)} total`\n }\n disabled={isSubmitting || !isReady}\n type=\"submit\"\n >\n {label}\n </button>\n </div>\n );\n}\n\ntype CompletePaymentResult = Awaited<ReturnType<typeof completePayment>>;\n\nfunction notifyPaymentRecovery(\n callback: LockerversePaymentProps[\"onPaymentRecoveryChange\"],\n recovery: Parameters<\n NonNullable<LockerversePaymentProps[\"onPaymentRecoveryChange\"]>\n >[0]\n) {\n try {\n callback?.(recovery);\n } catch {\n // Host persistence failures must not change authoritative payment state.\n }\n}\n\nfunction focusNamedFormControl(form: HTMLFormElement, name: string) {\n const control = form.elements.namedItem(name);\n if (control instanceof HTMLElement) {\n control.focus();\n return;\n }\n if (control instanceof RadioNodeList) {\n Array.from(control)\n .find((item) => item instanceof HTMLElement)\n ?.focus();\n }\n}\n\nfunction focusFirstValidationError({\n customFieldErrors,\n emailRef,\n form,\n parsedTipSuccess,\n phoneRef,\n validationErrors,\n}: {\n customFieldErrors: Record<string, string>;\n emailRef: React.RefObject<HTMLInputElement | null>;\n form: HTMLFormElement;\n parsedTipSuccess: boolean;\n phoneRef: React.RefObject<HTMLInputElement | null>;\n validationErrors: { email?: string; phone?: string };\n}) {\n if (validationErrors.email) {\n emailRef.current?.focus();\n return;\n }\n if (validationErrors.phone) {\n phoneRef.current?.focus();\n return;\n }\n if (!parsedTipSuccess) {\n form.querySelector<HTMLElement>('[name=\"tip\"]')?.focus();\n return;\n }\n const [firstFieldId] = Object.keys(customFieldErrors);\n if (firstFieldId) {\n focusNamedFormControl(form, `custom:${firstFieldId}`);\n }\n}\n\nfunction applyPaymentOutcome({\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n result,\n setDisplayedTotalCents,\n transitionWorkflow,\n}: {\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n result: CompletePaymentResult;\n setDisplayedTotalCents: (total: number) => void;\n transitionWorkflow: (event: PaymentWorkflowEvent) => void;\n}) {\n if (result.kind === \"quote_changed\") {\n const notice = `The total changed to ${formatMoney(result.quote.totalCents)}. Review it and pay again.`;\n onQuoteChange(result.quote, notice);\n setDisplayedTotalCents(result.quote.totalCents);\n transitionWorkflow({ type: \"quote_changed\" });\n return;\n }\n if (result.kind === \"payment_failed\") {\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({ error: result.message, type: \"retryable_failure\" });\n return;\n }\n if (result.kind === \"payment_unresolved\") {\n transitionWorkflow({\n message: \"Payment is still processing. Do not submit it again.\",\n paymentReference: result.paymentReference,\n reason: result.reason,\n type: \"unresolved\",\n });\n try {\n onPaymentUncertain?.({\n paymentReference: result.paymentReference,\n reason: result.reason,\n });\n } catch {\n // Host callback failures must not unlock an uncertain payment.\n }\n return;\n }\n onQuoteChange(result.quote);\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({\n message: result.payment.paymentRequired\n ? \"Payment completed successfully.\"\n : \"Order confirmed. No payment was required.\",\n type: \"succeeded\",\n });\n try {\n onPaymentComplete?.(result.payment);\n } catch {\n // Host callback failures must not turn a completed payment into an error.\n }\n}\n\nfunction ContactFields({\n email,\n emailDiscountPercentOff,\n emailErrorId,\n emailId,\n emailRef,\n errors,\n onEmailBlur,\n onEmailChange,\n onPhoneChange,\n onPhoneCountryChange,\n phone,\n phoneCountry,\n phoneEnabled,\n phoneErrorId,\n phoneId,\n phoneRef,\n}: {\n email: string;\n emailDiscountPercentOff: number | undefined;\n emailErrorId: string;\n emailId: string;\n emailRef: React.RefObject<HTMLInputElement | null>;\n errors: { email?: string; phone?: string };\n onEmailBlur: () => void;\n onEmailChange: (value: string) => void;\n onPhoneChange: (value: string) => void;\n onPhoneCountryChange: (value: string) => void;\n phone: string;\n phoneCountry: string;\n phoneEnabled: boolean;\n phoneErrorId: string;\n phoneId: string;\n phoneRef: React.RefObject<HTMLInputElement | null>;\n}) {\n return (\n <div className=\"lockerverse-payment__contact\">\n <label htmlFor={emailId}>Email</label>\n <input\n aria-describedby={errors.email ? emailErrorId : undefined}\n aria-invalid={errors.email ? \"true\" : undefined}\n autoComplete=\"email\"\n id={emailId}\n name=\"email\"\n onBlur={onEmailBlur}\n onChange={(event) => onEmailChange(event.currentTarget.value)}\n placeholder=\"name@example.com\"\n ref={emailRef}\n type=\"email\"\n value={email}\n />\n {errors.email ? (\n <p className=\"lockerverse-payment__field-message\" id={emailErrorId}>\n {errors.email}\n </p>\n ) : null}\n {emailDiscountPercentOff === undefined ? null : (\n <p className=\"lockerverse-payment__discount-message\" role=\"status\">\n Your email qualifies for {emailDiscountPercentOff}% off.\n </p>\n )}\n {phoneEnabled ? (\n <>\n <label htmlFor={phoneId}>Phone</label>\n <div className=\"lockerverse-payment__phone-control\">\n <LockerverseSelect\n ariaLabel=\"Phone number country\"\n className=\"lockerverse-payment__select--phone-country\"\n name=\"phoneCountry\"\n onValueChange={onPhoneCountryChange}\n options={PHONE_COUNTRIES}\n value={phoneCountry}\n />\n <input\n aria-describedby={errors.phone ? phoneErrorId : undefined}\n aria-invalid={errors.phone ? \"true\" : undefined}\n autoComplete=\"tel\"\n id={phoneId}\n inputMode=\"tel\"\n name=\"phone\"\n onChange={(event) => onPhoneChange(event.currentTarget.value)}\n placeholder=\"(201) 555-0123\"\n ref={phoneRef}\n type=\"tel\"\n value={phone}\n />\n </div>\n {errors.phone ? (\n <p className=\"lockerverse-payment__field-message\" id={phoneErrorId}>\n {errors.phone}\n </p>\n ) : null}\n </>\n ) : null}\n </div>\n );\n}\n\nfunction PaymentForm({\n catalog,\n checkoutItems,\n client,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onStateChange,\n quote,\n resumePayment,\n}: {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n metadata: Record<string, string> | undefined;\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n onStateChange: (state: PaymentWorkflowUiState) => void;\n quote: LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n}) {\n const [email, setEmail] = useState(\"\");\n const [phone, setPhone] = useState(\"\");\n const [phoneCountry, setPhoneCountry] = useState(\"US\");\n const [errors, setErrors] = useState<{ email?: string; phone?: string }>({});\n const [customFieldErrors, setCustomFieldErrors] = useState<\n Record<string, string>\n >({});\n const [tipError, setTipError] = useState<string>();\n const [promoError, setPromoError] = useState<string>();\n const [paymentWorkflow, dispatchPaymentWorkflow] = useReducer(\n paymentWorkflowReducer,\n resumePayment,\n createPaymentWorkflowState\n );\n const [isPaymentReady, setIsPaymentReady] = useState(false);\n const [isBillingAddressReady, setIsBillingAddressReady] = useState(false);\n const [isShippingAddressReady, setIsShippingAddressReady] = useState(false);\n const [fieldValues, setFieldValues] = useState<CheckoutFieldValues>({\n customFields: createCustomFieldValues(catalog.widget.customFields),\n customTip: \"\",\n includeServiceFee: catalog.widget.fields.serviceFee,\n memberId: \"\",\n merchSize: \"M\",\n promoCode: \"\",\n shippingMatchesBilling: true,\n tipPercent: \"10\",\n });\n const [displayedTotalCents, setDisplayedTotalCents] = useState(\n quote.totalCents\n );\n const addressesRef = useRef<CheckoutAddresses>({\n billing: null,\n shipping: null,\n });\n const emailRef = useRef<HTMLInputElement>(null);\n const phoneRef = useRef<HTMLInputElement>(null);\n const statusRef = useRef<HTMLParagraphElement>(null);\n const recoveryStartedRef = useRef(false);\n const quoteRequestRef = useRef(0);\n const paymentWasRequiredRef = useRef(quote.totalCents > 0);\n const paymentAttemptGenerationRef = useRef(0);\n const paymentWorkflowRef = useRef(paymentWorkflow);\n paymentWorkflowRef.current = paymentWorkflow;\n const elements = useElements();\n const stripe = useStripe();\n const idPrefix = `lockerverse-${useId()}`;\n const emailId = `${idPrefix}-email`;\n const emailErrorId = `${emailId}-error`;\n const phoneId = `${idPrefix}-phone`;\n const phoneErrorId = `${phoneId}-error`;\n const tipErrorId = `${idPrefix}-tip-error`;\n const paymentError = getPaymentError(paymentWorkflow);\n const terminalMessage =\n paymentWorkflow.phase === \"succeeded\" ||\n paymentWorkflow.phase === \"unresolved\"\n ? paymentWorkflow.message\n : undefined;\n const isSubmitting = isPaymentBusy(paymentWorkflow);\n const isRefreshingQuote = paymentWorkflow.phase === \"refreshing_quote\";\n const isRecovering = paymentWorkflow.phase === \"recovering\";\n const parsedTip = catalog.widget.fields.tipping\n ? getTipCents(quote.subtotalCents, fieldValues)\n : ({ cents: 0, success: true } as const);\n const parsedTipCents = parsedTip.success ? parsedTip.cents : null;\n const displayedTipCents = parsedTipCents ?? 0;\n const displayedBaseCents = displayedTotalCents - displayedTipCents;\n const isRequiredShippingReady =\n !catalog.widget.fields.shipping ||\n fieldValues.shippingMatchesBilling ||\n isShippingAddressReady;\n\n const updatePaymentWorkflow = useCallback(\n (event: PaymentWorkflowEvent, notifyHost = false) => {\n const previous = paymentWorkflowRef.current;\n const next = paymentWorkflowReducer(previous, event);\n if (next === previous) {\n return;\n }\n paymentWorkflowRef.current = next;\n dispatchPaymentWorkflow(event);\n if (notifyHost) {\n onStateChange(getPaymentUiState(next));\n }\n },\n [onStateChange]\n );\n\n const transitionWorkflow = useCallback(\n (event: PaymentWorkflowEvent) => {\n updatePaymentWorkflow(event, true);\n },\n [updatePaymentWorkflow]\n );\n\n const startPaymentAttempt = useCallback(() => {\n const generation = paymentAttemptGenerationRef.current + 1;\n paymentAttemptGenerationRef.current = generation;\n return () => paymentAttemptGenerationRef.current === generation;\n }, []);\n\n useEffect(\n () => () => {\n paymentAttemptGenerationRef.current += 1;\n },\n []\n );\n\n useEffect(() => {\n if (parsedTipCents === null) {\n return;\n }\n const previewServiceFeeCents =\n catalog.widget.fields.serviceFee && fieldValues.includeServiceFee\n ? quote.serviceFeeCents ||\n Math.round(\n (quote.subtotalCents *\n catalog.pricingPolicy.serviceFeeRateBasisPoints) /\n 10_000\n )\n : 0;\n const previewTotalCents =\n quote.totalCents -\n quote.serviceFeeCents -\n quote.tipCents +\n previewServiceFeeCents +\n parsedTipCents;\n setDisplayedTotalCents(previewTotalCents);\n if (previewTotalCents > 0) {\n elements?.update({ amount: previewTotalCents });\n }\n }, [\n catalog.widget.fields.serviceFee,\n catalog.widget.fields.tipping,\n elements,\n fieldValues.includeServiceFee,\n fieldValues.tipPercent,\n fieldValues.customTip,\n parsedTipCents,\n quote.serviceFeeCents,\n quote.tipCents,\n quote.totalCents,\n ]);\n\n useEffect(() => {\n if (isSubmitting) {\n statusRef.current?.focus();\n }\n }, [isSubmitting]);\n\n useEffect(() => {\n const paymentIsRequired = displayedTotalCents > 0;\n if (paymentIsRequired && !paymentWasRequiredRef.current) {\n setIsPaymentReady(false);\n setIsBillingAddressReady(false);\n }\n paymentWasRequiredRef.current = paymentIsRequired;\n }, [displayedTotalCents]);\n\n useEffect(() => {\n if (!(resumePayment && stripe) || recoveryStartedRef.current) {\n return;\n }\n recoveryStartedRef.current = true;\n const isAttemptActive = startPaymentAttempt();\n onStateChange(getPaymentUiState(paymentWorkflowRef.current));\n\n recoverPaymentAttempt(client, resumePayment.paymentReference, stripe).then(\n (outcome) => {\n if (!isAttemptActive()) {\n return;\n }\n if (outcome.kind === \"failed\") {\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({\n error:\n \"The previous payment failed. Check your details and try again.\",\n type: \"recovery_failed\",\n });\n return;\n }\n if (outcome.kind === \"unresolved\") {\n transitionWorkflow({\n message: \"Payment is still processing. Do not submit it again.\",\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n type: \"unresolved\",\n });\n try {\n onPaymentUncertain?.({\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n });\n } catch {\n // Host callback failures must not unlock an uncertain payment.\n }\n return;\n }\n\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({\n message: outcome.payment.paymentRequired\n ? \"Payment completed successfully.\"\n : \"Order confirmed. No payment was required.\",\n type: \"succeeded\",\n });\n try {\n onPaymentComplete?.(outcome.payment);\n } catch {\n // Host callback failures must not turn a completed payment into an error.\n }\n }\n );\n return () => {\n if (isAttemptActive()) {\n paymentAttemptGenerationRef.current += 1;\n }\n recoveryStartedRef.current = false;\n };\n }, [\n client,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onStateChange,\n resumePayment,\n stripe,\n startPaymentAttempt,\n transitionWorkflow,\n ]);\n\n function clearError(field: \"email\" | \"phone\") {\n updatePaymentWorkflow({ type: \"field_changed\" });\n setErrors((current) => {\n const next = { ...current };\n delete next[field];\n return next;\n });\n }\n\n function handleFieldValuesChange(nextValues: CheckoutFieldValues) {\n if (nextValues.promoCode !== fieldValues.promoCode) {\n setPromoError(undefined);\n }\n setFieldValues(nextValues);\n setCustomFieldErrors({});\n setTipError(undefined);\n updatePaymentWorkflow({ type: \"field_changed\" });\n }\n\n function handleStripeLoadError(message: string) {\n transitionWorkflow({ error: message, type: \"retryable_failure\" });\n }\n\n function updatePromoResult(quoteResult: LockerversePreparedCheckout) {\n setPromoError(\n quoteResult.appliedDiscount?.source === \"promo_code\"\n ? undefined\n : \"This promo code is invalid or cannot be applied.\"\n );\n }\n\n function handleQuoteRefreshError(error: unknown, validatePromo: boolean) {\n if (validatePromo) {\n setPromoError(\"This promo code is invalid or cannot be applied.\");\n return;\n }\n return error instanceof Error\n ? error.message\n : \"The order total could not be updated.\";\n }\n\n async function refreshAuthoritativeTotal(\n allowMissingEmail = false,\n validatePromo = false\n ) {\n const normalizedEmail = email.trim().toLowerCase();\n const emailValidation = validateContact(\n { email: normalizedEmail, phone: \"\" },\n false\n );\n if (!(parsedTip.success && (emailValidation.value || allowMissingEmail))) {\n return;\n }\n\n quoteRequestRef.current += 1;\n const requestId = quoteRequestRef.current;\n updatePaymentWorkflow({\n type: \"quote_refresh_started\",\n validatePromo,\n });\n try {\n const nextQuote = await client.calculateTotal({\n ...buildQuoteRequest(\n catalog,\n fieldValues,\n emailValidation.value?.email ?? \"\",\n parsedTip.cents\n ),\n items: checkoutItems,\n });\n if (requestId !== quoteRequestRef.current) {\n return;\n }\n updatePaymentWorkflow({ type: \"quote_refresh_succeeded\" });\n setDisplayedTotalCents(nextQuote.totalCents);\n onQuoteChange(nextQuote);\n if (validatePromo) {\n updatePromoResult(nextQuote);\n }\n } catch (error) {\n if (requestId === quoteRequestRef.current) {\n const message = handleQuoteRefreshError(error, validatePromo);\n updatePaymentWorkflow(\n message === undefined\n ? { type: \"quote_refresh_failed\" }\n : { error: message, type: \"quote_refresh_failed\" }\n );\n }\n }\n }\n\n async function handleApplyPromo() {\n setPromoError(undefined);\n await refreshAuthoritativeTotal(true, true);\n }\n\n async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {\n event.preventDefault();\n const validation = validateContact(\n { email, phone: getInternationalPhone(phone, phoneCountry) },\n catalog.widget.fields.phone\n );\n const nextCustomFieldErrors = validateCustomFields(\n catalog.widget.customFields,\n fieldValues.customFields\n );\n if (\n !(validation.value && parsedTip.success) ||\n Object.keys(nextCustomFieldErrors).length > 0\n ) {\n setErrors(validation.errors);\n setCustomFieldErrors(nextCustomFieldErrors);\n setTipError(parsedTip.success ? undefined : parsedTip.message);\n transitionWorkflow({ type: \"validation_failed\" });\n const form = event.currentTarget;\n queueMicrotask(() => {\n focusFirstValidationError({\n customFieldErrors: nextCustomFieldErrors,\n emailRef,\n form,\n parsedTipSuccess: parsedTip.success,\n phoneRef,\n validationErrors: validation.errors,\n });\n });\n return;\n }\n\n setErrors({});\n setCustomFieldErrors({});\n\n transitionWorkflow({ type: \"submission_started\" });\n const isAttemptActive = startPaymentAttempt();\n\n try {\n const result = await completePayment({\n addresses: addressesRef.current,\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n isAttemptActive,\n locallyPreviewedTotalCents: displayedTotalCents,\n metadata,\n onPaymentRecoveryChange,\n phone: getInternationalPhone(phone, phoneCountry),\n quote,\n stripe,\n });\n if (!isAttemptActive()) {\n return;\n }\n applyPaymentOutcome({\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n result,\n setDisplayedTotalCents,\n transitionWorkflow,\n });\n } catch (error) {\n if (!isAttemptActive()) {\n return;\n }\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({\n error:\n error instanceof Error\n ? error.message\n : \"Payment could not be completed.\",\n type: \"retryable_failure\",\n });\n }\n }\n\n if (terminalMessage) {\n return (\n <p\n className=\"lockerverse-payment__payment-status\"\n ref={statusRef}\n role=\"status\"\n tabIndex={-1}\n >\n {terminalMessage}\n </p>\n );\n }\n\n if (isRecovering) {\n return (\n <p className=\"lockerverse-payment__payment-status\" role=\"status\">\n Recovering payment…\n </p>\n );\n }\n\n return (\n <form\n aria-busy={isSubmitting}\n className=\"lockerverse-payment__form\"\n noValidate\n onSubmit={handleSubmit}\n >\n <div\n data-lockerverse-input-region=\"\"\n inert={isSubmitting ? true : undefined}\n >\n <fieldset\n className=\"lockerverse-payment__input-fieldset\"\n disabled={isSubmitting}\n >\n <PaymentSummary\n displayedBaseCents={displayedBaseCents}\n displayedTipCents={displayedTipCents}\n displayedTotalCents={displayedTotalCents}\n quote={quote}\n />\n <TipField\n enabled={catalog.widget.fields.tipping}\n error={tipError}\n errorId={tipErrorId}\n onChange={handleFieldValuesChange}\n values={fieldValues}\n />\n <ContactFields\n email={email}\n emailDiscountPercentOff={\n quote.appliedDiscount?.source === \"email_list\"\n ? quote.appliedDiscount.percentageOff\n : undefined\n }\n emailErrorId={emailErrorId}\n emailId={emailId}\n emailRef={emailRef}\n errors={errors}\n onEmailBlur={() => refreshAuthoritativeTotal()}\n onEmailChange={(value) => {\n setEmail(value);\n clearError(\"email\");\n }}\n onPhoneChange={(value) => {\n setPhone(value);\n clearError(\"phone\");\n }}\n onPhoneCountryChange={(value) => {\n setPhoneCountry(value);\n updatePaymentWorkflow({ type: \"field_changed\" });\n }}\n phone={phone}\n phoneCountry={phoneCountry}\n phoneEnabled={catalog.widget.fields.phone}\n phoneErrorId={phoneErrorId}\n phoneId={phoneId}\n phoneRef={phoneRef}\n />\n <StripeCheckoutFields\n catalog={catalog}\n displayedTotalCents={displayedTotalCents}\n fieldValues={fieldValues}\n isBillingAddressReady={isBillingAddressReady}\n isPaymentReady={isPaymentReady}\n isShippingAddressReady={isShippingAddressReady}\n onAddressChange={(mode, address) => {\n addressesRef.current[mode] = address;\n }}\n onFieldValuesChange={handleFieldValuesChange}\n onStripeLoadError={handleStripeLoadError}\n setIsBillingAddressReady={setIsBillingAddressReady}\n setIsPaymentReady={setIsPaymentReady}\n setIsShippingAddressReady={setIsShippingAddressReady}\n />\n <AdditionalCheckoutFields\n customFields={catalog.widget.customFields}\n errors={customFieldErrors}\n fields={catalog.widget.fields}\n idPrefix={idPrefix}\n isPromoApplying={isRefreshingQuote}\n onApplyPromo={handleApplyPromo}\n onChange={handleFieldValuesChange}\n promoError={promoError}\n values={fieldValues}\n />\n <PaymentAction\n catalog={catalog}\n displayedTotalCents={displayedTotalCents}\n fieldValues={fieldValues}\n isBillingAddressReady={isBillingAddressReady}\n isPaymentReady={isPaymentReady}\n isRequiredShippingReady={isRequiredShippingReady}\n isSubmitting={isSubmitting}\n onFieldValuesChange={handleFieldValuesChange}\n quote={quote}\n />\n </fieldset>\n </div>\n {isSubmitting ? (\n <p\n className=\"lockerverse-payment__sr-only\"\n ref={statusRef}\n role=\"status\"\n tabIndex={-1}\n >\n {displayedTotalCents === 0\n ? \"Completing order…\"\n : \"Processing payment…\"}\n </p>\n ) : null}\n <PaymentErrorMessage message={paymentError} />\n </form>\n );\n}\n\nfunction SkeletonLoaderBlock() {\n return (\n <div className=\"lockerverse-payment__skeleton-loader-block\">\n <span className=\"lockerverse-payment__skeleton-loader-label\" />\n <div className=\"lockerverse-payment__skeleton-loader-content\">\n <span className=\"lockerverse-payment__skeleton-loader-full\" />\n <div className=\"lockerverse-payment__skeleton-loader-grid\">\n <span className=\"lockerverse-payment__skeleton-loader-half\" />\n <span className=\"lockerverse-payment__skeleton-loader-half\" />\n </div>\n </div>\n </div>\n );\n}\n\nfunction PaymentSkeleton() {\n return (\n <div className=\"lockerverse-payment__loading\">\n <span\n aria-live=\"polite\"\n className=\"lockerverse-payment__sr-only\"\n role=\"status\"\n >\n Loading payment…\n </span>\n <div aria-hidden=\"true\" className=\"lockerverse-payment__skeleton\">\n <div className=\"lockerverse-payment__skeleton-branding\">\n <span className=\"lockerverse-payment__skeleton-avatar\" />\n <span className=\"lockerverse-payment__skeleton-community\" />\n </div>\n <div className=\"lockerverse-payment__skeleton-contact\">\n <div className=\"lockerverse-payment__skeleton-field\">\n <span className=\"lockerverse-payment__skeleton-label\" />\n <span className=\"lockerverse-payment__skeleton-input\" />\n </div>\n <div className=\"lockerverse-payment__skeleton-field\">\n <span className=\"lockerverse-payment__skeleton-label\" />\n <span className=\"lockerverse-payment__skeleton-input\" />\n </div>\n </div>\n <SkeletonLoaderBlock />\n <SkeletonLoaderBlock />\n <div className=\"lockerverse-payment__skeleton-actions\">\n <span className=\"lockerverse-payment__skeleton-check-line\" />\n <span className=\"lockerverse-payment__skeleton-button\" />\n </div>\n </div>\n </div>\n );\n}\n\nexport function LockerversePayment({\n apiBaseUrl,\n branding,\n className,\n communitySlug,\n environment,\n fetch,\n metadata,\n onError,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n requestTimeoutMs,\n resumePayment,\n selection,\n sentryDsn,\n style,\n stripeLoader = loadStripe,\n theme = \"dark\",\n widgetSlug,\n ...sectionProps\n}: LockerversePaymentProps) {\n const initialResumePayment = useRef(resumePayment).current;\n const selectPortalContainerRef = useRef<HTMLElement | null>(null);\n const [notice, setNotice] = useState<string>();\n const [paymentState, setPaymentState] =\n useState<CheckoutPaymentState>(\"idle\");\n const paymentStateRevisionRef = useRef<number | undefined>(undefined);\n const { retryCheckout, selectionError, session, updateCheckout } =\n usePaymentCheckout({\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n onError,\n paymentState,\n requestTimeoutMs,\n selection,\n sentryDsn,\n widgetSlug,\n });\n const readySessionRevision =\n session.phase === \"ready\" ? session.revision : undefined;\n const handlePaymentStateChange = useCallback(\n (state: CheckoutPaymentState) => {\n if (readySessionRevision !== undefined) {\n paymentStateRevisionRef.current = readySessionRevision;\n }\n setPaymentState(state);\n },\n [readySessionRevision]\n );\n\n useEffect(() => {\n if (session.phase === \"loading\") {\n setNotice(undefined);\n }\n }, [session.phase]);\n\n useLayoutEffect(() => {\n if (\n session.phase === \"ready\" &&\n paymentStateRevisionRef.current !== session.revision\n ) {\n setPaymentState((current) =>\n current === \"success\" || current === \"unresolved\" ? current : \"idle\"\n );\n }\n }, [session.phase, session.revision]);\n\n const rootClassName = [\"lockerverse-payment\", className]\n .filter(Boolean)\n .join(\" \");\n const effectiveBranding =\n branding ?? (session.phase === \"ready\" ? session.catalog.community : null);\n const effectiveAccent =\n style?.[\"--lockerverse-accent\"] ??\n effectiveBranding?.accentColor ??\n \"#38d77a\";\n const automaticAccentContrast = getAccentContrast(effectiveAccent);\n const rootStyle: LockerversePaymentProps[\"style\"] = {\n ...style,\n ...(effectiveBranding?.accentColor &&\n style?.[\"--lockerverse-accent\"] === undefined\n ? { \"--lockerverse-accent\": effectiveBranding.accentColor }\n : {}),\n ...(automaticAccentContrast &&\n style?.[\"--lockerverse-accent-contrast\"] === undefined\n ? { \"--lockerverse-accent-contrast\": automaticAccentContrast }\n : {}),\n };\n\n if (selectionError) {\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n role=\"alert\"\n style={rootStyle}\n >\n {selectionError}\n </section>\n );\n }\n\n if (session.phase === \"error\") {\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n style={rootStyle}\n >\n <p role=\"alert\">{session.failure}</p>\n <button onClick={retryCheckout} type=\"button\">\n Retry\n </button>\n </section>\n );\n }\n\n if (session.phase !== \"ready\") {\n return (\n <section\n {...sectionProps}\n aria-busy=\"true\"\n aria-label=\"Payment\"\n className={rootClassName}\n data-lockerverse-theme={theme}\n style={rootStyle}\n >\n <PaymentSkeleton />\n </section>\n );\n }\n\n const { catalog, checkoutItems, client, preparedCheckout } = session;\n\n return (\n <section\n {...sectionProps}\n aria-label=\"Payment\"\n className={rootClassName}\n data-lockerverse-theme={theme}\n data-payment-state={paymentState}\n ref={selectPortalContainerRef}\n style={rootStyle}\n >\n <header>\n {catalog.widget.showCommunityBranding && effectiveBranding ? (\n <div className=\"lockerverse-payment__branding\">\n {effectiveBranding.imageUrl ? (\n <img\n alt={effectiveBranding.name}\n height=\"48\"\n src={effectiveBranding.imageUrl}\n width=\"48\"\n />\n ) : null}\n <strong>{effectiveBranding.name}</strong>\n </div>\n ) : null}\n <h1>{catalog.widget.title ?? catalog.widget.name}</h1>\n {catalog.widget.description ? (\n <p>{catalog.widget.description}</p>\n ) : null}\n </header>\n {notice ? (\n <p className=\"lockerverse-payment__payment-status\" role=\"status\">\n {notice}\n </p>\n ) : null}\n <SelectPortalProvider container={selectPortalContainerRef}>\n <ReadyPayment\n accentColor={\n style?.[\"--lockerverse-accent\"] ??\n effectiveBranding?.accentColor ??\n \"#38d77a\"\n }\n catalog={catalog}\n checkoutItems={checkoutItems}\n client={client}\n fontFamily={\n style?.[\"--lockerverse-font-family\"] ?? DEFAULT_FONT_FAMILY\n }\n metadata={metadata}\n onPaymentComplete={onPaymentComplete}\n onPaymentRecoveryChange={onPaymentRecoveryChange}\n onPaymentUncertain={onPaymentUncertain}\n onQuoteChange={(nextQuote, nextNotice) => {\n setNotice(nextNotice);\n updateCheckout(nextQuote);\n }}\n onStateChange={handlePaymentStateChange}\n quote={preparedCheckout}\n resumePayment={initialResumePayment}\n stripeLoader={stripeLoader}\n theme={theme}\n visualStyle={rootStyle}\n />\n </SelectPortalProvider>\n </section>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lockerverse-payment.js","names":["formatMoney","normalizeContactPhone","formatMoney"],"sources":["../src/select-control.tsx","../src/checkout-fields.tsx","../src/payment-validation.ts","../src/payment-input.ts","../src/use-payment-checkout.ts","../src/payment-attempt.ts","../src/payment-workflow.ts","../src/use-payment-form-workflow.ts","../src/lockerverse-payment.tsx"],"sourcesContent":["import { Select } from \"@base-ui/react/select\";\nimport {\n createContext,\n type ReactNode,\n type RefObject,\n useContext,\n} from \"react\";\n\nexport type LockerverseSelectOption = {\n label: string;\n value: string;\n};\n\nconst SelectPortalContext = createContext<\n RefObject<HTMLElement | null> | undefined\n>(undefined);\n\nexport function SelectPortalProvider({\n children,\n container,\n}: {\n children: ReactNode;\n container: RefObject<HTMLElement | null>;\n}) {\n return (\n <SelectPortalContext.Provider value={container}>\n {children}\n </SelectPortalContext.Provider>\n );\n}\n\nfunction SelectIcon() {\n return (\n <svg aria-hidden=\"true\" fill=\"none\" viewBox=\"0 0 16 16\">\n <path d=\"m4 6 4 4 4-4\" />\n </svg>\n );\n}\n\nfunction SelectedIcon() {\n return (\n <svg aria-hidden=\"true\" fill=\"none\" viewBox=\"0 0 16 16\">\n <path d=\"m3 8 3 3 7-7\" />\n </svg>\n );\n}\n\nexport function LockerverseSelect({\n ariaDescribedBy,\n ariaLabel,\n ariaLabelledBy,\n className,\n id,\n invalid = false,\n name,\n onValueChange,\n options,\n value,\n}: {\n ariaDescribedBy?: string;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n className?: string;\n id?: string;\n invalid?: boolean;\n name: string;\n onValueChange: (value: string) => void;\n options: readonly LockerverseSelectOption[];\n value: string;\n}) {\n const portalContainer = useContext(SelectPortalContext);\n const rootClassName = [\"lockerverse-payment__select\", className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={rootClassName}>\n <Select.Root\n id={id}\n items={options}\n name={name}\n onValueChange={(nextValue) => {\n if (nextValue !== null) {\n onValueChange(nextValue);\n }\n }}\n value={value}\n >\n <Select.Trigger\n aria-describedby={ariaDescribedBy}\n aria-invalid={invalid || undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className=\"lockerverse-payment__select-trigger\"\n >\n <Select.Value />\n <Select.Icon\n aria-hidden=\"true\"\n className=\"lockerverse-payment__select-icon\"\n >\n <SelectIcon />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal container={portalContainer}>\n <Select.Positioner\n alignItemWithTrigger={false}\n className=\"lockerverse-payment__select-positioner\"\n sideOffset={6}\n >\n <Select.Popup className=\"lockerverse-payment__select-popup\">\n <Select.List className=\"lockerverse-payment__select-list\">\n {options.map((option) => (\n <Select.Item\n className=\"lockerverse-payment__select-item\"\n key={option.value}\n value={option.value}\n >\n <Select.ItemText>{option.label}</Select.ItemText>\n <Select.ItemIndicator\n aria-hidden=\"true\"\n className=\"lockerverse-payment__select-item-indicator\"\n >\n <SelectedIcon />\n </Select.ItemIndicator>\n </Select.Item>\n ))}\n </Select.List>\n </Select.Popup>\n </Select.Positioner>\n </Select.Portal>\n </Select.Root>\n </div>\n );\n}\n","import type {\n LockerverseCustomField,\n LockerverseWidgetFields,\n} from \"@lockerverse/sdk/checkout\";\nimport { CustomFields } from \"./custom-fields.tsx\";\nimport { LockerverseSelect } from \"./select-control.tsx\";\n\nexport const MERCH_SIZES = [\"XS\", \"S\", \"M\", \"L\", \"XL\", \"XXL\", \"XXXL\"] as const;\n\nexport type CheckoutFieldValues = {\n customTip: string;\n customFields: Record<string, string | string[]>;\n includeServiceFee: boolean;\n memberId: string;\n merchSize: (typeof MERCH_SIZES)[number];\n promoCode: string;\n shippingMatchesBilling: boolean;\n tipPercent: \"5\" | \"10\" | \"12\" | \"15\" | \"custom\";\n};\n\nconst TIP_OPTIONS = [\"15\", \"12\", \"10\", \"5\"] as const;\nconst TIP_VALUES = [...TIP_OPTIONS, \"custom\"] as const;\n\nexport function TipField({\n enabled,\n error,\n errorId,\n onChange,\n values,\n}: {\n enabled: boolean;\n error: string | undefined;\n errorId: string;\n onChange: (values: CheckoutFieldValues) => void;\n values: CheckoutFieldValues;\n}) {\n if (!enabled) {\n return null;\n }\n const update = (next: Partial<CheckoutFieldValues>) =>\n onChange({ ...values, ...next });\n const handleKeyDown = (\n event: React.KeyboardEvent<HTMLInputElement>,\n currentValue: CheckoutFieldValues[\"tipPercent\"]\n ) => {\n const currentIndex = TIP_VALUES.indexOf(currentValue);\n let nextIndex: number | undefined;\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowRight\":\n nextIndex = (currentIndex + 1) % TIP_VALUES.length;\n break;\n case \"ArrowLeft\":\n case \"ArrowUp\":\n nextIndex = (currentIndex - 1 + TIP_VALUES.length) % TIP_VALUES.length;\n break;\n case \"Home\":\n nextIndex = 0;\n break;\n case \"End\":\n nextIndex = TIP_VALUES.length - 1;\n break;\n default:\n return;\n }\n event.preventDefault();\n const nextValue = TIP_VALUES[nextIndex];\n if (!nextValue) {\n return;\n }\n const radios = event.currentTarget\n .closest('[role=\"radiogroup\"]')\n ?.querySelectorAll<HTMLElement>('input[type=\"radio\"]');\n radios?.[nextIndex]?.focus();\n update({ tipPercent: nextValue });\n };\n return (\n <div className=\"lockerverse-payment__tip-box\">\n <p>Add a tip to support the Lockerverse platform</p>\n <div aria-label=\"Tip amount\" role=\"radiogroup\">\n {TIP_OPTIONS.map((tip) => (\n <label className=\"lockerverse-payment__tip-choice\" key={tip}>\n <input\n checked={values.tipPercent === tip}\n name=\"tipPercent\"\n onChange={() => update({ tipPercent: tip })}\n onKeyDown={(event) => handleKeyDown(event, tip)}\n tabIndex={values.tipPercent === tip ? 0 : -1}\n type=\"radio\"\n value={tip}\n />\n <span>{tip}%</span>\n </label>\n ))}\n <label className=\"lockerverse-payment__tip-choice\">\n <input\n checked={values.tipPercent === \"custom\"}\n name=\"tipPercent\"\n onChange={() => update({ tipPercent: \"custom\" })}\n onKeyDown={(event) => handleKeyDown(event, \"custom\")}\n tabIndex={values.tipPercent === \"custom\" ? 0 : -1}\n type=\"radio\"\n value=\"custom\"\n />\n <span>Other</span>\n </label>\n </div>\n {values.tipPercent === \"custom\" ? (\n <label>\n <span>Custom tip</span>\n <span className=\"lockerverse-payment__money-input\">\n <span aria-hidden=\"true\">$</span>\n <input\n aria-describedby={error ? errorId : undefined}\n aria-invalid={error ? \"true\" : undefined}\n inputMode=\"decimal\"\n name=\"tip\"\n onChange={(event) =>\n update({ customTip: event.currentTarget.value })\n }\n placeholder=\"0.00\"\n value={values.customTip}\n />\n </span>\n {error ? (\n <span className=\"lockerverse-payment__field-message\" id={errorId}>\n {error}\n </span>\n ) : null}\n </label>\n ) : (\n <input name=\"tip\" type=\"hidden\" value={values.tipPercent} />\n )}\n </div>\n );\n}\n\nexport function CheckoutToggle({\n checked,\n children,\n name,\n onChange,\n}: {\n checked: boolean;\n children: React.ReactNode;\n name: string;\n onChange: (checked: boolean) => void;\n}) {\n return (\n <label className=\"lockerverse-payment__check-row\">\n <input\n checked={checked}\n name={name}\n onChange={(event) => onChange(event.currentTarget.checked)}\n type=\"checkbox\"\n />\n <span>{children}</span>\n </label>\n );\n}\n\nexport function AdditionalCheckoutFields({\n customFields,\n errors,\n fields,\n idPrefix,\n isPromoApplying,\n onChange,\n onApplyPromo,\n promoError,\n values,\n}: {\n customFields: LockerverseCustomField[];\n errors: Record<string, string>;\n fields: LockerverseWidgetFields;\n idPrefix: string;\n isPromoApplying: boolean;\n onChange: (values: CheckoutFieldValues) => void;\n onApplyPromo: () => void;\n promoError: string | undefined;\n values: CheckoutFieldValues;\n}) {\n const update = (next: Partial<CheckoutFieldValues>) =>\n onChange({ ...values, ...next });\n\n return (\n <div className=\"lockerverse-payment__additional-fields\">\n {fields.memberId ? (\n <label>\n <span>Member ID</span>\n <input\n name=\"memberId\"\n onChange={(event) =>\n update({ memberId: event.currentTarget.value })\n }\n placeholder=\"Optional\"\n value={values.memberId}\n />\n </label>\n ) : null}\n {fields.merchSize ? (\n <div className=\"lockerverse-payment__field\">\n <span id={`${idPrefix}-merch-size-label`}>Size</span>\n <LockerverseSelect\n ariaLabelledBy={`${idPrefix}-merch-size-label`}\n name=\"merchSize\"\n onValueChange={(merchSize) =>\n update({\n merchSize: merchSize as CheckoutFieldValues[\"merchSize\"],\n })\n }\n options={MERCH_SIZES.map((size) => ({\n label: size,\n value: size,\n }))}\n value={values.merchSize}\n />\n </div>\n ) : null}\n {fields.promoCode ? (\n <div className=\"lockerverse-payment__field\">\n <span id={`${idPrefix}-promo-code-label`}>Promo code</span>\n <div className=\"lockerverse-payment__promo-control\">\n <input\n aria-describedby={\n promoError ? `${idPrefix}-promo-code-error` : undefined\n }\n aria-invalid={promoError ? \"true\" : undefined}\n aria-labelledby={`${idPrefix}-promo-code-label`}\n name=\"promoCode\"\n onChange={(event) =>\n update({ promoCode: event.currentTarget.value })\n }\n placeholder=\"Optional\"\n value={values.promoCode}\n />\n <button\n disabled={!values.promoCode.trim() || isPromoApplying}\n onClick={onApplyPromo}\n type=\"button\"\n >\n {isPromoApplying ? \"Applying…\" : \"Apply\"}\n </button>\n </div>\n {promoError ? (\n <p\n className=\"lockerverse-payment__field-message\"\n id={`${idPrefix}-promo-code-error`}\n role=\"alert\"\n >\n {promoError}\n </p>\n ) : null}\n </div>\n ) : null}\n <CustomFields\n choiceClassName=\"lockerverse-payment__check-row\"\n errorClassName=\"lockerverse-payment__field-message\"\n errors={errors}\n fields={customFields}\n idPrefix={idPrefix}\n onChange={(nextCustomFields) =>\n update({ customFields: nextCustomFields })\n }\n values={values.customFields}\n />\n </div>\n );\n}\n\nexport function ServiceFeeField({\n amountCents,\n enabled,\n onChange,\n values,\n}: {\n amountCents: number;\n enabled: boolean;\n onChange: (values: CheckoutFieldValues) => void;\n values: CheckoutFieldValues;\n}) {\n if (!enabled) {\n return null;\n }\n return (\n <CheckoutToggle\n checked={values.includeServiceFee}\n name=\"includeServiceFee\"\n onChange={(includeServiceFee) =>\n onChange({ ...values, includeServiceFee })\n }\n >\n Add {formatMoney(amountCents)} to help cover processing fees\n </CheckoutToggle>\n );\n}\n\nfunction formatMoney(amountCents: number) {\n return new Intl.NumberFormat(\"en-US\", {\n currency: \"USD\",\n style: \"currency\",\n }).format(amountCents / 100);\n}\n","import { object, safeParse } from \"valibot\";\nimport {\n normalizePhone as normalizeContactPhone,\n requiredEmailSchema,\n requiredPhoneSchema,\n} from \"./contact-validation.ts\";\n\nexport function normalizePhone(input: string) {\n return normalizeContactPhone(input);\n}\n\nexport type ContactErrors = {\n email?: string;\n phone?: string;\n};\n\nexport function validateContact(\n input: { email: string; phone: string },\n requiresPhone: boolean\n) {\n const normalizedInput = requiresPhone\n ? { ...input, phone: normalizePhone(input.phone) }\n : input;\n const schema = requiresPhone\n ? object({ email: requiredEmailSchema, phone: requiredPhoneSchema })\n : object({ email: requiredEmailSchema });\n const result = safeParse(schema, normalizedInput);\n\n if (result.success) {\n return { errors: {} as ContactErrors, value: result.output } as const;\n }\n\n const errors: ContactErrors = {};\n for (const issue of result.issues) {\n const field = issue.path?.[0]?.key;\n if ((field === \"email\" || field === \"phone\") && !errors[field]) {\n errors[field] = issue.message;\n }\n }\n return { errors, value: null } as const;\n}\n","import {\n array,\n minLength,\n minValue,\n nonEmpty,\n number,\n pipe,\n regex,\n safeInteger,\n safeParse,\n strictObject,\n string,\n trim,\n union,\n} from \"valibot\";\n\nconst productSlugSchema = pipe(string(), trim(), nonEmpty());\nconst positiveSafeIntegerSchema = pipe(number(), safeInteger(), minValue(1));\n\nconst paymentSelectionSchema = pipe(\n array(\n union([\n strictObject({\n amountCents: positiveSafeIntegerSchema,\n productSlug: productSlugSchema,\n }),\n strictObject({\n productSlug: productSlugSchema,\n quantity: positiveSafeIntegerSchema,\n }),\n ])\n ),\n minLength(1)\n);\n\nconst customTipSchema = pipe(\n string(),\n trim(),\n regex(/^(?:0|[1-9]\\d*)(?:\\.\\d{1,2})?$/, \"Enter a valid tip amount.\")\n);\n\nexport function parseCustomTipCents(input: string) {\n const result = safeParse(customTipSchema, input);\n if (!result.success) {\n return {\n message: result.issues[0]?.message ?? \"Enter a valid tip amount.\",\n success: false,\n } as const;\n }\n const [dollars = \"0\", fraction = \"\"] = result.output.split(\".\");\n const cents = BigInt(dollars) * 100n + BigInt(fraction.padEnd(2, \"0\"));\n if (cents > BigInt(Number.MAX_SAFE_INTEGER)) {\n return { message: \"Enter a valid tip amount.\", success: false } as const;\n }\n return { cents: Number(cents), success: true } as const;\n}\n\nexport function parsePaymentSelection(input: unknown) {\n const result = safeParse(paymentSelectionSchema, input);\n return result.success\n ? ({ success: true, value: result.output } as const)\n : ({\n message: \"Lockerverse payment configuration is invalid.\",\n success: false,\n } as const);\n}\n","import type {\n CreateLockerverseWidgetOptions,\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutItem,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport { createLockerverseCheckoutClient } from \"@lockerverse/sdk/checkout\";\nimport { useEffect, useMemo, useReducer, useRef } from \"react\";\nimport { parsePaymentSelection } from \"./payment-input.ts\";\nimport type {\n LockerversePaymentProps,\n LockerversePaymentSelectionItem,\n} from \"./types.ts\";\n\nexport type CheckoutPaymentState =\n | \"error\"\n | \"idle\"\n | \"invalid\"\n | \"submitting\"\n | \"success\"\n | \"unresolved\";\n\ntype CheckoutConfiguration = {\n apiBaseUrl: LockerversePaymentProps[\"apiBaseUrl\"] | undefined;\n communitySlug: string;\n environment: LockerversePaymentProps[\"environment\"] | undefined;\n fetch: LockerversePaymentProps[\"fetch\"] | undefined;\n requestTimeoutMs: number | undefined;\n sentryDsn: string | null | undefined;\n widgetSlug: string;\n};\n\ntype SessionState =\n | { phase: \"idle\"; revision: number }\n | {\n configuration: CheckoutConfiguration;\n phase: \"loading\";\n revision: number;\n selectionKey: string;\n }\n | {\n configuration: CheckoutConfiguration;\n failure: string;\n phase: \"error\";\n revision: number;\n selectionKey: string;\n }\n | {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n configuration: CheckoutConfiguration;\n phase: \"ready\";\n preparedCheckout: LockerversePreparedCheckout;\n revision: number;\n selectionKey: string;\n };\n\ntype SessionAction =\n | {\n configuration: CheckoutConfiguration;\n selectionKey: string;\n type: \"loading\";\n }\n | {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n configuration: CheckoutConfiguration;\n preparedCheckout: LockerversePreparedCheckout;\n selectionKey: string;\n type: \"ready\";\n }\n | {\n configuration: CheckoutConfiguration;\n failure: string;\n selectionKey: string;\n type: \"error\";\n }\n | { preparedCheckout: LockerversePreparedCheckout; type: \"checkout\" }\n | { type: \"retry\" };\n\ntype LoadIdentity = {\n configuration: CheckoutConfiguration;\n selectionKey: string;\n};\n\nfunction sessionReducer(\n state: SessionState,\n action: SessionAction\n): SessionState {\n switch (action.type) {\n case \"loading\":\n return {\n configuration: action.configuration,\n phase: \"loading\",\n revision: state.revision,\n selectionKey: action.selectionKey,\n };\n case \"ready\":\n return {\n catalog: action.catalog,\n checkoutItems: action.checkoutItems,\n client: action.client,\n configuration: action.configuration,\n phase: \"ready\",\n preparedCheckout: action.preparedCheckout,\n revision: state.revision + 1,\n selectionKey: action.selectionKey,\n };\n case \"error\":\n return {\n configuration: action.configuration,\n failure: action.failure,\n phase: \"error\",\n revision: state.revision,\n selectionKey: action.selectionKey,\n };\n case \"checkout\":\n return state.phase === \"ready\"\n ? { ...state, preparedCheckout: action.preparedCheckout }\n : state;\n case \"retry\":\n return { phase: \"idle\", revision: state.revision + 1 };\n default:\n return state;\n }\n}\n\nfunction createCheckoutOptions(\n configuration: CheckoutConfiguration,\n onError: LockerversePaymentProps[\"onError\"]\n): CreateLockerverseWidgetOptions {\n const {\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n requestTimeoutMs,\n sentryDsn,\n widgetSlug,\n } = configuration;\n const common = {\n communitySlug,\n widgetSlug,\n ...(fetch ? { fetch } : {}),\n ...(onError ? { onError } : {}),\n ...(requestTimeoutMs === undefined ? {} : { requestTimeoutMs }),\n ...(sentryDsn === undefined ? {} : { sentryDsn }),\n };\n if (apiBaseUrl === undefined) {\n if (environment === \"development\") {\n throw new TypeError(\n \"Lockerverse development checkout requires an API base URL.\"\n );\n }\n return {\n ...common,\n ...(environment === \"production\" ? { environment } : {}),\n };\n }\n return {\n ...common,\n apiBaseUrl,\n ...(environment === undefined ? {} : { environment }),\n };\n}\n\nfunction isSameLoad(\n identity: LoadIdentity | undefined,\n configuration: CheckoutConfiguration,\n selectionKey: string\n) {\n return (\n identity?.configuration === configuration &&\n identity.selectionKey === selectionKey\n );\n}\n\nexport function usePaymentCheckout({\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n onError,\n paymentState,\n requestTimeoutMs,\n selection,\n sentryDsn,\n widgetSlug,\n}: CheckoutConfiguration & {\n onError: LockerversePaymentProps[\"onError\"];\n paymentState: CheckoutPaymentState;\n selection: LockerversePaymentProps[\"selection\"];\n}) {\n const configuration = useMemo<CheckoutConfiguration>(\n () => ({\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n requestTimeoutMs,\n sentryDsn,\n widgetSlug,\n }),\n [\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n requestTimeoutMs,\n sentryDsn,\n widgetSlug,\n ]\n );\n const parsedSelection = parsePaymentSelection(selection);\n const selectionKey = parsedSelection.success\n ? JSON.stringify(parsedSelection.value)\n : \"invalid-selection\";\n const stableSelection = useMemo(\n () =>\n parsedSelection.success\n ? (JSON.parse(selectionKey) as LockerversePaymentSelectionItem[])\n : [],\n [parsedSelection.success, selectionKey]\n );\n const [session, dispatch] = useReducer(sessionReducer, {\n phase: \"idle\",\n revision: 0,\n });\n const loadingRef = useRef<LoadIdentity | undefined>(undefined);\n const settledRef = useRef<LoadIdentity | undefined>(undefined);\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n\n useEffect(() => {\n if (!parsedSelection.success) {\n return;\n }\n if (\n paymentState === \"submitting\" ||\n paymentState === \"success\" ||\n paymentState === \"unresolved\" ||\n isSameLoad(settledRef.current, configuration, selectionKey) ||\n isSameLoad(loadingRef.current, configuration, selectionKey)\n ) {\n return;\n }\n\n let active = true;\n const identity = { configuration, selectionKey };\n loadingRef.current = identity;\n dispatch({ configuration, selectionKey, type: \"loading\" });\n\n async function loadPayment() {\n try {\n const client = createLockerverseCheckoutClient(\n createCheckoutOptions(configuration, (error) =>\n onErrorRef.current?.(error)\n )\n );\n const { catalog, checkout: preparedCheckout } =\n await client.bootstrapCheckout({ items: stableSelection });\n const checkoutItems = [...preparedCheckout.items];\n if (active) {\n loadingRef.current = undefined;\n settledRef.current = identity;\n dispatch({\n catalog,\n checkoutItems,\n client,\n configuration,\n preparedCheckout,\n selectionKey,\n type: \"ready\",\n });\n }\n } catch (error) {\n if (active) {\n loadingRef.current = undefined;\n settledRef.current = identity;\n dispatch({\n configuration,\n failure:\n error instanceof Error\n ? error.message\n : \"Lockerverse payment could not load.\",\n selectionKey,\n type: \"error\",\n });\n }\n }\n }\n\n loadPayment();\n return () => {\n active = false;\n if (isSameLoad(loadingRef.current, configuration, selectionKey)) {\n loadingRef.current = undefined;\n }\n };\n }, [\n configuration,\n parsedSelection.success,\n paymentState,\n selectionKey,\n session.revision,\n stableSelection,\n ]);\n\n return {\n retryCheckout: () => {\n loadingRef.current = undefined;\n settledRef.current = undefined;\n dispatch({ type: \"retry\" });\n },\n selectionError: parsedSelection.success\n ? undefined\n : parsedSelection.message,\n session,\n updateCheckout: (preparedCheckout: LockerversePreparedCheckout) =>\n dispatch({ preparedCheckout, type: \"checkout\" }),\n };\n}\n","import type {\n LockerverseCheckoutClient,\n LockerverseCheckoutQuote,\n LockerversePaymentResult,\n LockerverseSubmitPaymentInput,\n} from \"@lockerverse/sdk/checkout\";\nimport { LockerverseSdkError } from \"@lockerverse/sdk/checkout\";\nimport type { Stripe } from \"@stripe/stripe-js\";\n\nconst AMOUNT_KEYS = [\n \"amountCents\",\n \"discountableSubtotalCents\",\n \"discountCents\",\n \"serviceFeeCents\",\n \"subtotalCents\",\n \"tipCents\",\n \"totalCents\",\n] as const satisfies readonly (keyof LockerverseCheckoutQuote)[];\n\nconst SERVER_CONTROLLED_AMOUNT_KEYS = [\n \"discountableSubtotalCents\",\n \"discountCents\",\n \"subtotalCents\",\n] as const satisfies readonly (keyof LockerverseCheckoutQuote)[];\n\nexport function hasMaterialQuoteChange(\n displayed: LockerverseCheckoutQuote,\n current: LockerverseCheckoutQuote,\n locallyPreviewedTotalCents?: number\n) {\n const amountKeys =\n locallyPreviewedTotalCents === current.totalCents\n ? SERVER_CONTROLLED_AMOUNT_KEYS\n : AMOUNT_KEYS;\n return (\n amountKeys.some((key) => displayed[key] !== current[key]) ||\n displayed.payment.connectedAccountId !==\n current.payment.connectedAccountId ||\n displayed.payment.currency !== current.payment.currency ||\n JSON.stringify(displayed.appliedDiscount) !==\n JSON.stringify(current.appliedDiscount) ||\n JSON.stringify(displayed.lineItems) !== JSON.stringify(current.lineItems)\n );\n}\n\nexport type PaymentAttemptOutcome =\n | { kind: \"failed\"; payment: LockerversePaymentResult }\n | { kind: \"success\"; payment: LockerversePaymentResult }\n | {\n kind: \"unresolved\";\n paymentReference: string;\n reason: \"action_required\" | \"pending\" | \"recovery_failed\";\n };\n\nfunction classifyPayment(\n payment: LockerversePaymentResult\n): PaymentAttemptOutcome {\n if (payment.checkoutStatus === \"success\") {\n return { kind: \"success\", payment };\n }\n if (payment.checkoutStatus === \"failed\") {\n return { kind: \"failed\", payment };\n }\n return {\n kind: \"unresolved\",\n paymentReference: payment.paymentReference,\n reason:\n payment.checkoutStatus === \"action_required\"\n ? \"action_required\"\n : \"pending\",\n };\n}\n\nasync function settleRequiredAction(\n client: LockerverseCheckoutClient,\n payment: LockerversePaymentResult,\n stripe: Stripe | null | undefined\n): Promise<PaymentAttemptOutcome> {\n if (payment.checkoutStatus !== \"action_required\") {\n return classifyPayment(payment);\n }\n if (!stripe) {\n return {\n kind: \"unresolved\",\n paymentReference: payment.paymentReference,\n reason: \"action_required\",\n };\n }\n if (payment.clientSecret) {\n try {\n await stripe.handleNextAction({ clientSecret: payment.clientSecret });\n } catch {\n // Status recovery below is authoritative even when Stripe UI fails.\n }\n }\n try {\n const recovered = await client.getPaymentStatus(payment.paymentReference);\n return classifyPayment(recovered);\n } catch {\n return {\n kind: \"unresolved\",\n paymentReference: payment.paymentReference,\n reason: \"action_required\",\n };\n }\n}\n\nexport async function submitPaymentAttempt(\n client: LockerverseCheckoutClient,\n input: LockerverseSubmitPaymentInput,\n stripe?: Stripe | null\n): Promise<PaymentAttemptOutcome> {\n let payment: LockerversePaymentResult;\n try {\n payment = await client.submitPayment(input);\n } catch (error) {\n if (!(error instanceof LockerverseSdkError && error.recoveryRecommended)) {\n throw error;\n }\n try {\n payment = await client.getPaymentStatus(input.checkout.paymentReference);\n } catch {\n return {\n kind: \"unresolved\",\n paymentReference: input.checkout.paymentReference,\n reason: \"recovery_failed\",\n };\n }\n }\n return settleRequiredAction(client, payment, stripe);\n}\n\nexport async function recoverPaymentAttempt(\n client: LockerverseCheckoutClient,\n paymentReference: string,\n stripe: Stripe\n): Promise<PaymentAttemptOutcome> {\n try {\n const payment = await client.getPaymentStatus(paymentReference);\n return settleRequiredAction(client, payment, stripe);\n } catch {\n return {\n kind: \"unresolved\",\n paymentReference,\n reason: \"recovery_failed\",\n };\n }\n}\n","import type {\n LockerversePaymentProps,\n LockerversePaymentUncertain,\n} from \"./types.ts\";\n\ntype EditablePaymentWorkflowState = {\n error?: string;\n phase: \"editing\" | \"invalid\";\n};\n\nexport type PaymentWorkflowState =\n | EditablePaymentWorkflowState\n | {\n phase: \"refreshing_quote\";\n previousError?: string;\n validatePromo: boolean;\n }\n | { phase: \"submitting\" }\n | { phase: \"recovering\" }\n | { message: string; phase: \"succeeded\" }\n | {\n message: string;\n paymentReference: string;\n phase: \"unresolved\";\n reason: LockerversePaymentUncertain[\"reason\"];\n };\n\nexport type PaymentWorkflowEvent =\n | { type: \"field_changed\" }\n | { type: \"validation_failed\" }\n | { type: \"quote_refresh_started\"; validatePromo: boolean }\n | { type: \"quote_refresh_succeeded\" }\n | { error?: string; type: \"quote_refresh_failed\" }\n | { type: \"submission_started\" }\n | { type: \"quote_changed\" }\n | { error: string; type: \"retryable_failure\" }\n | { error: string; type: \"recovery_failed\" }\n | { message: string; type: \"succeeded\" }\n | {\n message: string;\n paymentReference: string;\n reason: LockerversePaymentUncertain[\"reason\"];\n type: \"unresolved\";\n };\n\nexport type PaymentWorkflowUiState =\n | \"error\"\n | \"idle\"\n | \"invalid\"\n | \"submitting\"\n | \"success\"\n | \"unresolved\";\n\nfunction assertNever(value: never): never {\n throw new Error(`Unexpected payment workflow value: ${String(value)}`);\n}\n\nfunction createEditableState(\n phase: EditablePaymentWorkflowState[\"phase\"],\n error?: string\n): EditablePaymentWorkflowState {\n return error === undefined ? { phase } : { error, phase };\n}\n\nexport function createPaymentWorkflowState(\n resumePayment: LockerversePaymentProps[\"resumePayment\"]\n): PaymentWorkflowState {\n return resumePayment ? { phase: \"recovering\" } : { phase: \"editing\" };\n}\n\nexport function getPaymentError(state: PaymentWorkflowState) {\n if (state.phase === \"editing\" || state.phase === \"invalid\") {\n return state.error;\n }\n return state.phase === \"refreshing_quote\" ? state.previousError : undefined;\n}\n\nexport function getPaymentUiState(\n state: PaymentWorkflowState\n): PaymentWorkflowUiState {\n if (state.phase === \"succeeded\") {\n return \"success\";\n }\n if (state.phase === \"unresolved\") {\n return \"unresolved\";\n }\n if (state.phase === \"submitting\" || state.phase === \"recovering\") {\n return \"submitting\";\n }\n if (state.phase === \"invalid\") {\n return \"invalid\";\n }\n return getPaymentError(state) ? \"error\" : \"idle\";\n}\n\nexport function isPaymentBusy(state: PaymentWorkflowState) {\n return state.phase === \"submitting\";\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Explicit cases keep payment transitions auditable.\nexport function paymentWorkflowReducer(\n state: PaymentWorkflowState,\n event: PaymentWorkflowEvent\n): PaymentWorkflowState {\n if (state.phase === \"succeeded\" || state.phase === \"unresolved\") {\n return state;\n }\n\n switch (event.type) {\n case \"field_changed\":\n return state.phase === \"invalid\"\n ? createEditableState(\"editing\", state.error)\n : state;\n case \"validation_failed\":\n return state.phase === \"submitting\" || state.phase === \"recovering\"\n ? state\n : createEditableState(\"invalid\", getPaymentError(state));\n case \"quote_refresh_started\": {\n if (state.phase === \"submitting\" || state.phase === \"recovering\") {\n return state;\n }\n const previousError = getPaymentError(state);\n return {\n ...(previousError === undefined ? {} : { previousError }),\n phase: \"refreshing_quote\",\n validatePromo: event.validatePromo,\n };\n }\n case \"quote_refresh_succeeded\":\n return state.phase === \"refreshing_quote\" ? { phase: \"editing\" } : state;\n case \"quote_refresh_failed\":\n return state.phase === \"refreshing_quote\"\n ? createEditableState(\"editing\", event.error ?? state.previousError)\n : state;\n case \"submission_started\":\n return state.phase === \"recovering\" ? state : { phase: \"submitting\" };\n case \"quote_changed\":\n return state.phase === \"submitting\" ? { phase: \"editing\" } : state;\n case \"retryable_failure\":\n return createEditableState(\"editing\", event.error);\n case \"recovery_failed\":\n return state.phase === \"recovering\"\n ? createEditableState(\"editing\", event.error)\n : state;\n case \"succeeded\":\n return state.phase === \"submitting\" || state.phase === \"recovering\"\n ? { message: event.message, phase: \"succeeded\" }\n : state;\n case \"unresolved\":\n return state.phase === \"submitting\" || state.phase === \"recovering\"\n ? {\n message: event.message,\n paymentReference: event.paymentReference,\n phase: \"unresolved\",\n reason: event.reason,\n }\n : state;\n default:\n return assertNever(event);\n }\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutItem,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport type {\n Stripe,\n StripeAddressElementChangeEvent,\n StripeElements,\n} from \"@stripe/stripe-js\";\nimport { useCallback, useEffect, useReducer, useRef, useState } from \"react\";\nimport type { CheckoutFieldValues } from \"./checkout-fields.tsx\";\nimport { buildCustomFieldAnswers } from \"./custom-fields.tsx\";\nimport {\n hasMaterialQuoteChange,\n recoverPaymentAttempt,\n submitPaymentAttempt,\n} from \"./payment-attempt.ts\";\nimport { parseCustomTipCents } from \"./payment-input.ts\";\nimport { normalizePhone, validateContact } from \"./payment-validation.ts\";\nimport {\n createPaymentWorkflowState,\n getPaymentError,\n getPaymentUiState,\n isPaymentBusy,\n type PaymentWorkflowEvent,\n type PaymentWorkflowUiState,\n paymentWorkflowReducer,\n} from \"./payment-workflow.ts\";\nimport type { LockerversePaymentProps } from \"./types.ts\";\n\nexport type CheckoutAddresses = Record<\n \"billing\" | \"shipping\",\n StripeAddressElementChangeEvent | null\n>;\n\nexport function getTipCents(\n subtotalCents: number,\n values: Pick<CheckoutFieldValues, \"customTip\" | \"tipPercent\">\n) {\n if (values.tipPercent === \"custom\") {\n if (!values.customTip.trim()) {\n return { cents: 0, success: true } as const;\n }\n return parseCustomTipCents(values.customTip);\n }\n return {\n cents: Math.round((subtotalCents * Number(values.tipPercent)) / 100),\n success: true,\n } as const;\n}\n\nfunction buildQuoteRequest(\n catalog: LockerverseCatalog,\n fieldValues: CheckoutFieldValues,\n email: string,\n tipCents: number\n) {\n return {\n ...(email ? { email } : {}),\n ...(catalog.widget.fields.serviceFee\n ? { includeServiceFee: fieldValues.includeServiceFee }\n : {}),\n ...(catalog.widget.fields.promoCode && fieldValues.promoCode.trim()\n ? { promoCode: fieldValues.promoCode.trim() }\n : {}),\n ...(catalog.widget.fields.tipping ? { tipCents } : {}),\n };\n}\n\nfunction getCompleteAddress(\n address: StripeAddressElementChangeEvent | null,\n label: \"Billing\" | \"Shipping\"\n) {\n if (!address?.complete) {\n throw new Error(`${label} address is required.`);\n }\n return address.value;\n}\n\nfunction getShippingAddress(\n catalog: LockerverseCatalog,\n fieldValues: CheckoutFieldValues,\n billingAddress: ReturnType<typeof getCompleteAddress>,\n addresses: CheckoutAddresses\n) {\n if (!catalog.widget.fields.shipping) {\n return;\n }\n return fieldValues.shippingMatchesBilling\n ? billingAddress\n : getCompleteAddress(addresses.shipping, \"Shipping\");\n}\n\nfunction buildConfirmationParams({\n billingAddress,\n catalog,\n email,\n phone,\n shippingAddress,\n}: {\n billingAddress: ReturnType<typeof getCompleteAddress>;\n catalog: LockerverseCatalog;\n email: string;\n phone: string;\n shippingAddress: Awaited<ReturnType<typeof getCompleteAddress>> | undefined;\n}) {\n return {\n payment_method_data: {\n billing_details: {\n address: billingAddress.address,\n email,\n name: billingAddress.name,\n ...(catalog.widget.fields.phone ? { phone } : {}),\n },\n },\n ...(shippingAddress\n ? {\n shipping: {\n address: shippingAddress.address,\n name: shippingAddress.name,\n phone: catalog.widget.fields.phone\n ? phone\n : (shippingAddress.phone ?? null),\n },\n }\n : {}),\n };\n}\n\nfunction buildPaymentRequest({\n catalog,\n confirmationToken,\n email,\n fieldValues,\n metadata,\n phone,\n shippingAddress,\n}: {\n catalog: LockerverseCatalog;\n confirmationToken?: string;\n email: string;\n fieldValues: CheckoutFieldValues;\n metadata: Record<string, string> | undefined;\n phone: string;\n shippingAddress?: Awaited<ReturnType<typeof getCompleteAddress>>;\n}) {\n return {\n ...(confirmationToken ? { confirmationToken } : {}),\n customFieldAnswers: buildCustomFieldAnswers(\n catalog.widget.customFields,\n fieldValues.customFields\n ),\n email,\n ...(metadata ? { metadata } : {}),\n ...(catalog.widget.fields.memberId && fieldValues.memberId.trim()\n ? { memberId: fieldValues.memberId.trim() }\n : {}),\n ...(catalog.widget.fields.merchSize\n ? { merchSize: fieldValues.merchSize }\n : {}),\n ...(catalog.widget.fields.phone ? { phone } : {}),\n ...(shippingAddress\n ? {\n shipping: {\n address: {\n city: shippingAddress.address.city ?? \"\",\n country: shippingAddress.address.country,\n line1: shippingAddress.address.line1 ?? \"\",\n ...(shippingAddress.address.line2\n ? { line2: shippingAddress.address.line2 }\n : {}),\n postal_code: shippingAddress.address.postal_code ?? \"\",\n state: shippingAddress.address.state ?? \"\",\n },\n name: shippingAddress.name,\n },\n }\n : {}),\n };\n}\n\nfunction notifyPaymentRecovery(\n callback: LockerversePaymentProps[\"onPaymentRecoveryChange\"],\n recovery: Parameters<\n NonNullable<LockerversePaymentProps[\"onPaymentRecoveryChange\"]>\n >[0]\n) {\n try {\n callback?.(recovery);\n } catch {\n // Host persistence failures must not change authoritative payment state.\n }\n}\n\nfunction assertPaymentAttemptActive(isAttemptActive: () => boolean) {\n if (!isAttemptActive()) {\n throw new Error(\"Payment component is no longer active.\");\n }\n}\n\nasync function completePayment({\n addresses,\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n isAttemptActive,\n locallyPreviewedTotalCents,\n metadata,\n onPaymentRecoveryChange,\n phone,\n quote,\n stripe,\n}: {\n addresses: CheckoutAddresses;\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n elements?: StripeElements | null;\n email: string;\n fieldValues: CheckoutFieldValues;\n isAttemptActive: () => boolean;\n locallyPreviewedTotalCents: number;\n metadata: Record<string, string> | undefined;\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n phone: string;\n quote: LockerversePreparedCheckout;\n stripe?: Stripe | null;\n}) {\n const normalizedEmail = email.trim().toLowerCase();\n const normalizedPhone = normalizePhone(phone);\n const parsedTip = getTipCents(quote.subtotalCents, fieldValues);\n if (!parsedTip.success) {\n throw new Error(parsedTip.message);\n }\n const pricing = buildQuoteRequest(\n catalog,\n fieldValues,\n normalizedEmail,\n parsedTip.cents\n );\n const currentQuote = await client.calculateTotal({\n ...pricing,\n items: checkoutItems,\n });\n assertPaymentAttemptActive(isAttemptActive);\n if (\n currentQuote.totalCents > 0 &&\n hasMaterialQuoteChange(quote, currentQuote, locallyPreviewedTotalCents)\n ) {\n return { kind: \"quote_changed\" as const, quote: currentQuote };\n }\n\n if (currentQuote.totalCents === 0) {\n let completeShippingAddress:\n | ReturnType<typeof getCompleteAddress>\n | undefined;\n if (catalog.widget.fields.shipping) {\n const completeBillingAddress = getCompleteAddress(\n addresses.billing,\n \"Billing\"\n );\n completeShippingAddress = getShippingAddress(\n catalog,\n fieldValues,\n completeBillingAddress,\n addresses\n );\n }\n assertPaymentAttemptActive(isAttemptActive);\n notifyPaymentRecovery(onPaymentRecoveryChange, {\n connectedAccountId: currentQuote.payment.connectedAccountId,\n paymentReference: currentQuote.paymentReference,\n });\n const outcome = await submitPaymentAttempt(\n client,\n {\n checkout: currentQuote,\n submission: buildPaymentRequest({\n catalog,\n email: normalizedEmail,\n fieldValues,\n metadata,\n phone: normalizedPhone,\n ...(completeShippingAddress\n ? { shippingAddress: completeShippingAddress }\n : {}),\n }),\n },\n stripe\n );\n assertPaymentAttemptActive(isAttemptActive);\n if (outcome.kind === \"failed\") {\n return {\n kind: \"payment_failed\" as const,\n message:\n \"Order could not be completed. Review the details and try again.\",\n };\n }\n if (outcome.kind === \"unresolved\") {\n return {\n kind: \"payment_unresolved\" as const,\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n };\n }\n return {\n kind: \"payment\" as const,\n payment: outcome.payment,\n quote: currentQuote,\n };\n }\n\n if (!(elements && stripe)) {\n throw new Error(\"Payment form is still loading.\");\n }\n await elements.update({ amount: currentQuote.totalCents });\n assertPaymentAttemptActive(isAttemptActive);\n const elementSubmission = await elements.submit();\n assertPaymentAttemptActive(isAttemptActive);\n if (elementSubmission.error) {\n throw new Error(elementSubmission.error.message);\n }\n\n const completeBillingAddress = getCompleteAddress(\n addresses.billing,\n \"Billing\"\n );\n const completeShippingAddress = getShippingAddress(\n catalog,\n fieldValues,\n completeBillingAddress,\n addresses\n );\n const tokenResult = await stripe.createConfirmationToken({\n elements,\n params: buildConfirmationParams({\n billingAddress: completeBillingAddress,\n catalog,\n email: normalizedEmail,\n phone: normalizedPhone,\n shippingAddress: completeShippingAddress,\n }),\n });\n assertPaymentAttemptActive(isAttemptActive);\n if (tokenResult.error) {\n throw new Error(tokenResult.error.message);\n }\n\n notifyPaymentRecovery(onPaymentRecoveryChange, {\n connectedAccountId: currentQuote.payment.connectedAccountId,\n paymentReference: currentQuote.paymentReference,\n });\n const outcome = await submitPaymentAttempt(\n client,\n {\n checkout: currentQuote,\n submission: buildPaymentRequest({\n catalog,\n confirmationToken: tokenResult.confirmationToken.id,\n email: normalizedEmail,\n fieldValues,\n metadata,\n phone: normalizedPhone,\n ...(completeShippingAddress\n ? { shippingAddress: completeShippingAddress }\n : {}),\n }),\n },\n stripe\n );\n assertPaymentAttemptActive(isAttemptActive);\n if (outcome.kind === \"failed\") {\n return {\n kind: \"payment_failed\" as const,\n message:\n \"Payment was declined. Check your payment details and try again.\",\n };\n }\n if (outcome.kind === \"unresolved\") {\n return {\n kind: \"payment_unresolved\" as const,\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n };\n }\n return {\n kind: \"payment\" as const,\n payment: outcome.payment,\n quote: currentQuote,\n };\n}\n\ntype WorkflowOptions = {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n elements: StripeElements | null;\n email: string;\n fieldValues: CheckoutFieldValues;\n metadata: Record<string, string> | undefined;\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n onStateChange: (state: PaymentWorkflowUiState) => void;\n quote: LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n stripe: Stripe | null;\n};\n\ntype SubmitPayment = {\n addresses: CheckoutAddresses;\n phone: string;\n};\n\ntype CompletePaymentResult = Awaited<ReturnType<typeof completePayment>>;\n\nfunction formatMoney(amountCents: number) {\n return new Intl.NumberFormat(\"en-US\", {\n currency: \"USD\",\n style: \"currency\",\n }).format(amountCents / 100);\n}\n\nfunction getQuoteRefreshError(error: unknown, validatePromo: boolean) {\n if (validatePromo) {\n return;\n }\n return error instanceof Error\n ? error.message\n : \"The order total could not be updated.\";\n}\n\nfunction applyQuoteRefreshSuccess({\n nextQuote,\n onQuoteChange,\n setDisplayedTotalCents,\n setPromoError,\n updateWorkflow,\n validatePromo,\n}: {\n nextQuote: LockerversePreparedCheckout;\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n setDisplayedTotalCents: (total: number) => void;\n setPromoError: (error: string | undefined) => void;\n updateWorkflow: (event: PaymentWorkflowEvent) => void;\n validatePromo: boolean;\n}) {\n updateWorkflow({ type: \"quote_refresh_succeeded\" });\n setDisplayedTotalCents(nextQuote.totalCents);\n onQuoteChange(nextQuote);\n if (validatePromo) {\n setPromoError(\n nextQuote.appliedDiscount?.source === \"promo_code\"\n ? undefined\n : \"This promo code is invalid or cannot be applied.\"\n );\n }\n}\n\nfunction applyQuoteRefreshFailure({\n error,\n setPromoError,\n updateWorkflow,\n validatePromo,\n}: {\n error: unknown;\n setPromoError: (error: string | undefined) => void;\n updateWorkflow: (event: PaymentWorkflowEvent) => void;\n validatePromo: boolean;\n}) {\n if (validatePromo) {\n setPromoError(\"This promo code is invalid or cannot be applied.\");\n }\n const message = getQuoteRefreshError(error, validatePromo);\n updateWorkflow(\n message === undefined\n ? { type: \"quote_refresh_failed\" }\n : { error: message, type: \"quote_refresh_failed\" }\n );\n}\n\nfunction applyPaymentOutcome({\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n result,\n setDisplayedTotalCents,\n transitionWorkflow,\n}: {\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n result: CompletePaymentResult;\n setDisplayedTotalCents: (total: number) => void;\n transitionWorkflow: (event: PaymentWorkflowEvent) => void;\n}) {\n if (result.kind === \"quote_changed\") {\n const notice = `The total changed to ${formatMoney(result.quote.totalCents)}. Review it and pay again.`;\n onQuoteChange(result.quote, notice);\n setDisplayedTotalCents(result.quote.totalCents);\n transitionWorkflow({ type: \"quote_changed\" });\n return;\n }\n if (result.kind === \"payment_failed\") {\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({ error: result.message, type: \"retryable_failure\" });\n return;\n }\n if (result.kind === \"payment_unresolved\") {\n transitionWorkflow({\n message: \"Payment is still processing. Do not submit it again.\",\n paymentReference: result.paymentReference,\n reason: result.reason,\n type: \"unresolved\",\n });\n try {\n onPaymentUncertain?.({\n paymentReference: result.paymentReference,\n reason: result.reason,\n });\n } catch {\n // Host callback failures must not unlock an uncertain payment.\n }\n return;\n }\n onQuoteChange(result.quote);\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({\n message: result.payment.paymentRequired\n ? \"Payment completed successfully.\"\n : \"Order confirmed. No payment was required.\",\n type: \"succeeded\",\n });\n try {\n onPaymentComplete?.(result.payment);\n } catch {\n // Host callback failures must not turn a completed payment into an error.\n }\n}\n\nexport function usePaymentFormWorkflow(options: WorkflowOptions) {\n const {\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onStateChange,\n quote,\n resumePayment,\n stripe,\n } = options;\n const [workflow, dispatchWorkflow] = useReducer(\n paymentWorkflowReducer,\n resumePayment,\n createPaymentWorkflowState\n );\n const [displayedTotalCents, setDisplayedTotalCents] = useState(\n quote.totalCents\n );\n const [promoError, setPromoError] = useState<string>();\n const recoveryStartedRef = useRef(false);\n const quoteRequestRef = useRef(0);\n const attemptGenerationRef = useRef(0);\n const workflowRef = useRef(workflow);\n workflowRef.current = workflow;\n\n const updateWorkflow = useCallback(\n (event: PaymentWorkflowEvent, notifyHost = false) => {\n const previous = workflowRef.current;\n const next = paymentWorkflowReducer(previous, event);\n if (next === previous) {\n return;\n }\n workflowRef.current = next;\n dispatchWorkflow(event);\n if (notifyHost) {\n onStateChange(getPaymentUiState(next));\n }\n },\n [onStateChange]\n );\n const transitionWorkflow = useCallback(\n (event: PaymentWorkflowEvent) => updateWorkflow(event, true),\n [updateWorkflow]\n );\n const startPaymentAttempt = useCallback(() => {\n const generation = attemptGenerationRef.current + 1;\n attemptGenerationRef.current = generation;\n return () => attemptGenerationRef.current === generation;\n }, []);\n\n useEffect(\n () => () => {\n attemptGenerationRef.current += 1;\n },\n []\n );\n\n const parsedTip = catalog.widget.fields.tipping\n ? getTipCents(quote.subtotalCents, fieldValues)\n : ({ cents: 0, success: true } as const);\n const parsedTipCents = parsedTip.success ? parsedTip.cents : null;\n\n useEffect(() => {\n if (parsedTipCents === null) {\n return;\n }\n const previewServiceFeeCents =\n catalog.widget.fields.serviceFee && fieldValues.includeServiceFee\n ? quote.serviceFeeCents ||\n Math.round(\n (quote.subtotalCents *\n catalog.pricingPolicy.serviceFeeRateBasisPoints) /\n 10_000\n )\n : 0;\n const previewTotalCents =\n quote.totalCents -\n quote.serviceFeeCents -\n quote.tipCents +\n previewServiceFeeCents +\n parsedTipCents;\n setDisplayedTotalCents(previewTotalCents);\n if (previewTotalCents > 0) {\n elements?.update({ amount: previewTotalCents });\n }\n }, [\n catalog.pricingPolicy.serviceFeeRateBasisPoints,\n catalog.widget.fields.serviceFee,\n elements,\n fieldValues.includeServiceFee,\n parsedTipCents,\n quote.serviceFeeCents,\n quote.tipCents,\n quote.totalCents,\n quote.subtotalCents,\n ]);\n\n useEffect(() => {\n if (!(resumePayment && stripe) || recoveryStartedRef.current) {\n return;\n }\n recoveryStartedRef.current = true;\n const isAttemptActive = startPaymentAttempt();\n onStateChange(getPaymentUiState(workflowRef.current));\n\n recoverPaymentAttempt(client, resumePayment.paymentReference, stripe).then(\n (outcome) => {\n if (!isAttemptActive()) {\n return;\n }\n if (outcome.kind === \"failed\") {\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({\n error:\n \"The previous payment failed. Check your details and try again.\",\n type: \"recovery_failed\",\n });\n return;\n }\n if (outcome.kind === \"unresolved\") {\n transitionWorkflow({\n message: \"Payment is still processing. Do not submit it again.\",\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n type: \"unresolved\",\n });\n try {\n onPaymentUncertain?.({\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n });\n } catch {\n // Host callback failures must not unlock an uncertain payment.\n }\n return;\n }\n\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({\n message: outcome.payment.paymentRequired\n ? \"Payment completed successfully.\"\n : \"Order confirmed. No payment was required.\",\n type: \"succeeded\",\n });\n try {\n onPaymentComplete?.(outcome.payment);\n } catch {\n // Host callback failures must not turn a completed payment into an error.\n }\n }\n );\n return () => {\n if (isAttemptActive()) {\n attemptGenerationRef.current += 1;\n }\n recoveryStartedRef.current = false;\n };\n }, [\n client,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onStateChange,\n resumePayment,\n stripe,\n startPaymentAttempt,\n transitionWorkflow,\n ]);\n\n const fieldChanged = useCallback(\n (clearPromo = false) => {\n if (clearPromo) {\n setPromoError(undefined);\n }\n updateWorkflow({ type: \"field_changed\" });\n },\n [updateWorkflow]\n );\n\n async function refreshAuthoritativeTotal(\n allowMissingEmail = false,\n validatePromo = false\n ) {\n const normalizedEmail = email.trim().toLowerCase();\n const emailValidation = validateContact(\n { email: normalizedEmail, phone: \"\" },\n false\n );\n if (!(parsedTip.success && (emailValidation.value || allowMissingEmail))) {\n return;\n }\n\n quoteRequestRef.current += 1;\n const requestId = quoteRequestRef.current;\n updateWorkflow({ type: \"quote_refresh_started\", validatePromo });\n try {\n const nextQuote = await client.calculateTotal({\n ...buildQuoteRequest(\n catalog,\n fieldValues,\n emailValidation.value?.email ?? \"\",\n parsedTip.cents\n ),\n items: checkoutItems,\n });\n if (requestId !== quoteRequestRef.current) {\n return;\n }\n applyQuoteRefreshSuccess({\n nextQuote,\n onQuoteChange,\n setDisplayedTotalCents,\n setPromoError,\n updateWorkflow,\n validatePromo,\n });\n } catch (error) {\n if (requestId !== quoteRequestRef.current) {\n return;\n }\n applyQuoteRefreshFailure({\n error,\n setPromoError,\n updateWorkflow,\n validatePromo,\n });\n }\n }\n\n async function applyPromo() {\n setPromoError(undefined);\n await refreshAuthoritativeTotal(true, true);\n }\n\n async function submit({ addresses, phone }: SubmitPayment) {\n transitionWorkflow({ type: \"submission_started\" });\n const isAttemptActive = startPaymentAttempt();\n try {\n const result = await completePayment({\n addresses,\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n isAttemptActive,\n locallyPreviewedTotalCents: displayedTotalCents,\n metadata,\n onPaymentRecoveryChange,\n phone,\n quote,\n stripe,\n });\n if (!isAttemptActive()) {\n return;\n }\n applyPaymentOutcome({\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n result,\n setDisplayedTotalCents,\n transitionWorkflow,\n });\n } catch (error) {\n if (!isAttemptActive()) {\n return;\n }\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n transitionWorkflow({\n error:\n error instanceof Error\n ? error.message\n : \"Payment could not be completed.\",\n type: \"retryable_failure\",\n });\n }\n }\n\n const terminalMessage =\n workflow.phase === \"succeeded\" || workflow.phase === \"unresolved\"\n ? workflow.message\n : undefined;\n return {\n commands: {\n applyPromo,\n fieldChanged,\n refreshAuthoritativeTotal,\n reportStripeLoadError: (message: string) =>\n transitionWorkflow({ error: message, type: \"retryable_failure\" }),\n reportValidationFailure: () =>\n transitionWorkflow({ type: \"validation_failed\" }),\n submit,\n },\n state: {\n displayedTotalCents,\n isRecovering: workflow.phase === \"recovering\",\n isRefreshingQuote: workflow.phase === \"refreshing_quote\",\n isSubmitting: isPaymentBusy(workflow),\n parsedTip,\n paymentError: getPaymentError(workflow),\n promoError,\n terminalMessage,\n },\n };\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutItem,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport {\n AddressElement,\n Elements,\n PaymentElement,\n useElements,\n useStripe,\n} from \"@stripe/react-stripe-js\";\nimport type { StripeAddressElementChangeEvent } from \"@stripe/stripe-js\";\nimport { loadStripe } from \"@stripe/stripe-js\";\nimport {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { getAccentContrast } from \"./accent-contrast.ts\";\nimport {\n AdditionalCheckoutFields,\n type CheckoutFieldValues,\n CheckoutToggle,\n ServiceFeeField,\n TipField,\n} from \"./checkout-fields.tsx\";\nimport {\n createCustomFieldValues,\n validateCustomFields,\n} from \"./custom-fields.tsx\";\nimport { validateContact } from \"./payment-validation.ts\";\nimport type { PaymentWorkflowUiState } from \"./payment-workflow.ts\";\nimport { LockerverseSelect, SelectPortalProvider } from \"./select-control.tsx\";\nimport type { LockerversePaymentProps } from \"./types.ts\";\nimport {\n type CheckoutPaymentState,\n usePaymentCheckout,\n} from \"./use-payment-checkout.ts\";\nimport {\n type CheckoutAddresses,\n usePaymentFormWorkflow,\n} from \"./use-payment-form-workflow.ts\";\n\nfunction formatMoney(amountCents: number) {\n return new Intl.NumberFormat(\"en-US\", {\n currency: \"USD\",\n style: \"currency\",\n }).format(amountCents / 100);\n}\n\nconst PHONE_COUNTRIES = [\n { callingCode: \"+1\", label: \"🇺🇸 +1\", value: \"US\" },\n { callingCode: \"+52\", label: \"🇲🇽 +52\", value: \"MX\" },\n { callingCode: \"+380\", label: \"🇺🇦 +380\", value: \"UA\" },\n { callingCode: \"+48\", label: \"🇵🇱 +48\", value: \"PL\" },\n { callingCode: \"+1\", label: \"🇨🇦 +1\", value: \"CA\" },\n { callingCode: \"+49\", label: \"🇩🇪 +49\", value: \"DE\" },\n { callingCode: \"+44\", label: \"🇬🇧 +44\", value: \"GB\" },\n { callingCode: \"+46\", label: \"🇸🇪 +46\", value: \"SE\" },\n { callingCode: \"+358\", label: \"🇫🇮 +358\", value: \"FI\" },\n { callingCode: \"+1\", label: \"🇵🇷 +1\", value: \"PR\" },\n] as const;\n\nconst DEFAULT_FONT_FAMILY =\n 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif';\n\nfunction getInternationalPhone(phone: string, country: string) {\n if (phone.trim().startsWith(\"+\")) {\n return phone;\n }\n const callingCode =\n PHONE_COUNTRIES.find((option) => option.value === country)?.callingCode ??\n \"+1\";\n return `${callingCode}${phone}`;\n}\n\nfunction ReadyPayment({\n accentColor,\n catalog,\n checkoutItems,\n client,\n fontFamily,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n quote,\n resumePayment,\n onStateChange,\n stripeLoader,\n theme,\n visualStyle,\n}: {\n accentColor: string;\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n fontFamily: string;\n metadata: Record<string, string> | undefined;\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n quote: LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n onStateChange: (\n state:\n | \"error\"\n | \"idle\"\n | \"invalid\"\n | \"submitting\"\n | \"success\"\n | \"unresolved\"\n ) => void;\n stripeLoader: NonNullable<LockerversePaymentProps[\"stripeLoader\"]>;\n theme: LockerversePaymentProps[\"theme\"];\n visualStyle: LockerversePaymentProps[\"style\"];\n}) {\n const connectedAccountId = resumePayment\n ? resumePayment.connectedAccountId\n : quote.payment.connectedAccountId;\n const stripe = useMemo(\n () =>\n stripeLoader(\n catalog.payment.publishableKey,\n connectedAccountId ? { stripeAccount: connectedAccountId } : undefined\n ).catch(() => null),\n [catalog.payment.publishableKey, connectedAccountId, stripeLoader]\n );\n\n return (\n <Elements\n key={`${catalog.payment.publishableKey}:${connectedAccountId ?? \"platform\"}`}\n options={{\n amount: Math.max(quote.totalCents, 100),\n appearance: {\n rules: {\n \".Input:focus\": {\n borderColor: accentColor,\n boxShadow: `0 0 0 1px ${accentColor}`,\n outline: \"none\",\n },\n },\n theme: theme === \"light\" ? \"stripe\" : \"night\",\n variables: {\n borderRadius: visualStyle?.[\"--lockerverse-radius\"] ?? \"10px\",\n colorBackground:\n visualStyle?.[\"--lockerverse-control\"] ??\n (theme === \"light\" ? \"#f5f6f7\" : \"#121212\"),\n colorDanger:\n visualStyle?.[\"--lockerverse-danger\"] ??\n (theme === \"light\" ? \"#c52b3e\" : \"#f08a98\"),\n colorPrimary: accentColor,\n colorText:\n visualStyle?.[\"--lockerverse-text\"] ??\n (theme === \"light\" ? \"#121416\" : \"#ffffff\"),\n colorTextPlaceholder:\n visualStyle?.[\"--lockerverse-placeholder\"] ??\n (theme === \"light\" ? \"#72767d\" : \"#6b6b6b\"),\n colorTextSecondary:\n visualStyle?.[\"--lockerverse-muted\"] ??\n (theme === \"light\" ? \"#62666d\" : \"#a1a1aa\"),\n focusBoxShadow: \"none\",\n focusOutline: \"none\",\n fontFamily,\n fontSizeBase: \"16px\",\n },\n },\n currency: quote.payment.currency,\n excludedPaymentMethodTypes: [\"us_bank_account\"],\n mode: \"payment\",\n syncAddressCheckbox: \"none\",\n }}\n stripe={stripe}\n >\n <PaymentForm\n catalog={catalog}\n checkoutItems={checkoutItems}\n client={client}\n metadata={metadata}\n onPaymentComplete={onPaymentComplete}\n onPaymentRecoveryChange={onPaymentRecoveryChange}\n onPaymentUncertain={onPaymentUncertain}\n onQuoteChange={onQuoteChange}\n onStateChange={onStateChange}\n quote={quote}\n resumePayment={resumePayment}\n />\n </Elements>\n );\n}\n\nfunction StripeElementLoader({ label }: { label: string }) {\n return (\n <div className=\"lockerverse-payment__stripe-loader\" role=\"status\">\n <p>{label}</p>\n <div aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </div>\n </div>\n );\n}\n\nfunction StripePaymentField({\n onError,\n onReady,\n ready,\n}: {\n onError: (message: string) => void;\n onReady: () => void;\n ready: boolean;\n}) {\n return (\n <div className=\"lockerverse-payment__stripe-element\" data-ready={ready}>\n {ready ? null : <StripeElementLoader label=\"Loading payment form...\" />}\n <div className=\"lockerverse-payment__stripe-mount\">\n <PaymentElement\n onLoadError={({ error }) =>\n onError(error.message ?? \"Payment form failed to load.\")\n }\n onReady={onReady}\n options={{\n business: { name: \"Lockerverse\" },\n fields: {\n billingDetails: {\n address: \"never\",\n email: \"never\",\n name: \"never\",\n phone: \"never\",\n },\n },\n layout: \"tabs\",\n terms: {\n applePay: \"auto\",\n auBecsDebit: \"never\",\n bancontact: \"never\",\n card: \"always\",\n cashapp: \"never\",\n googlePay: \"never\",\n ideal: \"never\",\n paypal: \"auto\",\n sepaDebit: \"never\",\n sofort: \"never\",\n usBankAccount: \"never\",\n },\n wallets: { applePay: \"auto\", googlePay: \"never\" },\n }}\n />\n </div>\n </div>\n );\n}\n\nfunction StripeAddressField({\n label,\n mode,\n onChange,\n onError,\n onReady,\n ready,\n}: {\n label: string;\n mode: \"billing\" | \"shipping\";\n onChange: (address: StripeAddressElementChangeEvent) => void;\n onError: (message: string) => void;\n onReady: () => void;\n ready: boolean;\n}) {\n return (\n <div className=\"lockerverse-payment__address\">\n <h2>{label}</h2>\n <div\n className=\"lockerverse-payment__stripe-element lockerverse-payment__stripe-element--address\"\n data-ready={ready}\n >\n {ready ? null : (\n <StripeElementLoader label={`Loading ${label.toLowerCase()}...`} />\n )}\n <div className=\"lockerverse-payment__stripe-mount\">\n <AddressElement\n onChange={onChange}\n onLoadError={({ error }) =>\n onError(error.message ?? `${label} failed to load.`)\n }\n onReady={onReady}\n options={{ autocomplete: { mode: \"automatic\" }, mode }}\n />\n </div>\n </div>\n </div>\n );\n}\n\nfunction PaymentErrorMessage({ message }: { message: string | undefined }) {\n if (!message) {\n return null;\n }\n return (\n <p className=\"lockerverse-payment__field-message\" role=\"alert\">\n {message}\n </p>\n );\n}\n\nfunction StripeCheckoutFields({\n catalog,\n displayedTotalCents,\n fieldValues,\n isBillingAddressReady,\n isPaymentReady,\n isShippingAddressReady,\n onAddressChange,\n onFieldValuesChange,\n onStripeLoadError,\n setIsBillingAddressReady,\n setIsPaymentReady,\n setIsShippingAddressReady,\n}: {\n catalog: LockerverseCatalog;\n displayedTotalCents: number;\n fieldValues: CheckoutFieldValues;\n isBillingAddressReady: boolean;\n isPaymentReady: boolean;\n isShippingAddressReady: boolean;\n onAddressChange: (\n mode: \"billing\" | \"shipping\",\n address: StripeAddressElementChangeEvent | null\n ) => void;\n onFieldValuesChange: (values: CheckoutFieldValues) => void;\n onStripeLoadError: (message: string) => void;\n setIsBillingAddressReady: (ready: boolean) => void;\n setIsPaymentReady: (ready: boolean) => void;\n setIsShippingAddressReady: (ready: boolean) => void;\n}) {\n const requiresPayment = displayedTotalCents > 0;\n\n return (\n <>\n {requiresPayment ? (\n <StripePaymentField\n onError={onStripeLoadError}\n onReady={() => setIsPaymentReady(true)}\n ready={isPaymentReady}\n />\n ) : null}\n {requiresPayment || catalog.widget.fields.shipping ? (\n <StripeAddressField\n label={requiresPayment ? \"Billing address\" : \"Shipping address\"}\n mode=\"billing\"\n onChange={(address) => onAddressChange(\"billing\", address)}\n onError={onStripeLoadError}\n onReady={() => setIsBillingAddressReady(true)}\n ready={isBillingAddressReady}\n />\n ) : null}\n {catalog.widget.fields.shipping ? (\n <div className=\"lockerverse-payment__shipping\">\n <CheckoutToggle\n checked={fieldValues.shippingMatchesBilling}\n name=\"shippingMatchesBilling\"\n onChange={(shippingMatchesBilling) => {\n onFieldValuesChange({\n ...fieldValues,\n shippingMatchesBilling,\n });\n if (shippingMatchesBilling) {\n onAddressChange(\"shipping\", null);\n } else {\n setIsShippingAddressReady(false);\n }\n }}\n >\n Shipping is same as billing information\n </CheckoutToggle>\n {fieldValues.shippingMatchesBilling ? null : (\n <StripeAddressField\n label=\"Shipping address\"\n mode=\"shipping\"\n onChange={(address) => onAddressChange(\"shipping\", address)}\n onError={onStripeLoadError}\n onReady={() => setIsShippingAddressReady(true)}\n ready={isShippingAddressReady}\n />\n )}\n </div>\n ) : null}\n </>\n );\n}\n\nfunction PaymentSummary({\n displayedBaseCents,\n displayedTipCents,\n displayedTotalCents,\n quote,\n}: {\n displayedBaseCents: number;\n displayedTipCents: number;\n displayedTotalCents: number;\n quote: LockerversePreparedCheckout;\n}) {\n const displayedServiceFeeCents = Math.max(\n 0,\n displayedBaseCents - quote.subtotalCents + quote.discountCents\n );\n return (\n <section\n aria-label=\"Payment summary\"\n className=\"lockerverse-payment__payment-summary\"\n >\n <h2>Order summary</h2>\n <div className=\"lockerverse-payment__payment-summary-items\">\n {quote.lineItems.map((item) => (\n <div\n className=\"lockerverse-payment__payment-summary-row\"\n key={item.listingId}\n >\n <span>\n {item.productName}\n {item.quantity > 1 ? (\n <>\n {\" \"}\n <small>× {item.quantity}</small>\n </>\n ) : null}\n </span>\n <strong>{formatMoney(item.subtotalCents)}</strong>\n </div>\n ))}\n </div>\n <div className=\"lockerverse-payment__payment-summary-totals\">\n {displayedServiceFeeCents > 0 ? (\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-detail\">\n <span>Service fee</span>\n <strong>{formatMoney(displayedServiceFeeCents)}</strong>\n </div>\n ) : null}\n {quote.discountCents > 0 && quote.appliedDiscount ? (\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-discount\">\n <span>\n {quote.appliedDiscount.source === \"email_list\"\n ? \"Email discount\"\n : \"Promo code discount\"}{\" \"}\n ({quote.appliedDiscount.percentageOff}% off)\n </span>\n <strong>-{formatMoney(quote.discountCents)}</strong>\n </div>\n ) : null}\n {displayedTipCents > 0 ? (\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-detail lockerverse-payment__payment-summary-tip\">\n <span>Tip</span>\n <strong>{formatMoney(displayedTipCents)}</strong>\n </div>\n ) : null}\n <div className=\"lockerverse-payment__payment-summary-row lockerverse-payment__payment-summary-total\">\n <span>Total</span>\n <strong>{formatMoney(displayedTotalCents)}</strong>\n </div>\n </div>\n </section>\n );\n}\n\nfunction PaymentAction({\n catalog,\n displayedTotalCents,\n fieldValues,\n isBillingAddressReady,\n isPaymentReady,\n isRequiredShippingReady,\n isSubmitting,\n onFieldValuesChange,\n quote,\n}: {\n catalog: LockerverseCatalog;\n displayedTotalCents: number;\n fieldValues: CheckoutFieldValues;\n isBillingAddressReady: boolean;\n isPaymentReady: boolean;\n isRequiredShippingReady: boolean;\n isSubmitting: boolean;\n onFieldValuesChange: (values: CheckoutFieldValues) => void;\n quote: LockerversePreparedCheckout;\n}) {\n const isFree = displayedTotalCents === 0;\n const isReady = isFree\n ? !catalog.widget.fields.shipping ||\n (isBillingAddressReady && isRequiredShippingReady)\n : isPaymentReady && isBillingAddressReady && isRequiredShippingReady;\n let label = isFree\n ? \"Complete order\"\n : `Pay ${formatMoney(displayedTotalCents)}`;\n if (isSubmitting) {\n label = isFree ? \"Completing…\" : \"Processing…\";\n }\n return (\n <div className=\"lockerverse-payment__actions\">\n <ServiceFeeField\n amountCents={\n quote.serviceFeeCents ||\n Math.round(\n (quote.subtotalCents *\n catalog.pricingPolicy.serviceFeeRateBasisPoints) /\n 10_000\n )\n }\n enabled={catalog.widget.fields.serviceFee}\n onChange={onFieldValuesChange}\n values={fieldValues}\n />\n <button\n aria-busy={isSubmitting}\n aria-label={\n isFree\n ? \"Complete order\"\n : `Process payment for ${formatMoney(displayedTotalCents)} total`\n }\n disabled={isSubmitting || !isReady}\n type=\"submit\"\n >\n {label}\n </button>\n </div>\n );\n}\n\nfunction focusNamedFormControl(form: HTMLFormElement, name: string) {\n const control = form.elements.namedItem(name);\n if (control instanceof HTMLElement) {\n control.focus();\n return;\n }\n if (control instanceof RadioNodeList) {\n Array.from(control)\n .find((item) => item instanceof HTMLElement)\n ?.focus();\n }\n}\n\nfunction focusFirstValidationError({\n customFieldErrors,\n emailRef,\n form,\n parsedTipSuccess,\n phoneRef,\n validationErrors,\n}: {\n customFieldErrors: Record<string, string>;\n emailRef: React.RefObject<HTMLInputElement | null>;\n form: HTMLFormElement;\n parsedTipSuccess: boolean;\n phoneRef: React.RefObject<HTMLInputElement | null>;\n validationErrors: { email?: string; phone?: string };\n}) {\n if (validationErrors.email) {\n emailRef.current?.focus();\n return;\n }\n if (validationErrors.phone) {\n phoneRef.current?.focus();\n return;\n }\n if (!parsedTipSuccess) {\n form.querySelector<HTMLElement>('[name=\"tip\"]')?.focus();\n return;\n }\n const [firstFieldId] = Object.keys(customFieldErrors);\n if (firstFieldId) {\n focusNamedFormControl(form, `custom:${firstFieldId}`);\n }\n}\n\nfunction ContactFields({\n email,\n emailDiscountPercentOff,\n emailErrorId,\n emailId,\n emailRef,\n errors,\n onEmailBlur,\n onEmailChange,\n onPhoneChange,\n onPhoneCountryChange,\n phone,\n phoneCountry,\n phoneEnabled,\n phoneErrorId,\n phoneId,\n phoneRef,\n}: {\n email: string;\n emailDiscountPercentOff: number | undefined;\n emailErrorId: string;\n emailId: string;\n emailRef: React.RefObject<HTMLInputElement | null>;\n errors: { email?: string; phone?: string };\n onEmailBlur: () => void;\n onEmailChange: (value: string) => void;\n onPhoneChange: (value: string) => void;\n onPhoneCountryChange: (value: string) => void;\n phone: string;\n phoneCountry: string;\n phoneEnabled: boolean;\n phoneErrorId: string;\n phoneId: string;\n phoneRef: React.RefObject<HTMLInputElement | null>;\n}) {\n return (\n <div className=\"lockerverse-payment__contact\">\n <label htmlFor={emailId}>Email</label>\n <input\n aria-describedby={errors.email ? emailErrorId : undefined}\n aria-invalid={errors.email ? \"true\" : undefined}\n autoComplete=\"email\"\n id={emailId}\n name=\"email\"\n onBlur={onEmailBlur}\n onChange={(event) => onEmailChange(event.currentTarget.value)}\n placeholder=\"name@example.com\"\n ref={emailRef}\n type=\"email\"\n value={email}\n />\n {errors.email ? (\n <p className=\"lockerverse-payment__field-message\" id={emailErrorId}>\n {errors.email}\n </p>\n ) : null}\n {emailDiscountPercentOff === undefined ? null : (\n <p className=\"lockerverse-payment__discount-message\" role=\"status\">\n Your email qualifies for {emailDiscountPercentOff}% off.\n </p>\n )}\n {phoneEnabled ? (\n <>\n <label htmlFor={phoneId}>Phone</label>\n <div className=\"lockerverse-payment__phone-control\">\n <LockerverseSelect\n ariaLabel=\"Phone number country\"\n className=\"lockerverse-payment__select--phone-country\"\n name=\"phoneCountry\"\n onValueChange={onPhoneCountryChange}\n options={PHONE_COUNTRIES}\n value={phoneCountry}\n />\n <input\n aria-describedby={errors.phone ? phoneErrorId : undefined}\n aria-invalid={errors.phone ? \"true\" : undefined}\n autoComplete=\"tel\"\n id={phoneId}\n inputMode=\"tel\"\n name=\"phone\"\n onChange={(event) => onPhoneChange(event.currentTarget.value)}\n placeholder=\"(201) 555-0123\"\n ref={phoneRef}\n type=\"tel\"\n value={phone}\n />\n </div>\n {errors.phone ? (\n <p className=\"lockerverse-payment__field-message\" id={phoneErrorId}>\n {errors.phone}\n </p>\n ) : null}\n </>\n ) : null}\n </div>\n );\n}\n\nfunction PaymentForm({\n catalog,\n checkoutItems,\n client,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onStateChange,\n quote,\n resumePayment,\n}: {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n metadata: Record<string, string> | undefined;\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n onStateChange: (state: PaymentWorkflowUiState) => void;\n quote: LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n}) {\n const [email, setEmail] = useState(\"\");\n const [phone, setPhone] = useState(\"\");\n const [phoneCountry, setPhoneCountry] = useState(\"US\");\n const [errors, setErrors] = useState<{ email?: string; phone?: string }>({});\n const [customFieldErrors, setCustomFieldErrors] = useState<\n Record<string, string>\n >({});\n const [tipError, setTipError] = useState<string>();\n const [isPaymentReady, setIsPaymentReady] = useState(false);\n const [isBillingAddressReady, setIsBillingAddressReady] = useState(false);\n const [isShippingAddressReady, setIsShippingAddressReady] = useState(false);\n const [fieldValues, setFieldValues] = useState<CheckoutFieldValues>({\n customFields: createCustomFieldValues(catalog.widget.customFields),\n customTip: \"\",\n includeServiceFee: catalog.widget.fields.serviceFee,\n memberId: \"\",\n merchSize: \"M\",\n promoCode: \"\",\n shippingMatchesBilling: true,\n tipPercent: \"10\",\n });\n const addressesRef = useRef<CheckoutAddresses>({\n billing: null,\n shipping: null,\n });\n const emailRef = useRef<HTMLInputElement>(null);\n const phoneRef = useRef<HTMLInputElement>(null);\n const statusRef = useRef<HTMLParagraphElement>(null);\n const paymentWasRequiredRef = useRef(quote.totalCents > 0);\n const elements = useElements();\n const stripe = useStripe();\n const workflow = usePaymentFormWorkflow({\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onStateChange,\n quote,\n resumePayment,\n stripe,\n });\n const {\n displayedTotalCents,\n isRecovering,\n isRefreshingQuote,\n isSubmitting,\n parsedTip,\n paymentError,\n promoError,\n terminalMessage,\n } = workflow.state;\n const idPrefix = `lockerverse-${useId()}`;\n const emailId = `${idPrefix}-email`;\n const emailErrorId = `${emailId}-error`;\n const phoneId = `${idPrefix}-phone`;\n const phoneErrorId = `${phoneId}-error`;\n const tipErrorId = `${idPrefix}-tip-error`;\n const parsedTipCents = parsedTip.success ? parsedTip.cents : null;\n const displayedTipCents = parsedTipCents ?? 0;\n const displayedBaseCents = displayedTotalCents - displayedTipCents;\n const isRequiredShippingReady =\n !catalog.widget.fields.shipping ||\n fieldValues.shippingMatchesBilling ||\n isShippingAddressReady;\n\n useEffect(() => {\n if (isSubmitting) {\n statusRef.current?.focus();\n }\n }, [isSubmitting]);\n\n useEffect(() => {\n const paymentIsRequired = displayedTotalCents > 0;\n if (paymentIsRequired && !paymentWasRequiredRef.current) {\n setIsPaymentReady(false);\n setIsBillingAddressReady(false);\n }\n paymentWasRequiredRef.current = paymentIsRequired;\n }, [displayedTotalCents]);\n\n function clearError(field: \"email\" | \"phone\") {\n workflow.commands.fieldChanged();\n setErrors((current) => {\n const next = { ...current };\n delete next[field];\n return next;\n });\n }\n\n function handleFieldValuesChange(nextValues: CheckoutFieldValues) {\n workflow.commands.fieldChanged(\n nextValues.promoCode !== fieldValues.promoCode\n );\n setFieldValues(nextValues);\n setCustomFieldErrors({});\n setTipError(undefined);\n }\n\n async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {\n event.preventDefault();\n const validation = validateContact(\n { email, phone: getInternationalPhone(phone, phoneCountry) },\n catalog.widget.fields.phone\n );\n const nextCustomFieldErrors = validateCustomFields(\n catalog.widget.customFields,\n fieldValues.customFields\n );\n if (\n !(validation.value && parsedTip.success) ||\n Object.keys(nextCustomFieldErrors).length > 0\n ) {\n setErrors(validation.errors);\n setCustomFieldErrors(nextCustomFieldErrors);\n setTipError(parsedTip.success ? undefined : parsedTip.message);\n workflow.commands.reportValidationFailure();\n const form = event.currentTarget;\n queueMicrotask(() => {\n focusFirstValidationError({\n customFieldErrors: nextCustomFieldErrors,\n emailRef,\n form,\n parsedTipSuccess: parsedTip.success,\n phoneRef,\n validationErrors: validation.errors,\n });\n });\n return;\n }\n\n setErrors({});\n setCustomFieldErrors({});\n\n await workflow.commands.submit({\n addresses: addressesRef.current,\n phone: getInternationalPhone(phone, phoneCountry),\n });\n }\n\n if (terminalMessage) {\n return (\n <p\n className=\"lockerverse-payment__payment-status\"\n ref={statusRef}\n role=\"status\"\n tabIndex={-1}\n >\n {terminalMessage}\n </p>\n );\n }\n\n if (isRecovering) {\n return (\n <p className=\"lockerverse-payment__payment-status\" role=\"status\">\n Recovering payment…\n </p>\n );\n }\n\n return (\n <form\n aria-busy={isSubmitting}\n className=\"lockerverse-payment__form\"\n noValidate\n onSubmit={handleSubmit}\n >\n <div\n data-lockerverse-input-region=\"\"\n inert={isSubmitting ? true : undefined}\n >\n <fieldset\n className=\"lockerverse-payment__input-fieldset\"\n disabled={isSubmitting}\n >\n <PaymentSummary\n displayedBaseCents={displayedBaseCents}\n displayedTipCents={displayedTipCents}\n displayedTotalCents={displayedTotalCents}\n quote={quote}\n />\n <TipField\n enabled={catalog.widget.fields.tipping}\n error={tipError}\n errorId={tipErrorId}\n onChange={handleFieldValuesChange}\n values={fieldValues}\n />\n <ContactFields\n email={email}\n emailDiscountPercentOff={\n quote.appliedDiscount?.source === \"email_list\"\n ? quote.appliedDiscount.percentageOff\n : undefined\n }\n emailErrorId={emailErrorId}\n emailId={emailId}\n emailRef={emailRef}\n errors={errors}\n onEmailBlur={() => workflow.commands.refreshAuthoritativeTotal()}\n onEmailChange={(value) => {\n setEmail(value);\n clearError(\"email\");\n }}\n onPhoneChange={(value) => {\n setPhone(value);\n clearError(\"phone\");\n }}\n onPhoneCountryChange={(value) => {\n setPhoneCountry(value);\n workflow.commands.fieldChanged();\n }}\n phone={phone}\n phoneCountry={phoneCountry}\n phoneEnabled={catalog.widget.fields.phone}\n phoneErrorId={phoneErrorId}\n phoneId={phoneId}\n phoneRef={phoneRef}\n />\n <StripeCheckoutFields\n catalog={catalog}\n displayedTotalCents={displayedTotalCents}\n fieldValues={fieldValues}\n isBillingAddressReady={isBillingAddressReady}\n isPaymentReady={isPaymentReady}\n isShippingAddressReady={isShippingAddressReady}\n onAddressChange={(mode, address) => {\n addressesRef.current[mode] = address;\n }}\n onFieldValuesChange={handleFieldValuesChange}\n onStripeLoadError={workflow.commands.reportStripeLoadError}\n setIsBillingAddressReady={setIsBillingAddressReady}\n setIsPaymentReady={setIsPaymentReady}\n setIsShippingAddressReady={setIsShippingAddressReady}\n />\n <AdditionalCheckoutFields\n customFields={catalog.widget.customFields}\n errors={customFieldErrors}\n fields={catalog.widget.fields}\n idPrefix={idPrefix}\n isPromoApplying={isRefreshingQuote}\n onApplyPromo={workflow.commands.applyPromo}\n onChange={handleFieldValuesChange}\n promoError={promoError}\n values={fieldValues}\n />\n <PaymentAction\n catalog={catalog}\n displayedTotalCents={displayedTotalCents}\n fieldValues={fieldValues}\n isBillingAddressReady={isBillingAddressReady}\n isPaymentReady={isPaymentReady}\n isRequiredShippingReady={isRequiredShippingReady}\n isSubmitting={isSubmitting}\n onFieldValuesChange={handleFieldValuesChange}\n quote={quote}\n />\n </fieldset>\n </div>\n {isSubmitting ? (\n <p\n className=\"lockerverse-payment__sr-only\"\n ref={statusRef}\n role=\"status\"\n tabIndex={-1}\n >\n {displayedTotalCents === 0\n ? \"Completing order…\"\n : \"Processing payment…\"}\n </p>\n ) : null}\n <PaymentErrorMessage message={paymentError} />\n </form>\n );\n}\n\nfunction SkeletonLoaderBlock() {\n return (\n <div className=\"lockerverse-payment__skeleton-loader-block\">\n <span className=\"lockerverse-payment__skeleton-loader-label\" />\n <div className=\"lockerverse-payment__skeleton-loader-content\">\n <span className=\"lockerverse-payment__skeleton-loader-full\" />\n <div className=\"lockerverse-payment__skeleton-loader-grid\">\n <span className=\"lockerverse-payment__skeleton-loader-half\" />\n <span className=\"lockerverse-payment__skeleton-loader-half\" />\n </div>\n </div>\n </div>\n );\n}\n\nfunction PaymentSkeleton() {\n return (\n <div className=\"lockerverse-payment__loading\">\n <span\n aria-live=\"polite\"\n className=\"lockerverse-payment__sr-only\"\n role=\"status\"\n >\n Loading payment…\n </span>\n <div aria-hidden=\"true\" className=\"lockerverse-payment__skeleton\">\n <div className=\"lockerverse-payment__skeleton-branding\">\n <span className=\"lockerverse-payment__skeleton-avatar\" />\n <span className=\"lockerverse-payment__skeleton-community\" />\n </div>\n <div className=\"lockerverse-payment__skeleton-contact\">\n <div className=\"lockerverse-payment__skeleton-field\">\n <span className=\"lockerverse-payment__skeleton-label\" />\n <span className=\"lockerverse-payment__skeleton-input\" />\n </div>\n <div className=\"lockerverse-payment__skeleton-field\">\n <span className=\"lockerverse-payment__skeleton-label\" />\n <span className=\"lockerverse-payment__skeleton-input\" />\n </div>\n </div>\n <SkeletonLoaderBlock />\n <SkeletonLoaderBlock />\n <div className=\"lockerverse-payment__skeleton-actions\">\n <span className=\"lockerverse-payment__skeleton-check-line\" />\n <span className=\"lockerverse-payment__skeleton-button\" />\n </div>\n </div>\n </div>\n );\n}\n\nexport function LockerversePayment({\n apiBaseUrl,\n branding,\n className,\n communitySlug,\n environment,\n fetch,\n metadata,\n onError,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n requestTimeoutMs,\n resumePayment,\n selection,\n sentryDsn,\n style,\n stripeLoader = loadStripe,\n theme = \"dark\",\n widgetSlug,\n ...sectionProps\n}: LockerversePaymentProps) {\n const initialResumePayment = useRef(resumePayment).current;\n const selectPortalContainerRef = useRef<HTMLElement | null>(null);\n const [notice, setNotice] = useState<string>();\n const [paymentState, setPaymentState] =\n useState<CheckoutPaymentState>(\"idle\");\n const paymentStateRevisionRef = useRef<number | undefined>(undefined);\n const { retryCheckout, selectionError, session, updateCheckout } =\n usePaymentCheckout({\n apiBaseUrl,\n communitySlug,\n environment,\n fetch,\n onError,\n paymentState,\n requestTimeoutMs,\n selection,\n sentryDsn,\n widgetSlug,\n });\n const readySessionRevision =\n session.phase === \"ready\" ? session.revision : undefined;\n const handlePaymentStateChange = useCallback(\n (state: CheckoutPaymentState) => {\n if (readySessionRevision !== undefined) {\n paymentStateRevisionRef.current = readySessionRevision;\n }\n setPaymentState(state);\n },\n [readySessionRevision]\n );\n\n useEffect(() => {\n if (session.phase === \"loading\") {\n setNotice(undefined);\n }\n }, [session.phase]);\n\n useLayoutEffect(() => {\n if (\n session.phase === \"ready\" &&\n paymentStateRevisionRef.current !== session.revision\n ) {\n setPaymentState((current) =>\n current === \"success\" || current === \"unresolved\" ? current : \"idle\"\n );\n }\n }, [session.phase, session.revision]);\n\n const rootClassName = [\"lockerverse-payment\", className]\n .filter(Boolean)\n .join(\" \");\n const effectiveBranding =\n branding ?? (session.phase === \"ready\" ? session.catalog.community : null);\n const effectiveAccent =\n style?.[\"--lockerverse-accent\"] ??\n effectiveBranding?.accentColor ??\n \"#38d77a\";\n const automaticAccentContrast = getAccentContrast(effectiveAccent);\n const rootStyle: LockerversePaymentProps[\"style\"] = {\n ...style,\n ...(effectiveBranding?.accentColor &&\n style?.[\"--lockerverse-accent\"] === undefined\n ? { \"--lockerverse-accent\": effectiveBranding.accentColor }\n : {}),\n ...(automaticAccentContrast &&\n style?.[\"--lockerverse-accent-contrast\"] === undefined\n ? { \"--lockerverse-accent-contrast\": automaticAccentContrast }\n : {}),\n };\n\n if (selectionError) {\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n role=\"alert\"\n style={rootStyle}\n >\n {selectionError}\n </section>\n );\n }\n\n if (session.phase === \"error\") {\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n style={rootStyle}\n >\n <p role=\"alert\">{session.failure}</p>\n <button onClick={retryCheckout} type=\"button\">\n Retry\n </button>\n </section>\n );\n }\n\n if (session.phase !== \"ready\") {\n return (\n <section\n {...sectionProps}\n aria-busy=\"true\"\n aria-label=\"Payment\"\n className={rootClassName}\n data-lockerverse-theme={theme}\n style={rootStyle}\n >\n <PaymentSkeleton />\n </section>\n );\n }\n\n const { catalog, checkoutItems, client, preparedCheckout } = session;\n\n return (\n <section\n {...sectionProps}\n aria-label=\"Payment\"\n className={rootClassName}\n data-lockerverse-theme={theme}\n data-payment-state={paymentState}\n ref={selectPortalContainerRef}\n style={rootStyle}\n >\n <header>\n {catalog.widget.showCommunityBranding && effectiveBranding ? (\n <div className=\"lockerverse-payment__branding\">\n {effectiveBranding.imageUrl ? (\n <img\n alt={effectiveBranding.name}\n height=\"48\"\n src={effectiveBranding.imageUrl}\n width=\"48\"\n />\n ) : null}\n <strong>{effectiveBranding.name}</strong>\n </div>\n ) : null}\n <h1>{catalog.widget.title ?? catalog.widget.name}</h1>\n {catalog.widget.description ? (\n <p>{catalog.widget.description}</p>\n ) : null}\n </header>\n {notice ? (\n <p className=\"lockerverse-payment__payment-status\" role=\"status\">\n {notice}\n </p>\n ) : null}\n <SelectPortalProvider container={selectPortalContainerRef}>\n <ReadyPayment\n accentColor={\n style?.[\"--lockerverse-accent\"] ??\n effectiveBranding?.accentColor ??\n \"#38d77a\"\n }\n catalog={catalog}\n checkoutItems={checkoutItems}\n client={client}\n fontFamily={\n style?.[\"--lockerverse-font-family\"] ?? DEFAULT_FONT_FAMILY\n }\n metadata={metadata}\n onPaymentComplete={onPaymentComplete}\n onPaymentRecoveryChange={onPaymentRecoveryChange}\n onPaymentUncertain={onPaymentUncertain}\n onQuoteChange={(nextQuote, nextNotice) => {\n setNotice(nextNotice);\n updateCheckout(nextQuote);\n }}\n onStateChange={handlePaymentStateChange}\n quote={preparedCheckout}\n resumePayment={initialResumePayment}\n stripeLoader={stripeLoader}\n theme={theme}\n visualStyle={rootStyle}\n />\n </SelectPortalProvider>\n </section>\n );\n}\n"],"mappings":"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"}
|