@lockerverse/react 0.2.175 → 0.2.176-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATIONS.md +85 -1
- package/dist/lockerverse-payment.js +1 -1
- package/dist/lockerverse-payment.js.map +1 -1
- package/guides/auctions.md +1 -1
- package/guides/events.md +1 -1
- package/guides/integration.md +1 -1
- package/guides/payment-widgets.md +1 -1
- package/guides/signup.md +1 -1
- package/package.json +2 -2
package/MIGRATIONS.md
CHANGED
|
@@ -36,8 +36,35 @@ If it cannot be found, report that limit and use the baseline review below. Do n
|
|
|
36
36
|
claim that every historical migration was applied. Read this file even if the
|
|
37
37
|
version already matches: a previous upgrade may have missed host adoption steps.
|
|
38
38
|
|
|
39
|
+
## 0.2.176-dev.1 — Secure checkout loading recovery
|
|
40
|
+
|
|
41
|
+
- **Affected:** React payment widget Stripe fields.
|
|
42
|
+
- **Automatic:** failed field or script loads show a reload action. Fields that
|
|
43
|
+
remain unready for 30 seconds show a delay message. Late readiness removes
|
|
44
|
+
the message without resetting the checkout or submitting a payment.
|
|
45
|
+
- **Required host changes:** none; keep Core and React versions matched.
|
|
46
|
+
- **Check:** block Stripe loading in an isolated browser, confirm the message,
|
|
47
|
+
restore access, and use Reload checkout. Confirm normal fields still load.
|
|
48
|
+
- Reload is an explicit customer action and can clear unsaved form entries.
|
|
49
|
+
Saved payment recovery remains in session storage.
|
|
50
|
+
|
|
39
51
|
## 0.2.175 — Match Stripe Elements payment method configuration
|
|
40
52
|
|
|
53
|
+
- **Affected:** Core checkout submission and React payment widgets.
|
|
54
|
+
- **Automatic:** React configures explicit card, Link, and community-enabled bank
|
|
55
|
+
methods in Stripe Elements and marks the confirmation request with
|
|
56
|
+
`paymentMethodConfiguration: "explicit"`. This matches the backend's Stripe
|
|
57
|
+
PaymentIntent configuration.
|
|
58
|
+
- **Required:** deploy the backend that supports this optional marker before
|
|
59
|
+
upgrading React. Keep Core and React matched. Existing Core-only callers omit
|
|
60
|
+
the marker and retain automatic payment methods. Custom Elements integrations
|
|
61
|
+
must send the marker only when they use the explicit method list.
|
|
62
|
+
- **Check:** submit card and bank payments through Stripe Elements in test mode,
|
|
63
|
+
including recurring checkout. Confirm pending recovery and settlement.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## 0.2.174-dev.1 — Match Stripe Elements payment method configuration
|
|
67
|
+
|
|
41
68
|
- **Affected:** Core checkout submission and React payment widgets.
|
|
42
69
|
- **Automatic:** React configures explicit card, Link, and community-enabled bank
|
|
43
70
|
methods in Stripe Elements and marks the confirmation request with
|
|
@@ -111,7 +138,39 @@ version already matches: a previous upgrade may have missed host adoption steps.
|
|
|
111
138
|
verify a changed selection cannot discard it. Check both paid and free order
|
|
112
139
|
confirmation panels. Do not submit a live transaction for this check.
|
|
113
140
|
|
|
114
|
-
## 0.2.
|
|
141
|
+
## 0.2.172-dev.1 — Check pending payment status
|
|
142
|
+
|
|
143
|
+
- **Affected:** React payment widgets with unresolved payments.
|
|
144
|
+
- **Automatic behavior:** the existing pending-payment screen now offers Check
|
|
145
|
+
payment status. It checks the saved payment reference and cannot submit a new
|
|
146
|
+
payment. The control is disabled while the check runs.
|
|
147
|
+
- **Required host changes:** none. Update Core and React together.
|
|
148
|
+
- **Verification:** complete a test bank payment, return to its pending checkout,
|
|
149
|
+
and check its status. Confirm completion clears recovery storage.
|
|
150
|
+
|
|
151
|
+
## 0.2.171-dev.1 — SDK payment recovery and completion UI
|
|
152
|
+
|
|
153
|
+
- **Affected:** React payment widgets and custom hosts that persist payment recovery.
|
|
154
|
+
- **Optional adoption:** pass `recoveryStorageKey` to `LockerversePayment` to let
|
|
155
|
+
the SDK save and restore the pending payment in session storage. Use a stable
|
|
156
|
+
key scoped to the API environment, community, and widget. Remove the host's
|
|
157
|
+
storage code and recovery-driven component key. Do not combine automatic
|
|
158
|
+
persistence with a second host persistence writer.
|
|
159
|
+
- **Compatibility:** the SDK reads the hosted Next app's existing version 1
|
|
160
|
+
records when the same key is used. It writes version 2 records with widget
|
|
161
|
+
identity. It checks widget and selection identity before recovery and keeps
|
|
162
|
+
an unresolved record if those details differ. Recovery uses the saved connected
|
|
163
|
+
account even if current payment routing has changed. Storage is read after hydration,
|
|
164
|
+
before the payable form mounts. No contact details or payment tokens are saved.
|
|
165
|
+
- **Optional UI adoption:** use `completionView="summary"` for the SDK confirmation
|
|
166
|
+
panel and remove the host's duplicate success panel. Completion callbacks still
|
|
167
|
+
run. The default inline message and explicit `resumePayment` integrations remain
|
|
168
|
+
supported. Auctions and legacy custom checkout forms are unchanged.
|
|
169
|
+
- **Check:** reload a pending checkout and confirm the existing payment is checked;
|
|
170
|
+
verify a changed selection cannot discard it. Check both paid and free order
|
|
171
|
+
confirmation panels. Do not submit a live transaction for this check.
|
|
172
|
+
|
|
173
|
+
## 0.2.169-dev.1 — six-month payment widgets
|
|
115
174
|
|
|
116
175
|
Affected: @lockerverse/sdk checkout and @lockerverse/react payment widgets.
|
|
117
176
|
|
|
@@ -127,6 +186,31 @@ Affected: @lockerverse/sdk checkout and @lockerverse/react payment widgets.
|
|
|
127
186
|
submission. Do not submit a live payment for an integration check.
|
|
128
187
|
|
|
129
188
|
|
|
189
|
+
## 0.2.168-dev.1 — bank authorization terms
|
|
190
|
+
|
|
191
|
+
- **Affected:** React payment widgets with ACH enabled.
|
|
192
|
+
- **Automatic:** Stripe displays its bank authorization terms before payment confirmation.
|
|
193
|
+
- **Adoption:** update the matching SDK/React development pair. No prop changes are required.
|
|
194
|
+
- **Check:** confirm that the bank authorization text is visible when a bank account is selected.
|
|
195
|
+
|
|
196
|
+
## 0.2.167-dev.1 — widget ACH and subscription payment recovery
|
|
197
|
+
|
|
198
|
+
- **Affected:** Core checkout data and React payment widgets.
|
|
199
|
+
- **Automatic:** bank payment availability follows the organization default and
|
|
200
|
+
community override returned by the backend. Missing policy remains disabled.
|
|
201
|
+
Pending payments keep their existing payment reference. A failed subscription
|
|
202
|
+
invoice can return `action_required` with `requiresAction: false` and `retryUrl`;
|
|
203
|
+
React shows a link to pay the same invoice instead of creating a second subscription.
|
|
204
|
+
- **Required for custom payment UI:** preserve the reference for pending and
|
|
205
|
+
action-required results. Handle `retryUrl` by opening that invoice, and recover
|
|
206
|
+
status before permitting a new checkout. Do not treat submission as settlement.
|
|
207
|
+
- **Adoption:** deploy the matching backend policy and recovery contract before
|
|
208
|
+
enabling ACH. Existing React hosts need no component prop changes. Keep Core and
|
|
209
|
+
React versions matched when upgrading. Auction payment methods are unchanged.
|
|
210
|
+
- **Check:** verify disabled/inherited/enabled bank visibility and pending, bank
|
|
211
|
+
verification, invoice retry, success, and terminal failure in Stripe test mode.
|
|
212
|
+
Do not create a live transaction for this check.
|
|
213
|
+
|
|
130
214
|
## 0.2.166 — single dropdown arrow
|
|
131
215
|
|
|
132
216
|
- **Affected:** native single-select custom fields in React signup and payment forms.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./format-money.js";import{t}from"./host-callback.js";import{n,t as r}from"./accent-contrast.js";import{d as i,i as a,n as o,p as s,t as c,u as l}from"./phone-field.js";import{a as u,i as d,n as f,r as p,s as m}from"./custom-fields.js";import{t as h}from"./form-skeleton.js";import{t as g}from"./payment-summary.js";import{i as _,n as v,r as y,t as b}from"./stripe-loader.js";import{useCallback as x,useEffect as S,useId as C,useLayoutEffect as w,useMemo as T,useReducer as E,useRef as D,useState as O}from"react";import{Fragment as k,jsx as A,jsxs as j}from"react/jsx-runtime";import{LockerverseSdkError as M,estimateLockerverseCheckout as N}from"@lockerverse/sdk/checkout";import{AddressElement as P,Elements as F,PaymentElement as I,useElements as L,useStripe as R}from"@stripe/react-stripe-js";import{array as z,literal as B,minLength as ee,minValue as V,nonEmpty as te,nullable as ne,number as re,object as H,optional as U,pipe as W,regex as G,safeInteger as ie,safeParse as K,strictObject as ae,string as q,trim as oe,union as se}from"valibot";function ce({ariaDescribedBy:e,ariaLabel:t,ariaLabelledBy:n,className:r,id:i,invalid:a=!1,name:o,onValueChange:s,options:c,value:l}){return A(`select`,{"aria-describedby":e,"aria-invalid":a||void 0,"aria-label":t,"aria-labelledby":n,className:[`lockerverse-form__control`,`lockerverse-form__select`,r].filter(Boolean).join(` `),id:i,name:o,onChange:e=>s(e.currentTarget.value),value:l,children:c.map(e=>A(`option`,{value:e.value,children:e.label},e.value))})}const le=[`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`],J=[`15`,`12`,`10`,`5`],Y=[...J,`custom`];function ue({enabled:e,error:t,errorId:n,onChange:r,values:i}){if(!e)return null;let a=e=>r({...i,...e}),o=(e,t)=>{let n=Y.indexOf(t),r;switch(e.key){case`ArrowDown`:case`ArrowRight`:r=(n+1)%Y.length;break;case`ArrowLeft`:case`ArrowUp`:r=(n-1+Y.length)%Y.length;break;case`Home`:r=0;break;case`End`:r=Y.length-1;break;default:return}e.preventDefault();let i=Y[r];i&&((e.currentTarget.closest(`[role="radiogroup"]`)?.querySelectorAll(`input[type="radio"]`))?.[r]?.focus(),a({tipPercent:i}))};return j(`div`,{className:`lockerverse-payment__tip-box`,children:[A(`p`,{children:`Add a tip to support the Lockerverse platform`}),j(`div`,{"aria-label":`Tip amount`,role:`radiogroup`,children:[J.map(e=>j(`label`,{className:`lockerverse-payment__tip-choice`,children:[A(`input`,{checked:i.tipPercent===e,name:`tipPercent`,onChange:()=>a({tipPercent:e}),onKeyDown:t=>o(t,e),tabIndex:i.tipPercent===e?0:-1,type:`radio`,value:e}),j(`span`,{children:[e,`%`]})]},e)),j(`label`,{className:`lockerverse-payment__tip-choice`,children:[A(`input`,{checked:i.tipPercent===`custom`,name:`tipPercent`,onChange:()=>a({tipPercent:`custom`}),onKeyDown:e=>o(e,`custom`),tabIndex:i.tipPercent===`custom`?0:-1,type:`radio`,value:`custom`}),A(`span`,{children:`Other`})]})]}),i.tipPercent===`custom`?j(`label`,{children:[A(`span`,{children:`Custom tip`}),j(`span`,{className:`lockerverse-payment__money-input`,children:[A(`span`,{"aria-hidden":`true`,children:`$`}),A(`input`,{"aria-describedby":t?n:void 0,"aria-invalid":t?`true`:void 0,inputMode:`decimal`,name:`tip`,onChange:e=>a({customTip:e.currentTarget.value}),placeholder:`0.00`,value:i.customTip})]}),t?A(`span`,{className:`lockerverse-payment__field-message`,id:n,children:t}):null]}):A(`input`,{name:`tip`,type:`hidden`,value:i.tipPercent})]})}function X({checked:e,children:t,name:n,onChange:r}){let i=C();return j(`label`,{className:`lockerverse-payment__check-row`,htmlFor:i,children:[A(l,{checked:e,id:i,name:n,onChange:e=>r(e.currentTarget.checked)}),A(`span`,{children:t})]})}function de({customFields:e,errors:t,fields:n,idPrefix:r,isPromoApplying:i,memberIdLabel:a,onChange:o,onApplyPromo:s,promoError:c,values:l}){let u=e=>o({...l,...e});return j(`div`,{className:`lockerverse-payment__additional-fields`,children:[n.memberId?j(`label`,{children:[A(`span`,{children:a?.trim()||`Member ID`}),A(`input`,{name:`memberId`,onChange:e=>u({memberId:e.currentTarget.value}),placeholder:`Optional`,value:l.memberId})]}):null,n.merchSize?j(`div`,{className:`lockerverse-payment__field`,children:[A(`span`,{id:`${r}-merch-size-label`,children:`Size`}),A(ce,{ariaLabelledBy:`${r}-merch-size-label`,name:`merchSize`,onValueChange:e=>{let t=le.find(t=>t===e);t&&u({merchSize:t})},options:le.map(e=>({label:e,value:e})),value:l.merchSize})]}):null,n.promoCode?j(`div`,{className:`lockerverse-payment__field`,children:[A(`span`,{id:`${r}-promo-code-label`,children:`Promo code`}),j(`div`,{className:`lockerverse-payment__promo-control`,children:[A(`input`,{"aria-describedby":c?`${r}-promo-code-error`:void 0,"aria-invalid":c?`true`:void 0,"aria-labelledby":`${r}-promo-code-label`,name:`promoCode`,onChange:e=>u({promoCode:e.currentTarget.value}),placeholder:`Optional`,value:l.promoCode}),A(`button`,{disabled:!l.promoCode.trim()||i,onClick:s,type:`button`,children:i?`Applying…`:`Apply`})]}),c?A(`p`,{className:`lockerverse-payment__field-message`,id:`${r}-promo-code-error`,role:`alert`,children:c}):null]}):null,A(f,{choiceClassName:`lockerverse-payment__check-row`,errorClassName:`lockerverse-payment__field-message`,errors:t,fields:e,idPrefix:r,onChange:e=>u({customFields:e}),values:l.customFields})]})}function fe({amountCents:t,enabled:n,onChange:r,values:i}){return n?j(X,{checked:i.includeServiceFee,name:`includeServiceFee`,onChange:e=>r({...i,includeServiceFee:e}),children:[`Add `,e(t),` to help cover processing fees`]}):null}function pe(e){return{error:void 0,message:void 0,status:e?`recovering`:`editing`}}function Z(e,t,n){return t.includes(e.status)?{...e,...n}:e}function Q(e,t){if(t.type===`recovery_started`&&e.status===`unresolved`)return{...e,message:void 0,status:`recovering`};if(e.status===`sold_out`||e.status===`succeeded`||e.status===`unresolved`)return e;switch(t.type){case`field_changed`:return Z(e,[`editing`,`invalid`,`refreshing_quote`],{error:void 0,status:`editing`});case`validation_failed`:return Z(e,[`editing`],{status:`invalid`});case`quote_refresh_started`:return Z(e,[`editing`,`invalid`],{status:`refreshing_quote`});case`quote_refresh_succeeded`:return Z(e,[`refreshing_quote`],{error:void 0,status:`editing`});case`quote_refresh_failed`:return Z(e,[`refreshing_quote`],{error:t.error??e.error,status:`editing`});case`submission_started`:return Z(e,[`editing`,`invalid`,`refreshing_quote`],{error:void 0,status:`submitting`});case`submission_validation_failed`:return Z(e,[`submitting`],{error:void 0,status:`invalid`});case`quote_changed`:return Z(e,[`submitting`],{status:`editing`});case`retryable_failure`:return Z(e,[`editing`,`invalid`,`submitting`],{error:t.error,status:`editing`});case`recovery_failed`:return Z(e,[`recovering`],{error:t.error,retryUrl:void 0,status:`editing`});case`sold_out`:return{error:void 0,message:void 0,status:`sold_out`};case`succeeded`:return Z(e,[`recovering`,`submitting`],{message:t.message,retryUrl:void 0,status:`succeeded`});case`unresolved`:return Z(e,[`recovering`,`submitting`],{message:t.message,retryUrl:t.retryUrl,status:`unresolved`});default:return e}}function me(e){return e.status===`editing`||e.status===`invalid`||e.status===`refreshing_quote`?e.error:void 0}function he(e){return e.status===`sold_out`?`sold_out`:e.status===`succeeded`?`success`:e.status===`unresolved`?`unresolved`:e.status===`submitting`||e.status===`recovering`?`submitting`:e.status===`invalid`?`invalid`:me(e)?`error`:`idle`}function ge(e){return e.status===`submitting`}const _e=[`amountCents`,`discountableSubtotalCents`,`discountCents`,`serviceFeeCents`,`subtotalCents`,`tipCents`,`totalCents`],ve=[`discountableSubtotalCents`,`discountCents`,`subtotalCents`];function ye(e,t,n,r){return(n===t.totalCents?ve:_e).some(n=>e[n]!==t[n])||r!==t.payment.connectedAccountId||e.authoritative&&(e.payment.connectedAccountId!==r||e.payment.currency!==t.payment.currency)||JSON.stringify(e.appliedDiscount)!==JSON.stringify(t.appliedDiscount)||JSON.stringify(e.lineItems)!==JSON.stringify(t.lineItems)}function be(e){if(e.checkoutStatus===`success`)return{kind:`success`,payment:e};if(e.checkoutStatus===`failed`)return{kind:`failed`,payment:e};let t={kind:`unresolved`,paymentReference:e.paymentReference,reason:e.checkoutStatus===`action_required`?`action_required`:`pending`};return e.retryUrl&&(t.retryUrl=e.retryUrl),t}async function xe(e,t,n){if(t.checkoutStatus!==`action_required`||!t.requiresAction)return be(t);if(!n)return{kind:`unresolved`,paymentReference:t.paymentReference,reason:`action_required`};if(t.clientSecret)try{await n.handleNextAction({clientSecret:t.clientSecret})}catch{}try{return be(await e.getPaymentStatus(t.paymentReference))}catch{return{kind:`unresolved`,paymentReference:t.paymentReference,reason:`action_required`}}}async function Se(e,t,n){let r;try{r=await e.submitPayment(t)}catch(n){if(!(n instanceof M&&n.recoveryRecommended))throw n;try{r=await e.getPaymentStatus(t.checkout.paymentReference)}catch{return{kind:`unresolved`,paymentReference:t.checkout.paymentReference,reason:`recovery_failed`}}}return xe(e,r,n)}async function Ce(e,t,n){try{return xe(e,await e.getPaymentStatus(t),n)}catch{return{kind:`unresolved`,paymentReference:t,reason:`recovery_failed`}}}const we=W(q(),oe(),te()),Te=W(re(),ie(),V(1)),Ee=W(z(se([ae({amountCents:Te,productSlug:we}),ae({productSlug:we,quantity:Te}),ae({productSlug:we})])),ee(1)),De=W(q(),oe(),G(/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/,`Enter a valid tip amount.`));function Oe(e){let t=K(De,e);if(!t.success)return{message:t.issues[0]?.message??`Enter a valid tip amount.`,success:!1};let[n=`0`,r=``]=t.output.split(`.`),i=BigInt(n)*100n+BigInt(r.padEnd(2,`0`));return i>BigInt(2**53-1)?{message:`Enter a valid tip amount.`,success:!1}:{cents:Number(i),success:!0}}function ke(e){let t=K(Ee,e);return t.success?{success:!0,value:t.output}:{message:`Lockerverse payment configuration is invalid.`,success:!1}}const Ae=`This promo code is invalid or cannot be applied.`;function je(e,t){return t.tipPercent===`custom`?t.customTip.trim()?Oe(t.customTip):{cents:0,success:!0}:{cents:Math.round(e*Number(t.tipPercent)/100),success:!0}}function Me(e,t,n,r){let i={};return n&&(i.email=n),e.widget.fields.serviceFee&&(i.includeServiceFee=t.includeServiceFee),e.widget.fields.promoCode&&t.promoCode.trim()&&(i.promoCode=t.promoCode.trim()),e.widget.fields.tipping&&(i.tipCents=r),i}function Ne(e,t,n){let r=e.widget.fields.tipping?je(n.subtotalCents,t):{cents:0,success:!0};if(!r.success)return{parsedTip:r,totalCents:null};let i=e.widget.fields.serviceFee&&t.includeServiceFee?n.serviceFeeCents||Math.round(n.subtotalCents*e.pricingPolicy.serviceFeeRateBasisPoints/1e4):0;return{parsedTip:r,totalCents:n.totalCents-n.serviceFeeCents-n.tipCents+i+r.cents}}function Pe(e,t){return{displayedTotalCents:e.totalCents,promoError:t&&e.appliedDiscount?.source!==`promo_code`?Ae:void 0}}function Fe(e,t){let n;return t||(n=e instanceof Error?e.message:`The order total could not be updated.`),{paymentError:n,promoError:t?Ae:void 0}}function Ie(e,t){if(!e?.complete)throw Error(`${t} address is required.`);return e.value}function Le(e,t,n,r){if(e.widget.fields.shipping)return t.shippingMatchesBilling?n:Ie(r.shipping,`Shipping`)}function Re({billingAddress:e,catalog:t,email:n,phone:r,shippingAddress:i}){let a={payment_method_data:{billing_details:t.widget.fields.phone?{address:e.address,email:n,name:e.name,phone:r}:{address:e.address,email:n,name:e.name}}};return i?{...a,shipping:{address:i.address,name:i.name,phone:t.widget.fields.phone?r:i.phone??null}}:a}function ze({catalog:e,checkoutItems:t,confirmationToken:n,email:r,fieldValues:i,metadata:a,phone:o,shippingAddress:s}){let c={customFieldAnswers:p(u(e,t),i.customFields),email:r};if(n&&(c.confirmationToken=n,c.paymentMethodConfiguration=`explicit`),a&&(c.metadata=a),e.widget.fields.memberId&&i.memberId.trim()&&(c.memberId=i.memberId.trim()),e.widget.fields.merchSize&&(c.merchSize=i.merchSize),e.widget.fields.phone&&(c.phone=o),s){let e={city:s.address.city??``,country:s.address.country,line1:s.address.line1??``,postal_code:s.address.postal_code??``,state:s.address.state??``};s.address.line2&&(e.line2=s.address.line2),c.shipping={address:e,name:s.name}}return c}function Be(e){if(!e())throw Error(`Payment component is no longer active.`)}function Ve(e,n){t(e,n)}function He(e,t,n,r){return e.kind===`failed`?{kind:`payment_failed`,message:r}:e.kind===`unresolved`?{kind:`payment_unresolved`,paymentReference:e.paymentReference,reason:e.reason,retryUrl:e.retryUrl}:{email:n,kind:`payment`,payment:e.payment,quote:t}}async function Ue({addresses:e,catalog:t,checkoutItems:n,client:r,elements:i,email:a,fieldValues:o,isAttemptActive:s,locallyPreviewedTotalCents:c,metadata:l,onPaymentRecoveryChange:u,phone:d,quote:f,stripe:p,stripeConnectedAccountId:m}){let h=a.trim().toLowerCase(),g=y(d),_=je(f.subtotalCents,o);if(!_.success)throw Error(_.message);let v=await r.calculateTotal({...Me(t,o,h,_.cents),catalog:t,items:n});if(Be(s),v.totalCents>0&&ye(f,v,c,m))return{kind:`quote_changed`,quote:v};let b,x;if(v.totalCents===0)t.widget.fields.shipping&&(b=Le(t,o,Ie(e.billing,`Billing`),e));else{if(!(i&&p))throw Error(`Payment form is still loading.`);await i.update({amount:v.totalCents}),Be(s);let n=await i.submit();if(Be(s),n.error)throw Error(n.error.message);let r=Ie(e.billing,`Billing`);b=Le(t,o,r,e);let a=await p.createConfirmationToken({elements:i,params:Re({billingAddress:r,catalog:t,email:h,phone:g,shippingAddress:b})});if(Be(s),a.error)throw Error(a.error.message);x=a.confirmationToken.id}Ve(u,{connectedAccountId:v.payment.connectedAccountId,paymentReference:v.paymentReference});let S=await Se(r,{checkout:v,submission:ze({catalog:t,checkoutItems:n,confirmationToken:x,email:h,fieldValues:o,metadata:l,phone:g,shippingAddress:b})},p);return Be(s),He(S,v,h,v.totalCents===0?`Order could not be completed. Review the details and try again.`:`Payment was declined. Check your payment details and try again.`)}function We(e,n){t(e,n)}function Ge(e,n){t(e,n)}function Ke(e,t){return{...e,...t}}function qe(e){let t={message:e.reason===`action_required`?`Payment needs your attention. Keep this checkout open.`:`Payment is not complete. Check its status before you try again.`,type:`unresolved`};return e.retryUrl&&(t.retryUrl=e.retryUrl),t}function Je(e,t,n){return e.kind===`unresolved`&&e.reason===`action_required`&&!e.retryUrl&&!t&&!n}function Ye(e){return e instanceof M&&e.serverCode===`PAYMENT_WIDGET_SALES_LIMIT_REACHED`}function Xe({nextQuote:e,onQuoteChange:t,setDisplayedTotalCents:n,setPromoError:r,updateState:i,validatePromo:a}){let o=Pe(e,a);i({type:`quote_refresh_succeeded`}),n(o.displayedTotalCents),t(e),a&&r(o.promoError)}function Ze({error:e,setPromoError:t,updateState:n,validatePromo:r}){let i=Fe(e,r);r&&t(i.promoError),n(i.paymentError===void 0?{type:`quote_refresh_failed`}:{error:i.paymentError,type:`quote_refresh_failed`})}function Qe({onPaymentComplete:n,onPaymentRecoveryChange:r,onPaymentUncertain:i,onQuoteChange:a,result:o,setDisplayedTotalCents:s,dispatchState:c,unresolvedReferenceRef:l}){if(o.kind===`quote_changed`){let t=`The total changed to ${e(o.quote.totalCents)}. Review it and pay again.`;a(o.quote,t),s(o.quote.totalCents),c({type:`quote_changed`});return}if(o.kind===`payment_failed`){We(r,null),c({error:o.message,type:`retryable_failure`});return}if(o.kind===`payment_unresolved`){l.current=o.paymentReference,c(qe(o)),Ge(i,{paymentReference:o.paymentReference,reason:o.reason});return}a(o.quote),We(r,null),c({message:o.payment.paymentRequired?`Payment completed successfully.`:`Order confirmed. No payment was required.`,type:`succeeded`}),t(n,Ke(o.payment,{email:o.email,lineItems:o.quote.lineItems}))}function $e(e){let{catalog:n,checkoutItems:r,client:i,elements:o,email:s,fieldValues:c,metadata:l,onPaymentComplete:u,onResumePaymentFailed:d,onPaymentRecoveryChange:f,onPaymentUncertain:p,onQuoteChange:m,onStateChange:h,quote:g,resumePayment:v,stripe:y,stripeConnectedAccountId:b,stripeLoadFailed:C,paymentState:w,updateState:T}=e,[E,k]=O(g.totalCents),[A,j]=O(),N=D(!1),P=D(void 0),F=D(0),I=D(0),L=x(e=>T(e,!0),[T]),R=x(()=>{let e=I.current+1;return I.current=e,()=>I.current===e},[]);S(()=>()=>{I.current+=1,F.current+=1},[]);let{parsedTip:z,totalCents:B}=Ne(n,c,g);S(()=>{B!==null&&(k(B),B>0&&o?.update({amount:B}))},[n.pricingPolicy.serviceFeeRateBasisPoints,n.widget.fields.serviceFee,o,c.includeServiceFee,B,g.serviceFeeCents,g.tipCents,g.totalCents,g.subtotalCents]),S(()=>{let e=v?.paymentReference??P.current;if(!e||N.current||w.status!==`recovering`)return;N.current=!0;let n=R();return h(he(w)),Ce(i,e,y).then(e=>{if(n()&&!Je(e,y,C)){if(e.kind===`failed`){We(f,null),d(),L({error:`The previous payment failed. Check your details and try again.`,type:`recovery_failed`});return}if(e.kind===`unresolved`){L(qe(e)),Ge(p,{paymentReference:e.paymentReference,reason:e.reason});return}We(f,null),L({message:e.payment.paymentRequired?`Payment completed successfully.`:`Order confirmed. No payment was required.`,type:`succeeded`}),t(u,Ke(e.payment,{email:null,lineItems:null}))}}),()=>{n()&&(I.current+=1),N.current=!1}},[i,u,d,f,p,h,v,y,C,R,L,w]);let ee=x((e=!1,t=!1)=>{t||(F.current+=1),e&&j(void 0),T({type:`field_changed`})},[T]);async function V(e=!1,t=!1){let a=s.trim().toLowerCase(),o=_({email:a,phone:``},!1);if(!(z.success&&(o.value||e)))return;F.current+=1;let l=F.current;T({type:`quote_refresh_started`});try{let e=await i.calculateTotal({...Me(n,c,o.value?.email??``,z.cents),catalog:n,items:r});if(l!==F.current)return;Xe({nextQuote:e,onQuoteChange:m,setDisplayedTotalCents:k,setPromoError:j,updateState:T,validatePromo:t})}catch(e){if(l!==F.current)return;if(Ye(e)){T({type:`sold_out`});return}Ze({error:e,setPromoError:j,updateState:T,validatePromo:t})}}async function te(){j(void 0),await V(!0,!0)}async function ne({addresses:e,phone:t}){L({type:`submission_started`});let d=R();try{let a=await Ue({addresses:e,catalog:n,checkoutItems:r,client:i,elements:o,email:s,fieldValues:c,isAttemptActive:d,locallyPreviewedTotalCents:E,metadata:l,onPaymentRecoveryChange:f,phone:t,quote:g,stripe:y,stripeConnectedAccountId:b});if(!d())return;Qe({dispatchState:L,onPaymentComplete:u,onPaymentRecoveryChange:f,onPaymentUncertain:p,onQuoteChange:m,result:a,setDisplayedTotalCents:k,unresolvedReferenceRef:P})}catch(e){if(!d())return;if(We(f,null),Ye(e)){L({type:`sold_out`});return}let t=e instanceof M?a(e.serverCode):void 0;if(t)return L({type:`submission_validation_failed`}),{phoneError:t};L({error:e instanceof Error?e.message:`Payment could not be completed.`,type:`retryable_failure`})}}let re=w.status===`succeeded`||w.status===`unresolved`?w.message:void 0;return{commands:{applyPromo:te,checkPaymentStatus:()=>L({type:`recovery_started`}),fieldChanged:ee,refreshAuthoritativeTotal:V,reportStripeLoadError:e=>L({error:e,type:`retryable_failure`}),reportValidationFailure:()=>L({type:`validation_failed`}),submit:ne},state:{displayedTotalCents:E,isRecovering:w.status===`recovering`,isRefreshingQuote:w.status===`refreshing_quote`,isSubmitting:ge(w),isUnresolved:w.status===`unresolved`,parsedTip:z,paymentError:me(w),promoError:A,retryUrl:w.retryUrl,terminalMessage:re}}}const et=b;function tt(e){let{connectedAccountId:t,publishableKey:n}=e.payment;return et(n,t?{stripeAccount:t}:void 0)}function nt(e){return e===`monthly`?{interval:`month`,label:`Monthly`}:e===`annually`?{interval:`year`,label:`Annual`}:e===`every-six-months`?{interval:`6 months`,label:`Every 6 months`}:null}function rt(e,t,n){if(n){let{connectedAccountId:e}=n;return e}if(`payment`in t){let{connectedAccountId:e}=t.payment;return e}let{connectedAccountId:r}=e.payment;return r}function it({accentColor:e,catalog:t,checkoutItems:n,client:r,appearanceRoot:i,initialCustomFieldValues:a,metadata:o,onPaymentComplete:s,onResumePaymentFailed:c,onPaymentRecoveryChange:l,onPaymentUncertain:u,onQuoteChange:d,quote:f,resumePayment:p,onStateChange:m,stripeLoader:g,theme:_,visualStyle:y}){let[b,C]=O(()=>pe(!!p)),w=D(b);w.current=b;let E=x((e,t=!1)=>{let n=Q(w.current,e);n!==w.current&&(w.current=n,C(n),t&&m(he(n)))},[m]),k=rt(t,f,p),j=D({connectedAccountId:k,paymentOption:f.paymentOption});b.status!==`submitting`&&b.status!==`recovering`&&(j.current={connectedAccountId:k,paymentOption:f.paymentOption});let{connectedAccountId:M,paymentOption:N}=j.current,P=T(()=>g(t.payment.publishableKey,M?{stripeAccount:M}:void 0).catch(()=>null),[t.payment.publishableKey,M,g]),[I,L]=O(!1);S(()=>{let e=!0;return L(!1),P.then(t=>{e&&t===null&&L(!0)}),()=>{e=!1}},[P]);let R=v(i,_,y,b.status===`submitting`||b.status===`recovering`,e);return R?A(F,{options:{amount:Math.max(f.totalCents,100),appearance:R,currency:t.payment.currency,mode:N===`one-time`?`payment`:`subscription`,paymentMethodTypes:t.community?.widgetAchEnabled?[`card`,`link`,`us_bank_account`]:[`card`,`link`],syncAddressCheckbox:`none`},stripe:P,children:A(mt,{catalog:t,checkoutItems:n,client:r,initialCustomFieldValues:a,metadata:o,onPaymentComplete:s,onPaymentRecoveryChange:l,onPaymentUncertain:u,onQuoteChange:d,onResumePaymentFailed:c,onStateChange:m,paymentState:b,quote:f,resumePayment:p,stripeConnectedAccountId:M,stripeLoadFailed:I,updateState:E})},`${t.payment.publishableKey}:${M??`platform`}:${N}`):A(h,{fieldCount:3,label:`Loading payment form`})}function at({label:e}){return j(`div`,{className:`lockerverse-payment__stripe-loader`,role:`status`,children:[A(`p`,{children:e}),j(`div`,{"aria-hidden":`true`,children:[A(`span`,{}),A(`span`,{}),A(`span`,{})]})]})}function ot({onError:e,onReady:t,ready:n}){return j(`div`,{className:`lockerverse-payment__stripe-element`,"data-ready":n,children:[n?null:A(at,{label:`Loading payment form...`}),A(`div`,{className:`lockerverse-payment__stripe-mount`,children:A(I,{onLoadError:({error:t})=>e(t.message??`Payment form failed to load.`),onReady:t,options:{business:{name:`Lockerverse`},fields:{billingDetails:{address:`never`,email:`never`,name:`never`,phone:`never`}},layout:`tabs`,terms:{applePay:`auto`,auBecsDebit:`never`,bancontact:`never`,card:`always`,cashapp:`never`,googlePay:`never`,ideal:`never`,paypal:`auto`,sepaDebit:`never`,sofort:`never`,usBankAccount:`auto`},wallets:{applePay:`auto`,googlePay:`never`}}})})]})}function st({label:e,mode:t,onChange:n,onError:r,onReady:i,ready:a}){return j(`div`,{className:`lockerverse-payment__address`,children:[A(`h2`,{children:e}),j(`div`,{className:`lockerverse-payment__stripe-element lockerverse-payment__stripe-element--address`,"data-ready":a,children:[a?null:A(at,{label:`Loading ${e.toLowerCase()}...`}),A(`div`,{className:`lockerverse-payment__stripe-mount`,children:A(P,{onChange:n,onLoadError:({error:t})=>r(t.message??`${e} failed to load.`),onReady:i,options:{autocomplete:{mode:`automatic`},mode:t}})})]})]})}function ct({message:e}){return e?A(`p`,{className:`lockerverse-payment__field-message`,role:`alert`,children:e}):null}function lt({catalog:e,displayedTotalCents:t,fieldValues:n,isBillingAddressReady:r,isPaymentReady:i,isShippingAddressReady:a,onAddressChange:o,onFieldValuesChange:s,onStripeLoadError:c,setIsBillingAddressReady:l,setIsPaymentReady:u,setIsShippingAddressReady:d}){let f=t>0;return j(k,{children:[f?A(ot,{onError:c,onReady:()=>u(!0),ready:i}):null,f||e.widget.fields.shipping?A(st,{label:f?`Billing address`:`Shipping address`,mode:`billing`,onChange:e=>o(`billing`,e),onError:c,onReady:()=>l(!0),ready:r}):null,e.widget.fields.shipping?j(`div`,{className:`lockerverse-payment__shipping`,children:[A(X,{checked:n.shippingMatchesBilling,name:`shippingMatchesBilling`,onChange:e=>{s({...n,shippingMatchesBilling:e}),e?o(`shipping`,null):d(!1)},children:`Shipping is same as billing information`}),n.shippingMatchesBilling?null:A(st,{label:`Shipping address`,mode:`shipping`,onChange:e=>o(`shipping`,e),onError:c,onReady:()=>d(!0),ready:a})]}):null]})}function ut({catalog:t,displayedTotalCents:n,fieldValues:r,isBillingAddressReady:i,isPaymentReady:a,isRequiredShippingReady:o,isSubmitting:s,onFieldValuesChange:c,quote:l}){let u=n===0,d=u?!t.widget.fields.shipping||i&&o:a&&i&&o,f=nt(l.paymentOption),p=u?`Complete order`:`Pay ${e(n)}`;!u&&f&&(p=`Subscribe for ${e(n)}/${f.interval}`),s&&(p=u?`Completing…`:`Processing…`);let m=`Process payment for ${e(n)} total`;return u?m=`Complete order`:f&&(m=`Start ${f.label.toLowerCase()} subscription for ${e(n)}`),j(`div`,{className:`lockerverse-payment__actions`,children:[A(fe,{amountCents:l.serviceFeeCents||Math.round(l.subtotalCents*t.pricingPolicy.serviceFeeRateBasisPoints/1e4),enabled:t.widget.fields.serviceFee,onChange:c,values:r}),A(`button`,{"aria-busy":s,"aria-label":m,disabled:s||!d,type:`submit`,children:p})]})}function dt(e,t){let n=e.elements.namedItem(t);if(n instanceof HTMLElement){n.focus();return}n instanceof RadioNodeList&&Array.from(n).find(e=>e instanceof HTMLElement)?.focus()}function ft({customFieldErrors:e,emailRef:t,form:n,parsedTipSuccess:r,phoneRef:i,validationErrors:a}){if(a.email){t.current?.focus();return}if(a.phone){i.current?.focus();return}if(!r){n.querySelector(`[name="tip"]`)?.focus();return}let[o]=Object.keys(e);o&&dt(n,`custom:${o}`)}function pt({email:e,emailDiscountPercentOff:t,emailErrorId:n,emailId:r,emailRef:a,errors:o,onEmailBlur:l,onEmailChange:u,onPhoneChange:d,phone:f,phoneCountry:p,phoneEnabled:m,phoneErrorId:h,phoneId:g,phoneRef:_}){return j(`div`,{className:`lockerverse-payment__contact`,children:[A(i,{error:o.email,errorId:n,id:r,label:`Email`,name:`email`,onBlur:l,onChange:e=>u(e.currentTarget.value),ref:a,required:!0,value:e}),t===void 0?null:j(`p`,{className:`lockerverse-payment__discount-message`,role:`status`,children:[`Your email qualifies for `,t,`% off.`]}),m?A(s,{error:o.phone,errorId:h,id:g,label:`Phone`,children:A(c,{country:p,error:o.phone,errorId:h,id:g,inputRef:_,name:`phone`,onChange:d,required:!0,value:f})}):null]})}function mt({catalog:e,checkoutItems:t,client:n,initialCustomFieldValues:r,metadata:i,onPaymentComplete:a,onResumePaymentFailed:s,onPaymentRecoveryChange:c,onPaymentUncertain:l,onQuoteChange:f,onStateChange:p,quote:h,resumePayment:v,stripeConnectedAccountId:y,stripeLoadFailed:b,paymentState:x,updateState:w}){let T=u(e,t),[E,M]=O(``),[N,P]=O(``),[F,I]=O(`US`),[z,B]=O({}),[ee,V]=O({}),[te,ne]=O(),[re,H]=O(!1),[U,W]=O(!1),[G,ie]=O(!1),[K,ae]=O(()=>({customFields:d(T,r),customTip:``,includeServiceFee:e.widget.fields.serviceFee,memberId:``,merchSize:`M`,promoCode:``,shippingMatchesBilling:!0,tipPercent:`10`})),q=D({billing:null,shipping:null}),oe=D(null),se=D(null),ce=D(null),le=D(h.totalCents>0),J=$e({catalog:e,checkoutItems:t,client:n,elements:L(),email:E,fieldValues:K,metadata:i,onPaymentComplete:a,onPaymentRecoveryChange:c,onPaymentUncertain:l,onQuoteChange:f,onResumePaymentFailed:s,onStateChange:p,paymentState:x,quote:h,resumePayment:v,stripe:R(),stripeConnectedAccountId:y,stripeLoadFailed:b,updateState:w}),{displayedTotalCents:Y,isRecovering:X,isUnresolved:fe,isRefreshingQuote:pe,isSubmitting:Z,parsedTip:Q,paymentError:me,promoError:he,terminalMessage:ge,retryUrl:_e}=J.state,ve=`lockerverse-${C()}`,ye=`${ve}-email`,be=`${ye}-error`,xe=`${ve}-phone`,Se=`${xe}-error`,Ce=`${ve}-tip-error`,we=(Q.success?Q.cents:null)??0,Te=Y-we,Ee=!e.widget.fields.shipping||K.shippingMatchesBilling||G;S(()=>{Z&&ce.current?.focus({preventScroll:!0})},[Z]),S(()=>{Z||z.email||!z.phone||se.current?.focus()},[z.email,z.phone,Z]),S(()=>{let e=Y>0;e&&!le.current&&(H(!1),W(!1)),le.current=e},[Y]);function De(e){J.commands.fieldChanged(!1,e!==`email`),B(t=>{let n={...t};return delete n[e],n})}function Oe(e){let t=e.promoCode!==K.promoCode,n=e.includeServiceFee!==K.includeServiceFee;J.commands.fieldChanged(t,!(t||n)),ae(e),V({}),ne(void 0)}async function ke(t){t.preventDefault();let n=e.widget.fields.phone?o(N,F):``,r=_({email:E,phone:n},e.widget.fields.phone),i=m(T,K.customFields);if(!(r.value&&Q.success)||Object.keys(i).length>0){B(r.errors),V(i),ne(Q.success?void 0:Q.message),J.commands.reportValidationFailure();let e=t.currentTarget;queueMicrotask(()=>{ft({customFieldErrors:i,emailRef:oe,form:e,parsedTipSuccess:Q.success,phoneRef:se,validationErrors:r.errors})});return}B({}),V({});let a=await J.commands.submit({addresses:q.current,phone:n});a?.phoneError&&B({phone:a.phoneError})}return ge||X?j(`div`,{className:`lockerverse-payment__actions`,children:[j(`p`,{className:`lockerverse-payment__payment-status`,ref:ce,role:`status`,tabIndex:-1,children:[X?`Recovering payment…`:ge,_e?j(k,{children:[` `,A(`a`,{href:_e,rel:`noopener noreferrer`,target:`_blank`,children:`Complete payment`})]}):null]}),fe||X?A(`button`,{"aria-busy":X,className:`lockerverse-payment__status-check`,disabled:X,onClick:J.commands.checkPaymentStatus,type:`button`,children:X?`Checking payment status…`:`Check payment status`}):null]}):j(`form`,{"aria-busy":Z,className:`lockerverse-payment__form`,noValidate:!0,onSubmit:ke,children:[A(`div`,{"data-lockerverse-input-region":``,inert:Z?!0:void 0,children:j(`fieldset`,{className:`lockerverse-payment__input-fieldset`,disabled:Z,children:[A(g,{displayedBaseCents:Te,displayedTipCents:we,displayedTotalCents:Y,quote:h}),A(ue,{enabled:e.widget.fields.tipping,error:te,errorId:Ce,onChange:Oe,values:K}),A(pt,{email:E,emailDiscountPercentOff:h.appliedDiscount?.source===`email_list`?h.appliedDiscount.percentageOff:void 0,emailErrorId:be,emailId:ye,emailRef:oe,errors:z,onEmailBlur:()=>J.commands.refreshAuthoritativeTotal(),onEmailChange:e=>{M(e),De(`email`)},onPhoneChange:({value:e,country:t})=>{P(e),I(t),De(`phone`)},phone:N,phoneCountry:F,phoneEnabled:e.widget.fields.phone,phoneErrorId:Se,phoneId:xe,phoneRef:se}),A(lt,{catalog:e,displayedTotalCents:Y,fieldValues:K,isBillingAddressReady:U,isPaymentReady:re,isShippingAddressReady:G,onAddressChange:(e,t)=>{q.current[e]=t},onFieldValuesChange:Oe,onStripeLoadError:J.commands.reportStripeLoadError,setIsBillingAddressReady:W,setIsPaymentReady:H,setIsShippingAddressReady:ie}),A(de,{customFields:T,errors:ee,fields:e.widget.fields,idPrefix:ve,isPromoApplying:pe,memberIdLabel:e.community?.memberIdLabel,onApplyPromo:J.commands.applyPromo,onChange:Oe,promoError:he,values:K}),A(ut,{catalog:e,displayedTotalCents:Y,fieldValues:K,isBillingAddressReady:U,isPaymentReady:re,isRequiredShippingReady:Ee,isSubmitting:Z,onFieldValuesChange:Oe,quote:h})]})}),Z?A(`p`,{className:`lockerverse-payment__sr-only`,ref:ce,role:`status`,tabIndex:-1,children:Y===0?`Completing order…`:`Processing payment…`}):null,A(ct,{message:me})]})}function ht(){return A(h,{fieldCount:2,label:`Loading payment…`,sectionCount:2,showCheckbox:!0})}function gt(e,t){switch(t.type){case`loading`:return{phase:`loading`,revision:e.revision};case`ready`:return yt(t.displayedQuote,e.revision+1);case`error`:return{failure:t.failure,phase:`error`,revision:e.revision};case`checkout`:return e.phase===`ready`?{...e,displayedQuote:t.checkout,quoteFailure:void 0}:e;case`quote-error`:return e.phase===`ready`?{...e,quoteFailure:t.failure}:e;default:return e}}function $(e,t,n){return e?.catalog===t&&e.selectionKey===n}function _t({checkout:e}){return{displayedQuote:e,type:`ready`}}function vt(e){return e instanceof Error?e.message:`Lockerverse payment could not load.`}function yt(e,t){return{checkoutItems:[...e.items],displayedQuote:e,phase:`ready`,quoteFailure:void 0,revision:t}}function bt(e,t){let n=e.widget.fields.serviceFee;return N(e,{includeServiceFee:n,selection:t})}function xt(e,t){try{return yt(bt(e,t),1)}catch(e){return{failure:vt(e),phase:`error`,revision:0}}}function St({catalog:e,client:t,paymentState:n,selection:r}){let i=ke(r),a=i.success?JSON.stringify(i.value):`invalid-selection`,o=T(()=>i.success?i.value:[],[i.success,a]),[s,c]=E(gt,void 0,()=>i.success?xt(e,o):{phase:`loading`,revision:0}),l=D(void 0),u=D(0),d=D(s.phase===`ready`?{catalog:e,selectionKey:a}:void 0),f=D(s.phase===`error`?{catalog:e,selectionKey:a}:void 0),p=n===`submitting`||n===`success`||n===`unresolved`;S(()=>{if(!i.success||p||$(f.current,e,a)||$(l.current,e,a))return;let n=!0;l.current={catalog:e,selectionKey:a};let r=$(d.current,e,a);r||c({type:`loading`});function s(e){n&&c(e)}function m(){n&&(l.current=void 0,f.current={catalog:e,selectionKey:a})}let h;function g(t){if(!n||(l.current=void 0,f.current={catalog:e,selectionKey:a},r&&h!==void 0&&u.current!==h))return;let i=vt(t);if(i===`This option is sold out.`){c({failure:i,type:`error`});return}c(r?{failure:i,type:`quote-error`}:{failure:i,type:`error`})}async function _(){try{h=u.current;let n=e.widget.fields.serviceFee;if(!r){let t=bt(e,o);r=!0,d.current={catalog:e,selectionKey:a},s(_t({checkout:t}))}let i=await t.calculateTotal({catalog:e,includeServiceFee:n,selection:o});m(),u.current===h&&s({checkout:i,type:`checkout`})}catch(e){g(e)}}return _(),()=>{n=!1,$(l.current,e,a)&&(l.current=void 0)}},[e,t,i.success,p,a,o]);let m=$(d.current,e,a)||$(f.current,e,a)||$(l.current,e,a),h=p||m?s:{phase:`loading`,revision:s.revision};return{selectionError:i.success?void 0:i.message,session:h,updateCheckout:e=>{u.current+=1,c({checkout:e,type:`checkout`})}}}const Ct=H({recovery:H({connectedAccountId:ne(q()),paymentReference:W(q(),oe(),te())}),selectionFingerprint:q(),version:se([B(1),B(2)]),widgetId:U(q())});function wt(e){let t=ke(e);return t.success?JSON.stringify(t.value.map(e=>{let t=e.productSlug.trim();return`quantity`in e?[`quantity`,t,e.quantity]:`amountCents`in e?[`amount`,t,e.amountCents]:[`product`,t]})):null}const Tt=`A previous payment uses different checkout details. Return to its original checkout to check the payment before you pay again.`;function Et(e,t,n){let r;try{r=window.sessionStorage.getItem(e)}catch{return{recovery:null}}if(!r)return{recovery:null};try{let e=K(Ct,JSON.parse(r));if(!e.success)throw Error(`Invalid recovery record`);let i=e.output;return i.selectionFingerprint!==t||i.version===2&&i.widgetId!==n?{error:Tt,recovery:null}:{recovery:{connectedAccountId:i.recovery.connectedAccountId,paymentReference:i.recovery.paymentReference}}}catch{return{error:`The saved payment could not be read. Contact support to check it before you pay again.`,recovery:null}}}function Dt({selection:e,storageKey:t,widgetId:n}){let r=wt(e),i=JSON.stringify([t,r,n]),[a,o]=O(null),s=D(null);S(()=>{if(!t)return;let e=s.current,a={recovery:null};e?.recovery?a=e.identity===i?{recovery:e.recovery}:{error:Tt,recovery:null}:r!==null&&(a=Et(t,r,n)),a.recovery&&(s.current={identity:i,recovery:a.recovery}),o({identity:i,...a})},[r,i,t,n]);let c=x(e=>{if(!(!t||r===null)){s.current=e?{identity:i,recovery:e}:null;try{e?window.sessionStorage.setItem(t,JSON.stringify({recovery:e,selectionFingerprint:r,version:2,widgetId:n})):window.sessionStorage.removeItem(t)}catch{}}},[r,i,t,n]);return{error:t&&a?.identity===i?a.error:void 0,ready:!t||a?.identity===i,recovery:t&&a?.identity===i?a.recovery:null,remember:c}}const Ot={annually:`/year`,"every-six-months":` every 6 months`,monthly:`/month`,"one-time":``};function kt({branding:e,catalog:t}){return j(`header`,{children:[t.widget.showCommunityBranding&&e?j(`div`,{className:`lockerverse-payment__branding`,children:[e.imageUrl?A(`img`,{alt:e.name,height:`48`,src:e.imageUrl,width:`48`}):null,A(`strong`,{children:e.name})]}):null,A(`h1`,{children:t.widget.title??t.widget.name}),t.widget.description?A(`p`,{children:t.widget.description}):null]})}function At({catalog:t,selection:n}){let r=n?.length?t.products.filter(e=>n.some(t=>t.productSlug===e.slug)):t.products;return r.length===0?null:j(`div`,{className:`lockerverse-payment__payment-summary`,children:[A(`h2`,{children:`Products`}),A(`div`,{className:`lockerverse-payment__payment-summary-items`,children:r.map(t=>{let n=t.pricingMode===`fixed`?t.amountCents:t.minimumAmountCents,r=Ot[t.paymentOption];return j(`div`,{className:`lockerverse-payment__payment-summary-row`,children:[A(`span`,{children:t.name}),A(`strong`,{children:n===null?`Choose amount`:`${t.pricingMode===`custom`?`From `:``}${e(n)}${r}`})]},t.id)})}),A(`p`,{children:`Base prices. Final total is checked at checkout.`})]})}function jt(e,t){let i=n(e?.[`--lockerverse-accent`]??t?.accentColor??`#38d77a`),a=r(i),o={...e};return(e?.[`--lockerverse-accent`]!==void 0||t?.accentColor)&&(o[`--lockerverse-accent`]=i),a&&e?.[`--lockerverse-accent-contrast`]===void 0&&(o[`--lockerverse-accent-contrast`]=a),{accent:i,rootStyle:o}}function Mt({catalog:e,client:n,loadError:r,onRetry:i,...a}){let{branding:o,className:s,completionView:c,recoveryStorageKey:l,initialCustomFieldValues:u,metadata:d,onPaymentComplete:f,onPaymentRecoveryChange:p,onPaymentUncertain:m,resumePayment:h,selection:g,style:_,stripeLoader:v=et,theme:y=`dark`,...b}=a,[C,T]=O(h),E=D(null),[k,M]=O(null),N=x(e=>{M(e),t(f,e)},[f]),[P,F]=O(),[I,L]=O(`idle`),R=D(void 0),{selectionError:z,session:B,updateCheckout:ee}=St({catalog:e,client:n,paymentState:I,selection:g}),V=B.phase===`ready`?B.revision:void 0,te=x(e=>{V!==void 0&&(R.current=V),L(e)},[V]),ne=x(e=>p?.(e),[p]),re=x(()=>{T(void 0)},[]);S(()=>{B.phase===`loading`&&F(void 0)},[B.phase]),w(()=>{B.phase===`ready`&&R.current!==B.revision&&L(e=>e===`success`||e===`unresolved`?e:`idle`)},[B.phase,B.revision]);let H=[`lockerverse-payment`,s].filter(Boolean).join(` `),U=o??e.community,{accent:W,rootStyle:G}=jt(_,U);return k&&c===`summary`?A(`section`,{...b,className:H,"data-lockerverse-theme":y,"data-payment-state":`success`,style:G,children:j(`div`,{className:`lockerverse-payment__completion`,role:`status`,children:[A(`span`,{"aria-hidden":`true`,className:`lockerverse-payment__completion-icon`,children:A(`svg`,{"aria-hidden":`true`,fill:`none`,height:`28`,stroke:`currentColor`,strokeWidth:`2`,viewBox:`0 0 24 24`,width:`28`,children:A(`path`,{d:`m5 12 4 4L19 6`})})}),A(`h1`,{children:k.paymentRequired?`Thank you`:`Order confirmed`}),A(`p`,{children:k.paymentRequired?`Your payment has been received.`:`Your order is confirmed. No payment was required.`})]})}):z?A(`section`,{...b,className:H,"data-lockerverse-theme":y,role:`alert`,style:G,children:z}):B.phase===`error`&&B.failure===`This option is sold out.`||I===`sold_out`?j(`section`,{...b,className:H,"data-lockerverse-theme":y,role:`alert`,style:G,children:[A(`h1`,{children:`Sold out`}),A(`p`,{children:`This option is sold out.`})]}):B.phase===`error`?A(`section`,{...b,className:H,"data-lockerverse-theme":y,style:G,children:A(`p`,{role:`alert`,children:B.failure})}):B.phase===`ready`?j(`section`,{...b,"aria-label":`Payment`,className:H,"data-lockerverse-theme":y,"data-payment-state":I,ref:E,style:G,children:[A(kt,{branding:U,catalog:e}),r?j(`div`,{role:`alert`,children:[A(`p`,{children:r.message}),A(`button`,{onClick:i,type:`button`,children:`Retry`})]}):null,P?A(`p`,{className:`lockerverse-payment__payment-status`,role:`status`,children:P}):null,B.quoteFailure?j(`div`,{className:`lockerverse-payment__payment-status`,role:`alert`,children:[A(`span`,{children:B.quoteFailure}),A(`span`,{children:` The final total will be checked when you submit.`})]}):null,A(it,{accentColor:W,appearanceRoot:E,catalog:e,checkoutItems:B.checkoutItems,client:n,initialCustomFieldValues:u,metadata:d,onPaymentComplete:N,onPaymentRecoveryChange:ne,onPaymentUncertain:m,onQuoteChange:(e,t)=>{F(t),ee(e)},onResumePaymentFailed:re,onStateChange:te,quote:B.displayedQuote,resumePayment:C,stripeLoader:v,theme:y,visualStyle:G},B.revision)]}):j(`section`,{...b,"aria-busy":`true`,"aria-label":`Payment`,className:H,"data-lockerverse-theme":y,style:G,children:[A(kt,{branding:U,catalog:e}),r?j(`div`,{role:`alert`,children:[A(`p`,{children:r.message}),A(`button`,{onClick:i,type:`button`,children:`Retry`})]}):null,A(ht,{})]})}function Nt({children:e,loading:t=!1,viewProps:i}){let{branding:a,className:o,completionView:s,recoveryStorageKey:c,initialCustomFieldValues:l,metadata:u,onPaymentComplete:d,onPaymentRecoveryChange:f,onPaymentUncertain:p,resumePayment:m,selection:h,stripeLoader:g,style:_,theme:v=`dark`,...y}=i,b=n(_?.[`--lockerverse-accent`]??a?.accentColor??`#38d77a`),x=r(b),S={..._};return(_?.[`--lockerverse-accent`]!==void 0||a?.accentColor)&&(S[`--lockerverse-accent`]=b),x&&_?.[`--lockerverse-accent-contrast`]===void 0&&(S[`--lockerverse-accent-contrast`]=x),A(`section`,{...y,...t?{"aria-busy":!0,"aria-label":`Payment`}:{},className:[`lockerverse-payment`,o].filter(Boolean).join(` `),"data-lockerverse-theme":v,style:S,children:e})}function Pt(e){let{catalog:n,client:r,loadError:i,onRetry:a,...o}=e,{onPaymentRecoveryChange:s,recoveryStorageKey:c,resumePayment:l,selection:u}=o,d=Dt({selection:u,storageKey:c,widgetId:n.widget.id}),f=x(e=>{d.remember(e),t(s,e)},[s,d.remember]);return!d.ready||d.error?A(Nt,{loading:!d.ready,viewProps:o,children:d.error?A(`p`,{role:`alert`,children:d.error}):A(ht,{})}):A(Mt,{...e,onPaymentRecoveryChange:f,resumePayment:l??d.recovery})}function Ft({widget:e,...t}){return e.error&&!e.catalog?j(Nt,{viewProps:t,children:[A(`p`,{role:`alert`,children:e.error.message}),A(`button`,{onClick:e.refresh,type:`button`,children:`Retry`})]}):e.loading?j(Nt,{loading:!0,viewProps:t,children:[e.catalog?j(k,{children:[A(kt,{branding:t.branding??e.catalog.community,catalog:e.catalog}),A(At,{catalog:e.catalog,selection:t.selection})]}):null,A(ht,{})]}):e.catalog?A(Pt,{catalog:e.catalog,client:e.client,loadError:e.error,onRetry:e.refresh,...t}):A(Nt,{loading:!0,viewProps:t,children:A(ht,{})})}export{tt as n,Ft as t};
|
|
1
|
+
import{t as e}from"./format-money.js";import{t}from"./host-callback.js";import{n,t as r}from"./accent-contrast.js";import{d as i,i as a,n as o,p as s,t as c,u as l}from"./phone-field.js";import{a as u,i as d,n as f,r as p,s as m}from"./custom-fields.js";import{t as h}from"./form-skeleton.js";import{t as g}from"./payment-summary.js";import{i as _,n as v,r as y,t as b}from"./stripe-loader.js";import{useCallback as x,useEffect as S,useId as ee,useLayoutEffect as C,useMemo as w,useReducer as T,useRef as E,useState as D}from"react";import{Fragment as O,jsx as k,jsxs as A}from"react/jsx-runtime";import{LockerverseSdkError as j,estimateLockerverseCheckout as M}from"@lockerverse/sdk/checkout";import{AddressElement as N,Elements as P,PaymentElement as F,useElements as I,useStripe as L}from"@stripe/react-stripe-js";import{array as R,literal as z,minLength as te,minValue as B,nonEmpty as ne,nullable as re,number as ie,object as V,optional as H,pipe as U,regex as W,safeInteger as ae,safeParse as oe,strictObject as se,string as G,trim as ce,union as le}from"valibot";function ue({ariaDescribedBy:e,ariaLabel:t,ariaLabelledBy:n,className:r,id:i,invalid:a=!1,name:o,onValueChange:s,options:c,value:l}){return k(`select`,{"aria-describedby":e,"aria-invalid":a||void 0,"aria-label":t,"aria-labelledby":n,className:[`lockerverse-form__control`,`lockerverse-form__select`,r].filter(Boolean).join(` `),id:i,name:o,onChange:e=>s(e.currentTarget.value),value:l,children:c.map(e=>k(`option`,{value:e.value,children:e.label},e.value))})}const de=[`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`],fe=[`15`,`12`,`10`,`5`],K=[...fe,`custom`];function pe({enabled:e,error:t,errorId:n,onChange:r,values:i}){if(!e)return null;let a=e=>r({...i,...e}),o=(e,t)=>{let n=K.indexOf(t),r;switch(e.key){case`ArrowDown`:case`ArrowRight`:r=(n+1)%K.length;break;case`ArrowLeft`:case`ArrowUp`:r=(n-1+K.length)%K.length;break;case`Home`:r=0;break;case`End`:r=K.length-1;break;default:return}e.preventDefault();let i=K[r];i&&((e.currentTarget.closest(`[role="radiogroup"]`)?.querySelectorAll(`input[type="radio"]`))?.[r]?.focus(),a({tipPercent:i}))};return A(`div`,{className:`lockerverse-payment__tip-box`,children:[k(`p`,{children:`Add a tip to support the Lockerverse platform`}),A(`div`,{"aria-label":`Tip amount`,role:`radiogroup`,children:[fe.map(e=>A(`label`,{className:`lockerverse-payment__tip-choice`,children:[k(`input`,{checked:i.tipPercent===e,name:`tipPercent`,onChange:()=>a({tipPercent:e}),onKeyDown:t=>o(t,e),tabIndex:i.tipPercent===e?0:-1,type:`radio`,value:e}),A(`span`,{children:[e,`%`]})]},e)),A(`label`,{className:`lockerverse-payment__tip-choice`,children:[k(`input`,{checked:i.tipPercent===`custom`,name:`tipPercent`,onChange:()=>a({tipPercent:`custom`}),onKeyDown:e=>o(e,`custom`),tabIndex:i.tipPercent===`custom`?0:-1,type:`radio`,value:`custom`}),k(`span`,{children:`Other`})]})]}),i.tipPercent===`custom`?A(`label`,{children:[k(`span`,{children:`Custom tip`}),A(`span`,{className:`lockerverse-payment__money-input`,children:[k(`span`,{"aria-hidden":`true`,children:`$`}),k(`input`,{"aria-describedby":t?n:void 0,"aria-invalid":t?`true`:void 0,inputMode:`decimal`,name:`tip`,onChange:e=>a({customTip:e.currentTarget.value}),placeholder:`0.00`,value:i.customTip})]}),t?k(`span`,{className:`lockerverse-payment__field-message`,id:n,children:t}):null]}):k(`input`,{name:`tip`,type:`hidden`,value:i.tipPercent})]})}function q({checked:e,children:t,name:n,onChange:r}){let i=ee();return A(`label`,{className:`lockerverse-payment__check-row`,htmlFor:i,children:[k(l,{checked:e,id:i,name:n,onChange:e=>r(e.currentTarget.checked)}),k(`span`,{children:t})]})}function me({customFields:e,errors:t,fields:n,idPrefix:r,isPromoApplying:i,memberIdLabel:a,onChange:o,onApplyPromo:s,promoError:c,values:l}){let u=e=>o({...l,...e});return A(`div`,{className:`lockerverse-payment__additional-fields`,children:[n.memberId?A(`label`,{children:[k(`span`,{children:a?.trim()||`Member ID`}),k(`input`,{name:`memberId`,onChange:e=>u({memberId:e.currentTarget.value}),placeholder:`Optional`,value:l.memberId})]}):null,n.merchSize?A(`div`,{className:`lockerverse-payment__field`,children:[k(`span`,{id:`${r}-merch-size-label`,children:`Size`}),k(ue,{ariaLabelledBy:`${r}-merch-size-label`,name:`merchSize`,onValueChange:e=>{let t=de.find(t=>t===e);t&&u({merchSize:t})},options:de.map(e=>({label:e,value:e})),value:l.merchSize})]}):null,n.promoCode?A(`div`,{className:`lockerverse-payment__field`,children:[k(`span`,{id:`${r}-promo-code-label`,children:`Promo code`}),A(`div`,{className:`lockerverse-payment__promo-control`,children:[k(`input`,{"aria-describedby":c?`${r}-promo-code-error`:void 0,"aria-invalid":c?`true`:void 0,"aria-labelledby":`${r}-promo-code-label`,name:`promoCode`,onChange:e=>u({promoCode:e.currentTarget.value}),placeholder:`Optional`,value:l.promoCode}),k(`button`,{disabled:!l.promoCode.trim()||i,onClick:s,type:`button`,children:i?`Applying…`:`Apply`})]}),c?k(`p`,{className:`lockerverse-payment__field-message`,id:`${r}-promo-code-error`,role:`alert`,children:c}):null]}):null,k(f,{choiceClassName:`lockerverse-payment__check-row`,errorClassName:`lockerverse-payment__field-message`,errors:t,fields:e,idPrefix:r,onChange:e=>u({customFields:e}),values:l.customFields})]})}function J({amountCents:t,enabled:n,onChange:r,values:i}){return n?A(q,{checked:i.includeServiceFee,name:`includeServiceFee`,onChange:e=>r({...i,includeServiceFee:e}),children:[`Add `,e(t),` to help cover processing fees`]}):null}function Y(e){return{error:void 0,message:void 0,status:e?`recovering`:`editing`}}function X(e,t,n){return t.includes(e.status)?{...e,...n}:e}function he(e,t){if(t.type===`recovery_started`&&e.status===`unresolved`)return{...e,message:void 0,status:`recovering`};if(e.status===`sold_out`||e.status===`succeeded`||e.status===`unresolved`)return e;switch(t.type){case`field_changed`:return X(e,[`editing`,`invalid`,`refreshing_quote`],{error:void 0,status:`editing`});case`validation_failed`:return X(e,[`editing`],{status:`invalid`});case`quote_refresh_started`:return X(e,[`editing`,`invalid`],{status:`refreshing_quote`});case`quote_refresh_succeeded`:return X(e,[`refreshing_quote`],{error:void 0,status:`editing`});case`quote_refresh_failed`:return X(e,[`refreshing_quote`],{error:t.error??e.error,status:`editing`});case`submission_started`:return X(e,[`editing`,`invalid`,`refreshing_quote`],{error:void 0,status:`submitting`});case`submission_validation_failed`:return X(e,[`submitting`],{error:void 0,status:`invalid`});case`quote_changed`:return X(e,[`submitting`],{status:`editing`});case`retryable_failure`:return X(e,[`editing`,`invalid`,`submitting`],{error:t.error,status:`editing`});case`recovery_failed`:return X(e,[`recovering`],{error:t.error,retryUrl:void 0,status:`editing`});case`sold_out`:return{error:void 0,message:void 0,status:`sold_out`};case`succeeded`:return X(e,[`recovering`,`submitting`],{message:t.message,retryUrl:void 0,status:`succeeded`});case`unresolved`:return X(e,[`recovering`,`submitting`],{message:t.message,retryUrl:t.retryUrl,status:`unresolved`});default:return e}}function Z(e){return e.status===`editing`||e.status===`invalid`||e.status===`refreshing_quote`?e.error:void 0}function Q(e){return e.status===`sold_out`?`sold_out`:e.status===`succeeded`?`success`:e.status===`unresolved`?`unresolved`:e.status===`submitting`||e.status===`recovering`?`submitting`:e.status===`invalid`?`invalid`:Z(e)?`error`:`idle`}function ge(e){return e.status===`submitting`}const _e=[`amountCents`,`discountableSubtotalCents`,`discountCents`,`serviceFeeCents`,`subtotalCents`,`tipCents`,`totalCents`],ve=[`discountableSubtotalCents`,`discountCents`,`subtotalCents`];function ye(e,t,n,r){return(n===t.totalCents?ve:_e).some(n=>e[n]!==t[n])||r!==t.payment.connectedAccountId||e.authoritative&&(e.payment.connectedAccountId!==r||e.payment.currency!==t.payment.currency)||JSON.stringify(e.appliedDiscount)!==JSON.stringify(t.appliedDiscount)||JSON.stringify(e.lineItems)!==JSON.stringify(t.lineItems)}function be(e){if(e.checkoutStatus===`success`)return{kind:`success`,payment:e};if(e.checkoutStatus===`failed`)return{kind:`failed`,payment:e};let t={kind:`unresolved`,paymentReference:e.paymentReference,reason:e.checkoutStatus===`action_required`?`action_required`:`pending`};return e.retryUrl&&(t.retryUrl=e.retryUrl),t}async function xe(e,t,n){if(t.checkoutStatus!==`action_required`||!t.requiresAction)return be(t);if(!n)return{kind:`unresolved`,paymentReference:t.paymentReference,reason:`action_required`};if(t.clientSecret)try{await n.handleNextAction({clientSecret:t.clientSecret})}catch{}try{return be(await e.getPaymentStatus(t.paymentReference))}catch{return{kind:`unresolved`,paymentReference:t.paymentReference,reason:`action_required`}}}async function Se(e,t,n){let r;try{r=await e.submitPayment(t)}catch(n){if(!(n instanceof j&&n.recoveryRecommended))throw n;try{r=await e.getPaymentStatus(t.checkout.paymentReference)}catch{return{kind:`unresolved`,paymentReference:t.checkout.paymentReference,reason:`recovery_failed`}}}return xe(e,r,n)}async function Ce(e,t,n){try{return xe(e,await e.getPaymentStatus(t),n)}catch{return{kind:`unresolved`,paymentReference:t,reason:`recovery_failed`}}}const we=U(G(),ce(),ne()),Te=U(ie(),ae(),B(1)),Ee=U(R(le([se({amountCents:Te,productSlug:we}),se({productSlug:we,quantity:Te}),se({productSlug:we})])),te(1)),De=U(G(),ce(),W(/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/,`Enter a valid tip amount.`));function Oe(e){let t=oe(De,e);if(!t.success)return{message:t.issues[0]?.message??`Enter a valid tip amount.`,success:!1};let[n=`0`,r=``]=t.output.split(`.`),i=BigInt(n)*100n+BigInt(r.padEnd(2,`0`));return i>BigInt(2**53-1)?{message:`Enter a valid tip amount.`,success:!1}:{cents:Number(i),success:!0}}function ke(e){let t=oe(Ee,e);return t.success?{success:!0,value:t.output}:{message:`Lockerverse payment configuration is invalid.`,success:!1}}const Ae=`This promo code is invalid or cannot be applied.`;function je(e,t){return t.tipPercent===`custom`?t.customTip.trim()?Oe(t.customTip):{cents:0,success:!0}:{cents:Math.round(e*Number(t.tipPercent)/100),success:!0}}function Me(e,t,n,r){let i={};return n&&(i.email=n),e.widget.fields.serviceFee&&(i.includeServiceFee=t.includeServiceFee),e.widget.fields.promoCode&&t.promoCode.trim()&&(i.promoCode=t.promoCode.trim()),e.widget.fields.tipping&&(i.tipCents=r),i}function Ne(e,t,n){let r=e.widget.fields.tipping?je(n.subtotalCents,t):{cents:0,success:!0};if(!r.success)return{parsedTip:r,totalCents:null};let i=e.widget.fields.serviceFee&&t.includeServiceFee?n.serviceFeeCents||Math.round(n.subtotalCents*e.pricingPolicy.serviceFeeRateBasisPoints/1e4):0;return{parsedTip:r,totalCents:n.totalCents-n.serviceFeeCents-n.tipCents+i+r.cents}}function Pe(e,t){return{displayedTotalCents:e.totalCents,promoError:t&&e.appliedDiscount?.source!==`promo_code`?Ae:void 0}}function Fe(e,t){let n;return t||(n=e instanceof Error?e.message:`The order total could not be updated.`),{paymentError:n,promoError:t?Ae:void 0}}function Ie(e,t){if(!e?.complete)throw Error(`${t} address is required.`);return e.value}function Le(e,t,n,r){if(e.widget.fields.shipping)return t.shippingMatchesBilling?n:Ie(r.shipping,`Shipping`)}function Re({billingAddress:e,catalog:t,email:n,phone:r,shippingAddress:i}){let a={payment_method_data:{billing_details:t.widget.fields.phone?{address:e.address,email:n,name:e.name,phone:r}:{address:e.address,email:n,name:e.name}}};return i?{...a,shipping:{address:i.address,name:i.name,phone:t.widget.fields.phone?r:i.phone??null}}:a}function ze({catalog:e,checkoutItems:t,confirmationToken:n,email:r,fieldValues:i,metadata:a,phone:o,shippingAddress:s}){let c={customFieldAnswers:p(u(e,t),i.customFields),email:r};if(n&&(c.confirmationToken=n,c.paymentMethodConfiguration=`explicit`),a&&(c.metadata=a),e.widget.fields.memberId&&i.memberId.trim()&&(c.memberId=i.memberId.trim()),e.widget.fields.merchSize&&(c.merchSize=i.merchSize),e.widget.fields.phone&&(c.phone=o),s){let e={city:s.address.city??``,country:s.address.country,line1:s.address.line1??``,postal_code:s.address.postal_code??``,state:s.address.state??``};s.address.line2&&(e.line2=s.address.line2),c.shipping={address:e,name:s.name}}return c}function Be(e){if(!e())throw Error(`Payment component is no longer active.`)}function Ve(e,n){t(e,n)}function He(e,t,n,r){return e.kind===`failed`?{kind:`payment_failed`,message:r}:e.kind===`unresolved`?{kind:`payment_unresolved`,paymentReference:e.paymentReference,reason:e.reason,retryUrl:e.retryUrl}:{email:n,kind:`payment`,payment:e.payment,quote:t}}async function Ue({addresses:e,catalog:t,checkoutItems:n,client:r,elements:i,email:a,fieldValues:o,isAttemptActive:s,locallyPreviewedTotalCents:c,metadata:l,onPaymentRecoveryChange:u,phone:d,quote:f,stripe:p,stripeConnectedAccountId:m}){let h=a.trim().toLowerCase(),g=y(d),_=je(f.subtotalCents,o);if(!_.success)throw Error(_.message);let v=await r.calculateTotal({...Me(t,o,h,_.cents),catalog:t,items:n});if(Be(s),v.totalCents>0&&ye(f,v,c,m))return{kind:`quote_changed`,quote:v};let b,x;if(v.totalCents===0)t.widget.fields.shipping&&(b=Le(t,o,Ie(e.billing,`Billing`),e));else{if(!(i&&p))throw Error(`Payment form is still loading.`);await i.update({amount:v.totalCents}),Be(s);let n=await i.submit();if(Be(s),n.error)throw Error(n.error.message);let r=Ie(e.billing,`Billing`);b=Le(t,o,r,e);let a=await p.createConfirmationToken({elements:i,params:Re({billingAddress:r,catalog:t,email:h,phone:g,shippingAddress:b})});if(Be(s),a.error)throw Error(a.error.message);x=a.confirmationToken.id}Ve(u,{connectedAccountId:v.payment.connectedAccountId,paymentReference:v.paymentReference});let S=await Se(r,{checkout:v,submission:ze({catalog:t,checkoutItems:n,confirmationToken:x,email:h,fieldValues:o,metadata:l,phone:g,shippingAddress:b})},p);return Be(s),He(S,v,h,v.totalCents===0?`Order could not be completed. Review the details and try again.`:`Payment was declined. Check your payment details and try again.`)}function We(e,n){t(e,n)}function Ge(e,n){t(e,n)}function Ke(e,t){return{...e,...t}}function qe(e){let t={message:e.reason===`action_required`?`Payment needs your attention. Keep this checkout open.`:`Payment is not complete. Check its status before you try again.`,type:`unresolved`};return e.retryUrl&&(t.retryUrl=e.retryUrl),t}function Je(e,t,n){return e.kind===`unresolved`&&e.reason===`action_required`&&!e.retryUrl&&!t&&!n}function Ye(e){return e instanceof j&&e.serverCode===`PAYMENT_WIDGET_SALES_LIMIT_REACHED`}function Xe({nextQuote:e,onQuoteChange:t,setDisplayedTotalCents:n,setPromoError:r,updateState:i,validatePromo:a}){let o=Pe(e,a);i({type:`quote_refresh_succeeded`}),n(o.displayedTotalCents),t(e),a&&r(o.promoError)}function Ze({error:e,setPromoError:t,updateState:n,validatePromo:r}){let i=Fe(e,r);r&&t(i.promoError),n(i.paymentError===void 0?{type:`quote_refresh_failed`}:{error:i.paymentError,type:`quote_refresh_failed`})}function Qe({onPaymentComplete:n,onPaymentRecoveryChange:r,onPaymentUncertain:i,onQuoteChange:a,result:o,setDisplayedTotalCents:s,dispatchState:c,unresolvedReferenceRef:l}){if(o.kind===`quote_changed`){let t=`The total changed to ${e(o.quote.totalCents)}. Review it and pay again.`;a(o.quote,t),s(o.quote.totalCents),c({type:`quote_changed`});return}if(o.kind===`payment_failed`){We(r,null),c({error:o.message,type:`retryable_failure`});return}if(o.kind===`payment_unresolved`){l.current=o.paymentReference,c(qe(o)),Ge(i,{paymentReference:o.paymentReference,reason:o.reason});return}a(o.quote),We(r,null),c({message:o.payment.paymentRequired?`Payment completed successfully.`:`Order confirmed. No payment was required.`,type:`succeeded`}),t(n,Ke(o.payment,{email:o.email,lineItems:o.quote.lineItems}))}function $e(e){let{catalog:n,checkoutItems:r,client:i,elements:o,email:s,fieldValues:c,metadata:l,onPaymentComplete:u,onResumePaymentFailed:d,onPaymentRecoveryChange:f,onPaymentUncertain:p,onQuoteChange:m,onStateChange:h,quote:g,resumePayment:v,stripe:y,stripeConnectedAccountId:b,stripeLoadFailed:ee,paymentState:C,updateState:w}=e,[T,O]=D(g.totalCents),[k,A]=D(),M=E(!1),N=E(void 0),P=E(0),F=E(0),I=x(e=>w(e,!0),[w]),L=x(()=>{let e=F.current+1;return F.current=e,()=>F.current===e},[]);S(()=>()=>{F.current+=1,P.current+=1},[]);let{parsedTip:R,totalCents:z}=Ne(n,c,g);S(()=>{z!==null&&(O(z),z>0&&o?.update({amount:z}))},[n.pricingPolicy.serviceFeeRateBasisPoints,n.widget.fields.serviceFee,o,c.includeServiceFee,z,g.serviceFeeCents,g.tipCents,g.totalCents,g.subtotalCents]),S(()=>{let e=v?.paymentReference??N.current;if(!e||M.current||C.status!==`recovering`)return;M.current=!0;let n=L();return h(Q(C)),Ce(i,e,y).then(e=>{if(n()&&!Je(e,y,ee)){if(e.kind===`failed`){We(f,null),d(),I({error:`The previous payment failed. Check your details and try again.`,type:`recovery_failed`});return}if(e.kind===`unresolved`){I(qe(e)),Ge(p,{paymentReference:e.paymentReference,reason:e.reason});return}We(f,null),I({message:e.payment.paymentRequired?`Payment completed successfully.`:`Order confirmed. No payment was required.`,type:`succeeded`}),t(u,Ke(e.payment,{email:null,lineItems:null}))}}),()=>{n()&&(F.current+=1),M.current=!1}},[i,u,d,f,p,h,v,y,ee,L,I,C]);let te=x((e=!1,t=!1)=>{t||(P.current+=1),e&&A(void 0),w({type:`field_changed`})},[w]);async function B(e=!1,t=!1){let a=s.trim().toLowerCase(),o=_({email:a,phone:``},!1);if(!(R.success&&(o.value||e)))return;P.current+=1;let l=P.current;w({type:`quote_refresh_started`});try{let e=await i.calculateTotal({...Me(n,c,o.value?.email??``,R.cents),catalog:n,items:r});if(l!==P.current)return;Xe({nextQuote:e,onQuoteChange:m,setDisplayedTotalCents:O,setPromoError:A,updateState:w,validatePromo:t})}catch(e){if(l!==P.current)return;if(Ye(e)){w({type:`sold_out`});return}Ze({error:e,setPromoError:A,updateState:w,validatePromo:t})}}async function ne(){A(void 0),await B(!0,!0)}async function re({addresses:e,phone:t}){I({type:`submission_started`});let d=L();try{let a=await Ue({addresses:e,catalog:n,checkoutItems:r,client:i,elements:o,email:s,fieldValues:c,isAttemptActive:d,locallyPreviewedTotalCents:T,metadata:l,onPaymentRecoveryChange:f,phone:t,quote:g,stripe:y,stripeConnectedAccountId:b});if(!d())return;Qe({dispatchState:I,onPaymentComplete:u,onPaymentRecoveryChange:f,onPaymentUncertain:p,onQuoteChange:m,result:a,setDisplayedTotalCents:O,unresolvedReferenceRef:N})}catch(e){if(!d())return;if(We(f,null),Ye(e)){I({type:`sold_out`});return}let t=e instanceof j?a(e.serverCode):void 0;if(t)return I({type:`submission_validation_failed`}),{phoneError:t};I({error:e instanceof Error?e.message:`Payment could not be completed.`,type:`retryable_failure`})}}let ie=C.status===`succeeded`||C.status===`unresolved`?C.message:void 0;return{commands:{applyPromo:ne,checkPaymentStatus:()=>I({type:`recovery_started`}),fieldChanged:te,refreshAuthoritativeTotal:B,reportValidationFailure:()=>I({type:`validation_failed`}),submit:re},state:{displayedTotalCents:T,isRecovering:C.status===`recovering`,isRefreshingQuote:C.status===`refreshing_quote`,isSubmitting:ge(C),isUnresolved:C.status===`unresolved`,parsedTip:R,paymentError:Z(C),promoError:k,retryUrl:C.retryUrl,terminalMessage:ie}}}const et=b;function tt(e){let{connectedAccountId:t,publishableKey:n}=e.payment;return et(n,t?{stripeAccount:t}:void 0)}function nt(e){return e===`monthly`?{interval:`month`,label:`Monthly`}:e===`annually`?{interval:`year`,label:`Annual`}:e===`every-six-months`?{interval:`6 months`,label:`Every 6 months`}:null}function rt(e,t,n){if(n){let{connectedAccountId:e}=n;return e}if(`payment`in t){let{connectedAccountId:e}=t.payment;return e}let{connectedAccountId:r}=e.payment;return r}function it({accentColor:e,catalog:t,checkoutItems:n,client:r,appearanceRoot:i,initialCustomFieldValues:a,metadata:o,onPaymentComplete:s,onResumePaymentFailed:c,onPaymentRecoveryChange:l,onPaymentUncertain:u,onQuoteChange:d,quote:f,resumePayment:p,onStateChange:m,stripeLoader:g,theme:_,visualStyle:y}){let[b,ee]=D(()=>Y(!!p)),C=E(b);C.current=b;let T=x((e,t=!1)=>{let n=he(C.current,e);n!==C.current&&(C.current=n,ee(n),t&&m(Q(n)))},[m]),O=rt(t,f,p),A=E({connectedAccountId:O,paymentOption:f.paymentOption});b.status!==`submitting`&&b.status!==`recovering`&&(A.current={connectedAccountId:O,paymentOption:f.paymentOption});let{connectedAccountId:j,paymentOption:M}=A.current,N=w(()=>g(t.payment.publishableKey,j?{stripeAccount:j}:void 0).catch(()=>null),[t.payment.publishableKey,j,g]),[F,I]=D(!1);S(()=>{let e=!0;return I(!1),N.then(t=>{e&&t===null&&I(!0)}),()=>{e=!1}},[N]);let L=v(i,_,y,b.status===`submitting`||b.status===`recovering`,e);return L?k(P,{options:{amount:Math.max(f.totalCents,100),appearance:L,currency:t.payment.currency,mode:M===`one-time`?`payment`:`subscription`,paymentMethodTypes:t.community?.widgetAchEnabled?[`card`,`link`,`us_bank_account`]:[`card`,`link`],syncAddressCheckbox:`none`},stripe:N,children:k(gt,{catalog:t,checkoutItems:n,client:r,initialCustomFieldValues:a,metadata:o,onPaymentComplete:s,onPaymentRecoveryChange:l,onPaymentUncertain:u,onQuoteChange:d,onResumePaymentFailed:c,onStateChange:m,paymentState:b,quote:f,resumePayment:p,stripeConnectedAccountId:j,stripeLoadFailed:F,updateState:T})},`${t.payment.publishableKey}:${j??`platform`}:${M}`):k(h,{fieldCount:3,label:`Loading payment form`})}function at({label:e}){return A(`div`,{className:`lockerverse-payment__stripe-loader`,role:`status`,children:[k(`p`,{children:e}),A(`div`,{"aria-hidden":`true`,children:[k(`span`,{}),k(`span`,{}),k(`span`,{})]})]})}function ot({onError:e,onReady:t,ready:n}){return A(`div`,{className:`lockerverse-payment__stripe-element`,"data-ready":n,children:[n?null:k(at,{label:`Loading payment form...`}),k(`div`,{className:`lockerverse-payment__stripe-mount`,children:k(F,{onLoadError:({error:t})=>e(t.message??`Payment form failed to load.`),onReady:t,options:{business:{name:`Lockerverse`},fields:{billingDetails:{address:`never`,email:`never`,name:`never`,phone:`never`}},layout:`tabs`,terms:{applePay:`auto`,auBecsDebit:`never`,bancontact:`never`,card:`always`,cashapp:`never`,googlePay:`never`,ideal:`never`,paypal:`auto`,sepaDebit:`never`,sofort:`never`,usBankAccount:`auto`},wallets:{applePay:`auto`,googlePay:`never`}}})})]})}function st({label:e,mode:t,onChange:n,onError:r,onReady:i,ready:a}){return A(`div`,{className:`lockerverse-payment__address`,children:[k(`h2`,{children:e}),A(`div`,{className:`lockerverse-payment__stripe-element lockerverse-payment__stripe-element--address`,"data-ready":a,children:[a?null:k(at,{label:`Loading ${e.toLowerCase()}...`}),k(`div`,{className:`lockerverse-payment__stripe-mount`,children:k(N,{onChange:n,onLoadError:({error:t})=>r(t.message??`${e} failed to load.`),onReady:i,options:{autocomplete:{mode:`automatic`},mode:t}})})]})]})}function ct({message:e}){return e?k(`p`,{className:`lockerverse-payment__field-message`,role:`alert`,children:e}):null}function lt({catalog:e,displayedTotalCents:t,fieldValues:n,isBillingAddressReady:r,isPaymentReady:i,isShippingAddressReady:a,onAddressChange:o,onFieldValuesChange:s,onStripeLoadError:c,setIsBillingAddressReady:l,setIsPaymentReady:u,setIsShippingAddressReady:d}){let f=t>0;return A(O,{children:[f?k(ot,{onError:c,onReady:()=>u(!0),ready:i}):null,f||e.widget.fields.shipping?k(st,{label:f?`Billing address`:`Shipping address`,mode:`billing`,onChange:e=>o(`billing`,e),onError:c,onReady:()=>l(!0),ready:r}):null,e.widget.fields.shipping?A(`div`,{className:`lockerverse-payment__shipping`,children:[k(q,{checked:n.shippingMatchesBilling,name:`shippingMatchesBilling`,onChange:e=>{s({...n,shippingMatchesBilling:e}),e?o(`shipping`,null):d(!1)},children:`Shipping is same as billing information`}),n.shippingMatchesBilling?null:k(st,{label:`Shipping address`,mode:`shipping`,onChange:e=>o(`shipping`,e),onError:c,onReady:()=>d(!0),ready:a})]}):null]})}function ut({catalog:t,displayedTotalCents:n,fieldValues:r,isBillingAddressReady:i,isPaymentReady:a,isRequiredShippingReady:o,isSubmitting:s,onFieldValuesChange:c,quote:l}){let u=n===0,d=u?!t.widget.fields.shipping||i&&o:a&&i&&o,f=nt(l.paymentOption),p=u?`Complete order`:`Pay ${e(n)}`;!u&&f&&(p=`Subscribe for ${e(n)}/${f.interval}`),s&&(p=u?`Completing…`:`Processing…`);let m=`Process payment for ${e(n)} total`;return u?m=`Complete order`:f&&(m=`Start ${f.label.toLowerCase()} subscription for ${e(n)}`),A(`div`,{className:`lockerverse-payment__actions`,children:[k(J,{amountCents:l.serviceFeeCents||Math.round(l.subtotalCents*t.pricingPolicy.serviceFeeRateBasisPoints/1e4),enabled:t.widget.fields.serviceFee,onChange:c,values:r}),k(`button`,{"aria-busy":s,"aria-label":m,disabled:s||!d,type:`submit`,children:p})]})}function dt(e,t){let n=e.elements.namedItem(t);if(n instanceof HTMLElement){n.focus();return}n instanceof RadioNodeList&&Array.from(n).find(e=>e instanceof HTMLElement)?.focus()}function ft({customFieldErrors:e,emailRef:t,form:n,parsedTipSuccess:r,phoneRef:i,validationErrors:a}){if(a.email){t.current?.focus();return}if(a.phone){i.current?.focus();return}if(!r){n.querySelector(`[name="tip"]`)?.focus();return}let[o]=Object.keys(e);o&&dt(n,`custom:${o}`)}function pt({email:e,emailDiscountPercentOff:t,emailErrorId:n,emailId:r,emailRef:a,errors:o,onEmailBlur:l,onEmailChange:u,onPhoneChange:d,phone:f,phoneCountry:p,phoneEnabled:m,phoneErrorId:h,phoneId:g,phoneRef:_}){return A(`div`,{className:`lockerverse-payment__contact`,children:[k(i,{error:o.email,errorId:n,id:r,label:`Email`,name:`email`,onBlur:l,onChange:e=>u(e.currentTarget.value),ref:a,required:!0,value:e}),t===void 0?null:A(`p`,{className:`lockerverse-payment__discount-message`,role:`status`,children:[`Your email qualifies for `,t,`% off.`]}),m?k(s,{error:o.phone,errorId:h,id:g,label:`Phone`,children:k(c,{country:p,error:o.phone,errorId:h,id:g,inputRef:_,name:`phone`,onChange:d,required:!0,value:f})}):null]})}function mt({message:e}){return e?A(`div`,{className:`lockerverse-payment__actions`,children:[k(`p`,{className:`lockerverse-payment__field-message`,role:`alert`,children:e}),k(`button`,{className:`lockerverse-payment__status-check`,onClick:()=>window.location.reload(),type:`button`,children:`Reload checkout`})]}):null}function ht({paymentRequired:e,shippingRequired:t,isPaymentReady:n,isBillingAddressReady:r,isRequiredShippingReady:i,isSubmitting:a,scriptFailed:o,elementError:s,clearElementError:c}){let[l,u]=D(!1),d=e||t,f=(!e||n)&&(!d||r)&&i;if(S(()=>{if(u(!1),f&&c(void 0),!d||f||a)return;let e=window.setTimeout(()=>u(!0),3e4);return()=>window.clearTimeout(e)},[d,f,a,c]),!(!d||f||a)){if(o||s)return`The secure checkout fields could not load. Check your connection, then reload the checkout.`;if(l)return`The secure checkout fields are taking longer than expected. You can wait or reload the checkout.`}}function gt({catalog:e,checkoutItems:t,client:n,initialCustomFieldValues:r,metadata:i,onPaymentComplete:a,onResumePaymentFailed:s,onPaymentRecoveryChange:c,onPaymentUncertain:l,onQuoteChange:f,onStateChange:p,quote:h,resumePayment:v,stripeConnectedAccountId:y,stripeLoadFailed:b,paymentState:x,updateState:C}){let w=u(e,t),[T,j]=D(``),[M,N]=D(``),[P,F]=D(`US`),[R,z]=D({}),[te,B]=D({}),[ne,re]=D(),[ie,V]=D(),[H,U]=D(!1),[W,ae]=D(!1),[oe,se]=D(!1),[G,ce]=D(()=>({customFields:d(w,r),customTip:``,includeServiceFee:e.widget.fields.serviceFee,memberId:``,merchSize:`M`,promoCode:``,shippingMatchesBilling:!0,tipPercent:`10`})),le=E({billing:null,shipping:null}),ue=E(null),de=E(null),fe=E(null),K=E(h.totalCents>0),q=$e({catalog:e,checkoutItems:t,client:n,elements:I(),email:T,fieldValues:G,metadata:i,onPaymentComplete:a,onPaymentRecoveryChange:c,onPaymentUncertain:l,onQuoteChange:f,onResumePaymentFailed:s,onStateChange:p,paymentState:x,quote:h,resumePayment:v,stripe:L(),stripeConnectedAccountId:y,stripeLoadFailed:b,updateState:C}),{displayedTotalCents:J,isRecovering:Y,isUnresolved:X,isRefreshingQuote:he,isSubmitting:Z,parsedTip:Q,paymentError:ge,promoError:_e,terminalMessage:ve,retryUrl:ye}=q.state,be=`lockerverse-${ee()}`,xe=`${be}-email`,Se=`${xe}-error`,Ce=`${be}-phone`,we=`${Ce}-error`,Te=`${be}-tip-error`,Ee=(Q.success?Q.cents:null)??0,De=J-Ee,Oe=!e.widget.fields.shipping||G.shippingMatchesBilling||oe,ke=ht({clearElementError:V,elementError:ie,isBillingAddressReady:W,isPaymentReady:H,isRequiredShippingReady:Oe,isSubmitting:Z,paymentRequired:J>0,scriptFailed:b,shippingRequired:e.widget.fields.shipping});S(()=>{Z&&fe.current?.focus({preventScroll:!0})},[Z]),S(()=>{Z||R.email||!R.phone||de.current?.focus()},[R.email,R.phone,Z]),S(()=>{let e=J>0;e&&!K.current&&(U(!1),ae(!1)),K.current=e},[J]);function Ae(e){q.commands.fieldChanged(!1,e!==`email`),z(t=>{let n={...t};return delete n[e],n})}function je(e){let t=e.promoCode!==G.promoCode,n=e.includeServiceFee!==G.includeServiceFee;q.commands.fieldChanged(t,!(t||n)),ce(e),B({}),re(void 0)}async function Me(t){t.preventDefault();let n=e.widget.fields.phone?o(M,P):``,r=_({email:T,phone:n},e.widget.fields.phone),i=m(w,G.customFields);if(!(r.value&&Q.success)||Object.keys(i).length>0){z(r.errors),B(i),re(Q.success?void 0:Q.message),q.commands.reportValidationFailure();let e=t.currentTarget;queueMicrotask(()=>{ft({customFieldErrors:i,emailRef:ue,form:e,parsedTipSuccess:Q.success,phoneRef:de,validationErrors:r.errors})});return}z({}),B({});let a=await q.commands.submit({addresses:le.current,phone:n});a?.phoneError&&z({phone:a.phoneError})}return ve||Y?A(`div`,{className:`lockerverse-payment__actions`,children:[A(`p`,{className:`lockerverse-payment__payment-status`,ref:fe,role:`status`,tabIndex:-1,children:[Y?`Recovering payment…`:ve,ye?A(O,{children:[` `,k(`a`,{href:ye,rel:`noopener noreferrer`,target:`_blank`,children:`Complete payment`})]}):null]}),X||Y?k(`button`,{"aria-busy":Y,className:`lockerverse-payment__status-check`,disabled:Y,onClick:q.commands.checkPaymentStatus,type:`button`,children:Y?`Checking payment status…`:`Check payment status`}):null]}):A(`form`,{"aria-busy":Z,className:`lockerverse-payment__form`,noValidate:!0,onSubmit:Me,children:[k(`div`,{"data-lockerverse-input-region":``,inert:Z?!0:void 0,children:A(`fieldset`,{className:`lockerverse-payment__input-fieldset`,disabled:Z,children:[k(g,{displayedBaseCents:De,displayedTipCents:Ee,displayedTotalCents:J,quote:h}),k(pe,{enabled:e.widget.fields.tipping,error:ne,errorId:Te,onChange:je,values:G}),k(pt,{email:T,emailDiscountPercentOff:h.appliedDiscount?.source===`email_list`?h.appliedDiscount.percentageOff:void 0,emailErrorId:Se,emailId:xe,emailRef:ue,errors:R,onEmailBlur:()=>q.commands.refreshAuthoritativeTotal(),onEmailChange:e=>{j(e),Ae(`email`)},onPhoneChange:({value:e,country:t})=>{N(e),F(t),Ae(`phone`)},phone:M,phoneCountry:P,phoneEnabled:e.widget.fields.phone,phoneErrorId:we,phoneId:Ce,phoneRef:de}),k(mt,{message:ke}),k(lt,{catalog:e,displayedTotalCents:J,fieldValues:G,isBillingAddressReady:W,isPaymentReady:H,isShippingAddressReady:oe,onAddressChange:(e,t)=>{le.current[e]=t},onFieldValuesChange:je,onStripeLoadError:V,setIsBillingAddressReady:ae,setIsPaymentReady:U,setIsShippingAddressReady:se}),k(me,{customFields:w,errors:te,fields:e.widget.fields,idPrefix:be,isPromoApplying:he,memberIdLabel:e.community?.memberIdLabel,onApplyPromo:q.commands.applyPromo,onChange:je,promoError:_e,values:G}),k(ut,{catalog:e,displayedTotalCents:J,fieldValues:G,isBillingAddressReady:W,isPaymentReady:H,isRequiredShippingReady:Oe,isSubmitting:Z,onFieldValuesChange:je,quote:h})]})}),Z?k(`p`,{className:`lockerverse-payment__sr-only`,ref:fe,role:`status`,tabIndex:-1,children:J===0?`Completing order…`:`Processing payment…`}):null,k(ct,{message:ge})]})}function _t(){return k(h,{fieldCount:2,label:`Loading payment…`,sectionCount:2,showCheckbox:!0})}function vt(e,t){switch(t.type){case`loading`:return{phase:`loading`,revision:e.revision};case`ready`:return xt(t.displayedQuote,e.revision+1);case`error`:return{failure:t.failure,phase:`error`,revision:e.revision};case`checkout`:return e.phase===`ready`?{...e,displayedQuote:t.checkout,quoteFailure:void 0}:e;case`quote-error`:return e.phase===`ready`?{...e,quoteFailure:t.failure}:e;default:return e}}function $(e,t,n){return e?.catalog===t&&e.selectionKey===n}function yt({checkout:e}){return{displayedQuote:e,type:`ready`}}function bt(e){return e instanceof Error?e.message:`Lockerverse payment could not load.`}function xt(e,t){return{checkoutItems:[...e.items],displayedQuote:e,phase:`ready`,quoteFailure:void 0,revision:t}}function St(e,t){let n=e.widget.fields.serviceFee;return M(e,{includeServiceFee:n,selection:t})}function Ct(e,t){try{return xt(St(e,t),1)}catch(e){return{failure:bt(e),phase:`error`,revision:0}}}function wt({catalog:e,client:t,paymentState:n,selection:r}){let i=ke(r),a=i.success?JSON.stringify(i.value):`invalid-selection`,o=w(()=>i.success?i.value:[],[i.success,a]),[s,c]=T(vt,void 0,()=>i.success?Ct(e,o):{phase:`loading`,revision:0}),l=E(void 0),u=E(0),d=E(s.phase===`ready`?{catalog:e,selectionKey:a}:void 0),f=E(s.phase===`error`?{catalog:e,selectionKey:a}:void 0),p=n===`submitting`||n===`success`||n===`unresolved`;S(()=>{if(!i.success||p||$(f.current,e,a)||$(l.current,e,a))return;let n=!0;l.current={catalog:e,selectionKey:a};let r=$(d.current,e,a);r||c({type:`loading`});function s(e){n&&c(e)}function m(){n&&(l.current=void 0,f.current={catalog:e,selectionKey:a})}let h;function g(t){if(!n||(l.current=void 0,f.current={catalog:e,selectionKey:a},r&&h!==void 0&&u.current!==h))return;let i=bt(t);if(i===`This option is sold out.`){c({failure:i,type:`error`});return}c(r?{failure:i,type:`quote-error`}:{failure:i,type:`error`})}async function _(){try{h=u.current;let n=e.widget.fields.serviceFee;if(!r){let t=St(e,o);r=!0,d.current={catalog:e,selectionKey:a},s(yt({checkout:t}))}let i=await t.calculateTotal({catalog:e,includeServiceFee:n,selection:o});m(),u.current===h&&s({checkout:i,type:`checkout`})}catch(e){g(e)}}return _(),()=>{n=!1,$(l.current,e,a)&&(l.current=void 0)}},[e,t,i.success,p,a,o]);let m=$(d.current,e,a)||$(f.current,e,a)||$(l.current,e,a),h=p||m?s:{phase:`loading`,revision:s.revision};return{selectionError:i.success?void 0:i.message,session:h,updateCheckout:e=>{u.current+=1,c({checkout:e,type:`checkout`})}}}const Tt=V({recovery:V({connectedAccountId:re(G()),paymentReference:U(G(),ce(),ne())}),selectionFingerprint:G(),version:le([z(1),z(2)]),widgetId:H(G())});function Et(e){let t=ke(e);return t.success?JSON.stringify(t.value.map(e=>{let t=e.productSlug.trim();return`quantity`in e?[`quantity`,t,e.quantity]:`amountCents`in e?[`amount`,t,e.amountCents]:[`product`,t]})):null}const Dt=`A previous payment uses different checkout details. Return to its original checkout to check the payment before you pay again.`;function Ot(e,t,n){let r;try{r=window.sessionStorage.getItem(e)}catch{return{recovery:null}}if(!r)return{recovery:null};try{let e=oe(Tt,JSON.parse(r));if(!e.success)throw Error(`Invalid recovery record`);let i=e.output;return i.selectionFingerprint!==t||i.version===2&&i.widgetId!==n?{error:Dt,recovery:null}:{recovery:{connectedAccountId:i.recovery.connectedAccountId,paymentReference:i.recovery.paymentReference}}}catch{return{error:`The saved payment could not be read. Contact support to check it before you pay again.`,recovery:null}}}function kt({selection:e,storageKey:t,widgetId:n}){let r=Et(e),i=JSON.stringify([t,r,n]),[a,o]=D(null),s=E(null);S(()=>{if(!t)return;let e=s.current,a={recovery:null};e?.recovery?a=e.identity===i?{recovery:e.recovery}:{error:Dt,recovery:null}:r!==null&&(a=Ot(t,r,n)),a.recovery&&(s.current={identity:i,recovery:a.recovery}),o({identity:i,...a})},[r,i,t,n]);let c=x(e=>{if(!(!t||r===null)){s.current=e?{identity:i,recovery:e}:null;try{e?window.sessionStorage.setItem(t,JSON.stringify({recovery:e,selectionFingerprint:r,version:2,widgetId:n})):window.sessionStorage.removeItem(t)}catch{}}},[r,i,t,n]);return{error:t&&a?.identity===i?a.error:void 0,ready:!t||a?.identity===i,recovery:t&&a?.identity===i?a.recovery:null,remember:c}}const At={annually:`/year`,"every-six-months":` every 6 months`,monthly:`/month`,"one-time":``};function jt({branding:e,catalog:t}){return A(`header`,{children:[t.widget.showCommunityBranding&&e?A(`div`,{className:`lockerverse-payment__branding`,children:[e.imageUrl?k(`img`,{alt:e.name,height:`48`,src:e.imageUrl,width:`48`}):null,k(`strong`,{children:e.name})]}):null,k(`h1`,{children:t.widget.title??t.widget.name}),t.widget.description?k(`p`,{children:t.widget.description}):null]})}function Mt({catalog:t,selection:n}){let r=n?.length?t.products.filter(e=>n.some(t=>t.productSlug===e.slug)):t.products;return r.length===0?null:A(`div`,{className:`lockerverse-payment__payment-summary`,children:[k(`h2`,{children:`Products`}),k(`div`,{className:`lockerverse-payment__payment-summary-items`,children:r.map(t=>{let n=t.pricingMode===`fixed`?t.amountCents:t.minimumAmountCents,r=At[t.paymentOption];return A(`div`,{className:`lockerverse-payment__payment-summary-row`,children:[k(`span`,{children:t.name}),k(`strong`,{children:n===null?`Choose amount`:`${t.pricingMode===`custom`?`From `:``}${e(n)}${r}`})]},t.id)})}),k(`p`,{children:`Base prices. Final total is checked at checkout.`})]})}function Nt(e,t){let i=n(e?.[`--lockerverse-accent`]??t?.accentColor??`#38d77a`),a=r(i),o={...e};return(e?.[`--lockerverse-accent`]!==void 0||t?.accentColor)&&(o[`--lockerverse-accent`]=i),a&&e?.[`--lockerverse-accent-contrast`]===void 0&&(o[`--lockerverse-accent-contrast`]=a),{accent:i,rootStyle:o}}function Pt({catalog:e,client:n,loadError:r,onRetry:i,...a}){let{branding:o,className:s,completionView:c,recoveryStorageKey:l,initialCustomFieldValues:u,metadata:d,onPaymentComplete:f,onPaymentRecoveryChange:p,onPaymentUncertain:m,resumePayment:h,selection:g,style:_,stripeLoader:v=et,theme:y=`dark`,...b}=a,[ee,w]=D(h),T=E(null),[O,j]=D(null),M=x(e=>{j(e),t(f,e)},[f]),[N,P]=D(),[F,I]=D(`idle`),L=E(void 0),{selectionError:R,session:z,updateCheckout:te}=wt({catalog:e,client:n,paymentState:F,selection:g}),B=z.phase===`ready`?z.revision:void 0,ne=x(e=>{B!==void 0&&(L.current=B),I(e)},[B]),re=x(e=>p?.(e),[p]),ie=x(()=>{w(void 0)},[]);S(()=>{z.phase===`loading`&&P(void 0)},[z.phase]),C(()=>{z.phase===`ready`&&L.current!==z.revision&&I(e=>e===`success`||e===`unresolved`?e:`idle`)},[z.phase,z.revision]);let V=[`lockerverse-payment`,s].filter(Boolean).join(` `),H=o??e.community,{accent:U,rootStyle:W}=Nt(_,H);return O&&c===`summary`?k(`section`,{...b,className:V,"data-lockerverse-theme":y,"data-payment-state":`success`,style:W,children:A(`div`,{className:`lockerverse-payment__completion`,role:`status`,children:[k(`span`,{"aria-hidden":`true`,className:`lockerverse-payment__completion-icon`,children:k(`svg`,{"aria-hidden":`true`,fill:`none`,height:`28`,stroke:`currentColor`,strokeWidth:`2`,viewBox:`0 0 24 24`,width:`28`,children:k(`path`,{d:`m5 12 4 4L19 6`})})}),k(`h1`,{children:O.paymentRequired?`Thank you`:`Order confirmed`}),k(`p`,{children:O.paymentRequired?`Your payment has been received.`:`Your order is confirmed. No payment was required.`})]})}):R?k(`section`,{...b,className:V,"data-lockerverse-theme":y,role:`alert`,style:W,children:R}):z.phase===`error`&&z.failure===`This option is sold out.`||F===`sold_out`?A(`section`,{...b,className:V,"data-lockerverse-theme":y,role:`alert`,style:W,children:[k(`h1`,{children:`Sold out`}),k(`p`,{children:`This option is sold out.`})]}):z.phase===`error`?k(`section`,{...b,className:V,"data-lockerverse-theme":y,style:W,children:k(`p`,{role:`alert`,children:z.failure})}):z.phase===`ready`?A(`section`,{...b,"aria-label":`Payment`,className:V,"data-lockerverse-theme":y,"data-payment-state":F,ref:T,style:W,children:[k(jt,{branding:H,catalog:e}),r?A(`div`,{role:`alert`,children:[k(`p`,{children:r.message}),k(`button`,{onClick:i,type:`button`,children:`Retry`})]}):null,N?k(`p`,{className:`lockerverse-payment__payment-status`,role:`status`,children:N}):null,z.quoteFailure?A(`div`,{className:`lockerverse-payment__payment-status`,role:`alert`,children:[k(`span`,{children:z.quoteFailure}),k(`span`,{children:` The final total will be checked when you submit.`})]}):null,k(it,{accentColor:U,appearanceRoot:T,catalog:e,checkoutItems:z.checkoutItems,client:n,initialCustomFieldValues:u,metadata:d,onPaymentComplete:M,onPaymentRecoveryChange:re,onPaymentUncertain:m,onQuoteChange:(e,t)=>{P(t),te(e)},onResumePaymentFailed:ie,onStateChange:ne,quote:z.displayedQuote,resumePayment:ee,stripeLoader:v,theme:y,visualStyle:W},z.revision)]}):A(`section`,{...b,"aria-busy":`true`,"aria-label":`Payment`,className:V,"data-lockerverse-theme":y,style:W,children:[k(jt,{branding:H,catalog:e}),r?A(`div`,{role:`alert`,children:[k(`p`,{children:r.message}),k(`button`,{onClick:i,type:`button`,children:`Retry`})]}):null,k(_t,{})]})}function Ft({children:e,loading:t=!1,viewProps:i}){let{branding:a,className:o,completionView:s,recoveryStorageKey:c,initialCustomFieldValues:l,metadata:u,onPaymentComplete:d,onPaymentRecoveryChange:f,onPaymentUncertain:p,resumePayment:m,selection:h,stripeLoader:g,style:_,theme:v=`dark`,...y}=i,b=n(_?.[`--lockerverse-accent`]??a?.accentColor??`#38d77a`),x=r(b),S={..._};return(_?.[`--lockerverse-accent`]!==void 0||a?.accentColor)&&(S[`--lockerverse-accent`]=b),x&&_?.[`--lockerverse-accent-contrast`]===void 0&&(S[`--lockerverse-accent-contrast`]=x),k(`section`,{...y,...t?{"aria-busy":!0,"aria-label":`Payment`}:{},className:[`lockerverse-payment`,o].filter(Boolean).join(` `),"data-lockerverse-theme":v,style:S,children:e})}function It(e){let{catalog:n,client:r,loadError:i,onRetry:a,...o}=e,{onPaymentRecoveryChange:s,recoveryStorageKey:c,resumePayment:l,selection:u}=o,d=kt({selection:u,storageKey:c,widgetId:n.widget.id}),f=x(e=>{d.remember(e),t(s,e)},[s,d.remember]);return!d.ready||d.error?k(Ft,{loading:!d.ready,viewProps:o,children:d.error?k(`p`,{role:`alert`,children:d.error}):k(_t,{})}):k(Pt,{...e,onPaymentRecoveryChange:f,resumePayment:l??d.recovery})}function Lt({widget:e,...t}){return e.error&&!e.catalog?A(Ft,{viewProps:t,children:[k(`p`,{role:`alert`,children:e.error.message}),k(`button`,{onClick:e.refresh,type:`button`,children:`Retry`})]}):e.loading?A(Ft,{loading:!0,viewProps:t,children:[e.catalog?A(O,{children:[k(jt,{branding:t.branding??e.catalog.community,catalog:e.catalog}),k(Mt,{catalog:e.catalog,selection:t.selection})]}):null,k(_t,{})]}):e.catalog?k(It,{catalog:e.catalog,client:e.client,loadError:e.error,onRetry:e.refresh,...t}):k(Ft,{loading:!0,viewProps:t,children:k(_t,{})})}export{tt as n,Lt as t};
|
|
2
2
|
//# sourceMappingURL=lockerverse-payment.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lockerverse-payment.js","names":["notifyPaymentRecovery","cachedStripeLoader"],"sources":["../src/select-control.tsx","../src/checkout-fields.tsx","../src/payment-form-state.ts","../src/payment-attempt.ts","../src/payment-input.ts","../src/payment-quote.ts","../src/payment-submission.ts","../src/use-payment-form-controller.ts","../src/payment-form.tsx","../src/use-payment-checkout.ts","../src/use-payment-recovery-storage.ts","../src/lockerverse-payment.tsx"],"sourcesContent":["export type LockerverseSelectOption = {\n label: string;\n value: string;\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 return (\n <select\n aria-describedby={ariaDescribedBy}\n aria-invalid={invalid || undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className={[\n \"lockerverse-form__control\",\n \"lockerverse-form__select\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n id={id}\n name={name}\n onChange={(event) => onValueChange(event.currentTarget.value)}\n value={value}\n >\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n );\n}\n","import type {\n LockerverseCustomField,\n LockerverseWidgetFields,\n} from \"@lockerverse/sdk/checkout\";\nimport { useId } from \"react\";\nimport { CustomFields, type CustomFieldValues } from \"./custom-fields.tsx\";\nimport { Checkbox } from \"./form-field.tsx\";\nimport { formatMoney } from \"./format-money.ts\";\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: CustomFieldValues;\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 const id = useId();\n return (\n <label className=\"lockerverse-payment__check-row\" htmlFor={id}>\n <Checkbox\n checked={checked}\n id={id}\n name={name}\n onChange={(event) => onChange(event.currentTarget.checked)}\n />\n <span>{children}</span>\n </label>\n );\n}\n\nexport function AdditionalCheckoutFields({\n customFields,\n errors,\n fields,\n idPrefix,\n isPromoApplying,\n memberIdLabel,\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 memberIdLabel: string | null | undefined;\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>{memberIdLabel?.trim() || \"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={(value) => {\n const merchSize = MERCH_SIZES.find((size) => size === value);\n if (merchSize) {\n update({ 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","type PaymentFormStatus =\n | \"editing\"\n | \"invalid\"\n | \"recovering\"\n | \"refreshing_quote\"\n | \"submitting\"\n | \"succeeded\"\n | \"sold_out\"\n | \"unresolved\";\n\nexport type PaymentFormState = {\n error: string | undefined;\n message: string | undefined;\n retryUrl?: string | undefined;\n status: PaymentFormStatus;\n};\n\nexport type PaymentFormAction =\n | { type: \"field_changed\" }\n | { type: \"recovery_started\" }\n | { type: \"validation_failed\" }\n | { type: \"quote_refresh_started\" }\n | { type: \"quote_refresh_succeeded\" }\n | { error?: string; type: \"quote_refresh_failed\" }\n | { type: \"submission_started\" }\n | { type: \"submission_validation_failed\" }\n | { type: \"quote_changed\" }\n | { error: string; type: \"retryable_failure\" }\n | { error: string; type: \"recovery_failed\" }\n | { type: \"sold_out\" }\n | { message: string; type: \"succeeded\" }\n | { message: string; retryUrl?: string; type: \"unresolved\" };\n\nexport type PaymentUiState =\n | \"error\"\n | \"idle\"\n | \"invalid\"\n | \"sold_out\"\n | \"submitting\"\n | \"success\"\n | \"unresolved\";\n\nexport function createPaymentFormState(\n recoverPayment: boolean\n): PaymentFormState {\n return {\n error: undefined,\n message: undefined,\n status: recoverPayment ? \"recovering\" : \"editing\",\n };\n}\n\nfunction updateState(\n state: PaymentFormState,\n allowedStatuses: PaymentFormStatus[],\n changes: Partial<PaymentFormState>\n) {\n return allowedStatuses.includes(state.status)\n ? { ...state, ...changes }\n : state;\n}\n\nexport function paymentFormReducer(\n state: PaymentFormState,\n action: PaymentFormAction\n): PaymentFormState {\n if (action.type === \"recovery_started\" && state.status === \"unresolved\") {\n return { ...state, message: undefined, status: \"recovering\" };\n }\n\n if (\n state.status === \"sold_out\" ||\n state.status === \"succeeded\" ||\n state.status === \"unresolved\"\n ) {\n return state;\n }\n\n switch (action.type) {\n case \"field_changed\":\n return updateState(state, [\"editing\", \"invalid\", \"refreshing_quote\"], {\n error: undefined,\n status: \"editing\",\n });\n case \"validation_failed\":\n return updateState(state, [\"editing\"], { status: \"invalid\" });\n case \"quote_refresh_started\":\n return updateState(state, [\"editing\", \"invalid\"], {\n status: \"refreshing_quote\",\n });\n case \"quote_refresh_succeeded\":\n return updateState(state, [\"refreshing_quote\"], {\n error: undefined,\n status: \"editing\",\n });\n case \"quote_refresh_failed\":\n return updateState(state, [\"refreshing_quote\"], {\n error: action.error ?? state.error,\n status: \"editing\",\n });\n case \"submission_started\":\n return updateState(state, [\"editing\", \"invalid\", \"refreshing_quote\"], {\n error: undefined,\n status: \"submitting\",\n });\n case \"submission_validation_failed\":\n return updateState(state, [\"submitting\"], {\n error: undefined,\n status: \"invalid\",\n });\n case \"quote_changed\":\n return updateState(state, [\"submitting\"], { status: \"editing\" });\n case \"retryable_failure\":\n return updateState(state, [\"editing\", \"invalid\", \"submitting\"], {\n error: action.error,\n status: \"editing\",\n });\n case \"recovery_failed\":\n return updateState(state, [\"recovering\"], {\n error: action.error,\n retryUrl: undefined,\n status: \"editing\",\n });\n case \"sold_out\":\n return {\n error: undefined,\n message: undefined,\n status: \"sold_out\",\n };\n case \"succeeded\":\n return updateState(state, [\"recovering\", \"submitting\"], {\n message: action.message,\n retryUrl: undefined,\n status: \"succeeded\",\n });\n case \"unresolved\": {\n const changes: Partial<PaymentFormState> = {\n message: action.message,\n retryUrl: action.retryUrl,\n status: \"unresolved\",\n };\n return updateState(state, [\"recovering\", \"submitting\"], changes);\n }\n default:\n return state;\n }\n}\n\nexport function getPaymentError(state: PaymentFormState) {\n return state.status === \"editing\" ||\n state.status === \"invalid\" ||\n state.status === \"refreshing_quote\"\n ? state.error\n : undefined;\n}\n\nexport function getPaymentUiState(state: PaymentFormState): PaymentUiState {\n if (state.status === \"sold_out\") {\n return \"sold_out\";\n }\n if (state.status === \"succeeded\") {\n return \"success\";\n }\n if (state.status === \"unresolved\") {\n return \"unresolved\";\n }\n if (state.status === \"submitting\" || state.status === \"recovering\") {\n return \"submitting\";\n }\n if (state.status === \"invalid\") {\n return \"invalid\";\n }\n return getPaymentError(state) ? \"error\" : \"idle\";\n}\n\nexport function isPaymentBusy(state: PaymentFormState) {\n return state.status === \"submitting\";\n}\n","import type {\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\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: LockerverseCheckoutEstimate | LockerverseCheckoutQuote,\n current: LockerverseCheckoutQuote,\n locallyPreviewedTotalCents: number | undefined,\n stripeConnectedAccountId: string | null\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 stripeConnectedAccountId !== current.payment.connectedAccountId ||\n (displayed.authoritative &&\n (displayed.payment.connectedAccountId !== stripeConnectedAccountId ||\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 retryUrl?: string;\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 const outcome: PaymentAttemptOutcome = {\n kind: \"unresolved\",\n paymentReference: payment.paymentReference,\n reason:\n payment.checkoutStatus === \"action_required\"\n ? \"action_required\"\n : \"pending\",\n };\n if (payment.retryUrl) {\n outcome.retryUrl = payment.retryUrl;\n }\n return outcome;\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\" || !payment.requiresAction) {\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 | null\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\";\nimport type { LockerversePaymentSelectionItem } from \"./types.ts\";\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 strictObject({\n productSlug: productSlugSchema,\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(\n input: LockerversePaymentSelectionItem[]\n) {\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 LockerverseCatalog,\n LockerverseCheckoutEstimate,\n LockerverseCheckoutPricingInput,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport type { CheckoutFieldValues } from \"./checkout-fields.tsx\";\nimport { parseCustomTipCents } from \"./payment-input.ts\";\n\nconst INVALID_PROMO_MESSAGE =\n \"This promo code is invalid or cannot be applied.\";\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\nexport function buildQuoteRequest(\n catalog: LockerverseCatalog,\n fieldValues: CheckoutFieldValues,\n email: string,\n tipCents: number\n) {\n const request: LockerverseCheckoutPricingInput = {};\n if (email) {\n request.email = email;\n }\n if (catalog.widget.fields.serviceFee) {\n request.includeServiceFee = fieldValues.includeServiceFee;\n }\n if (catalog.widget.fields.promoCode && fieldValues.promoCode.trim()) {\n request.promoCode = fieldValues.promoCode.trim();\n }\n if (catalog.widget.fields.tipping) {\n request.tipCents = tipCents;\n }\n return request;\n}\n\nexport function getLocalQuotePreview(\n catalog: LockerverseCatalog,\n fieldValues: CheckoutFieldValues,\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout\n) {\n const parsedTip = catalog.widget.fields.tipping\n ? getTipCents(quote.subtotalCents, fieldValues)\n : ({ cents: 0, success: true } as const);\n if (!parsedTip.success) {\n return { parsedTip, totalCents: null };\n }\n\n const serviceFeeCents =\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 return {\n parsedTip,\n totalCents:\n quote.totalCents -\n quote.serviceFeeCents -\n quote.tipCents +\n serviceFeeCents +\n parsedTip.cents,\n };\n}\n\nexport function getQuoteRefreshSuccess(\n quote: LockerversePreparedCheckout,\n validatePromo: boolean\n) {\n return {\n displayedTotalCents: quote.totalCents,\n promoError:\n validatePromo && quote.appliedDiscount?.source !== \"promo_code\"\n ? INVALID_PROMO_MESSAGE\n : undefined,\n };\n}\n\nexport function getQuoteRefreshFailure<ErrorValue>(\n error: ErrorValue,\n validatePromo: boolean\n) {\n let paymentError: string | undefined;\n if (!validatePromo) {\n paymentError =\n error instanceof Error\n ? error.message\n : \"The order total could not be updated.\";\n }\n return {\n paymentError,\n promoError: validatePromo ? INVALID_PROMO_MESSAGE : undefined,\n };\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\n LockerverseCheckoutItem,\n LockerversePaymentSubmission,\n LockerversePreparedCheckout,\n LockerverseShipping,\n} from \"@lockerverse/sdk/checkout\";\nimport type {\n Stripe,\n StripeAddressElementChangeEvent,\n StripeElements,\n} from \"@stripe/stripe-js\";\nimport type { CheckoutFieldValues } from \"./checkout-fields.tsx\";\nimport {\n buildCustomFieldAnswers,\n getCheckoutCustomFields,\n} from \"./custom-fields.tsx\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport {\n hasMaterialQuoteChange,\n type PaymentAttemptOutcome,\n submitPaymentAttempt,\n} from \"./payment-attempt.ts\";\nimport { buildQuoteRequest, getTipCents } from \"./payment-quote.ts\";\nimport { normalizePhone } from \"./payment-validation.ts\";\nimport type { LockerversePaymentProps } from \"./types.ts\";\n\nexport type CheckoutAddresses = Record<\n \"billing\" | \"shipping\",\n StripeAddressElementChangeEvent | null\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: ReturnType<typeof getCompleteAddress> | undefined;\n}) {\n const billingDetails = catalog.widget.fields.phone\n ? {\n address: billingAddress.address,\n email,\n name: billingAddress.name,\n phone,\n }\n : {\n address: billingAddress.address,\n email,\n name: billingAddress.name,\n };\n const params = {\n payment_method_data: {\n billing_details: billingDetails,\n },\n };\n if (!shippingAddress) {\n return params;\n }\n return {\n ...params,\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\nfunction buildPaymentRequest({\n catalog,\n checkoutItems,\n confirmationToken,\n email,\n fieldValues,\n metadata,\n phone,\n shippingAddress,\n}: {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n confirmationToken: string | undefined;\n email: string;\n fieldValues: CheckoutFieldValues;\n metadata: Record<string, string> | undefined;\n phone: string;\n shippingAddress: ReturnType<typeof getCompleteAddress> | undefined;\n}) {\n const request: LockerversePaymentSubmission = {\n customFieldAnswers: buildCustomFieldAnswers(\n getCheckoutCustomFields(catalog, checkoutItems),\n fieldValues.customFields\n ),\n email,\n };\n if (confirmationToken) {\n request.confirmationToken = confirmationToken;\n request.paymentMethodConfiguration = \"explicit\";\n }\n if (metadata) {\n request.metadata = metadata;\n }\n if (catalog.widget.fields.memberId && fieldValues.memberId.trim()) {\n request.memberId = fieldValues.memberId.trim();\n }\n if (catalog.widget.fields.merchSize) {\n request.merchSize = fieldValues.merchSize;\n }\n if (catalog.widget.fields.phone) {\n request.phone = phone;\n }\n if (shippingAddress) {\n const address: LockerverseShipping[\"address\"] = {\n city: shippingAddress.address.city ?? \"\",\n country: shippingAddress.address.country,\n line1: shippingAddress.address.line1 ?? \"\",\n postal_code: shippingAddress.address.postal_code ?? \"\",\n state: shippingAddress.address.state ?? \"\",\n };\n if (shippingAddress.address.line2) {\n address.line2 = shippingAddress.address.line2;\n }\n request.shipping = { address, name: shippingAddress.name };\n }\n return request;\n}\n\nfunction assertPaymentAttemptActive(isAttemptActive: () => boolean) {\n if (!isAttemptActive()) {\n throw new Error(\"Payment component is no longer active.\");\n }\n}\n\nfunction notifyPaymentRecovery(\n callback: LockerversePaymentProps[\"onPaymentRecoveryChange\"],\n recovery: Parameters<\n NonNullable<LockerversePaymentProps[\"onPaymentRecoveryChange\"]>\n >[0]\n) {\n notifyHostCallback(callback, recovery);\n}\n\nfunction mapPaymentAttemptOutcome(\n outcome: PaymentAttemptOutcome,\n quote: LockerversePreparedCheckout,\n email: string,\n failureMessage: string\n) {\n if (outcome.kind === \"failed\") {\n return {\n kind: \"payment_failed\" as const,\n message: failureMessage,\n };\n }\n if (outcome.kind === \"unresolved\") {\n return {\n kind: \"payment_unresolved\" as const,\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n retryUrl: outcome.retryUrl,\n };\n }\n return {\n email,\n kind: \"payment\" as const,\n payment: outcome.payment,\n quote,\n };\n}\n\nexport type CompletePaymentOptions = {\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: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n stripe?: Stripe | null;\n stripeConnectedAccountId: string | null;\n};\n\nexport async 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 stripeConnectedAccountId,\n}: CompletePaymentOptions) {\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 currentQuote = await client.calculateTotal({\n ...buildQuoteRequest(\n catalog,\n fieldValues,\n normalizedEmail,\n parsedTip.cents\n ),\n catalog,\n items: checkoutItems,\n });\n assertPaymentAttemptActive(isAttemptActive);\n if (\n currentQuote.totalCents > 0 &&\n hasMaterialQuoteChange(\n quote,\n currentQuote,\n locallyPreviewedTotalCents,\n stripeConnectedAccountId\n )\n ) {\n return { kind: \"quote_changed\" as const, quote: currentQuote };\n }\n\n let completeShippingAddress:\n | ReturnType<typeof getCompleteAddress>\n | undefined;\n let confirmationToken: string | undefined;\n if (currentQuote.totalCents === 0) {\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 } else {\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 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 confirmationToken = tokenResult.confirmationToken.id;\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 checkoutItems,\n confirmationToken,\n email: normalizedEmail,\n fieldValues,\n metadata,\n phone: normalizedPhone,\n shippingAddress: completeShippingAddress,\n }),\n },\n stripe\n );\n assertPaymentAttemptActive(isAttemptActive);\n return mapPaymentAttemptOutcome(\n outcome,\n currentQuote,\n normalizedEmail,\n currentQuote.totalCents === 0\n ? \"Order could not be completed. Review the details and try again.\"\n : \"Payment was declined. Check your payment details and try again.\"\n );\n}\n\nexport type CompletePaymentResult = Awaited<ReturnType<typeof completePayment>>;\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\n LockerverseCheckoutItem,\n LockerversePaymentCompletion,\n LockerversePaymentResult,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport { LockerverseSdkError } from \"@lockerverse/sdk/checkout\";\nimport type { Stripe, StripeElements } from \"@stripe/stripe-js\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { CheckoutFieldValues } from \"./checkout-fields.tsx\";\nimport { getPhoneServerError } from \"./contact-validation.ts\";\nimport { formatMoney } from \"./format-money.ts\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport {\n type PaymentAttemptOutcome,\n recoverPaymentAttempt,\n} from \"./payment-attempt.ts\";\nimport {\n getPaymentError,\n getPaymentUiState,\n isPaymentBusy,\n type PaymentFormAction,\n type PaymentFormState,\n type PaymentUiState,\n} from \"./payment-form-state.ts\";\nimport {\n buildQuoteRequest,\n getLocalQuotePreview,\n getQuoteRefreshFailure,\n getQuoteRefreshSuccess,\n} from \"./payment-quote.ts\";\nimport {\n type CheckoutAddresses,\n type CompletePaymentResult,\n completePayment,\n} from \"./payment-submission.ts\";\nimport { validateContact } from \"./payment-validation.ts\";\nimport type { LockerversePaymentProps } from \"./types.ts\";\n\nfunction notifyPaymentRecovery(\n callback: LockerversePaymentProps[\"onPaymentRecoveryChange\"],\n recovery: Parameters<\n NonNullable<LockerversePaymentProps[\"onPaymentRecoveryChange\"]>\n >[0]\n) {\n notifyHostCallback(callback, recovery);\n}\n\nfunction notifyPaymentUncertain(\n callback: LockerversePaymentProps[\"onPaymentUncertain\"],\n payment: Parameters<\n NonNullable<LockerversePaymentProps[\"onPaymentUncertain\"]>\n >[0]\n) {\n notifyHostCallback(callback, payment);\n}\n\nfunction createPaymentCompletion(\n payment: LockerversePaymentResult,\n context: Pick<LockerversePaymentCompletion, \"email\" | \"lineItems\">\n): LockerversePaymentCompletion {\n return { ...payment, ...context };\n}\n\nfunction unresolvedPaymentState(outcome: {\n reason: string;\n retryUrl?: string | undefined;\n}) {\n const action: PaymentFormAction = {\n message:\n outcome.reason === \"action_required\"\n ? \"Payment needs your attention. Keep this checkout open.\"\n : \"Payment is not complete. Check its status before you try again.\",\n type: \"unresolved\",\n };\n if (outcome.retryUrl) {\n action.retryUrl = outcome.retryUrl;\n }\n return action;\n}\n\nfunction mustWaitForStripe(\n outcome: PaymentAttemptOutcome,\n stripe: Stripe | null,\n stripeLoadFailed: boolean\n) {\n return (\n outcome.kind === \"unresolved\" &&\n outcome.reason === \"action_required\" &&\n !outcome.retryUrl &&\n !stripe &&\n !stripeLoadFailed\n );\n}\n\nfunction isSoldOutError<ErrorValue>(error: ErrorValue) {\n return (\n error instanceof LockerverseSdkError &&\n error.serverCode === \"PAYMENT_WIDGET_SALES_LIMIT_REACHED\"\n );\n}\n\nexport type PaymentFormControllerOptions = {\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 onResumePaymentFailed: () => void;\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n onStateChange: (state: PaymentUiState) => void;\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n stripe: Stripe | null;\n stripeConnectedAccountId: string | null;\n stripeLoadFailed: boolean;\n paymentState: PaymentFormState;\n updateState: (action: PaymentFormAction, notifyHost?: boolean) => void;\n};\n\ntype SubmitPayment = {\n addresses: CheckoutAddresses;\n phone: string;\n};\n\nfunction applyQuoteRefreshSuccess({\n nextQuote,\n onQuoteChange,\n setDisplayedTotalCents,\n setPromoError,\n updateState,\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 updateState: (action: PaymentFormAction) => void;\n validatePromo: boolean;\n}) {\n const result = getQuoteRefreshSuccess(nextQuote, validatePromo);\n updateState({ type: \"quote_refresh_succeeded\" });\n setDisplayedTotalCents(result.displayedTotalCents);\n onQuoteChange(nextQuote);\n if (validatePromo) {\n setPromoError(result.promoError);\n }\n}\n\nfunction applyQuoteRefreshFailure({\n error,\n setPromoError,\n updateState,\n validatePromo,\n}: {\n error: unknown;\n setPromoError: (error: string | undefined) => void;\n updateState: (action: PaymentFormAction) => void;\n validatePromo: boolean;\n}) {\n const result = getQuoteRefreshFailure(error, validatePromo);\n if (validatePromo) {\n setPromoError(result.promoError);\n }\n updateState(\n result.paymentError === undefined\n ? { type: \"quote_refresh_failed\" }\n : { error: result.paymentError, type: \"quote_refresh_failed\" }\n );\n}\n\nfunction applyPaymentOutcome({\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n result,\n setDisplayedTotalCents,\n dispatchState,\n unresolvedReferenceRef,\n}: {\n unresolvedReferenceRef: { current: string | undefined };\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 dispatchState: (action: PaymentFormAction) => 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 dispatchState({ type: \"quote_changed\" });\n return;\n }\n if (result.kind === \"payment_failed\") {\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n dispatchState({ error: result.message, type: \"retryable_failure\" });\n return;\n }\n if (result.kind === \"payment_unresolved\") {\n unresolvedReferenceRef.current = result.paymentReference;\n dispatchState(unresolvedPaymentState(result));\n notifyPaymentUncertain(onPaymentUncertain, {\n paymentReference: result.paymentReference,\n reason: result.reason,\n });\n return;\n }\n onQuoteChange(result.quote);\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n dispatchState({\n message: result.payment.paymentRequired\n ? \"Payment completed successfully.\"\n : \"Order confirmed. No payment was required.\",\n type: \"succeeded\",\n });\n notifyHostCallback(\n onPaymentComplete,\n createPaymentCompletion(result.payment, {\n email: result.email,\n lineItems: result.quote.lineItems,\n })\n );\n}\n\nexport function usePaymentFormController(\n options: PaymentFormControllerOptions\n) {\n const {\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n metadata,\n onPaymentComplete,\n onResumePaymentFailed,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onStateChange,\n quote,\n resumePayment,\n stripe,\n stripeConnectedAccountId,\n stripeLoadFailed,\n paymentState,\n updateState,\n } = options;\n const [displayedTotalCents, setDisplayedTotalCents] = useState(\n quote.totalCents\n );\n const [promoError, setPromoError] = useState<string>();\n const recoveryStartedRef = useRef(false);\n const unresolvedReferenceRef = useRef<string | undefined>(undefined);\n const quoteRequestRef = useRef(0);\n const attemptGenerationRef = useRef(0);\n const dispatchState = useCallback(\n (action: PaymentFormAction) => updateState(action, true),\n [updateState]\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 quoteRequestRef.current += 1;\n },\n []\n );\n\n const { parsedTip, totalCents: previewTotalCents } = getLocalQuotePreview(\n catalog,\n fieldValues,\n quote\n );\n\n useEffect(() => {\n if (previewTotalCents === null) {\n return;\n }\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 previewTotalCents,\n quote.serviceFeeCents,\n quote.tipCents,\n quote.totalCents,\n quote.subtotalCents,\n ]);\n\n useEffect(() => {\n const paymentReference =\n resumePayment?.paymentReference ?? unresolvedReferenceRef.current;\n if (\n !paymentReference ||\n recoveryStartedRef.current ||\n paymentState.status !== \"recovering\"\n ) {\n return;\n }\n recoveryStartedRef.current = true;\n const isAttemptActive = startPaymentAttempt();\n onStateChange(getPaymentUiState(paymentState));\n\n recoverPaymentAttempt(client, paymentReference, stripe).then((outcome) => {\n if (!isAttemptActive()) {\n return;\n }\n if (mustWaitForStripe(outcome, stripe, stripeLoadFailed)) {\n return;\n }\n if (outcome.kind === \"failed\") {\n const message =\n \"The previous payment failed. Check your details and try again.\";\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n onResumePaymentFailed();\n dispatchState({\n error: message,\n type: \"recovery_failed\",\n });\n return;\n }\n if (outcome.kind === \"unresolved\") {\n dispatchState(unresolvedPaymentState(outcome));\n notifyPaymentUncertain(onPaymentUncertain, {\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n });\n return;\n }\n\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n dispatchState({\n message: outcome.payment.paymentRequired\n ? \"Payment completed successfully.\"\n : \"Order confirmed. No payment was required.\",\n type: \"succeeded\",\n });\n notifyHostCallback(\n onPaymentComplete,\n createPaymentCompletion(outcome.payment, {\n email: null,\n lineItems: null,\n })\n );\n });\n return () => {\n if (isAttemptActive()) {\n attemptGenerationRef.current += 1;\n }\n recoveryStartedRef.current = false;\n };\n }, [\n client,\n onPaymentComplete,\n onResumePaymentFailed,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onStateChange,\n resumePayment,\n stripe,\n stripeLoadFailed,\n startPaymentAttempt,\n dispatchState,\n paymentState,\n ]);\n\n const fieldChanged = useCallback(\n (clearPromo = false, preserveQuoteRequest = false) => {\n if (!preserveQuoteRequest) {\n quoteRequestRef.current += 1;\n }\n if (clearPromo) {\n setPromoError(undefined);\n }\n updateState({ type: \"field_changed\" });\n },\n [updateState]\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 updateState({ type: \"quote_refresh_started\" });\n try {\n const nextQuote = await client.calculateTotal({\n ...buildQuoteRequest(\n catalog,\n fieldValues,\n emailValidation.value?.email ?? \"\",\n parsedTip.cents\n ),\n catalog,\n items: checkoutItems,\n });\n if (requestId !== quoteRequestRef.current) {\n return;\n }\n applyQuoteRefreshSuccess({\n nextQuote,\n onQuoteChange,\n setDisplayedTotalCents,\n setPromoError,\n updateState,\n validatePromo,\n });\n } catch (error) {\n if (requestId !== quoteRequestRef.current) {\n return;\n }\n if (isSoldOutError(error)) {\n updateState({ type: \"sold_out\" });\n return;\n }\n applyQuoteRefreshFailure({\n error,\n setPromoError,\n updateState,\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 dispatchState({ 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 stripeConnectedAccountId,\n });\n if (!isAttemptActive()) {\n return;\n }\n applyPaymentOutcome({\n dispatchState,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n result,\n setDisplayedTotalCents,\n unresolvedReferenceRef,\n });\n } catch (error) {\n if (!isAttemptActive()) {\n return;\n }\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n if (isSoldOutError(error)) {\n dispatchState({ type: \"sold_out\" });\n return;\n }\n const phoneError =\n error instanceof LockerverseSdkError\n ? getPhoneServerError(error.serverCode)\n : undefined;\n if (phoneError) {\n dispatchState({ type: \"submission_validation_failed\" });\n return { phoneError };\n }\n dispatchState({\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 paymentState.status === \"succeeded\" || paymentState.status === \"unresolved\"\n ? paymentState.message\n : undefined;\n return {\n commands: {\n applyPromo,\n checkPaymentStatus: () => dispatchState({ type: \"recovery_started\" }),\n fieldChanged,\n refreshAuthoritativeTotal,\n reportStripeLoadError: (message: string) =>\n dispatchState({ error: message, type: \"retryable_failure\" }),\n reportValidationFailure: () =>\n dispatchState({ type: \"validation_failed\" }),\n submit,\n },\n state: {\n displayedTotalCents,\n isRecovering: paymentState.status === \"recovering\",\n isRefreshingQuote: paymentState.status === \"refreshing_quote\",\n isSubmitting: isPaymentBusy(paymentState),\n isUnresolved: paymentState.status === \"unresolved\",\n parsedTip,\n paymentError: getPaymentError(paymentState),\n promoError,\n retryUrl: paymentState.retryUrl,\n terminalMessage,\n },\n };\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\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 {\n type RefObject,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n AdditionalCheckoutFields,\n type CheckoutFieldValues,\n CheckoutToggle,\n ServiceFeeField,\n TipField,\n} from \"./checkout-fields.tsx\";\nimport {\n createCustomFieldValues,\n getCheckoutCustomFields,\n validateCustomFields,\n} from \"./custom-fields.tsx\";\nimport { EmailField, FormField } from \"./form-field.tsx\";\nimport { FormSkeleton } from \"./form-skeleton.tsx\";\nimport { formatMoney } from \"./format-money.ts\";\nimport {\n createPaymentFormState,\n getPaymentUiState,\n type PaymentFormAction,\n type PaymentFormState,\n type PaymentUiState,\n paymentFormReducer,\n} from \"./payment-form-state.ts\";\nimport type { CheckoutAddresses } from \"./payment-submission.ts\";\nimport { PaymentSummary } from \"./payment-summary.tsx\";\nimport { validateContact } from \"./payment-validation.ts\";\nimport { getInternationalPhone } from \"./phone.ts\";\nimport type { PhoneInputValue } from \"./phone-field.tsx\";\nimport { PhoneInput } from \"./phone-field.tsx\";\nimport { useStripeAppearance } from \"./stripe-appearance.ts\";\nimport { defaultLockerverseStripeLoader as cachedStripeLoader } from \"./stripe-loader.ts\";\nimport type { LockerversePaymentProps } from \"./types.ts\";\nimport { usePaymentFormController } from \"./use-payment-form-controller.ts\";\n\nexport const defaultLockerverseStripeLoader = cachedStripeLoader;\n\nexport function preloadLockerversePayment(\n catalog: Pick<LockerverseCatalog, \"payment\">\n) {\n const { connectedAccountId, publishableKey } = catalog.payment;\n return defaultLockerverseStripeLoader(\n publishableKey,\n connectedAccountId ? { stripeAccount: connectedAccountId } : undefined\n );\n}\n\nfunction getRecurringCadence(\n paymentOption: LockerversePreparedCheckout[\"paymentOption\"]\n) {\n if (paymentOption === \"monthly\") {\n return { interval: \"month\", label: \"Monthly\" } as const;\n }\n if (paymentOption === \"annually\") {\n return { interval: \"year\", label: \"Annual\" } as const;\n }\n if (paymentOption === \"every-six-months\") {\n return { interval: \"6 months\", label: \"Every 6 months\" } as const;\n }\n return null;\n}\n\nfunction getConnectedAccountId(\n catalog: LockerverseCatalog,\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout,\n resumePayment: LockerversePaymentProps[\"resumePayment\"]\n) {\n if (resumePayment) {\n const { connectedAccountId } = resumePayment;\n return connectedAccountId;\n }\n if (\"payment\" in quote) {\n const { connectedAccountId } = quote.payment;\n return connectedAccountId;\n }\n const { connectedAccountId } = catalog.payment;\n return connectedAccountId;\n}\n\nexport function ReadyPayment({\n accentColor,\n catalog,\n checkoutItems,\n client,\n appearanceRoot,\n initialCustomFieldValues,\n metadata,\n onPaymentComplete,\n onResumePaymentFailed,\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 appearanceRoot: RefObject<HTMLElement | null>;\n initialCustomFieldValues: LockerversePaymentProps[\"initialCustomFieldValues\"];\n metadata: Record<string, string> | undefined;\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onResumePaymentFailed: () => void;\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n onStateChange: (state: PaymentUiState) => void;\n stripeLoader: NonNullable<LockerversePaymentProps[\"stripeLoader\"]>;\n theme: LockerversePaymentProps[\"theme\"];\n visualStyle: LockerversePaymentProps[\"style\"];\n}) {\n const [paymentState, setPaymentState] = useState(() =>\n createPaymentFormState(Boolean(resumePayment))\n );\n const paymentStateRef = useRef(paymentState);\n paymentStateRef.current = paymentState;\n const updateState = useCallback(\n (action: PaymentFormAction, notifyHost = false) => {\n const next = paymentFormReducer(paymentStateRef.current, action);\n if (next === paymentStateRef.current) {\n return;\n }\n paymentStateRef.current = next;\n setPaymentState(next);\n if (notifyHost) {\n onStateChange(getPaymentUiState(next));\n }\n },\n [onStateChange]\n );\n const requestedConnectedAccountId = getConnectedAccountId(\n catalog,\n quote,\n resumePayment\n );\n const stripeConfigurationRef = useRef({\n connectedAccountId: requestedConnectedAccountId,\n paymentOption: quote.paymentOption,\n });\n if (\n paymentState.status !== \"submitting\" &&\n paymentState.status !== \"recovering\"\n ) {\n stripeConfigurationRef.current = {\n connectedAccountId: requestedConnectedAccountId,\n paymentOption: quote.paymentOption,\n };\n }\n const { connectedAccountId, paymentOption } = stripeConfigurationRef.current;\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 const [stripeLoadFailed, setStripeLoadFailed] = useState(false);\n useEffect(() => {\n let active = true;\n setStripeLoadFailed(false);\n stripe.then((loadedStripe) => {\n if (active && loadedStripe === null) {\n setStripeLoadFailed(true);\n }\n });\n return () => {\n active = false;\n };\n }, [stripe]);\n\n const appearance = useStripeAppearance(\n appearanceRoot,\n theme,\n visualStyle,\n paymentState.status === \"submitting\" ||\n paymentState.status === \"recovering\",\n accentColor\n );\n if (!appearance) {\n return <FormSkeleton fieldCount={3} label=\"Loading payment form\" />;\n }\n\n return (\n <Elements\n key={`${catalog.payment.publishableKey}:${connectedAccountId ?? \"platform\"}:${paymentOption}`}\n options={{\n amount: Math.max(quote.totalCents, 100),\n appearance,\n currency: catalog.payment.currency,\n mode: paymentOption === \"one-time\" ? \"payment\" : \"subscription\",\n paymentMethodTypes: catalog.community?.widgetAchEnabled\n ? [\"card\", \"link\", \"us_bank_account\"]\n : [\"card\", \"link\"],\n syncAddressCheckbox: \"none\",\n }}\n stripe={stripe}\n >\n <PaymentForm\n catalog={catalog}\n checkoutItems={checkoutItems}\n client={client}\n initialCustomFieldValues={initialCustomFieldValues}\n metadata={metadata}\n onPaymentComplete={onPaymentComplete}\n onPaymentRecoveryChange={onPaymentRecoveryChange}\n onPaymentUncertain={onPaymentUncertain}\n onQuoteChange={onQuoteChange}\n onResumePaymentFailed={onResumePaymentFailed}\n onStateChange={onStateChange}\n paymentState={paymentState}\n quote={quote}\n resumePayment={resumePayment}\n stripeConnectedAccountId={connectedAccountId}\n stripeLoadFailed={stripeLoadFailed}\n updateState={updateState}\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: \"auto\",\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 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: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n}) {\n const isFree = displayedTotalCents === 0;\n const isReady = isFree\n ? !catalog.widget.fields.shipping ||\n (isBillingAddressReady && isRequiredShippingReady)\n : isPaymentReady && isBillingAddressReady && isRequiredShippingReady;\n const cadence = getRecurringCadence(quote.paymentOption);\n let label = isFree\n ? \"Complete order\"\n : `Pay ${formatMoney(displayedTotalCents)}`;\n if (!isFree && cadence) {\n label = `Subscribe for ${formatMoney(displayedTotalCents)}/${cadence.interval}`;\n }\n if (isSubmitting) {\n label = isFree ? \"Completing…\" : \"Processing…\";\n }\n let actionLabel = `Process payment for ${formatMoney(displayedTotalCents)} total`;\n if (isFree) {\n actionLabel = \"Complete order\";\n } else if (cadence) {\n actionLabel = `Start ${cadence.label.toLowerCase()} subscription for ${formatMoney(displayedTotalCents)}`;\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={actionLabel}\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 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: PhoneInputValue) => 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 <EmailField\n error={errors.email}\n errorId={emailErrorId}\n id={emailId}\n label=\"Email\"\n name=\"email\"\n onBlur={onEmailBlur}\n onChange={(event) => onEmailChange(event.currentTarget.value)}\n ref={emailRef}\n required\n value={email}\n />\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 <FormField\n error={errors.phone}\n errorId={phoneErrorId}\n id={phoneId}\n label=\"Phone\"\n >\n <PhoneInput\n country={phoneCountry}\n error={errors.phone}\n errorId={phoneErrorId}\n id={phoneId}\n inputRef={phoneRef}\n name=\"phone\"\n onChange={onPhoneChange}\n required\n value={phone}\n />\n </FormField>\n ) : null}\n </div>\n );\n}\n\nfunction PaymentForm({\n catalog,\n checkoutItems,\n client,\n initialCustomFieldValues,\n metadata,\n onPaymentComplete,\n onResumePaymentFailed,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onStateChange,\n quote,\n resumePayment,\n stripeConnectedAccountId,\n stripeLoadFailed,\n paymentState,\n updateState,\n}: {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n initialCustomFieldValues: LockerversePaymentProps[\"initialCustomFieldValues\"];\n metadata: Record<string, string> | undefined;\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onResumePaymentFailed: () => void;\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n onStateChange: (state: PaymentUiState) => void;\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n stripeConnectedAccountId: string | null;\n stripeLoadFailed: boolean;\n paymentState: PaymentFormState;\n updateState: (action: PaymentFormAction, notifyHost?: boolean) => void;\n}) {\n const customFields = getCheckoutCustomFields(catalog, checkoutItems);\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(\n customFields,\n initialCustomFieldValues\n ),\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 controller = usePaymentFormController({\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onResumePaymentFailed,\n onStateChange,\n paymentState,\n quote,\n resumePayment,\n stripe,\n stripeConnectedAccountId,\n stripeLoadFailed,\n updateState,\n });\n const {\n displayedTotalCents,\n isRecovering,\n isUnresolved,\n isRefreshingQuote,\n isSubmitting,\n parsedTip,\n paymentError,\n promoError,\n terminalMessage,\n retryUrl,\n } = controller.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({ preventScroll: true });\n }\n }, [isSubmitting]);\n\n useEffect(() => {\n if (!(isSubmitting || errors.email || !errors.phone)) {\n phoneRef.current?.focus();\n }\n }, [errors.email, errors.phone, 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 controller.commands.fieldChanged(false, field !== \"email\");\n setErrors((current) => {\n const next = { ...current };\n delete next[field];\n return next;\n });\n }\n\n function handleFieldValuesChange(nextValues: CheckoutFieldValues) {\n const promoChanged = nextValues.promoCode !== fieldValues.promoCode;\n const serviceFeeChanged =\n nextValues.includeServiceFee !== fieldValues.includeServiceFee;\n controller.commands.fieldChanged(\n promoChanged,\n !(promoChanged || serviceFeeChanged)\n );\n setFieldValues(nextValues);\n setCustomFieldErrors({});\n setTipError(undefined);\n }\n\n async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {\n event.preventDefault();\n const internationalPhone = catalog.widget.fields.phone\n ? getInternationalPhone(phone, phoneCountry)\n : \"\";\n const validation = validateContact(\n { email, phone: internationalPhone },\n catalog.widget.fields.phone\n );\n const nextCustomFieldErrors = validateCustomFields(\n 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 controller.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 const result = await controller.commands.submit({\n addresses: addressesRef.current,\n phone: internationalPhone,\n });\n if (result?.phoneError) {\n setErrors({ phone: result.phoneError });\n }\n }\n\n if (terminalMessage || isRecovering) {\n return (\n <div className=\"lockerverse-payment__actions\">\n <p\n className=\"lockerverse-payment__payment-status\"\n ref={statusRef}\n role=\"status\"\n tabIndex={-1}\n >\n {isRecovering ? \"Recovering payment…\" : terminalMessage}\n {retryUrl ? (\n <>\n {\" \"}\n <a href={retryUrl} rel=\"noopener noreferrer\" target=\"_blank\">\n Complete payment\n </a>\n </>\n ) : null}\n </p>\n {isUnresolved || isRecovering ? (\n <button\n aria-busy={isRecovering}\n className=\"lockerverse-payment__status-check\"\n disabled={isRecovering}\n onClick={controller.commands.checkPaymentStatus}\n type=\"button\"\n >\n {isRecovering ? \"Checking payment status…\" : \"Check payment status\"}\n </button>\n ) : null}\n </div>\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={() => controller.commands.refreshAuthoritativeTotal()}\n onEmailChange={(value) => {\n setEmail(value);\n clearError(\"email\");\n }}\n onPhoneChange={({ value, country }) => {\n setPhone(value);\n setPhoneCountry(country);\n clearError(\"phone\");\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={controller.commands.reportStripeLoadError}\n setIsBillingAddressReady={setIsBillingAddressReady}\n setIsPaymentReady={setIsPaymentReady}\n setIsShippingAddressReady={setIsShippingAddressReady}\n />\n <AdditionalCheckoutFields\n customFields={customFields}\n errors={customFieldErrors}\n fields={catalog.widget.fields}\n idPrefix={idPrefix}\n isPromoApplying={isRefreshingQuote}\n memberIdLabel={catalog.community?.memberIdLabel}\n onApplyPromo={controller.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\nexport function PaymentSkeleton() {\n return (\n <FormSkeleton\n fieldCount={2}\n label=\"Loading payment…\"\n sectionCount={2}\n showCheckbox\n />\n );\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\n LockerverseCheckoutItem,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport { estimateLockerverseCheckout } from \"@lockerverse/sdk/checkout\";\nimport { useEffect, useMemo, useReducer, useRef } from \"react\";\nimport type { PaymentUiState } from \"./payment-form-state.ts\";\nimport { parsePaymentSelection } from \"./payment-input.ts\";\nimport type {\n LockerversePaymentProps,\n LockerversePaymentSelectionItem,\n} from \"./types.ts\";\n\ntype SessionState =\n | {\n phase: \"loading\";\n revision: number;\n }\n | {\n failure: string;\n phase: \"error\";\n revision: number;\n }\n | {\n checkoutItems: LockerverseCheckoutItem[];\n displayedQuote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n phase: \"ready\";\n quoteFailure: string | undefined;\n revision: number;\n };\n\ntype SessionAction =\n | {\n type: \"loading\";\n }\n | {\n displayedQuote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n type: \"ready\";\n }\n | {\n failure: string;\n type: \"error\";\n }\n | { checkout: LockerversePreparedCheckout; type: \"checkout\" }\n | { failure: string; type: \"quote-error\" };\n\nfunction sessionReducer(\n state: SessionState,\n action: SessionAction\n): SessionState {\n switch (action.type) {\n case \"loading\":\n return {\n phase: \"loading\",\n revision: state.revision,\n };\n case \"ready\":\n return createReadySession(action.displayedQuote, state.revision + 1);\n case \"error\":\n return {\n failure: action.failure,\n phase: \"error\",\n revision: state.revision,\n };\n case \"checkout\":\n return state.phase === \"ready\"\n ? {\n ...state,\n displayedQuote: action.checkout,\n quoteFailure: undefined,\n }\n : state;\n case \"quote-error\":\n return state.phase === \"ready\"\n ? {\n ...state,\n quoteFailure: action.failure,\n }\n : state;\n default:\n return state;\n }\n}\n\ntype LoadIdentity = {\n catalog: LockerverseCatalog;\n selectionKey: string;\n};\n\nfunction isSameLoad(\n identity: LoadIdentity | undefined,\n catalog: LockerverseCatalog,\n selectionKey: string\n) {\n return (\n identity?.catalog === catalog && identity.selectionKey === selectionKey\n );\n}\n\nfunction createReadyAction({\n checkout,\n}: {\n checkout: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n}): Extract<SessionAction, { type: \"ready\" }> {\n return {\n displayedQuote: checkout,\n type: \"ready\",\n };\n}\n\nfunction getLoadFailure<ErrorValue>(error: ErrorValue) {\n return error instanceof Error\n ? error.message\n : \"Lockerverse payment could not load.\";\n}\n\nfunction createReadySession(\n checkout: LockerverseCheckoutEstimate | LockerversePreparedCheckout,\n revision: number\n): SessionState {\n return {\n checkoutItems: [...checkout.items],\n displayedQuote: checkout,\n phase: \"ready\",\n quoteFailure: undefined,\n revision,\n };\n}\n\nfunction estimateCheckout(\n catalog: LockerverseCatalog,\n selection: LockerversePaymentSelectionItem[]\n) {\n const includeServiceFee = catalog.widget.fields.serviceFee;\n return estimateLockerverseCheckout(catalog, {\n includeServiceFee,\n selection,\n });\n}\n\nfunction createInitialSession(\n catalog: LockerverseCatalog,\n selection: LockerversePaymentSelectionItem[]\n): SessionState {\n try {\n return createReadySession(estimateCheckout(catalog, selection), 1);\n } catch (error) {\n return {\n failure: getLoadFailure(error),\n phase: \"error\",\n revision: 0,\n };\n }\n}\n\nexport function usePaymentCheckout({\n catalog,\n client,\n paymentState,\n selection,\n}: {\n catalog: LockerverseCatalog;\n client: LockerverseCheckoutClient;\n paymentState: PaymentUiState;\n selection: LockerversePaymentProps[\"selection\"];\n}) {\n const parsedSelection = parsePaymentSelection(selection);\n const selectionKey = parsedSelection.success\n ? JSON.stringify(parsedSelection.value)\n : \"invalid-selection\";\n const stableSelection = useMemo(\n () => (parsedSelection.success ? parsedSelection.value : []),\n [parsedSelection.success, selectionKey]\n );\n const [session, dispatch] = useReducer(\n sessionReducer,\n undefined,\n (): SessionState =>\n parsedSelection.success\n ? createInitialSession(catalog, stableSelection)\n : { phase: \"loading\", revision: 0 }\n );\n const loadingRef = useRef<LoadIdentity | undefined>(undefined);\n const quoteRevisionRef = useRef(0);\n const estimatedRef = useRef<LoadIdentity | undefined>(\n session.phase === \"ready\" ? { catalog, selectionKey } : undefined\n );\n const settledRef = useRef<LoadIdentity | undefined>(\n session.phase === \"error\" ? { catalog, selectionKey } : undefined\n );\n const sessionIsLocked =\n paymentState === \"submitting\" ||\n paymentState === \"success\" ||\n paymentState === \"unresolved\";\n useEffect(() => {\n if (!parsedSelection.success) {\n return;\n }\n if (\n sessionIsLocked ||\n isSameLoad(settledRef.current, catalog, selectionKey) ||\n isSameLoad(loadingRef.current, catalog, selectionKey)\n ) {\n return;\n }\n\n let active = true;\n loadingRef.current = { catalog, selectionKey };\n let estimateIsReady = isSameLoad(\n estimatedRef.current,\n catalog,\n selectionKey\n );\n if (!estimateIsReady) {\n dispatch({ type: \"loading\" });\n }\n\n function dispatchWhenActive(action: SessionAction) {\n if (active) {\n dispatch(action);\n }\n }\n\n function settleWhenActive() {\n if (active) {\n loadingRef.current = undefined;\n settledRef.current = { catalog, selectionKey };\n }\n }\n\n let initialQuoteRevision: number | undefined;\n\n function failWhenActive<ErrorValue>(error: ErrorValue) {\n if (!active) {\n return;\n }\n loadingRef.current = undefined;\n settledRef.current = { catalog, selectionKey };\n if (\n estimateIsReady &&\n initialQuoteRevision !== undefined &&\n quoteRevisionRef.current !== initialQuoteRevision\n ) {\n return;\n }\n const failure = getLoadFailure(error);\n if (failure === \"This option is sold out.\") {\n dispatch({ failure, type: \"error\" });\n return;\n }\n if (estimateIsReady) {\n dispatch({ failure, type: \"quote-error\" });\n } else {\n dispatch({\n failure,\n type: \"error\",\n });\n }\n }\n\n async function loadPayment() {\n try {\n initialQuoteRevision = quoteRevisionRef.current;\n const includeServiceFee = catalog.widget.fields.serviceFee;\n if (!estimateIsReady) {\n const estimate = estimateCheckout(catalog, stableSelection);\n estimateIsReady = true;\n estimatedRef.current = { catalog, selectionKey };\n dispatchWhenActive(createReadyAction({ checkout: estimate }));\n }\n const preparedCheckout = await client.calculateTotal({\n catalog,\n includeServiceFee,\n selection: stableSelection,\n });\n settleWhenActive();\n if (quoteRevisionRef.current === initialQuoteRevision) {\n dispatchWhenActive({\n checkout: preparedCheckout,\n type: \"checkout\",\n });\n }\n } catch (error) {\n failWhenActive(error);\n }\n }\n\n loadPayment();\n return () => {\n active = false;\n if (isSameLoad(loadingRef.current, catalog, selectionKey)) {\n loadingRef.current = undefined;\n }\n };\n }, [\n catalog,\n client,\n parsedSelection.success,\n sessionIsLocked,\n selectionKey,\n stableSelection,\n ]);\n\n const loadIsCurrent =\n isSameLoad(estimatedRef.current, catalog, selectionKey) ||\n isSameLoad(settledRef.current, catalog, selectionKey) ||\n isSameLoad(loadingRef.current, catalog, selectionKey);\n const currentSession =\n sessionIsLocked || loadIsCurrent\n ? session\n : ({ phase: \"loading\", revision: session.revision } as const);\n\n return {\n selectionError: parsedSelection.success\n ? undefined\n : parsedSelection.message,\n session: currentSession,\n updateCheckout: (checkout: LockerversePreparedCheckout) => {\n quoteRevisionRef.current += 1;\n dispatch({ checkout, type: \"checkout\" });\n },\n };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n literal,\n nonEmpty,\n nullable,\n object,\n optional,\n pipe,\n safeParse,\n string,\n trim,\n union,\n} from \"valibot\";\nimport { parsePaymentSelection } from \"./payment-input.ts\";\nimport type {\n LockerversePaymentRecovery,\n LockerversePaymentSelectionItem,\n} from \"./types.ts\";\n\nconst storedRecoverySchema = object({\n recovery: object({\n connectedAccountId: nullable(string()),\n paymentReference: pipe(string(), trim(), nonEmpty()),\n }),\n selectionFingerprint: string(),\n version: union([literal(1), literal(2)]),\n widgetId: optional(string()),\n});\n\nfunction selectionFingerprint(selection: LockerversePaymentSelectionItem[]) {\n const parsed = parsePaymentSelection(selection);\n if (!parsed.success) {\n return null;\n }\n return JSON.stringify(\n parsed.value.map((item) => {\n const slug = item.productSlug.trim();\n if (\"quantity\" in item) {\n return [\"quantity\", slug, item.quantity];\n }\n if (\"amountCents\" in item) {\n return [\"amount\", slug, item.amountCents];\n }\n return [\"product\", slug];\n })\n );\n}\n\nconst mismatchedPaymentMessage =\n \"A previous payment uses different checkout details. Return to its original checkout to check the payment before you pay again.\";\n\ntype RecoveryState = {\n error?: string;\n identity: string;\n recovery: LockerversePaymentRecovery | null;\n};\n\nfunction readRecovery(\n key: string,\n fingerprint: string,\n widgetId: string\n): Omit<RecoveryState, \"identity\"> {\n let saved: string | null;\n try {\n saved = window.sessionStorage.getItem(key);\n } catch {\n // Storage can be blocked. In-page recovery still stays with the form.\n return { recovery: null };\n }\n if (!saved) {\n return { recovery: null };\n }\n try {\n const parsed = safeParse(storedRecoverySchema, JSON.parse(saved));\n if (!parsed.success) {\n throw new Error(\"Invalid recovery record\");\n }\n const value = parsed.output;\n if (\n value.selectionFingerprint !== fingerprint ||\n (value.version === 2 && value.widgetId !== widgetId)\n ) {\n return {\n error: mismatchedPaymentMessage,\n recovery: null,\n };\n }\n return {\n recovery: {\n connectedAccountId: value.recovery.connectedAccountId,\n paymentReference: value.recovery.paymentReference,\n },\n };\n } catch {\n // An unreadable record is not proof that the previous payment failed.\n return {\n error:\n \"The saved payment could not be read. Contact support to check it before you pay again.\",\n recovery: null,\n };\n }\n}\n\n/** Read browser state after hydration, before mounting a payable form. */\nexport function usePaymentRecoveryStorage({\n selection,\n storageKey,\n widgetId,\n}: {\n selection: LockerversePaymentSelectionItem[];\n storageKey: string | undefined;\n widgetId: string;\n}) {\n const fingerprint = selectionFingerprint(selection);\n const identity = JSON.stringify([storageKey, fingerprint, widgetId]);\n const [state, setState] = useState<RecoveryState | null>(null);\n const pendingRef = useRef<RecoveryState | null>(null);\n useEffect(() => {\n if (!storageKey) {\n return;\n }\n const pending = pendingRef.current;\n let restored: Omit<RecoveryState, \"identity\"> = { recovery: null };\n if (pending?.recovery) {\n restored =\n pending.identity === identity\n ? { recovery: pending.recovery }\n : { error: mismatchedPaymentMessage, recovery: null };\n } else if (fingerprint !== null) {\n restored = readRecovery(storageKey, fingerprint, widgetId);\n }\n if (restored.recovery) {\n pendingRef.current = { identity, recovery: restored.recovery };\n }\n setState({ identity, ...restored });\n }, [fingerprint, identity, storageKey, widgetId]);\n\n const remember = useCallback(\n (recovery: LockerversePaymentRecovery | null) => {\n if (!storageKey || fingerprint === null) {\n return;\n }\n pendingRef.current = recovery ? { identity, recovery } : null;\n try {\n if (recovery) {\n window.sessionStorage.setItem(\n storageKey,\n JSON.stringify({\n recovery,\n selectionFingerprint: fingerprint,\n version: 2,\n widgetId,\n })\n );\n } else {\n window.sessionStorage.removeItem(storageKey);\n }\n } catch {\n // Keep recovery in the mounted form if browser storage is unavailable.\n }\n },\n [fingerprint, identity, storageKey, widgetId]\n );\n return {\n error: storageKey && state?.identity === identity ? state.error : undefined,\n ready: !storageKey || state?.identity === identity,\n recovery:\n storageKey && state?.identity === identity ? state.recovery : null,\n remember,\n };\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerversePaymentCompletion,\n} from \"@lockerverse/sdk/checkout\";\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport { getAccentContrast, normalizeAccentColor } from \"./accent-contrast.ts\";\nimport { formatMoney } from \"./format-money.ts\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport {\n defaultLockerverseStripeLoader,\n PaymentSkeleton,\n ReadyPayment,\n} from \"./payment-form.tsx\";\nimport type { PaymentUiState } from \"./payment-form-state.ts\";\nimport type {\n LockerversePaymentProps,\n LockerversePaymentRecovery,\n} from \"./types.ts\";\nimport { usePaymentCheckout } from \"./use-payment-checkout.ts\";\nimport { usePaymentRecoveryStorage } from \"./use-payment-recovery-storage.ts\";\n\ntype PaymentViewProps = Omit<LockerversePaymentProps, \"widget\">;\nconst paymentCadence = {\n annually: \"/year\",\n \"every-six-months\": \" every 6 months\",\n monthly: \"/month\",\n \"one-time\": \"\",\n};\n\nfunction PaymentCatalogHeader({\n branding,\n catalog,\n}: {\n branding: LockerversePaymentProps[\"branding\"] | null;\n catalog: LockerverseCatalog;\n}) {\n return (\n <header>\n {catalog.widget.showCommunityBranding && branding ? (\n <div className=\"lockerverse-payment__branding\">\n {branding.imageUrl ? (\n <img\n alt={branding.name}\n height=\"48\"\n src={branding.imageUrl}\n width=\"48\"\n />\n ) : null}\n <strong>{branding.name}</strong>\n </div>\n ) : null}\n <h1>{catalog.widget.title ?? catalog.widget.name}</h1>\n {catalog.widget.description ? <p>{catalog.widget.description}</p> : null}\n </header>\n );\n}\n\nfunction PaymentCatalogSummary({\n catalog,\n selection,\n}: {\n catalog: LockerverseCatalog;\n selection: LockerversePaymentProps[\"selection\"];\n}) {\n const products = selection?.length\n ? catalog.products.filter((product) =>\n selection.some((item) => item.productSlug === product.slug)\n )\n : catalog.products;\n if (products.length === 0) {\n return null;\n }\n return (\n <div className=\"lockerverse-payment__payment-summary\">\n <h2>Products</h2>\n <div className=\"lockerverse-payment__payment-summary-items\">\n {products.map((product) => {\n const amount =\n product.pricingMode === \"fixed\"\n ? product.amountCents\n : product.minimumAmountCents;\n const cadence = paymentCadence[product.paymentOption];\n return (\n <div\n className=\"lockerverse-payment__payment-summary-row\"\n key={product.id}\n >\n <span>{product.name}</span>\n <strong>\n {amount === null\n ? \"Choose amount\"\n : `${product.pricingMode === \"custom\" ? \"From \" : \"\"}${formatMoney(amount)}${cadence}`}\n </strong>\n </div>\n );\n })}\n </div>\n <p>Base prices. Final total is checked at checkout.</p>\n </div>\n );\n}\n\nfunction getPaymentAppearance(\n style: LockerversePaymentProps[\"style\"],\n branding: LockerversePaymentProps[\"branding\"] | null\n) {\n const accent = normalizeAccentColor(\n style?.[\"--lockerverse-accent\"] ?? branding?.accentColor ?? \"#38d77a\"\n );\n const accentContrast = getAccentContrast(accent);\n const rootStyle: LockerversePaymentProps[\"style\"] = { ...style };\n if (style?.[\"--lockerverse-accent\"] !== undefined || branding?.accentColor) {\n rootStyle[\"--lockerverse-accent\"] = accent;\n }\n if (\n accentContrast &&\n style?.[\"--lockerverse-accent-contrast\"] === undefined\n ) {\n rootStyle[\"--lockerverse-accent-contrast\"] = accentContrast;\n }\n return { accent, rootStyle };\n}\n\nfunction LoadedPayment({\n catalog,\n client,\n loadError,\n onRetry,\n ...viewProps\n}: PaymentViewProps & {\n catalog: LockerverseCatalog;\n client: LockerverseCheckoutClient;\n loadError?: Error | null;\n onRetry?: () => void;\n}) {\n const {\n branding,\n className,\n completionView,\n recoveryStorageKey: _recoveryStorageKey,\n initialCustomFieldValues,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n resumePayment,\n selection,\n style,\n stripeLoader = defaultLockerverseStripeLoader,\n theme = \"dark\",\n ...sectionProps\n } = viewProps;\n const [activeResumePayment, setActiveResumePayment] = useState(resumePayment);\n const appearanceRootRef = useRef<HTMLElement | null>(null);\n const [completion, setCompletion] =\n useState<LockerversePaymentCompletion | null>(null);\n const handlePaymentComplete = useCallback(\n (payment: LockerversePaymentCompletion) => {\n setCompletion(payment);\n notifyHostCallback(onPaymentComplete, payment);\n },\n [onPaymentComplete]\n );\n const [notice, setNotice] = useState<string>();\n const [paymentState, setPaymentState] = useState<PaymentUiState>(\"idle\");\n const paymentStateRevisionRef = useRef<number | undefined>(undefined);\n const { selectionError, session, updateCheckout } = usePaymentCheckout({\n catalog,\n client,\n paymentState,\n selection,\n });\n const readySessionRevision =\n session.phase === \"ready\" ? session.revision : undefined;\n const handlePaymentStateChange = useCallback(\n (state: PaymentUiState) => {\n if (readySessionRevision !== undefined) {\n paymentStateRevisionRef.current = readySessionRevision;\n }\n setPaymentState(state);\n },\n [readySessionRevision]\n );\n const handlePaymentRecoveryChange = useCallback(\n (recovery: LockerversePaymentRecovery | null) =>\n onPaymentRecoveryChange?.(recovery),\n [onPaymentRecoveryChange]\n );\n const handleResumePaymentFailed = useCallback(() => {\n setActiveResumePayment(undefined);\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 = branding ?? catalog.community;\n const { accent: effectiveAccent, rootStyle } = getPaymentAppearance(\n style,\n effectiveBranding\n );\n\n if (completion && completionView === \"summary\") {\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n data-payment-state=\"success\"\n style={rootStyle}\n >\n <div className=\"lockerverse-payment__completion\" role=\"status\">\n <span\n aria-hidden=\"true\"\n className=\"lockerverse-payment__completion-icon\"\n >\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height=\"28\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n width=\"28\"\n >\n <path d=\"m5 12 4 4L19 6\" />\n </svg>\n </span>\n <h1>\n {completion.paymentRequired ? \"Thank you\" : \"Order confirmed\"}\n </h1>\n <p>\n {completion.paymentRequired\n ? \"Your payment has been received.\"\n : \"Your order is confirmed. No payment was required.\"}\n </p>\n </div>\n </section>\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 const sessionIsSoldOut =\n session.phase === \"error\" && session.failure === \"This option is sold out.\";\n\n if (sessionIsSoldOut || paymentState === \"sold_out\") {\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n role=\"alert\"\n style={rootStyle}\n >\n <h1>Sold out</h1>\n <p>This option is sold out.</p>\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 </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 <PaymentCatalogHeader branding={effectiveBranding} catalog={catalog} />\n {loadError ? (\n <div role=\"alert\">\n <p>{loadError.message}</p>\n <button onClick={onRetry} type=\"button\">\n Retry\n </button>\n </div>\n ) : null}\n <PaymentSkeleton />\n </section>\n );\n }\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={appearanceRootRef}\n style={rootStyle}\n >\n <PaymentCatalogHeader branding={effectiveBranding} catalog={catalog} />\n {loadError ? (\n <div role=\"alert\">\n <p>{loadError.message}</p>\n <button onClick={onRetry} type=\"button\">\n Retry\n </button>\n </div>\n ) : null}\n {notice ? (\n <p className=\"lockerverse-payment__payment-status\" role=\"status\">\n {notice}\n </p>\n ) : null}\n {session.quoteFailure ? (\n <div className=\"lockerverse-payment__payment-status\" role=\"alert\">\n <span>{session.quoteFailure}</span>\n <span> The final total will be checked when you submit.</span>\n </div>\n ) : null}\n <ReadyPayment\n accentColor={effectiveAccent}\n appearanceRoot={appearanceRootRef}\n catalog={catalog}\n checkoutItems={session.checkoutItems}\n client={client}\n initialCustomFieldValues={initialCustomFieldValues}\n key={session.revision}\n metadata={metadata}\n onPaymentComplete={handlePaymentComplete}\n onPaymentRecoveryChange={handlePaymentRecoveryChange}\n onPaymentUncertain={onPaymentUncertain}\n onQuoteChange={(nextQuote, nextNotice) => {\n setNotice(nextNotice);\n updateCheckout(nextQuote);\n }}\n onResumePaymentFailed={handleResumePaymentFailed}\n onStateChange={handlePaymentStateChange}\n quote={session.displayedQuote}\n resumePayment={activeResumePayment}\n stripeLoader={stripeLoader}\n theme={theme}\n visualStyle={rootStyle}\n />\n </section>\n );\n}\n\nfunction PaymentWidgetState({\n children,\n loading = false,\n viewProps,\n}: {\n children: ReactNode;\n loading?: boolean;\n viewProps: PaymentViewProps;\n}) {\n const {\n branding,\n className,\n completionView: _completionView,\n recoveryStorageKey: _recoveryStorageKey,\n initialCustomFieldValues: _initialCustomFieldValues,\n metadata: _metadata,\n onPaymentComplete: _onPaymentComplete,\n onPaymentRecoveryChange: _onPaymentRecoveryChange,\n onPaymentUncertain: _onPaymentUncertain,\n resumePayment: _resumePayment,\n selection: _selection,\n stripeLoader: _stripeLoader,\n style,\n theme = \"dark\",\n ...sectionProps\n } = viewProps;\n const accent = normalizeAccentColor(\n style?.[\"--lockerverse-accent\"] ?? branding?.accentColor ?? \"#38d77a\"\n );\n const accentContrast = getAccentContrast(accent);\n const rootStyle: LockerversePaymentProps[\"style\"] = { ...style };\n if (style?.[\"--lockerverse-accent\"] !== undefined || branding?.accentColor) {\n rootStyle[\"--lockerverse-accent\"] = accent;\n }\n if (\n accentContrast &&\n style?.[\"--lockerverse-accent-contrast\"] === undefined\n ) {\n rootStyle[\"--lockerverse-accent-contrast\"] = accentContrast;\n }\n\n return (\n <section\n {...sectionProps}\n {...(loading ? { \"aria-busy\": true, \"aria-label\": \"Payment\" } : {})}\n className={[\"lockerverse-payment\", className].filter(Boolean).join(\" \")}\n data-lockerverse-theme={theme}\n style={rootStyle}\n >\n {children}\n </section>\n );\n}\n\nfunction RecoverablePayment(\n props: PaymentViewProps & {\n catalog: LockerverseCatalog;\n client: LockerverseCheckoutClient;\n loadError?: Error | null;\n onRetry?: () => void;\n }\n) {\n const {\n catalog,\n client: _client,\n loadError: _loadError,\n onRetry: _onRetry,\n ...viewProps\n } = props;\n const {\n onPaymentRecoveryChange,\n recoveryStorageKey,\n resumePayment,\n selection,\n } = viewProps;\n const stored = usePaymentRecoveryStorage({\n selection,\n storageKey: recoveryStorageKey,\n widgetId: catalog.widget.id,\n });\n const handleRecoveryChange = useCallback(\n (recovery: LockerversePaymentRecovery | null) => {\n stored.remember(recovery);\n notifyHostCallback(onPaymentRecoveryChange, recovery);\n },\n [onPaymentRecoveryChange, stored.remember]\n );\n if (!stored.ready || stored.error) {\n return (\n <PaymentWidgetState loading={!stored.ready} viewProps={viewProps}>\n {stored.error ? (\n <p role=\"alert\">{stored.error}</p>\n ) : (\n <PaymentSkeleton />\n )}\n </PaymentWidgetState>\n );\n }\n return (\n <LoadedPayment\n {...props}\n onPaymentRecoveryChange={handleRecoveryChange}\n resumePayment={resumePayment ?? stored.recovery}\n />\n );\n}\n\nexport function LockerversePayment({\n widget,\n ...viewProps\n}: LockerversePaymentProps) {\n if (widget.error && !widget.catalog) {\n return (\n <PaymentWidgetState viewProps={viewProps}>\n <p role=\"alert\">{widget.error.message}</p>\n <button onClick={widget.refresh} type=\"button\">\n Retry\n </button>\n </PaymentWidgetState>\n );\n }\n if (widget.loading) {\n return (\n <PaymentWidgetState loading viewProps={viewProps}>\n {widget.catalog ? (\n <>\n <PaymentCatalogHeader\n branding={viewProps.branding ?? widget.catalog.community}\n catalog={widget.catalog}\n />\n <PaymentCatalogSummary\n catalog={widget.catalog}\n selection={viewProps.selection}\n />\n </>\n ) : null}\n <PaymentSkeleton />\n </PaymentWidgetState>\n );\n }\n if (!widget.catalog) {\n return (\n <PaymentWidgetState loading viewProps={viewProps}>\n <PaymentSkeleton />\n </PaymentWidgetState>\n );\n }\n return (\n <RecoverablePayment\n catalog={widget.catalog}\n client={widget.client}\n loadError={widget.error}\n onRetry={widget.refresh}\n {...viewProps}\n />\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lockerverse-payment.js","names":["notifyPaymentRecovery","cachedStripeLoader"],"sources":["../src/select-control.tsx","../src/checkout-fields.tsx","../src/payment-form-state.ts","../src/payment-attempt.ts","../src/payment-input.ts","../src/payment-quote.ts","../src/payment-submission.ts","../src/use-payment-form-controller.ts","../src/payment-form.tsx","../src/use-payment-checkout.ts","../src/use-payment-recovery-storage.ts","../src/lockerverse-payment.tsx"],"sourcesContent":["export type LockerverseSelectOption = {\n label: string;\n value: string;\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 return (\n <select\n aria-describedby={ariaDescribedBy}\n aria-invalid={invalid || undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className={[\n \"lockerverse-form__control\",\n \"lockerverse-form__select\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n id={id}\n name={name}\n onChange={(event) => onValueChange(event.currentTarget.value)}\n value={value}\n >\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n );\n}\n","import type {\n LockerverseCustomField,\n LockerverseWidgetFields,\n} from \"@lockerverse/sdk/checkout\";\nimport { useId } from \"react\";\nimport { CustomFields, type CustomFieldValues } from \"./custom-fields.tsx\";\nimport { Checkbox } from \"./form-field.tsx\";\nimport { formatMoney } from \"./format-money.ts\";\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: CustomFieldValues;\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 const id = useId();\n return (\n <label className=\"lockerverse-payment__check-row\" htmlFor={id}>\n <Checkbox\n checked={checked}\n id={id}\n name={name}\n onChange={(event) => onChange(event.currentTarget.checked)}\n />\n <span>{children}</span>\n </label>\n );\n}\n\nexport function AdditionalCheckoutFields({\n customFields,\n errors,\n fields,\n idPrefix,\n isPromoApplying,\n memberIdLabel,\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 memberIdLabel: string | null | undefined;\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>{memberIdLabel?.trim() || \"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={(value) => {\n const merchSize = MERCH_SIZES.find((size) => size === value);\n if (merchSize) {\n update({ 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","type PaymentFormStatus =\n | \"editing\"\n | \"invalid\"\n | \"recovering\"\n | \"refreshing_quote\"\n | \"submitting\"\n | \"succeeded\"\n | \"sold_out\"\n | \"unresolved\";\n\nexport type PaymentFormState = {\n error: string | undefined;\n message: string | undefined;\n retryUrl?: string | undefined;\n status: PaymentFormStatus;\n};\n\nexport type PaymentFormAction =\n | { type: \"field_changed\" }\n | { type: \"recovery_started\" }\n | { type: \"validation_failed\" }\n | { type: \"quote_refresh_started\" }\n | { type: \"quote_refresh_succeeded\" }\n | { error?: string; type: \"quote_refresh_failed\" }\n | { type: \"submission_started\" }\n | { type: \"submission_validation_failed\" }\n | { type: \"quote_changed\" }\n | { error: string; type: \"retryable_failure\" }\n | { error: string; type: \"recovery_failed\" }\n | { type: \"sold_out\" }\n | { message: string; type: \"succeeded\" }\n | { message: string; retryUrl?: string; type: \"unresolved\" };\n\nexport type PaymentUiState =\n | \"error\"\n | \"idle\"\n | \"invalid\"\n | \"sold_out\"\n | \"submitting\"\n | \"success\"\n | \"unresolved\";\n\nexport function createPaymentFormState(\n recoverPayment: boolean\n): PaymentFormState {\n return {\n error: undefined,\n message: undefined,\n status: recoverPayment ? \"recovering\" : \"editing\",\n };\n}\n\nfunction updateState(\n state: PaymentFormState,\n allowedStatuses: PaymentFormStatus[],\n changes: Partial<PaymentFormState>\n) {\n return allowedStatuses.includes(state.status)\n ? { ...state, ...changes }\n : state;\n}\n\nexport function paymentFormReducer(\n state: PaymentFormState,\n action: PaymentFormAction\n): PaymentFormState {\n if (action.type === \"recovery_started\" && state.status === \"unresolved\") {\n return { ...state, message: undefined, status: \"recovering\" };\n }\n\n if (\n state.status === \"sold_out\" ||\n state.status === \"succeeded\" ||\n state.status === \"unresolved\"\n ) {\n return state;\n }\n\n switch (action.type) {\n case \"field_changed\":\n return updateState(state, [\"editing\", \"invalid\", \"refreshing_quote\"], {\n error: undefined,\n status: \"editing\",\n });\n case \"validation_failed\":\n return updateState(state, [\"editing\"], { status: \"invalid\" });\n case \"quote_refresh_started\":\n return updateState(state, [\"editing\", \"invalid\"], {\n status: \"refreshing_quote\",\n });\n case \"quote_refresh_succeeded\":\n return updateState(state, [\"refreshing_quote\"], {\n error: undefined,\n status: \"editing\",\n });\n case \"quote_refresh_failed\":\n return updateState(state, [\"refreshing_quote\"], {\n error: action.error ?? state.error,\n status: \"editing\",\n });\n case \"submission_started\":\n return updateState(state, [\"editing\", \"invalid\", \"refreshing_quote\"], {\n error: undefined,\n status: \"submitting\",\n });\n case \"submission_validation_failed\":\n return updateState(state, [\"submitting\"], {\n error: undefined,\n status: \"invalid\",\n });\n case \"quote_changed\":\n return updateState(state, [\"submitting\"], { status: \"editing\" });\n case \"retryable_failure\":\n return updateState(state, [\"editing\", \"invalid\", \"submitting\"], {\n error: action.error,\n status: \"editing\",\n });\n case \"recovery_failed\":\n return updateState(state, [\"recovering\"], {\n error: action.error,\n retryUrl: undefined,\n status: \"editing\",\n });\n case \"sold_out\":\n return {\n error: undefined,\n message: undefined,\n status: \"sold_out\",\n };\n case \"succeeded\":\n return updateState(state, [\"recovering\", \"submitting\"], {\n message: action.message,\n retryUrl: undefined,\n status: \"succeeded\",\n });\n case \"unresolved\": {\n const changes: Partial<PaymentFormState> = {\n message: action.message,\n retryUrl: action.retryUrl,\n status: \"unresolved\",\n };\n return updateState(state, [\"recovering\", \"submitting\"], changes);\n }\n default:\n return state;\n }\n}\n\nexport function getPaymentError(state: PaymentFormState) {\n return state.status === \"editing\" ||\n state.status === \"invalid\" ||\n state.status === \"refreshing_quote\"\n ? state.error\n : undefined;\n}\n\nexport function getPaymentUiState(state: PaymentFormState): PaymentUiState {\n if (state.status === \"sold_out\") {\n return \"sold_out\";\n }\n if (state.status === \"succeeded\") {\n return \"success\";\n }\n if (state.status === \"unresolved\") {\n return \"unresolved\";\n }\n if (state.status === \"submitting\" || state.status === \"recovering\") {\n return \"submitting\";\n }\n if (state.status === \"invalid\") {\n return \"invalid\";\n }\n return getPaymentError(state) ? \"error\" : \"idle\";\n}\n\nexport function isPaymentBusy(state: PaymentFormState) {\n return state.status === \"submitting\";\n}\n","import type {\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\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: LockerverseCheckoutEstimate | LockerverseCheckoutQuote,\n current: LockerverseCheckoutQuote,\n locallyPreviewedTotalCents: number | undefined,\n stripeConnectedAccountId: string | null\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 stripeConnectedAccountId !== current.payment.connectedAccountId ||\n (displayed.authoritative &&\n (displayed.payment.connectedAccountId !== stripeConnectedAccountId ||\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 retryUrl?: string;\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 const outcome: PaymentAttemptOutcome = {\n kind: \"unresolved\",\n paymentReference: payment.paymentReference,\n reason:\n payment.checkoutStatus === \"action_required\"\n ? \"action_required\"\n : \"pending\",\n };\n if (payment.retryUrl) {\n outcome.retryUrl = payment.retryUrl;\n }\n return outcome;\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\" || !payment.requiresAction) {\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 | null\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\";\nimport type { LockerversePaymentSelectionItem } from \"./types.ts\";\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 strictObject({\n productSlug: productSlugSchema,\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(\n input: LockerversePaymentSelectionItem[]\n) {\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 LockerverseCatalog,\n LockerverseCheckoutEstimate,\n LockerverseCheckoutPricingInput,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport type { CheckoutFieldValues } from \"./checkout-fields.tsx\";\nimport { parseCustomTipCents } from \"./payment-input.ts\";\n\nconst INVALID_PROMO_MESSAGE =\n \"This promo code is invalid or cannot be applied.\";\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\nexport function buildQuoteRequest(\n catalog: LockerverseCatalog,\n fieldValues: CheckoutFieldValues,\n email: string,\n tipCents: number\n) {\n const request: LockerverseCheckoutPricingInput = {};\n if (email) {\n request.email = email;\n }\n if (catalog.widget.fields.serviceFee) {\n request.includeServiceFee = fieldValues.includeServiceFee;\n }\n if (catalog.widget.fields.promoCode && fieldValues.promoCode.trim()) {\n request.promoCode = fieldValues.promoCode.trim();\n }\n if (catalog.widget.fields.tipping) {\n request.tipCents = tipCents;\n }\n return request;\n}\n\nexport function getLocalQuotePreview(\n catalog: LockerverseCatalog,\n fieldValues: CheckoutFieldValues,\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout\n) {\n const parsedTip = catalog.widget.fields.tipping\n ? getTipCents(quote.subtotalCents, fieldValues)\n : ({ cents: 0, success: true } as const);\n if (!parsedTip.success) {\n return { parsedTip, totalCents: null };\n }\n\n const serviceFeeCents =\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 return {\n parsedTip,\n totalCents:\n quote.totalCents -\n quote.serviceFeeCents -\n quote.tipCents +\n serviceFeeCents +\n parsedTip.cents,\n };\n}\n\nexport function getQuoteRefreshSuccess(\n quote: LockerversePreparedCheckout,\n validatePromo: boolean\n) {\n return {\n displayedTotalCents: quote.totalCents,\n promoError:\n validatePromo && quote.appliedDiscount?.source !== \"promo_code\"\n ? INVALID_PROMO_MESSAGE\n : undefined,\n };\n}\n\nexport function getQuoteRefreshFailure<ErrorValue>(\n error: ErrorValue,\n validatePromo: boolean\n) {\n let paymentError: string | undefined;\n if (!validatePromo) {\n paymentError =\n error instanceof Error\n ? error.message\n : \"The order total could not be updated.\";\n }\n return {\n paymentError,\n promoError: validatePromo ? INVALID_PROMO_MESSAGE : undefined,\n };\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\n LockerverseCheckoutItem,\n LockerversePaymentSubmission,\n LockerversePreparedCheckout,\n LockerverseShipping,\n} from \"@lockerverse/sdk/checkout\";\nimport type {\n Stripe,\n StripeAddressElementChangeEvent,\n StripeElements,\n} from \"@stripe/stripe-js\";\nimport type { CheckoutFieldValues } from \"./checkout-fields.tsx\";\nimport {\n buildCustomFieldAnswers,\n getCheckoutCustomFields,\n} from \"./custom-fields.tsx\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport {\n hasMaterialQuoteChange,\n type PaymentAttemptOutcome,\n submitPaymentAttempt,\n} from \"./payment-attempt.ts\";\nimport { buildQuoteRequest, getTipCents } from \"./payment-quote.ts\";\nimport { normalizePhone } from \"./payment-validation.ts\";\nimport type { LockerversePaymentProps } from \"./types.ts\";\n\nexport type CheckoutAddresses = Record<\n \"billing\" | \"shipping\",\n StripeAddressElementChangeEvent | null\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: ReturnType<typeof getCompleteAddress> | undefined;\n}) {\n const billingDetails = catalog.widget.fields.phone\n ? {\n address: billingAddress.address,\n email,\n name: billingAddress.name,\n phone,\n }\n : {\n address: billingAddress.address,\n email,\n name: billingAddress.name,\n };\n const params = {\n payment_method_data: {\n billing_details: billingDetails,\n },\n };\n if (!shippingAddress) {\n return params;\n }\n return {\n ...params,\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\nfunction buildPaymentRequest({\n catalog,\n checkoutItems,\n confirmationToken,\n email,\n fieldValues,\n metadata,\n phone,\n shippingAddress,\n}: {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n confirmationToken: string | undefined;\n email: string;\n fieldValues: CheckoutFieldValues;\n metadata: Record<string, string> | undefined;\n phone: string;\n shippingAddress: ReturnType<typeof getCompleteAddress> | undefined;\n}) {\n const request: LockerversePaymentSubmission = {\n customFieldAnswers: buildCustomFieldAnswers(\n getCheckoutCustomFields(catalog, checkoutItems),\n fieldValues.customFields\n ),\n email,\n };\n if (confirmationToken) {\n request.confirmationToken = confirmationToken;\n request.paymentMethodConfiguration = \"explicit\";\n }\n if (metadata) {\n request.metadata = metadata;\n }\n if (catalog.widget.fields.memberId && fieldValues.memberId.trim()) {\n request.memberId = fieldValues.memberId.trim();\n }\n if (catalog.widget.fields.merchSize) {\n request.merchSize = fieldValues.merchSize;\n }\n if (catalog.widget.fields.phone) {\n request.phone = phone;\n }\n if (shippingAddress) {\n const address: LockerverseShipping[\"address\"] = {\n city: shippingAddress.address.city ?? \"\",\n country: shippingAddress.address.country,\n line1: shippingAddress.address.line1 ?? \"\",\n postal_code: shippingAddress.address.postal_code ?? \"\",\n state: shippingAddress.address.state ?? \"\",\n };\n if (shippingAddress.address.line2) {\n address.line2 = shippingAddress.address.line2;\n }\n request.shipping = { address, name: shippingAddress.name };\n }\n return request;\n}\n\nfunction assertPaymentAttemptActive(isAttemptActive: () => boolean) {\n if (!isAttemptActive()) {\n throw new Error(\"Payment component is no longer active.\");\n }\n}\n\nfunction notifyPaymentRecovery(\n callback: LockerversePaymentProps[\"onPaymentRecoveryChange\"],\n recovery: Parameters<\n NonNullable<LockerversePaymentProps[\"onPaymentRecoveryChange\"]>\n >[0]\n) {\n notifyHostCallback(callback, recovery);\n}\n\nfunction mapPaymentAttemptOutcome(\n outcome: PaymentAttemptOutcome,\n quote: LockerversePreparedCheckout,\n email: string,\n failureMessage: string\n) {\n if (outcome.kind === \"failed\") {\n return {\n kind: \"payment_failed\" as const,\n message: failureMessage,\n };\n }\n if (outcome.kind === \"unresolved\") {\n return {\n kind: \"payment_unresolved\" as const,\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n retryUrl: outcome.retryUrl,\n };\n }\n return {\n email,\n kind: \"payment\" as const,\n payment: outcome.payment,\n quote,\n };\n}\n\nexport type CompletePaymentOptions = {\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: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n stripe?: Stripe | null;\n stripeConnectedAccountId: string | null;\n};\n\nexport async 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 stripeConnectedAccountId,\n}: CompletePaymentOptions) {\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 currentQuote = await client.calculateTotal({\n ...buildQuoteRequest(\n catalog,\n fieldValues,\n normalizedEmail,\n parsedTip.cents\n ),\n catalog,\n items: checkoutItems,\n });\n assertPaymentAttemptActive(isAttemptActive);\n if (\n currentQuote.totalCents > 0 &&\n hasMaterialQuoteChange(\n quote,\n currentQuote,\n locallyPreviewedTotalCents,\n stripeConnectedAccountId\n )\n ) {\n return { kind: \"quote_changed\" as const, quote: currentQuote };\n }\n\n let completeShippingAddress:\n | ReturnType<typeof getCompleteAddress>\n | undefined;\n let confirmationToken: string | undefined;\n if (currentQuote.totalCents === 0) {\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 } else {\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 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 confirmationToken = tokenResult.confirmationToken.id;\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 checkoutItems,\n confirmationToken,\n email: normalizedEmail,\n fieldValues,\n metadata,\n phone: normalizedPhone,\n shippingAddress: completeShippingAddress,\n }),\n },\n stripe\n );\n assertPaymentAttemptActive(isAttemptActive);\n return mapPaymentAttemptOutcome(\n outcome,\n currentQuote,\n normalizedEmail,\n currentQuote.totalCents === 0\n ? \"Order could not be completed. Review the details and try again.\"\n : \"Payment was declined. Check your payment details and try again.\"\n );\n}\n\nexport type CompletePaymentResult = Awaited<ReturnType<typeof completePayment>>;\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\n LockerverseCheckoutItem,\n LockerversePaymentCompletion,\n LockerversePaymentResult,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport { LockerverseSdkError } from \"@lockerverse/sdk/checkout\";\nimport type { Stripe, StripeElements } from \"@stripe/stripe-js\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { CheckoutFieldValues } from \"./checkout-fields.tsx\";\nimport { getPhoneServerError } from \"./contact-validation.ts\";\nimport { formatMoney } from \"./format-money.ts\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport {\n type PaymentAttemptOutcome,\n recoverPaymentAttempt,\n} from \"./payment-attempt.ts\";\nimport {\n getPaymentError,\n getPaymentUiState,\n isPaymentBusy,\n type PaymentFormAction,\n type PaymentFormState,\n type PaymentUiState,\n} from \"./payment-form-state.ts\";\nimport {\n buildQuoteRequest,\n getLocalQuotePreview,\n getQuoteRefreshFailure,\n getQuoteRefreshSuccess,\n} from \"./payment-quote.ts\";\nimport {\n type CheckoutAddresses,\n type CompletePaymentResult,\n completePayment,\n} from \"./payment-submission.ts\";\nimport { validateContact } from \"./payment-validation.ts\";\nimport type { LockerversePaymentProps } from \"./types.ts\";\n\nfunction notifyPaymentRecovery(\n callback: LockerversePaymentProps[\"onPaymentRecoveryChange\"],\n recovery: Parameters<\n NonNullable<LockerversePaymentProps[\"onPaymentRecoveryChange\"]>\n >[0]\n) {\n notifyHostCallback(callback, recovery);\n}\n\nfunction notifyPaymentUncertain(\n callback: LockerversePaymentProps[\"onPaymentUncertain\"],\n payment: Parameters<\n NonNullable<LockerversePaymentProps[\"onPaymentUncertain\"]>\n >[0]\n) {\n notifyHostCallback(callback, payment);\n}\n\nfunction createPaymentCompletion(\n payment: LockerversePaymentResult,\n context: Pick<LockerversePaymentCompletion, \"email\" | \"lineItems\">\n): LockerversePaymentCompletion {\n return { ...payment, ...context };\n}\n\nfunction unresolvedPaymentState(outcome: {\n reason: string;\n retryUrl?: string | undefined;\n}) {\n const action: PaymentFormAction = {\n message:\n outcome.reason === \"action_required\"\n ? \"Payment needs your attention. Keep this checkout open.\"\n : \"Payment is not complete. Check its status before you try again.\",\n type: \"unresolved\",\n };\n if (outcome.retryUrl) {\n action.retryUrl = outcome.retryUrl;\n }\n return action;\n}\n\nfunction mustWaitForStripe(\n outcome: PaymentAttemptOutcome,\n stripe: Stripe | null,\n stripeLoadFailed: boolean\n) {\n return (\n outcome.kind === \"unresolved\" &&\n outcome.reason === \"action_required\" &&\n !outcome.retryUrl &&\n !stripe &&\n !stripeLoadFailed\n );\n}\n\nfunction isSoldOutError<ErrorValue>(error: ErrorValue) {\n return (\n error instanceof LockerverseSdkError &&\n error.serverCode === \"PAYMENT_WIDGET_SALES_LIMIT_REACHED\"\n );\n}\n\nexport type PaymentFormControllerOptions = {\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 onResumePaymentFailed: () => void;\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n onStateChange: (state: PaymentUiState) => void;\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n stripe: Stripe | null;\n stripeConnectedAccountId: string | null;\n stripeLoadFailed: boolean;\n paymentState: PaymentFormState;\n updateState: (action: PaymentFormAction, notifyHost?: boolean) => void;\n};\n\ntype SubmitPayment = {\n addresses: CheckoutAddresses;\n phone: string;\n};\n\nfunction applyQuoteRefreshSuccess({\n nextQuote,\n onQuoteChange,\n setDisplayedTotalCents,\n setPromoError,\n updateState,\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 updateState: (action: PaymentFormAction) => void;\n validatePromo: boolean;\n}) {\n const result = getQuoteRefreshSuccess(nextQuote, validatePromo);\n updateState({ type: \"quote_refresh_succeeded\" });\n setDisplayedTotalCents(result.displayedTotalCents);\n onQuoteChange(nextQuote);\n if (validatePromo) {\n setPromoError(result.promoError);\n }\n}\n\nfunction applyQuoteRefreshFailure({\n error,\n setPromoError,\n updateState,\n validatePromo,\n}: {\n error: unknown;\n setPromoError: (error: string | undefined) => void;\n updateState: (action: PaymentFormAction) => void;\n validatePromo: boolean;\n}) {\n const result = getQuoteRefreshFailure(error, validatePromo);\n if (validatePromo) {\n setPromoError(result.promoError);\n }\n updateState(\n result.paymentError === undefined\n ? { type: \"quote_refresh_failed\" }\n : { error: result.paymentError, type: \"quote_refresh_failed\" }\n );\n}\n\nfunction applyPaymentOutcome({\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n result,\n setDisplayedTotalCents,\n dispatchState,\n unresolvedReferenceRef,\n}: {\n unresolvedReferenceRef: { current: string | undefined };\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 dispatchState: (action: PaymentFormAction) => 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 dispatchState({ type: \"quote_changed\" });\n return;\n }\n if (result.kind === \"payment_failed\") {\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n dispatchState({ error: result.message, type: \"retryable_failure\" });\n return;\n }\n if (result.kind === \"payment_unresolved\") {\n unresolvedReferenceRef.current = result.paymentReference;\n dispatchState(unresolvedPaymentState(result));\n notifyPaymentUncertain(onPaymentUncertain, {\n paymentReference: result.paymentReference,\n reason: result.reason,\n });\n return;\n }\n onQuoteChange(result.quote);\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n dispatchState({\n message: result.payment.paymentRequired\n ? \"Payment completed successfully.\"\n : \"Order confirmed. No payment was required.\",\n type: \"succeeded\",\n });\n notifyHostCallback(\n onPaymentComplete,\n createPaymentCompletion(result.payment, {\n email: result.email,\n lineItems: result.quote.lineItems,\n })\n );\n}\n\nexport function usePaymentFormController(\n options: PaymentFormControllerOptions\n) {\n const {\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n metadata,\n onPaymentComplete,\n onResumePaymentFailed,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onStateChange,\n quote,\n resumePayment,\n stripe,\n stripeConnectedAccountId,\n stripeLoadFailed,\n paymentState,\n updateState,\n } = options;\n const [displayedTotalCents, setDisplayedTotalCents] = useState(\n quote.totalCents\n );\n const [promoError, setPromoError] = useState<string>();\n const recoveryStartedRef = useRef(false);\n const unresolvedReferenceRef = useRef<string | undefined>(undefined);\n const quoteRequestRef = useRef(0);\n const attemptGenerationRef = useRef(0);\n const dispatchState = useCallback(\n (action: PaymentFormAction) => updateState(action, true),\n [updateState]\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 quoteRequestRef.current += 1;\n },\n []\n );\n\n const { parsedTip, totalCents: previewTotalCents } = getLocalQuotePreview(\n catalog,\n fieldValues,\n quote\n );\n\n useEffect(() => {\n if (previewTotalCents === null) {\n return;\n }\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 previewTotalCents,\n quote.serviceFeeCents,\n quote.tipCents,\n quote.totalCents,\n quote.subtotalCents,\n ]);\n\n useEffect(() => {\n const paymentReference =\n resumePayment?.paymentReference ?? unresolvedReferenceRef.current;\n if (\n !paymentReference ||\n recoveryStartedRef.current ||\n paymentState.status !== \"recovering\"\n ) {\n return;\n }\n recoveryStartedRef.current = true;\n const isAttemptActive = startPaymentAttempt();\n onStateChange(getPaymentUiState(paymentState));\n\n recoverPaymentAttempt(client, paymentReference, stripe).then((outcome) => {\n if (!isAttemptActive()) {\n return;\n }\n if (mustWaitForStripe(outcome, stripe, stripeLoadFailed)) {\n return;\n }\n if (outcome.kind === \"failed\") {\n const message =\n \"The previous payment failed. Check your details and try again.\";\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n onResumePaymentFailed();\n dispatchState({\n error: message,\n type: \"recovery_failed\",\n });\n return;\n }\n if (outcome.kind === \"unresolved\") {\n dispatchState(unresolvedPaymentState(outcome));\n notifyPaymentUncertain(onPaymentUncertain, {\n paymentReference: outcome.paymentReference,\n reason: outcome.reason,\n });\n return;\n }\n\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n dispatchState({\n message: outcome.payment.paymentRequired\n ? \"Payment completed successfully.\"\n : \"Order confirmed. No payment was required.\",\n type: \"succeeded\",\n });\n notifyHostCallback(\n onPaymentComplete,\n createPaymentCompletion(outcome.payment, {\n email: null,\n lineItems: null,\n })\n );\n });\n return () => {\n if (isAttemptActive()) {\n attemptGenerationRef.current += 1;\n }\n recoveryStartedRef.current = false;\n };\n }, [\n client,\n onPaymentComplete,\n onResumePaymentFailed,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onStateChange,\n resumePayment,\n stripe,\n stripeLoadFailed,\n startPaymentAttempt,\n dispatchState,\n paymentState,\n ]);\n\n const fieldChanged = useCallback(\n (clearPromo = false, preserveQuoteRequest = false) => {\n if (!preserveQuoteRequest) {\n quoteRequestRef.current += 1;\n }\n if (clearPromo) {\n setPromoError(undefined);\n }\n updateState({ type: \"field_changed\" });\n },\n [updateState]\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 updateState({ type: \"quote_refresh_started\" });\n try {\n const nextQuote = await client.calculateTotal({\n ...buildQuoteRequest(\n catalog,\n fieldValues,\n emailValidation.value?.email ?? \"\",\n parsedTip.cents\n ),\n catalog,\n items: checkoutItems,\n });\n if (requestId !== quoteRequestRef.current) {\n return;\n }\n applyQuoteRefreshSuccess({\n nextQuote,\n onQuoteChange,\n setDisplayedTotalCents,\n setPromoError,\n updateState,\n validatePromo,\n });\n } catch (error) {\n if (requestId !== quoteRequestRef.current) {\n return;\n }\n if (isSoldOutError(error)) {\n updateState({ type: \"sold_out\" });\n return;\n }\n applyQuoteRefreshFailure({\n error,\n setPromoError,\n updateState,\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 dispatchState({ 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 stripeConnectedAccountId,\n });\n if (!isAttemptActive()) {\n return;\n }\n applyPaymentOutcome({\n dispatchState,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n result,\n setDisplayedTotalCents,\n unresolvedReferenceRef,\n });\n } catch (error) {\n if (!isAttemptActive()) {\n return;\n }\n notifyPaymentRecovery(onPaymentRecoveryChange, null);\n if (isSoldOutError(error)) {\n dispatchState({ type: \"sold_out\" });\n return;\n }\n const phoneError =\n error instanceof LockerverseSdkError\n ? getPhoneServerError(error.serverCode)\n : undefined;\n if (phoneError) {\n dispatchState({ type: \"submission_validation_failed\" });\n return { phoneError };\n }\n dispatchState({\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 paymentState.status === \"succeeded\" || paymentState.status === \"unresolved\"\n ? paymentState.message\n : undefined;\n return {\n commands: {\n applyPromo,\n checkPaymentStatus: () => dispatchState({ type: \"recovery_started\" }),\n fieldChanged,\n refreshAuthoritativeTotal,\n reportValidationFailure: () =>\n dispatchState({ type: \"validation_failed\" }),\n submit,\n },\n state: {\n displayedTotalCents,\n isRecovering: paymentState.status === \"recovering\",\n isRefreshingQuote: paymentState.status === \"refreshing_quote\",\n isSubmitting: isPaymentBusy(paymentState),\n isUnresolved: paymentState.status === \"unresolved\",\n parsedTip,\n paymentError: getPaymentError(paymentState),\n promoError,\n retryUrl: paymentState.retryUrl,\n terminalMessage,\n },\n };\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\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 {\n type RefObject,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n AdditionalCheckoutFields,\n type CheckoutFieldValues,\n CheckoutToggle,\n ServiceFeeField,\n TipField,\n} from \"./checkout-fields.tsx\";\nimport {\n createCustomFieldValues,\n getCheckoutCustomFields,\n validateCustomFields,\n} from \"./custom-fields.tsx\";\nimport { EmailField, FormField } from \"./form-field.tsx\";\nimport { FormSkeleton } from \"./form-skeleton.tsx\";\nimport { formatMoney } from \"./format-money.ts\";\nimport {\n createPaymentFormState,\n getPaymentUiState,\n type PaymentFormAction,\n type PaymentFormState,\n type PaymentUiState,\n paymentFormReducer,\n} from \"./payment-form-state.ts\";\nimport type { CheckoutAddresses } from \"./payment-submission.ts\";\nimport { PaymentSummary } from \"./payment-summary.tsx\";\nimport { validateContact } from \"./payment-validation.ts\";\nimport { getInternationalPhone } from \"./phone.ts\";\nimport type { PhoneInputValue } from \"./phone-field.tsx\";\nimport { PhoneInput } from \"./phone-field.tsx\";\nimport { useStripeAppearance } from \"./stripe-appearance.ts\";\nimport { defaultLockerverseStripeLoader as cachedStripeLoader } from \"./stripe-loader.ts\";\nimport type { LockerversePaymentProps } from \"./types.ts\";\nimport { usePaymentFormController } from \"./use-payment-form-controller.ts\";\n\nexport const defaultLockerverseStripeLoader = cachedStripeLoader;\n\nexport function preloadLockerversePayment(\n catalog: Pick<LockerverseCatalog, \"payment\">\n) {\n const { connectedAccountId, publishableKey } = catalog.payment;\n return defaultLockerverseStripeLoader(\n publishableKey,\n connectedAccountId ? { stripeAccount: connectedAccountId } : undefined\n );\n}\n\nfunction getRecurringCadence(\n paymentOption: LockerversePreparedCheckout[\"paymentOption\"]\n) {\n if (paymentOption === \"monthly\") {\n return { interval: \"month\", label: \"Monthly\" } as const;\n }\n if (paymentOption === \"annually\") {\n return { interval: \"year\", label: \"Annual\" } as const;\n }\n if (paymentOption === \"every-six-months\") {\n return { interval: \"6 months\", label: \"Every 6 months\" } as const;\n }\n return null;\n}\n\nfunction getConnectedAccountId(\n catalog: LockerverseCatalog,\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout,\n resumePayment: LockerversePaymentProps[\"resumePayment\"]\n) {\n if (resumePayment) {\n const { connectedAccountId } = resumePayment;\n return connectedAccountId;\n }\n if (\"payment\" in quote) {\n const { connectedAccountId } = quote.payment;\n return connectedAccountId;\n }\n const { connectedAccountId } = catalog.payment;\n return connectedAccountId;\n}\n\nexport function ReadyPayment({\n accentColor,\n catalog,\n checkoutItems,\n client,\n appearanceRoot,\n initialCustomFieldValues,\n metadata,\n onPaymentComplete,\n onResumePaymentFailed,\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 appearanceRoot: RefObject<HTMLElement | null>;\n initialCustomFieldValues: LockerversePaymentProps[\"initialCustomFieldValues\"];\n metadata: Record<string, string> | undefined;\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onResumePaymentFailed: () => void;\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n onStateChange: (state: PaymentUiState) => void;\n stripeLoader: NonNullable<LockerversePaymentProps[\"stripeLoader\"]>;\n theme: LockerversePaymentProps[\"theme\"];\n visualStyle: LockerversePaymentProps[\"style\"];\n}) {\n const [paymentState, setPaymentState] = useState(() =>\n createPaymentFormState(Boolean(resumePayment))\n );\n const paymentStateRef = useRef(paymentState);\n paymentStateRef.current = paymentState;\n const updateState = useCallback(\n (action: PaymentFormAction, notifyHost = false) => {\n const next = paymentFormReducer(paymentStateRef.current, action);\n if (next === paymentStateRef.current) {\n return;\n }\n paymentStateRef.current = next;\n setPaymentState(next);\n if (notifyHost) {\n onStateChange(getPaymentUiState(next));\n }\n },\n [onStateChange]\n );\n const requestedConnectedAccountId = getConnectedAccountId(\n catalog,\n quote,\n resumePayment\n );\n const stripeConfigurationRef = useRef({\n connectedAccountId: requestedConnectedAccountId,\n paymentOption: quote.paymentOption,\n });\n if (\n paymentState.status !== \"submitting\" &&\n paymentState.status !== \"recovering\"\n ) {\n stripeConfigurationRef.current = {\n connectedAccountId: requestedConnectedAccountId,\n paymentOption: quote.paymentOption,\n };\n }\n const { connectedAccountId, paymentOption } = stripeConfigurationRef.current;\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 const [stripeLoadFailed, setStripeLoadFailed] = useState(false);\n useEffect(() => {\n let active = true;\n setStripeLoadFailed(false);\n stripe.then((loadedStripe) => {\n if (active && loadedStripe === null) {\n setStripeLoadFailed(true);\n }\n });\n return () => {\n active = false;\n };\n }, [stripe]);\n\n const appearance = useStripeAppearance(\n appearanceRoot,\n theme,\n visualStyle,\n paymentState.status === \"submitting\" ||\n paymentState.status === \"recovering\",\n accentColor\n );\n if (!appearance) {\n return <FormSkeleton fieldCount={3} label=\"Loading payment form\" />;\n }\n\n return (\n <Elements\n key={`${catalog.payment.publishableKey}:${connectedAccountId ?? \"platform\"}:${paymentOption}`}\n options={{\n amount: Math.max(quote.totalCents, 100),\n appearance,\n currency: catalog.payment.currency,\n mode: paymentOption === \"one-time\" ? \"payment\" : \"subscription\",\n paymentMethodTypes: catalog.community?.widgetAchEnabled\n ? [\"card\", \"link\", \"us_bank_account\"]\n : [\"card\", \"link\"],\n syncAddressCheckbox: \"none\",\n }}\n stripe={stripe}\n >\n <PaymentForm\n catalog={catalog}\n checkoutItems={checkoutItems}\n client={client}\n initialCustomFieldValues={initialCustomFieldValues}\n metadata={metadata}\n onPaymentComplete={onPaymentComplete}\n onPaymentRecoveryChange={onPaymentRecoveryChange}\n onPaymentUncertain={onPaymentUncertain}\n onQuoteChange={onQuoteChange}\n onResumePaymentFailed={onResumePaymentFailed}\n onStateChange={onStateChange}\n paymentState={paymentState}\n quote={quote}\n resumePayment={resumePayment}\n stripeConnectedAccountId={connectedAccountId}\n stripeLoadFailed={stripeLoadFailed}\n updateState={updateState}\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: \"auto\",\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 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: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n}) {\n const isFree = displayedTotalCents === 0;\n const isReady = isFree\n ? !catalog.widget.fields.shipping ||\n (isBillingAddressReady && isRequiredShippingReady)\n : isPaymentReady && isBillingAddressReady && isRequiredShippingReady;\n const cadence = getRecurringCadence(quote.paymentOption);\n let label = isFree\n ? \"Complete order\"\n : `Pay ${formatMoney(displayedTotalCents)}`;\n if (!isFree && cadence) {\n label = `Subscribe for ${formatMoney(displayedTotalCents)}/${cadence.interval}`;\n }\n if (isSubmitting) {\n label = isFree ? \"Completing…\" : \"Processing…\";\n }\n let actionLabel = `Process payment for ${formatMoney(displayedTotalCents)} total`;\n if (isFree) {\n actionLabel = \"Complete order\";\n } else if (cadence) {\n actionLabel = `Start ${cadence.label.toLowerCase()} subscription for ${formatMoney(displayedTotalCents)}`;\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={actionLabel}\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 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: PhoneInputValue) => 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 <EmailField\n error={errors.email}\n errorId={emailErrorId}\n id={emailId}\n label=\"Email\"\n name=\"email\"\n onBlur={onEmailBlur}\n onChange={(event) => onEmailChange(event.currentTarget.value)}\n ref={emailRef}\n required\n value={email}\n />\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 <FormField\n error={errors.phone}\n errorId={phoneErrorId}\n id={phoneId}\n label=\"Phone\"\n >\n <PhoneInput\n country={phoneCountry}\n error={errors.phone}\n errorId={phoneErrorId}\n id={phoneId}\n inputRef={phoneRef}\n name=\"phone\"\n onChange={onPhoneChange}\n required\n value={phone}\n />\n </FormField>\n ) : null}\n </div>\n );\n}\n\nfunction StripeLoadingNotice({ message }: { message: string | undefined }) {\n if (!message) {\n return null;\n }\n return (\n <div className=\"lockerverse-payment__actions\">\n <p className=\"lockerverse-payment__field-message\" role=\"alert\">\n {message}\n </p>\n <button\n className=\"lockerverse-payment__status-check\"\n onClick={() => window.location.reload()}\n type=\"button\"\n >\n Reload checkout\n </button>\n </div>\n );\n}\n\nfunction useStripeLoadingMessage({\n paymentRequired,\n shippingRequired,\n isPaymentReady,\n isBillingAddressReady,\n isRequiredShippingReady,\n isSubmitting,\n scriptFailed,\n elementError,\n clearElementError,\n}: {\n paymentRequired: boolean;\n shippingRequired: boolean;\n isPaymentReady: boolean;\n isBillingAddressReady: boolean;\n isRequiredShippingReady: boolean;\n isSubmitting: boolean;\n scriptFailed: boolean;\n elementError: string | undefined;\n clearElementError: (error: undefined) => void;\n}) {\n const [delayed, setDelayed] = useState(false);\n const needed = paymentRequired || shippingRequired;\n const ready =\n (!paymentRequired || isPaymentReady) &&\n (!needed || isBillingAddressReady) &&\n isRequiredShippingReady;\n useEffect(() => {\n setDelayed(false);\n if (ready) {\n clearElementError(undefined);\n }\n if (!needed || ready || isSubmitting) {\n return;\n }\n const timeout = window.setTimeout(() => setDelayed(true), 30_000);\n return () => window.clearTimeout(timeout);\n }, [needed, ready, isSubmitting, clearElementError]);\n if (!needed || ready || isSubmitting) {\n return;\n }\n if (scriptFailed || elementError) {\n return \"The secure checkout fields could not load. Check your connection, then reload the checkout.\";\n }\n if (delayed) {\n return \"The secure checkout fields are taking longer than expected. You can wait or reload the checkout.\";\n }\n}\n\nfunction PaymentForm({\n catalog,\n checkoutItems,\n client,\n initialCustomFieldValues,\n metadata,\n onPaymentComplete,\n onResumePaymentFailed,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onStateChange,\n quote,\n resumePayment,\n stripeConnectedAccountId,\n stripeLoadFailed,\n paymentState,\n updateState,\n}: {\n catalog: LockerverseCatalog;\n checkoutItems: LockerverseCheckoutItem[];\n client: LockerverseCheckoutClient;\n initialCustomFieldValues: LockerversePaymentProps[\"initialCustomFieldValues\"];\n metadata: Record<string, string> | undefined;\n onPaymentComplete: LockerversePaymentProps[\"onPaymentComplete\"];\n onResumePaymentFailed: () => void;\n onPaymentRecoveryChange: LockerversePaymentProps[\"onPaymentRecoveryChange\"];\n onPaymentUncertain: LockerversePaymentProps[\"onPaymentUncertain\"];\n onQuoteChange: (quote: LockerversePreparedCheckout, notice?: string) => void;\n onStateChange: (state: PaymentUiState) => void;\n quote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n resumePayment: LockerversePaymentProps[\"resumePayment\"];\n stripeConnectedAccountId: string | null;\n stripeLoadFailed: boolean;\n paymentState: PaymentFormState;\n updateState: (action: PaymentFormAction, notifyHost?: boolean) => void;\n}) {\n const customFields = getCheckoutCustomFields(catalog, checkoutItems);\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 [stripeElementError, setStripeElementError] = 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(\n customFields,\n initialCustomFieldValues\n ),\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 controller = usePaymentFormController({\n catalog,\n checkoutItems,\n client,\n elements,\n email,\n fieldValues,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n onQuoteChange,\n onResumePaymentFailed,\n onStateChange,\n paymentState,\n quote,\n resumePayment,\n stripe,\n stripeConnectedAccountId,\n stripeLoadFailed,\n updateState,\n });\n const {\n displayedTotalCents,\n isRecovering,\n isUnresolved,\n isRefreshingQuote,\n isSubmitting,\n parsedTip,\n paymentError,\n promoError,\n terminalMessage,\n retryUrl,\n } = controller.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 const stripeLoadingMessage = useStripeLoadingMessage({\n clearElementError: setStripeElementError,\n elementError: stripeElementError,\n isBillingAddressReady,\n isPaymentReady,\n isRequiredShippingReady,\n isSubmitting,\n paymentRequired: displayedTotalCents > 0,\n scriptFailed: stripeLoadFailed,\n shippingRequired: catalog.widget.fields.shipping,\n });\n\n useEffect(() => {\n if (isSubmitting) {\n statusRef.current?.focus({ preventScroll: true });\n }\n }, [isSubmitting]);\n\n useEffect(() => {\n if (!(isSubmitting || errors.email || !errors.phone)) {\n phoneRef.current?.focus();\n }\n }, [errors.email, errors.phone, 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 controller.commands.fieldChanged(false, field !== \"email\");\n setErrors((current) => {\n const next = { ...current };\n delete next[field];\n return next;\n });\n }\n\n function handleFieldValuesChange(nextValues: CheckoutFieldValues) {\n const promoChanged = nextValues.promoCode !== fieldValues.promoCode;\n const serviceFeeChanged =\n nextValues.includeServiceFee !== fieldValues.includeServiceFee;\n controller.commands.fieldChanged(\n promoChanged,\n !(promoChanged || serviceFeeChanged)\n );\n setFieldValues(nextValues);\n setCustomFieldErrors({});\n setTipError(undefined);\n }\n\n async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {\n event.preventDefault();\n const internationalPhone = catalog.widget.fields.phone\n ? getInternationalPhone(phone, phoneCountry)\n : \"\";\n const validation = validateContact(\n { email, phone: internationalPhone },\n catalog.widget.fields.phone\n );\n const nextCustomFieldErrors = validateCustomFields(\n 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 controller.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 const result = await controller.commands.submit({\n addresses: addressesRef.current,\n phone: internationalPhone,\n });\n if (result?.phoneError) {\n setErrors({ phone: result.phoneError });\n }\n }\n\n if (terminalMessage || isRecovering) {\n return (\n <div className=\"lockerverse-payment__actions\">\n <p\n className=\"lockerverse-payment__payment-status\"\n ref={statusRef}\n role=\"status\"\n tabIndex={-1}\n >\n {isRecovering ? \"Recovering payment…\" : terminalMessage}\n {retryUrl ? (\n <>\n {\" \"}\n <a href={retryUrl} rel=\"noopener noreferrer\" target=\"_blank\">\n Complete payment\n </a>\n </>\n ) : null}\n </p>\n {isUnresolved || isRecovering ? (\n <button\n aria-busy={isRecovering}\n className=\"lockerverse-payment__status-check\"\n disabled={isRecovering}\n onClick={controller.commands.checkPaymentStatus}\n type=\"button\"\n >\n {isRecovering ? \"Checking payment status…\" : \"Check payment status\"}\n </button>\n ) : null}\n </div>\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={() => controller.commands.refreshAuthoritativeTotal()}\n onEmailChange={(value) => {\n setEmail(value);\n clearError(\"email\");\n }}\n onPhoneChange={({ value, country }) => {\n setPhone(value);\n setPhoneCountry(country);\n clearError(\"phone\");\n }}\n phone={phone}\n phoneCountry={phoneCountry}\n phoneEnabled={catalog.widget.fields.phone}\n phoneErrorId={phoneErrorId}\n phoneId={phoneId}\n phoneRef={phoneRef}\n />\n <StripeLoadingNotice message={stripeLoadingMessage} />\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={setStripeElementError}\n setIsBillingAddressReady={setIsBillingAddressReady}\n setIsPaymentReady={setIsPaymentReady}\n setIsShippingAddressReady={setIsShippingAddressReady}\n />\n <AdditionalCheckoutFields\n customFields={customFields}\n errors={customFieldErrors}\n fields={catalog.widget.fields}\n idPrefix={idPrefix}\n isPromoApplying={isRefreshingQuote}\n memberIdLabel={catalog.community?.memberIdLabel}\n onApplyPromo={controller.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\nexport function PaymentSkeleton() {\n return (\n <FormSkeleton\n fieldCount={2}\n label=\"Loading payment…\"\n sectionCount={2}\n showCheckbox\n />\n );\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerverseCheckoutEstimate,\n LockerverseCheckoutItem,\n LockerversePreparedCheckout,\n} from \"@lockerverse/sdk/checkout\";\nimport { estimateLockerverseCheckout } from \"@lockerverse/sdk/checkout\";\nimport { useEffect, useMemo, useReducer, useRef } from \"react\";\nimport type { PaymentUiState } from \"./payment-form-state.ts\";\nimport { parsePaymentSelection } from \"./payment-input.ts\";\nimport type {\n LockerversePaymentProps,\n LockerversePaymentSelectionItem,\n} from \"./types.ts\";\n\ntype SessionState =\n | {\n phase: \"loading\";\n revision: number;\n }\n | {\n failure: string;\n phase: \"error\";\n revision: number;\n }\n | {\n checkoutItems: LockerverseCheckoutItem[];\n displayedQuote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n phase: \"ready\";\n quoteFailure: string | undefined;\n revision: number;\n };\n\ntype SessionAction =\n | {\n type: \"loading\";\n }\n | {\n displayedQuote: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n type: \"ready\";\n }\n | {\n failure: string;\n type: \"error\";\n }\n | { checkout: LockerversePreparedCheckout; type: \"checkout\" }\n | { failure: string; type: \"quote-error\" };\n\nfunction sessionReducer(\n state: SessionState,\n action: SessionAction\n): SessionState {\n switch (action.type) {\n case \"loading\":\n return {\n phase: \"loading\",\n revision: state.revision,\n };\n case \"ready\":\n return createReadySession(action.displayedQuote, state.revision + 1);\n case \"error\":\n return {\n failure: action.failure,\n phase: \"error\",\n revision: state.revision,\n };\n case \"checkout\":\n return state.phase === \"ready\"\n ? {\n ...state,\n displayedQuote: action.checkout,\n quoteFailure: undefined,\n }\n : state;\n case \"quote-error\":\n return state.phase === \"ready\"\n ? {\n ...state,\n quoteFailure: action.failure,\n }\n : state;\n default:\n return state;\n }\n}\n\ntype LoadIdentity = {\n catalog: LockerverseCatalog;\n selectionKey: string;\n};\n\nfunction isSameLoad(\n identity: LoadIdentity | undefined,\n catalog: LockerverseCatalog,\n selectionKey: string\n) {\n return (\n identity?.catalog === catalog && identity.selectionKey === selectionKey\n );\n}\n\nfunction createReadyAction({\n checkout,\n}: {\n checkout: LockerverseCheckoutEstimate | LockerversePreparedCheckout;\n}): Extract<SessionAction, { type: \"ready\" }> {\n return {\n displayedQuote: checkout,\n type: \"ready\",\n };\n}\n\nfunction getLoadFailure<ErrorValue>(error: ErrorValue) {\n return error instanceof Error\n ? error.message\n : \"Lockerverse payment could not load.\";\n}\n\nfunction createReadySession(\n checkout: LockerverseCheckoutEstimate | LockerversePreparedCheckout,\n revision: number\n): SessionState {\n return {\n checkoutItems: [...checkout.items],\n displayedQuote: checkout,\n phase: \"ready\",\n quoteFailure: undefined,\n revision,\n };\n}\n\nfunction estimateCheckout(\n catalog: LockerverseCatalog,\n selection: LockerversePaymentSelectionItem[]\n) {\n const includeServiceFee = catalog.widget.fields.serviceFee;\n return estimateLockerverseCheckout(catalog, {\n includeServiceFee,\n selection,\n });\n}\n\nfunction createInitialSession(\n catalog: LockerverseCatalog,\n selection: LockerversePaymentSelectionItem[]\n): SessionState {\n try {\n return createReadySession(estimateCheckout(catalog, selection), 1);\n } catch (error) {\n return {\n failure: getLoadFailure(error),\n phase: \"error\",\n revision: 0,\n };\n }\n}\n\nexport function usePaymentCheckout({\n catalog,\n client,\n paymentState,\n selection,\n}: {\n catalog: LockerverseCatalog;\n client: LockerverseCheckoutClient;\n paymentState: PaymentUiState;\n selection: LockerversePaymentProps[\"selection\"];\n}) {\n const parsedSelection = parsePaymentSelection(selection);\n const selectionKey = parsedSelection.success\n ? JSON.stringify(parsedSelection.value)\n : \"invalid-selection\";\n const stableSelection = useMemo(\n () => (parsedSelection.success ? parsedSelection.value : []),\n [parsedSelection.success, selectionKey]\n );\n const [session, dispatch] = useReducer(\n sessionReducer,\n undefined,\n (): SessionState =>\n parsedSelection.success\n ? createInitialSession(catalog, stableSelection)\n : { phase: \"loading\", revision: 0 }\n );\n const loadingRef = useRef<LoadIdentity | undefined>(undefined);\n const quoteRevisionRef = useRef(0);\n const estimatedRef = useRef<LoadIdentity | undefined>(\n session.phase === \"ready\" ? { catalog, selectionKey } : undefined\n );\n const settledRef = useRef<LoadIdentity | undefined>(\n session.phase === \"error\" ? { catalog, selectionKey } : undefined\n );\n const sessionIsLocked =\n paymentState === \"submitting\" ||\n paymentState === \"success\" ||\n paymentState === \"unresolved\";\n useEffect(() => {\n if (!parsedSelection.success) {\n return;\n }\n if (\n sessionIsLocked ||\n isSameLoad(settledRef.current, catalog, selectionKey) ||\n isSameLoad(loadingRef.current, catalog, selectionKey)\n ) {\n return;\n }\n\n let active = true;\n loadingRef.current = { catalog, selectionKey };\n let estimateIsReady = isSameLoad(\n estimatedRef.current,\n catalog,\n selectionKey\n );\n if (!estimateIsReady) {\n dispatch({ type: \"loading\" });\n }\n\n function dispatchWhenActive(action: SessionAction) {\n if (active) {\n dispatch(action);\n }\n }\n\n function settleWhenActive() {\n if (active) {\n loadingRef.current = undefined;\n settledRef.current = { catalog, selectionKey };\n }\n }\n\n let initialQuoteRevision: number | undefined;\n\n function failWhenActive<ErrorValue>(error: ErrorValue) {\n if (!active) {\n return;\n }\n loadingRef.current = undefined;\n settledRef.current = { catalog, selectionKey };\n if (\n estimateIsReady &&\n initialQuoteRevision !== undefined &&\n quoteRevisionRef.current !== initialQuoteRevision\n ) {\n return;\n }\n const failure = getLoadFailure(error);\n if (failure === \"This option is sold out.\") {\n dispatch({ failure, type: \"error\" });\n return;\n }\n if (estimateIsReady) {\n dispatch({ failure, type: \"quote-error\" });\n } else {\n dispatch({\n failure,\n type: \"error\",\n });\n }\n }\n\n async function loadPayment() {\n try {\n initialQuoteRevision = quoteRevisionRef.current;\n const includeServiceFee = catalog.widget.fields.serviceFee;\n if (!estimateIsReady) {\n const estimate = estimateCheckout(catalog, stableSelection);\n estimateIsReady = true;\n estimatedRef.current = { catalog, selectionKey };\n dispatchWhenActive(createReadyAction({ checkout: estimate }));\n }\n const preparedCheckout = await client.calculateTotal({\n catalog,\n includeServiceFee,\n selection: stableSelection,\n });\n settleWhenActive();\n if (quoteRevisionRef.current === initialQuoteRevision) {\n dispatchWhenActive({\n checkout: preparedCheckout,\n type: \"checkout\",\n });\n }\n } catch (error) {\n failWhenActive(error);\n }\n }\n\n loadPayment();\n return () => {\n active = false;\n if (isSameLoad(loadingRef.current, catalog, selectionKey)) {\n loadingRef.current = undefined;\n }\n };\n }, [\n catalog,\n client,\n parsedSelection.success,\n sessionIsLocked,\n selectionKey,\n stableSelection,\n ]);\n\n const loadIsCurrent =\n isSameLoad(estimatedRef.current, catalog, selectionKey) ||\n isSameLoad(settledRef.current, catalog, selectionKey) ||\n isSameLoad(loadingRef.current, catalog, selectionKey);\n const currentSession =\n sessionIsLocked || loadIsCurrent\n ? session\n : ({ phase: \"loading\", revision: session.revision } as const);\n\n return {\n selectionError: parsedSelection.success\n ? undefined\n : parsedSelection.message,\n session: currentSession,\n updateCheckout: (checkout: LockerversePreparedCheckout) => {\n quoteRevisionRef.current += 1;\n dispatch({ checkout, type: \"checkout\" });\n },\n };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n literal,\n nonEmpty,\n nullable,\n object,\n optional,\n pipe,\n safeParse,\n string,\n trim,\n union,\n} from \"valibot\";\nimport { parsePaymentSelection } from \"./payment-input.ts\";\nimport type {\n LockerversePaymentRecovery,\n LockerversePaymentSelectionItem,\n} from \"./types.ts\";\n\nconst storedRecoverySchema = object({\n recovery: object({\n connectedAccountId: nullable(string()),\n paymentReference: pipe(string(), trim(), nonEmpty()),\n }),\n selectionFingerprint: string(),\n version: union([literal(1), literal(2)]),\n widgetId: optional(string()),\n});\n\nfunction selectionFingerprint(selection: LockerversePaymentSelectionItem[]) {\n const parsed = parsePaymentSelection(selection);\n if (!parsed.success) {\n return null;\n }\n return JSON.stringify(\n parsed.value.map((item) => {\n const slug = item.productSlug.trim();\n if (\"quantity\" in item) {\n return [\"quantity\", slug, item.quantity];\n }\n if (\"amountCents\" in item) {\n return [\"amount\", slug, item.amountCents];\n }\n return [\"product\", slug];\n })\n );\n}\n\nconst mismatchedPaymentMessage =\n \"A previous payment uses different checkout details. Return to its original checkout to check the payment before you pay again.\";\n\ntype RecoveryState = {\n error?: string;\n identity: string;\n recovery: LockerversePaymentRecovery | null;\n};\n\nfunction readRecovery(\n key: string,\n fingerprint: string,\n widgetId: string\n): Omit<RecoveryState, \"identity\"> {\n let saved: string | null;\n try {\n saved = window.sessionStorage.getItem(key);\n } catch {\n // Storage can be blocked. In-page recovery still stays with the form.\n return { recovery: null };\n }\n if (!saved) {\n return { recovery: null };\n }\n try {\n const parsed = safeParse(storedRecoverySchema, JSON.parse(saved));\n if (!parsed.success) {\n throw new Error(\"Invalid recovery record\");\n }\n const value = parsed.output;\n if (\n value.selectionFingerprint !== fingerprint ||\n (value.version === 2 && value.widgetId !== widgetId)\n ) {\n return {\n error: mismatchedPaymentMessage,\n recovery: null,\n };\n }\n return {\n recovery: {\n connectedAccountId: value.recovery.connectedAccountId,\n paymentReference: value.recovery.paymentReference,\n },\n };\n } catch {\n // An unreadable record is not proof that the previous payment failed.\n return {\n error:\n \"The saved payment could not be read. Contact support to check it before you pay again.\",\n recovery: null,\n };\n }\n}\n\n/** Read browser state after hydration, before mounting a payable form. */\nexport function usePaymentRecoveryStorage({\n selection,\n storageKey,\n widgetId,\n}: {\n selection: LockerversePaymentSelectionItem[];\n storageKey: string | undefined;\n widgetId: string;\n}) {\n const fingerprint = selectionFingerprint(selection);\n const identity = JSON.stringify([storageKey, fingerprint, widgetId]);\n const [state, setState] = useState<RecoveryState | null>(null);\n const pendingRef = useRef<RecoveryState | null>(null);\n useEffect(() => {\n if (!storageKey) {\n return;\n }\n const pending = pendingRef.current;\n let restored: Omit<RecoveryState, \"identity\"> = { recovery: null };\n if (pending?.recovery) {\n restored =\n pending.identity === identity\n ? { recovery: pending.recovery }\n : { error: mismatchedPaymentMessage, recovery: null };\n } else if (fingerprint !== null) {\n restored = readRecovery(storageKey, fingerprint, widgetId);\n }\n if (restored.recovery) {\n pendingRef.current = { identity, recovery: restored.recovery };\n }\n setState({ identity, ...restored });\n }, [fingerprint, identity, storageKey, widgetId]);\n\n const remember = useCallback(\n (recovery: LockerversePaymentRecovery | null) => {\n if (!storageKey || fingerprint === null) {\n return;\n }\n pendingRef.current = recovery ? { identity, recovery } : null;\n try {\n if (recovery) {\n window.sessionStorage.setItem(\n storageKey,\n JSON.stringify({\n recovery,\n selectionFingerprint: fingerprint,\n version: 2,\n widgetId,\n })\n );\n } else {\n window.sessionStorage.removeItem(storageKey);\n }\n } catch {\n // Keep recovery in the mounted form if browser storage is unavailable.\n }\n },\n [fingerprint, identity, storageKey, widgetId]\n );\n return {\n error: storageKey && state?.identity === identity ? state.error : undefined,\n ready: !storageKey || state?.identity === identity,\n recovery:\n storageKey && state?.identity === identity ? state.recovery : null,\n remember,\n };\n}\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutClient,\n LockerversePaymentCompletion,\n} from \"@lockerverse/sdk/checkout\";\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport { getAccentContrast, normalizeAccentColor } from \"./accent-contrast.ts\";\nimport { formatMoney } from \"./format-money.ts\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport {\n defaultLockerverseStripeLoader,\n PaymentSkeleton,\n ReadyPayment,\n} from \"./payment-form.tsx\";\nimport type { PaymentUiState } from \"./payment-form-state.ts\";\nimport type {\n LockerversePaymentProps,\n LockerversePaymentRecovery,\n} from \"./types.ts\";\nimport { usePaymentCheckout } from \"./use-payment-checkout.ts\";\nimport { usePaymentRecoveryStorage } from \"./use-payment-recovery-storage.ts\";\n\ntype PaymentViewProps = Omit<LockerversePaymentProps, \"widget\">;\nconst paymentCadence = {\n annually: \"/year\",\n \"every-six-months\": \" every 6 months\",\n monthly: \"/month\",\n \"one-time\": \"\",\n};\n\nfunction PaymentCatalogHeader({\n branding,\n catalog,\n}: {\n branding: LockerversePaymentProps[\"branding\"] | null;\n catalog: LockerverseCatalog;\n}) {\n return (\n <header>\n {catalog.widget.showCommunityBranding && branding ? (\n <div className=\"lockerverse-payment__branding\">\n {branding.imageUrl ? (\n <img\n alt={branding.name}\n height=\"48\"\n src={branding.imageUrl}\n width=\"48\"\n />\n ) : null}\n <strong>{branding.name}</strong>\n </div>\n ) : null}\n <h1>{catalog.widget.title ?? catalog.widget.name}</h1>\n {catalog.widget.description ? <p>{catalog.widget.description}</p> : null}\n </header>\n );\n}\n\nfunction PaymentCatalogSummary({\n catalog,\n selection,\n}: {\n catalog: LockerverseCatalog;\n selection: LockerversePaymentProps[\"selection\"];\n}) {\n const products = selection?.length\n ? catalog.products.filter((product) =>\n selection.some((item) => item.productSlug === product.slug)\n )\n : catalog.products;\n if (products.length === 0) {\n return null;\n }\n return (\n <div className=\"lockerverse-payment__payment-summary\">\n <h2>Products</h2>\n <div className=\"lockerverse-payment__payment-summary-items\">\n {products.map((product) => {\n const amount =\n product.pricingMode === \"fixed\"\n ? product.amountCents\n : product.minimumAmountCents;\n const cadence = paymentCadence[product.paymentOption];\n return (\n <div\n className=\"lockerverse-payment__payment-summary-row\"\n key={product.id}\n >\n <span>{product.name}</span>\n <strong>\n {amount === null\n ? \"Choose amount\"\n : `${product.pricingMode === \"custom\" ? \"From \" : \"\"}${formatMoney(amount)}${cadence}`}\n </strong>\n </div>\n );\n })}\n </div>\n <p>Base prices. Final total is checked at checkout.</p>\n </div>\n );\n}\n\nfunction getPaymentAppearance(\n style: LockerversePaymentProps[\"style\"],\n branding: LockerversePaymentProps[\"branding\"] | null\n) {\n const accent = normalizeAccentColor(\n style?.[\"--lockerverse-accent\"] ?? branding?.accentColor ?? \"#38d77a\"\n );\n const accentContrast = getAccentContrast(accent);\n const rootStyle: LockerversePaymentProps[\"style\"] = { ...style };\n if (style?.[\"--lockerverse-accent\"] !== undefined || branding?.accentColor) {\n rootStyle[\"--lockerverse-accent\"] = accent;\n }\n if (\n accentContrast &&\n style?.[\"--lockerverse-accent-contrast\"] === undefined\n ) {\n rootStyle[\"--lockerverse-accent-contrast\"] = accentContrast;\n }\n return { accent, rootStyle };\n}\n\nfunction LoadedPayment({\n catalog,\n client,\n loadError,\n onRetry,\n ...viewProps\n}: PaymentViewProps & {\n catalog: LockerverseCatalog;\n client: LockerverseCheckoutClient;\n loadError?: Error | null;\n onRetry?: () => void;\n}) {\n const {\n branding,\n className,\n completionView,\n recoveryStorageKey: _recoveryStorageKey,\n initialCustomFieldValues,\n metadata,\n onPaymentComplete,\n onPaymentRecoveryChange,\n onPaymentUncertain,\n resumePayment,\n selection,\n style,\n stripeLoader = defaultLockerverseStripeLoader,\n theme = \"dark\",\n ...sectionProps\n } = viewProps;\n const [activeResumePayment, setActiveResumePayment] = useState(resumePayment);\n const appearanceRootRef = useRef<HTMLElement | null>(null);\n const [completion, setCompletion] =\n useState<LockerversePaymentCompletion | null>(null);\n const handlePaymentComplete = useCallback(\n (payment: LockerversePaymentCompletion) => {\n setCompletion(payment);\n notifyHostCallback(onPaymentComplete, payment);\n },\n [onPaymentComplete]\n );\n const [notice, setNotice] = useState<string>();\n const [paymentState, setPaymentState] = useState<PaymentUiState>(\"idle\");\n const paymentStateRevisionRef = useRef<number | undefined>(undefined);\n const { selectionError, session, updateCheckout } = usePaymentCheckout({\n catalog,\n client,\n paymentState,\n selection,\n });\n const readySessionRevision =\n session.phase === \"ready\" ? session.revision : undefined;\n const handlePaymentStateChange = useCallback(\n (state: PaymentUiState) => {\n if (readySessionRevision !== undefined) {\n paymentStateRevisionRef.current = readySessionRevision;\n }\n setPaymentState(state);\n },\n [readySessionRevision]\n );\n const handlePaymentRecoveryChange = useCallback(\n (recovery: LockerversePaymentRecovery | null) =>\n onPaymentRecoveryChange?.(recovery),\n [onPaymentRecoveryChange]\n );\n const handleResumePaymentFailed = useCallback(() => {\n setActiveResumePayment(undefined);\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 = branding ?? catalog.community;\n const { accent: effectiveAccent, rootStyle } = getPaymentAppearance(\n style,\n effectiveBranding\n );\n\n if (completion && completionView === \"summary\") {\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n data-payment-state=\"success\"\n style={rootStyle}\n >\n <div className=\"lockerverse-payment__completion\" role=\"status\">\n <span\n aria-hidden=\"true\"\n className=\"lockerverse-payment__completion-icon\"\n >\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height=\"28\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n width=\"28\"\n >\n <path d=\"m5 12 4 4L19 6\" />\n </svg>\n </span>\n <h1>\n {completion.paymentRequired ? \"Thank you\" : \"Order confirmed\"}\n </h1>\n <p>\n {completion.paymentRequired\n ? \"Your payment has been received.\"\n : \"Your order is confirmed. No payment was required.\"}\n </p>\n </div>\n </section>\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 const sessionIsSoldOut =\n session.phase === \"error\" && session.failure === \"This option is sold out.\";\n\n if (sessionIsSoldOut || paymentState === \"sold_out\") {\n return (\n <section\n {...sectionProps}\n className={rootClassName}\n data-lockerverse-theme={theme}\n role=\"alert\"\n style={rootStyle}\n >\n <h1>Sold out</h1>\n <p>This option is sold out.</p>\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 </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 <PaymentCatalogHeader branding={effectiveBranding} catalog={catalog} />\n {loadError ? (\n <div role=\"alert\">\n <p>{loadError.message}</p>\n <button onClick={onRetry} type=\"button\">\n Retry\n </button>\n </div>\n ) : null}\n <PaymentSkeleton />\n </section>\n );\n }\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={appearanceRootRef}\n style={rootStyle}\n >\n <PaymentCatalogHeader branding={effectiveBranding} catalog={catalog} />\n {loadError ? (\n <div role=\"alert\">\n <p>{loadError.message}</p>\n <button onClick={onRetry} type=\"button\">\n Retry\n </button>\n </div>\n ) : null}\n {notice ? (\n <p className=\"lockerverse-payment__payment-status\" role=\"status\">\n {notice}\n </p>\n ) : null}\n {session.quoteFailure ? (\n <div className=\"lockerverse-payment__payment-status\" role=\"alert\">\n <span>{session.quoteFailure}</span>\n <span> The final total will be checked when you submit.</span>\n </div>\n ) : null}\n <ReadyPayment\n accentColor={effectiveAccent}\n appearanceRoot={appearanceRootRef}\n catalog={catalog}\n checkoutItems={session.checkoutItems}\n client={client}\n initialCustomFieldValues={initialCustomFieldValues}\n key={session.revision}\n metadata={metadata}\n onPaymentComplete={handlePaymentComplete}\n onPaymentRecoveryChange={handlePaymentRecoveryChange}\n onPaymentUncertain={onPaymentUncertain}\n onQuoteChange={(nextQuote, nextNotice) => {\n setNotice(nextNotice);\n updateCheckout(nextQuote);\n }}\n onResumePaymentFailed={handleResumePaymentFailed}\n onStateChange={handlePaymentStateChange}\n quote={session.displayedQuote}\n resumePayment={activeResumePayment}\n stripeLoader={stripeLoader}\n theme={theme}\n visualStyle={rootStyle}\n />\n </section>\n );\n}\n\nfunction PaymentWidgetState({\n children,\n loading = false,\n viewProps,\n}: {\n children: ReactNode;\n loading?: boolean;\n viewProps: PaymentViewProps;\n}) {\n const {\n branding,\n className,\n completionView: _completionView,\n recoveryStorageKey: _recoveryStorageKey,\n initialCustomFieldValues: _initialCustomFieldValues,\n metadata: _metadata,\n onPaymentComplete: _onPaymentComplete,\n onPaymentRecoveryChange: _onPaymentRecoveryChange,\n onPaymentUncertain: _onPaymentUncertain,\n resumePayment: _resumePayment,\n selection: _selection,\n stripeLoader: _stripeLoader,\n style,\n theme = \"dark\",\n ...sectionProps\n } = viewProps;\n const accent = normalizeAccentColor(\n style?.[\"--lockerverse-accent\"] ?? branding?.accentColor ?? \"#38d77a\"\n );\n const accentContrast = getAccentContrast(accent);\n const rootStyle: LockerversePaymentProps[\"style\"] = { ...style };\n if (style?.[\"--lockerverse-accent\"] !== undefined || branding?.accentColor) {\n rootStyle[\"--lockerverse-accent\"] = accent;\n }\n if (\n accentContrast &&\n style?.[\"--lockerverse-accent-contrast\"] === undefined\n ) {\n rootStyle[\"--lockerverse-accent-contrast\"] = accentContrast;\n }\n\n return (\n <section\n {...sectionProps}\n {...(loading ? { \"aria-busy\": true, \"aria-label\": \"Payment\" } : {})}\n className={[\"lockerverse-payment\", className].filter(Boolean).join(\" \")}\n data-lockerverse-theme={theme}\n style={rootStyle}\n >\n {children}\n </section>\n );\n}\n\nfunction RecoverablePayment(\n props: PaymentViewProps & {\n catalog: LockerverseCatalog;\n client: LockerverseCheckoutClient;\n loadError?: Error | null;\n onRetry?: () => void;\n }\n) {\n const {\n catalog,\n client: _client,\n loadError: _loadError,\n onRetry: _onRetry,\n ...viewProps\n } = props;\n const {\n onPaymentRecoveryChange,\n recoveryStorageKey,\n resumePayment,\n selection,\n } = viewProps;\n const stored = usePaymentRecoveryStorage({\n selection,\n storageKey: recoveryStorageKey,\n widgetId: catalog.widget.id,\n });\n const handleRecoveryChange = useCallback(\n (recovery: LockerversePaymentRecovery | null) => {\n stored.remember(recovery);\n notifyHostCallback(onPaymentRecoveryChange, recovery);\n },\n [onPaymentRecoveryChange, stored.remember]\n );\n if (!stored.ready || stored.error) {\n return (\n <PaymentWidgetState loading={!stored.ready} viewProps={viewProps}>\n {stored.error ? (\n <p role=\"alert\">{stored.error}</p>\n ) : (\n <PaymentSkeleton />\n )}\n </PaymentWidgetState>\n );\n }\n return (\n <LoadedPayment\n {...props}\n onPaymentRecoveryChange={handleRecoveryChange}\n resumePayment={resumePayment ?? stored.recovery}\n />\n );\n}\n\nexport function LockerversePayment({\n widget,\n ...viewProps\n}: LockerversePaymentProps) {\n if (widget.error && !widget.catalog) {\n return (\n <PaymentWidgetState viewProps={viewProps}>\n <p role=\"alert\">{widget.error.message}</p>\n <button onClick={widget.refresh} type=\"button\">\n Retry\n </button>\n </PaymentWidgetState>\n );\n }\n if (widget.loading) {\n return (\n <PaymentWidgetState loading viewProps={viewProps}>\n {widget.catalog ? (\n <>\n <PaymentCatalogHeader\n branding={viewProps.branding ?? widget.catalog.community}\n catalog={widget.catalog}\n />\n <PaymentCatalogSummary\n catalog={widget.catalog}\n selection={viewProps.selection}\n />\n </>\n ) : null}\n <PaymentSkeleton />\n </PaymentWidgetState>\n );\n }\n if (!widget.catalog) {\n return (\n <PaymentWidgetState loading viewProps={viewProps}>\n <PaymentSkeleton />\n </PaymentWidgetState>\n );\n }\n return (\n <RecoverablePayment\n catalog={widget.catalog}\n client={widget.client}\n loadError={widget.error}\n onRetry={widget.refresh}\n {...viewProps}\n />\n );\n}\n"],"mappings":"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"}
|
package/guides/auctions.md
CHANGED
package/guides/events.md
CHANGED
package/guides/integration.md
CHANGED
package/guides/signup.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lockerverse/react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.176-dev.1",
|
|
4
4
|
"description": "Tree-shakable React payment and signup UI for Lockerverse",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
"embla-carousel-react": "8.6.0",
|
|
137
137
|
"lucide-react": "0.536.0",
|
|
138
138
|
"valibot": "1.4.2",
|
|
139
|
-
"@lockerverse/sdk": "0.2.
|
|
139
|
+
"@lockerverse/sdk": "0.2.176-dev.1"
|
|
140
140
|
},
|
|
141
141
|
"devDependencies": {
|
|
142
142
|
"@size-limit/file": "13.0.3",
|