@lockerverse/sdk 0.1.17 → 0.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,132 +1,103 @@
1
1
  # Lockerverse SDK
2
2
 
3
- Framework-free browser SDK for building native Lockerverse checkout and signup
4
- experiences.
5
-
6
- This package provides independent workflow entries. Checkout loads a public
7
- Product catalog, maintains a headless selection, calculates an authoritative
8
- total, and submits a Stripe confirmation token. Signup loads configured fields
9
- and submits a registration. The SDK does not render UI, initialize React,
10
- collect analytics, or include auction behavior.
3
+ Stateless browser client for Lockerverse checkout and signup APIs. It validates
4
+ public inputs and backend responses, returns immutable snapshots, and never
5
+ renders UI or owns host application state.
11
6
 
12
7
  ## Checkout
13
8
 
14
9
  ```ts
15
- import { createLockerverseCheckout } from "@lockerverse/sdk/checkout";
10
+ import { createLockerverseCheckoutClient } from "@lockerverse/sdk/checkout";
16
11
 
17
- const checkout = createLockerverseCheckout({
12
+ const client = createLockerverseCheckoutClient({
18
13
  communitySlug: "auburn",
19
14
  widgetSlug: "auburn-tailgate-party",
20
15
  onError(error) {
21
- // Optional host notification. Reportable failures are also sent directly
22
- // to Lockerverse's Sentry project by an isolated SDK client.
23
16
  console.error(error.code, error.operation);
24
17
  },
25
18
  });
26
19
 
27
- const { products, widget } = await checkout.load();
28
-
29
- // Render `products` and `widget.customFields` with any DOM or UI framework.
30
- checkout.setQuantity("adult", 2);
31
- checkout.setAmount("donation", 1000);
20
+ const catalog = await client.load();
32
21
 
33
- const selection = checkout.getSelection();
22
+ // The host owns Product selection. Use IDs from the current catalog.
23
+ const items = [
24
+ { productId: catalog.products[0].id, quantity: 2 },
25
+ ];
34
26
  const pricing = {
35
27
  email: "customer@example.com",
36
28
  includeServiceFee: true,
37
29
  tipCents: 500,
38
30
  };
39
31
 
40
- // Synchronous host feedback. Discounts remain null until Lockerverse verifies
41
- // the same input on the backend.
42
- const preview = checkout.previewTotal(pricing);
43
-
44
- // Subscribe once to drive any host UI from immutable public snapshots.
45
- const unsubscribe = checkout.subscribe((state) => {
46
- renderCheckoutState(state);
47
- });
48
- const total = await checkout.calculateTotal(pricing);
49
-
50
- // Initialize Stripe.js in the host with total.payment.publishableKey and
51
- // total.payment.connectedAccountId. Persist total.paymentReference if the host
52
- // wants to recover this payment after a refresh.
53
-
54
- // Collect payment details with Stripe Elements, then pass its short-lived
55
- // confirmation token to Lockerverse.
56
- const payment = await checkout.submitPayment({
57
- confirmationToken: "ctoken_...",
58
- customFieldAnswers: [
59
- { fieldId: "guest-name", value: "Ada Lovelace" },
60
- { fieldId: "interests", value: ["meetups", "merch"] },
61
- ],
62
- email: "customer@example.com",
32
+ // Lockerverse resolves current prices, availability, discounts, fees, and the
33
+ // connected Stripe account authoritatively.
34
+ const checkout = await client.calculateTotal({ ...pricing, items });
35
+
36
+ // Render Stripe Elements with checkout.payment.publishableKey,
37
+ // checkout.payment.connectedAccountId, and checkout.totalCents. The prepared
38
+ // checkout also binds the normalized items and pricing used for this total.
39
+ const payment = await client.submitPayment({
40
+ checkout,
41
+ submission: {
42
+ confirmationToken: "ctoken_...",
43
+ customFieldAnswers: [
44
+ { fieldId: "guest-name", value: "Ada Lovelace" },
45
+ { fieldId: "interests", value: ["meetups", "merch"] },
46
+ ],
47
+ email: "customer@example.com",
48
+ },
63
49
  });
64
50
 
65
- // Safe after a refresh or an interrupted response.
66
- const recoveredPayment = await checkout.getPaymentStatus(
67
- total.paymentReference,
68
- );
69
-
70
- unsubscribe();
51
+ // Safe after a refresh or an interrupted confirmation response.
52
+ const recovered = await client.getPaymentStatus(checkout.paymentReference);
71
53
  ```
72
54
 
73
- `getState()` returns the current immutable snapshot immediately. `subscribe()`
74
- immediately receives that snapshot, then receives each observable phase change:
75
- `idle`, `loading`, `ready`, `quoting`, `quoted`, `submitting`, `recovering`,
76
- `payment`, or `error`. Its unsubscribe function is safe to call more than once.
77
- Hosts should enable payment only in `quoted`, and freeze catalog, selection, and
78
- pricing controls in `submitting`.
55
+ `createLockerverseCheckoutClient()` exposes only `load`, `calculateTotal`,
56
+ `submitPayment`, and `getPaymentStatus`. It has no selection store, lifecycle
57
+ state, subscriptions, or Stripe state. React applications can use
58
+ `@lockerverse/react` for the complete payment UI and orchestration.
79
59
 
80
- The default endpoint is production. A custom endpoint must always name its
81
- environment so a staging or proxy hostname can never silently select live
82
- Stripe configuration. Custom endpoints must be HTTP(S) URLs without embedded
83
- credentials, query strings, or fragments. HTTPS is required except for literal
84
- `localhost`, `127.0.0.1`, and `[::1]` endpoints in the development environment:
60
+ Fixed prices in the catalog are display data. `calculateTotal()` sends Product
61
+ IDs and selections to Lockerverse, which resolves the payable amount. The host
62
+ returns them together as one immutable prepared checkout. Pass that prepared
63
+ checkout to `submitPayment()` so a host cannot accidentally submit different
64
+ inputs from the ones Lockerverse quoted. It owns one stable payment reference
65
+ so Lockerverse can prevent duplicate checkout creation and recover ambiguous
66
+ outcomes.
85
67
 
86
- ```ts
87
- const checkout = createLockerverseCheckout({
88
- apiBaseUrl: "https://portal-dev.lockerverse.com/api",
89
- communitySlug: "auburn",
90
- environment: "development",
91
- widgetSlug: "auburn-tailgate-party",
92
- });
93
- ```
68
+ If `submitPayment()` throws an error with `recoveryRecommended: true`, the
69
+ request may still have reached Lockerverse. Query `getPaymentStatus()` with the
70
+ prepared checkout's payment reference before allowing another payment. Other
71
+ failures are definitive and do not require recovery.
72
+
73
+ ## 0.2 checkout migration
94
74
 
95
- Every SDK HTTP operation has a 20-second deadline by default. Hosts can choose a
96
- different positive whole-number deadline in milliseconds, up to
97
- `2_147_483_647`, with `requestTimeoutMs` on either checkout or signup. The
98
- deadline includes receiving and validating the complete JSON response body:
75
+ The 0.2 checkout API is intentionally stateless. Replace the old stateful
76
+ checkout facade with `createLockerverseCheckoutClient()`. Keep Product
77
+ selection and workflow state in the host, or use `@lockerverse/react`. Also
78
+ replace `submitPayment({ items, pricing, quote, submission })` with
79
+ `submitPayment({ checkout, submission })`, where `checkout` is the object
80
+ returned by `calculateTotal()`.
81
+
82
+ ## Runtime configuration
83
+
84
+ Production is the default endpoint and environment. A custom endpoint must name
85
+ its environment so a development host cannot silently select live Stripe
86
+ configuration:
99
87
 
100
88
  ```ts
101
- const checkout = createLockerverseCheckout({
89
+ const client = createLockerverseCheckoutClient({
90
+ apiBaseUrl: "https://portal-dev.lockerverse.com/api",
102
91
  communitySlug: "auburn",
103
- requestTimeoutMs: 10_000,
92
+ environment: "development",
104
93
  widgetSlug: "auburn-tailgate-party",
105
94
  });
106
95
  ```
107
96
 
108
- A timeout only means the browser stopped waiting; it does not prove that a
109
- payment mutation failed on Lockerverse's server. After an ambiguous payment
110
- confirmation, read `recoverablePaymentReference` from the `error` state and
111
- pass it to `getPaymentStatus()`.
112
-
113
- `widget.customFields` is a discriminated union covering `text`, `textarea`,
114
- `select`, `multi_select`, `radio`, and `checkboxes`. Archived fields and options
115
- are omitted. Hosts own rendering and client-side required-field feedback:
116
- single-value fields submit a string, while `multi_select` and `checkboxes`
117
- submit a string array. Lockerverse validates the answers again when the payment
118
- is submitted.
119
-
120
- Fixed prices are display data only. `calculateTotal()` sends Product IDs and
121
- selections to Lockerverse, which resolves the authoritative price,
122
- availability, discount eligibility, and subtotal. Changing the selection
123
- invalidates that total, so `submitPayment()` requires recalculation first.
124
- The email submitted for payment must be the normalized email used for the
125
- accepted quote, because email-list eligibility is part of the payable amount.
126
- Repeated submissions of one calculated total carry the same payment reference;
127
- Lockerverse uses it to prevent duplicate checkout creation. Payment references
128
- are generated internally with `crypto.randomUUID()` and exposed on the
129
- calculated total for recovery.
97
+ Custom endpoints must be HTTP(S) URLs without credentials, query strings, or
98
+ fragments. HTTPS is required except for literal `localhost`, `127.0.0.1`, and
99
+ `[::1]` endpoints in development. Requests have a 20-second deadline by
100
+ default; override it with a positive `requestTimeoutMs` value.
130
101
 
131
102
  ## Signup
132
103
 
@@ -139,9 +110,6 @@ const signup = createLockerverseSignup({
139
110
  });
140
111
 
141
112
  const definition = await signup.load();
142
-
143
- // Render definition.fields and definition.customFields with any DOM or UI
144
- // framework, then submit the collected values.
145
113
  const submission = await signup.submit({
146
114
  answers: [{ fieldId: "guest-type", value: "student" }],
147
115
  email: "customer@example.com",
@@ -150,71 +118,36 @@ const submission = await signup.submit({
150
118
  });
151
119
  ```
152
120
 
153
- The same ambiguity applies when a signup submission times out. Read
154
- `recoverableSubmissionReference` from the `error` state and retry the same
155
- values with that reference so Lockerverse can return the original submission
156
- instead of creating a duplicate:
121
+ Signup currently retains its small workflow facade. Its immutable states are
122
+ `idle`, `loading`, `ready`, `submitting`, `submitted`, and `error`. When a
123
+ submission times out, reuse `recoverableSubmissionReference` with the same
124
+ values so Lockerverse can return the original submission.
157
125
 
158
- ```ts
159
- const state = signup.getState();
160
- if (state.phase === "error" && state.recoverableSubmissionReference) {
161
- await signup.submit(values, {
162
- submissionReference: state.recoverableSubmissionReference,
163
- });
164
- }
165
- ```
126
+ ## Security and observability
166
127
 
167
- `subscribe()` observes `idle`, `loading`, `ready`, `submitting`, `submitted`,
168
- and `error`. Definitions and submission results are immutable snapshots.
169
- Lockerverse validates enabled and required built-in fields, custom-field
170
- answers, and signup availability authoritatively when submitted. A host may
171
- pass a hidden bot-trap value as `honeypot`; a legitimate user should never
172
- populate it.
128
+ - No Stripe or Lockerverse secret is accepted by the public API.
129
+ - Successful catalog, quote, confirmation, and status responses are validated
130
+ before being returned.
131
+ - Public workflow inputs are validated with private Valibot schemas.
132
+ - Backend response bodies and validation internals never escape in SDK errors.
133
+ - Expected input errors are `reportable: false`; unexpected network and server
134
+ failures are `reportable: true`.
135
+ - Reportable failures are sent directly to Lockerverse Sentry with allowlisted
136
+ workflow context. `sentryDsn: null` disables loading and sending telemetry.
137
+ - The Sentry runtime is an isolated failure-only chunk and does not replace or
138
+ mutate the host application's Sentry client.
139
+ - Stripe's shared publishable key is selected by environment. The authoritative
140
+ quote supplies the community's connected account.
141
+ - Analytics and auctions are intentionally out of scope.
173
142
 
174
143
  ## Commands
175
144
 
176
145
  Run these from the repository root:
177
146
 
178
147
  ```sh
179
- pnpm demo
148
+ pnpm dev:react
180
149
  pnpm typecheck
181
150
  pnpm test
182
151
  pnpm build
183
152
  pnpm --filter @lockerverse/sdk pack:check
184
153
  ```
185
-
186
- `pnpm demo` starts a throwaway browser playground at
187
- `http://127.0.0.1:4173`. It loads a public dev widget and completes an end-to-end
188
- Stripe test-mode payment with plain host HTML and Stripe Elements. It cannot
189
- create a live charge.
190
-
191
- ## Security and observability
192
-
193
- - No Stripe or Lockerverse secret is accepted by the public API.
194
- - Runtime options require non-empty community and workflow slugs, a known
195
- environment, and a secure custom endpoint.
196
- - Backend response bodies are not included in SDK errors.
197
- - Every successful catalog, quote, confirmation, and status response is
198
- structurally validated before it enters SDK state or is returned to the host.
199
- A successful HTTP status alone is insufficient; invalid JSON or response
200
- shapes become sanitized, reportable `LockerverseSdkError` failures.
201
- - Public workflow input is validated before it reaches transport. Private
202
- Valibot schemas own these runtime boundaries and infer their internal types;
203
- schema implementation details and validation payloads do not escape through
204
- the public API.
205
- - Expected selection errors are marked `reportable: false`.
206
- - Unexpected network/server failures are marked `reportable: true`.
207
- - Reportable failures are sent directly to Sentry with only allowlisted SDK and
208
- workflow context; request data, users, and breadcrumbs are removed.
209
- - The Sentry runtime is a private failure-only chunk. It is not loaded by the
210
- successful checkout path, and `sentryDsn: null` prevents both loading and
211
- sending.
212
- - The SDK does not initialize a global Sentry client in the host application.
213
- - Hosts with a restrictive Content Security Policy must allow the configured
214
- Sentry ingest origin in `connect-src`, or disable SDK reporting with
215
- `sentryDsn: null`.
216
- - Stripe's shared publishable key is selected by environment; the community's
217
- connected account comes from the authoritative checkout quote. The backend
218
- builds that quote with the same charge-target resolver used to create
219
- payments.
220
- - Analytics are intentionally out of scope for v0.
@@ -1,6 +1,6 @@
1
- import { A as LockerverseSingleOptionCustomField, C as LockerversePaymentSubmission, D as LockerverseSdkOperation, E as LockerverseSdkErrorCode, F as LockerverseWidgetState, M as LockerverseWidget, N as LockerverseWidgetConfiguration, O as LockerverseSelection, P as LockerverseWidgetFields, S as LockerversePaymentStatus, T as LockerverseSdkError, _ as LockerverseEnvironment, a as LockerverseCheckoutAmounts, b as LockerversePaymentOption, c as LockerverseCheckoutPreview, d as LockerverseCheckoutQuote, f as LockerverseCheckoutTotal, g as LockerverseCustomFieldOption, h as LockerverseCustomFieldAnswerValue, i as LockerverseCatalog, j as LockerverseTextCustomField, k as LockerverseSelectionItem, l as LockerverseCheckoutPricingInput, m as LockerverseCustomFieldAnswer, n as LOCKERVERSE_SDK_VERSION, o as LockerverseCheckoutLineItem, p as LockerverseCustomField, r as LockerverseAppliedDiscount, s as LockerverseCheckoutPaymentConfiguration, t as CreateLockerverseWidgetOptions, u as LockerverseCheckoutPricingPolicy, v as LockerverseMultiOptionCustomField, w as LockerverseProduct, x as LockerversePaymentResult, y as LockerversePaymentConfiguration } from "./types.js";
2
- //#region src/checkout.d.ts
3
- declare function createLockerverseCheckout(options: CreateLockerverseWidgetOptions): LockerverseWidget;
1
+ import { A as LockerverseSdkOperation, C as LockerversePaymentResult, D as LockerverseProduct, E as LockerversePreparedCheckout, F as LockerverseWidgetFields, M as LockerverseSubmitPaymentInput, N as LockerverseTextCustomField, O as LockerverseSdkError, P as LockerverseWidgetConfiguration, S as LockerversePaymentOption, T as LockerversePaymentSubmission, _ as LockerverseCustomFieldAnswerValue, a as LockerverseCatalog, b as LockerverseMultiOptionCustomField, c as LockerverseCheckoutItem, d as LockerverseCheckoutPricingInput, f as LockerverseCheckoutPricingPolicy, g as LockerverseCustomFieldAnswer, h as LockerverseCustomField, i as LockerverseCalculateTotalInput, j as LockerverseSingleOptionCustomField, k as LockerverseSdkErrorCode, l as LockerverseCheckoutLineItem, m as LockerverseCheckoutTotal, n as LOCKERVERSE_SDK_VERSION, o as LockerverseCheckoutAmounts, p as LockerverseCheckoutQuote, r as LockerverseAppliedDiscount, s as LockerverseCheckoutClient, t as CreateLockerverseWidgetOptions, u as LockerverseCheckoutPaymentConfiguration, v as LockerverseCustomFieldOption, w as LockerversePaymentStatus, x as LockerversePaymentConfiguration, y as LockerverseEnvironment } from "./types.js";
2
+ //#region src/checkout-client.d.ts
3
+ declare function createLockerverseCheckoutClient(options: CreateLockerverseWidgetOptions): LockerverseCheckoutClient;
4
4
  //#endregion
5
- export { CreateLockerverseWidgetOptions, LOCKERVERSE_SDK_VERSION, LockerverseAppliedDiscount, LockerverseCatalog, LockerverseCheckoutAmounts, LockerverseCheckoutLineItem, LockerverseCheckoutPaymentConfiguration, LockerverseCheckoutPreview, LockerverseCheckoutPricingInput, LockerverseCheckoutPricingPolicy, LockerverseCheckoutQuote, LockerverseCheckoutTotal, LockerverseCustomField, LockerverseCustomFieldAnswer, LockerverseCustomFieldAnswerValue, LockerverseCustomFieldOption, LockerverseEnvironment, LockerverseMultiOptionCustomField, LockerversePaymentConfiguration, LockerversePaymentOption, LockerversePaymentResult, LockerversePaymentStatus, LockerversePaymentSubmission, LockerverseProduct, LockerverseSdkError, LockerverseSdkErrorCode, LockerverseSdkOperation, LockerverseSelection, LockerverseSelectionItem, LockerverseSingleOptionCustomField, LockerverseTextCustomField, LockerverseWidget, LockerverseWidgetConfiguration, LockerverseWidgetFields, LockerverseWidgetState, createLockerverseCheckout };
5
+ export { CreateLockerverseWidgetOptions, LOCKERVERSE_SDK_VERSION, LockerverseAppliedDiscount, LockerverseCalculateTotalInput, LockerverseCatalog, LockerverseCheckoutAmounts, LockerverseCheckoutClient, LockerverseCheckoutItem, LockerverseCheckoutLineItem, LockerverseCheckoutPaymentConfiguration, LockerverseCheckoutPricingInput, LockerverseCheckoutPricingPolicy, LockerverseCheckoutQuote, LockerverseCheckoutTotal, LockerverseCustomField, LockerverseCustomFieldAnswer, LockerverseCustomFieldAnswerValue, LockerverseCustomFieldOption, LockerverseEnvironment, LockerverseMultiOptionCustomField, LockerversePaymentConfiguration, LockerversePaymentOption, LockerversePaymentResult, LockerversePaymentStatus, LockerversePaymentSubmission, LockerversePreparedCheckout, LockerverseProduct, LockerverseSdkError, LockerverseSdkErrorCode, LockerverseSdkOperation, LockerverseSingleOptionCustomField, LockerverseSubmitPaymentInput, LockerverseTextCustomField, LockerverseWidgetConfiguration, LockerverseWidgetFields, createLockerverseCheckoutClient };
6
6
  //# sourceMappingURL=checkout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkout.d.ts","names":[],"sources":["../src/checkout.ts"],"mappings":";;iBAmCgB,0BACd,SAAS,iCACR"}
1
+ {"version":3,"file":"checkout.d.ts","names":[],"sources":["../src/checkout-client.ts"],"mappings":";;iBA0CgB,gCACd,SAAS,iCACR"}
package/dist/checkout.js CHANGED
@@ -1,2 +1,2 @@
1
- import{A as e,C as t,D as n,E as r,O as i,S as a,T as o,_ as s,a as c,b as l,c as u,f as d,h as f,i as p,j as m,k as h,l as g,m as _,n as v,o as y,p as b,r as x,s as S,t as C,u as w,v as T,w as E,x as D,y as O}from"./transport.js";import{n as k,t as A}from"./types.js";const j={development:`pk_test_51O7FkjDHAhgRuLtFHdkXdIe8T5i7rOVaG9PCtDetK3UUVKojVUEKHmQacGzigf9mOX1wz3zSOKoYwFjRcTfML9PU00OjJko2lk`,production:`pk_live_51O7FkjDHAhgRuLtFlzLdxJrwo7F09WCKTlzT9lnBePjOGizWnuijkH9oCkoAddkmBT8ngIuqAPkDiHlPEAH4KXbz00Tm0DaPT4`};function M(e){let t=w(e,`widgetSlug`);return{...t,stripePublishableKey:j[t.environment],widgetSlug:t.resourceSlug,widgetSlugValue:t.resourceSlugValue}}const N=E(t(i({email:t(h()),includeServiceFee:t(b()),promoCode:t(h()),tipCents:t(g(0))}),{})),P=E(i({confirmationToken:S,customFieldAnswers:t(d(c)),email:h(),memberId:t(h()),merchSize:t(o([`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`])),metadata:t(n(h(),h())),phone:t(h())})),F=o([`one-time`,`monthly`,`annually`]),I=l(g(0)),L={description:u,id:S,inventoryQuantity:I,maxQuantity:I,minimumAmountCents:I,minQuantity:I,name:S,paymentOption:F},R=r(m(`pricingMode`,[a({...L,amountCents:g(0),pricingMode:s(`fixed`)}),a({...L,amountCents:I,pricingMode:s(`custom`)})]),_(({maxQuantity:e,minQuantity:t})=>e===null||t===null||t<=e)),z=a({acceptsDiscounts:t(b(),!1),id:S,product:R,productId:S,slug:S}),B=t(a({memberId:t(b(),!1),merchSize:t(b(),!1),phone:t(b(),!1),promoCode:t(b(),!1),serviceFee:t(b(),!1),shipping:t(b(),!1),tipping:t(b(),!1)}),{}),V=r(a({config:t(a({customFields:y,fields:B})),description:u,id:t(h(),``),name:t(h(),`Lockerverse widget`),pricingPolicy:t(a({currency:t(s(`usd`),`usd`),serviceFeeRateBasisPoints:t(g(0),0)})),products:t(d(z),[]),showCommunityBranding:t(b(),!0),title:u}),e(e=>({...e,config:{customFields:e.config?.customFields??[],fields:{memberId:e.config?.fields?.memberId??!1,merchSize:e.config?.fields?.merchSize??!1,phone:e.config?.fields?.phone??!1,promoCode:e.config?.fields?.promoCode??!1,serviceFee:e.config?.fields?.serviceFee??!1,shipping:e.config?.fields?.shipping??!1,tipping:e.config?.fields?.tipping??!1}},pricingPolicy:e.pricingPolicy??{currency:`usd`,serviceFeeRateBasisPoints:0}}))),H=l(a({percentageOff:r(D(),f(),O(0),T(100)),source:o([`email_list`,`promo_code`])})),U=a({acceptsDiscounts:b(),listingId:S,listingSlug:S,paymentOption:F,pricingMode:o([`fixed`,`custom`]),productId:S,productName:S,quantity:g(1),subtotalCents:g(0),unitAmountCents:g(0)}),W=a({amountCents:g(0),appliedDiscount:H,connectedAccountId:l(S),discountableSubtotalCents:g(0),discountCents:g(0),lineItems:d(U),paymentOption:F,serviceFeeCents:g(0),subtotalCents:g(0),tipCents:g(0),totalCents:g(0)}),G=a({checkoutId:S,checkoutStatus:o([`action_required`,`failed`,`pending`,`success`]),clientSecret:l(h()),paymentReference:S,requiresAction:b(),status:l(h())}),K=E(W),q=E(G),ee=E(V),J=1e4;function Y(e,t){if(!Number.isSafeInteger(e)||e<0)throw TypeError(t);return e}function X(e,t){return Y(e+t,`The selected checkout total is too large.`)}function te(e,t){return Y(e*t,`The selected Product quantity produces an unsafe total.`)}function ne(e,t){let n=(BigInt(e)*BigInt(t)+BigInt(J/2))/BigInt(J);if(n>BigInt(2**53-1))throw TypeError(`The selected checkout total is too large.`);return Number(n)}function Z(e,t,n){let r=0,i=0;for(let n of t.items){let t=e.products.find(({id:e,slug:t})=>e===n.productId&&t===n.productSlug);if(!t)throw TypeError(`The selected Product is no longer available.`);if(t.paymentOption!==`one-time`)throw TypeError(`Recurring Products are not supported by this SDK checkout yet.`);let a=`quantity`in n?te(t.amountCents??0,n.quantity):n.amountCents;r=X(r,a),t.acceptsDiscounts&&(i=X(i,a))}let a=n.includeServiceFee?ne(r,e.pricingPolicy.serviceFeeRateBasisPoints):0,o=n.tipCents??0,s=X(r,a);return{amountCents:s,appliedDiscount:null,authoritative:!1,discountableSubtotalCents:i,discountCents:0,serviceFeeCents:a,subtotalCents:r,tipCents:o,totalCents:X(s,o)}}function re(e){let{product:t}=e;return{acceptsDiscounts:e.acceptsDiscounts??!1,amountCents:t.amountCents,description:t.description??null,id:t.id,inventoryQuantity:t.inventoryQuantity,listingId:e.id,maximumQuantity:t.maxQuantity,minimumAmountCents:t.minimumAmountCents,minimumQuantity:t.minQuantity,name:t.name,paymentOption:t.paymentOption,pricingMode:t.pricingMode,slug:e.slug}}function ie(e,t){let n=e.config?.fields??{};return{payment:{currency:`usd`,publishableKey:t},pricingPolicy:{currency:`usd`,serviceFeeRateBasisPoints:e.pricingPolicy?.serviceFeeRateBasisPoints??0},products:(e.products??[]).map(re),widget:{customFields:e.config?.customFields??[],description:e.description??null,fields:{memberId:n.memberId??!1,merchSize:n.merchSize??!1,phone:n.phone??!1,promoCode:n.promoCode??!1,serviceFee:n.serviceFee??!1,shipping:n.shipping??!1,tipping:n.tipping??!1},id:e.id??``,name:e.name??`Lockerverse widget`,showCommunityBranding:e.showCommunityBranding??!0,title:e.title??null}}}function ae(e){return $(e)}function oe(e){return $(e)}function Q(e){return $(e)}function $(e){return p(structuredClone(e))}function se(e){let{apiBaseUrl:t,communitySlug:n,communitySlugValue:r,environment:i,fetchImplementation:a,onError:o,requestTimeoutMs:s,sentryDsn:c,stripePublishableKey:l,widgetSlug:u,widgetSlugValue:d}=M(e),f=null,m=null,h=null,g=null,_=null,y=0,b=0,S=!1,w=new Map,T=v({phase:`idle`,selection:p({items:[]})});function E(e){let t=f,n=t?t.products.find(({slug:t})=>t===e):void 0;if(!n)throw Error(`Lockerverse Product "${e}" is unavailable.`);return n}let D=x({communitySlug:r,environment:i,getContext:()=>({paymentReference:g,widgetSlug:d}),onError:o,resourceContextName:`lockerverse_widget`,sentryDsn:c});function O(e,t=`update_selection`){throw D(new k({code:`invalid_selection`,message:e,operation:t,reportable:!1}))}let{requestJson:A}=C(a,D,s);function j(){let e=f;return p({items:(e?e.products:[]).flatMap(e=>{let t=w.get(e.slug);return t?[{productId:e.id,productSlug:e.slug,...t}]:[]})})}function F(){m=null,h=null,g=null,_=null}function I(){S&&O(`Selection cannot change while a payment is being submitted.`)}function L(e){S&&O(`This operation cannot run while a payment is being submitted.`,e)}function R(){b+=1,F()}function z(e=null){f&&T.commit({catalog:f,phase:`ready`,preview:e,selection:j()})}function B(e,t=null){T.commit({catalog:f,error:e,phase:`error`,recoverablePaymentReference:t,selection:j()})}function V(e,t){return e instanceof k?e:new k({...t,reportable:!0})}function H(){return y+=1,y}function U(e,t,n=!0){if(e===y)return;let r=new k({...t,reportable:!1});throw n?D(r):r}function W(e,t){if(e!==b||t!==y)throw D(new k({code:`total_calculation_failed`,message:`This Lockerverse checkout total was superseded. Calculate the total again for the current selection.`,operation:`calculate_total`,reportable:!1}))}function G(e={}){if(L(`calculate_total`),!f)throw Error(`Load the Lockerverse widget before previewing the total.`);w.size===0&&O(`Select at least one Product before previewing.`);let t=J(f,e);R();try{let e=p(Z(f,j(),t));return _=e,z(e),e}catch(e){O(e instanceof Error?e.message:`Unable to preview checkout.`)}}function J(e,t){let n;try{n=N(t)}catch{O(`Checkout pricing input is invalid.`)}Y(e,n);let r=n.tipCents??0,i=n.email?.trim().toLowerCase(),a=n.promoCode?.trim();return{...i?{email:i}:{},...n.includeServiceFee===void 0?{}:{includeServiceFee:n.includeServiceFee},...a?{promoCode:a}:{},...n.tipCents===void 0?{}:{tipCents:r}}}function Y(e,t){let n=t.tipCents??0;(!Number.isSafeInteger(n)||n<0)&&O(`Tip must be a non-negative whole number of cents.`),t.includeServiceFee&&!e.widget.fields.serviceFee&&O(`Service fee is not enabled for this widget.`),t.includeServiceFee&&e.pricingPolicy.serviceFeeRateBasisPoints===0&&O(`Service fee pricing is unavailable. Reload the widget and try again.`),n>0&&!e.widget.fields.tipping&&O(`Tipping is not enabled for this widget.`)}async function X(e={}){if(L(`calculate_total`),!f)throw Error(`Load the Lockerverse widget before calculating the total.`);let r=J(f,e);w.size===0&&O(`Select at least one Product before calculating the total.`,`calculate_total`);let i=j(),a=H(),o=p(Z(f,i,r));_=o,T.commit({catalog:f,phase:`quoting`,preview:o,selection:i});let s=i.items.map(({productSlug:e,...t})=>t),c=b;m=null,g=null;let l=A(`${t}/v2/community/${n}/payment-widgets/${u}/checkout/quote`,{body:JSON.stringify({...r,items:s}),headers:{"Content-Type":`application/json`},method:`POST`},K,{code:`total_calculation_failed`,message:`Unable to calculate the Lockerverse checkout total because the request failed.`,operation:`calculate_total`,report:!1},{code:`total_calculation_failed`,message:`Lockerverse returned an invalid checkout total.`,operation:`calculate_total`,report:!1}),d;try{d=await l}catch(e){throw W(c,a),e instanceof k?(B(e),D(e)):e}if(W(c,a),!d.ok){let e=new k({code:`total_calculation_failed`,message:`Unable to calculate the Lockerverse checkout total (${d.response.status}).`,operation:`calculate_total`,reportable:d.response.status>=500,status:d.response.status});throw B(e),D(e)}let v;try{if(v=d.value,v.paymentOption!==`one-time`)throw new k({code:`total_calculation_failed`,message:`Lockerverse returned an unsupported checkout cadence.`,operation:`calculate_total`,reportable:!0})}catch(e){throw W(c,a),e instanceof k?(B(e),D(e)):e}W(c,a);let y=globalThis.crypto.randomUUID(),{connectedAccountId:x,paymentOption:S,...C}=v,E=p({...C,authoritative:!0,payment:{...f.payment,connectedAccountId:x},paymentOption:`one-time`,paymentReference:y});return m=E,h=p({...r}),g=y,T.commit({catalog:f,phase:`quoted`,preview:o,quote:E,selection:i}),oe(E)}return{calculateTotal:X,clear(){I(),w.clear(),R(),z()},async getPaymentStatus(e=g??``){L(`get_payment_status`),e||O(`Provide a payment reference to recover its status.`,`get_payment_status`);let r=H(),i={code:`payment_status_failed`,message:`This Lockerverse payment status request was superseded.`,operation:`get_payment_status`};g=e;let a=j();T.commit({catalog:f,paymentReference:e,phase:`recovering`,selection:a});try{let o=await A(`${t}/v2/community/${n}/payment-widgets/${u}/checkout/${encodeURIComponent(e)}/status`,void 0,q,{code:`payment_status_failed`,message:`Unable to recover the Lockerverse payment status because the request failed.`,operation:`get_payment_status`,report:!1},{code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`,report:!1});if(U(r,i,!1),!o.ok)throw new k({code:`payment_status_failed`,message:`Unable to recover the Lockerverse payment status (${o.response.status}).`,operation:`get_payment_status`,reportable:o.response.status>=500,status:o.response.status});let s=Q(o.value);if(U(r,i,!1),s.paymentReference!==e)throw new k({code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`,reportable:!0});return T.commit({catalog:f,payment:s,phase:`payment`,quote:m?.paymentReference===e?m:null,selection:a}),Q(s)}catch(t){U(r,i);let n=V(t,{code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`});throw B(n,e),D(n)}},getSelection:j,getState:T.getState,async load(){L(`load_widget`);let e=H(),r={code:`widget_load_failed`,message:`This Lockerverse widget load was superseded.`,operation:`load_widget`};R(),T.commit({phase:`loading`,selection:j()});let i={code:`widget_load_failed`,message:`Unable to load Lockerverse widget because the request failed.`,operation:`load_widget`,report:!1};try{let a=await A(`${t}/v2/community/${n}/payment-widgets/${u}`,void 0,ee,i,{code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`,report:!1});if(U(e,r,!1),!a.ok)throw new k({code:`widget_load_failed`,message:`Unable to load Lockerverse widget (${a.response.status}).`,operation:`load_widget`,reportable:a.response.status>=500,status:a.response.status});let o=a.value;U(e,r,!1);let s=p(ie(o,l)),c=ae(s);return w.clear(),f=s,z(),c}catch(t){U(e,r);let n=V(t,{code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`});throw B(n),D(n)}},previewTotal:G,remove(e){I(),w.delete(e),R(),z()},setAmount(e,t){I();let n=E(e);n.pricingMode!==`custom`&&O(`Fixed-price Products do not accept custom amounts.`),(!Number.isSafeInteger(t)||t<=0)&&O(`Product amount must be a positive integer in cents.`),n.minimumAmountCents!==null&&t<n.minimumAmountCents&&O(`Product amount must be at least ${n.minimumAmountCents} cents.`),w.set(e,{amountCents:t}),R(),z()},setQuantity(e,t){I();let n=E(e);n.pricingMode!==`fixed`&&O(`Custom-amount Products do not accept quantities.`),(!Number.isSafeInteger(t)||t<=0)&&O(`Product quantity must be a positive integer.`),n.minimumQuantity!==null&&t<n.minimumQuantity&&O(`Product quantity must be at least ${n.minimumQuantity}.`),n.maximumQuantity!==null&&t>n.maximumQuantity&&O(`Product quantity must not exceed ${n.maximumQuantity}.`),n.inventoryQuantity!==null&&t>n.inventoryQuantity&&O(`Requested Product quantity is unavailable.`),w.set(e,{quantity:t}),R(),z()},async submitPayment(e){f&&m&&h||O(`Calculate the current total before submitting a payment.`,`submit_payment`),S&&O(`A Lockerverse payment is already being submitted.`,`submit_payment`);let r=f,i=m,a=h,o=j(),s=_??Z(r,o,a),c;try{c=P(e)}catch{let e=new k({code:`payment_submit_failed`,message:`Lockerverse payment submission is invalid.`,operation:`submit_payment`,reportable:!0});throw B(e,i.paymentReference),D(e)}let l=c.email.trim().toLowerCase();(!l||l!==a.email)&&O(`Payment email must match the current checkout quote.`,`submit_payment`);let d=o.items.map(({productSlug:e,...t})=>t);H(),S=!0,T.commit({catalog:r,phase:`submitting`,preview:s,quote:i,selection:o});try{let e=await A(`${t}/v2/community/${n}/payment-widgets/${u}/checkout/confirm`,{body:JSON.stringify({confirmationToken:c.confirmationToken,customFieldAnswers:c.customFieldAnswers,email:l,expectedAmountCents:i.amountCents,expectedAppliedDiscount:i.appliedDiscount,expectedConnectedAccountId:i.payment.connectedAccountId,expectedDiscountableSubtotalCents:i.discountableSubtotalCents,expectedDiscountCents:i.discountCents,expectedServiceFeeCents:i.serviceFeeCents,expectedSubtotalCents:i.subtotalCents,expectedTipCents:i.tipCents,expectedTotalCents:i.totalCents,...a,items:d,memberId:c.memberId,merchSize:c.merchSize,metadata:c.metadata,paymentReference:i.paymentReference,phone:c.phone,quoteContractVersion:1}),headers:{"Content-Type":`application/json`},method:`POST`},q,{code:`payment_submit_failed`,message:`Unable to submit the Lockerverse payment because the request failed.`,operation:`submit_payment`,report:!1},{code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`,report:!1});if(!e.ok)throw new k({code:`payment_submit_failed`,message:`Unable to submit the Lockerverse payment (${e.response.status}).`,operation:`submit_payment`,reportable:e.response.status>=500,status:e.response.status});let s=Q(e.value);if(s.paymentReference!==i.paymentReference)throw new k({code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`,reportable:!0});return T.commit({catalog:r,payment:s,phase:`payment`,quote:i,selection:o}),Q(s)}catch(e){let t=V(e,{code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`});throw B(t,i.paymentReference),D(t)}finally{S=!1}},subscribe:T.subscribe}}export{A as LOCKERVERSE_SDK_VERSION,k as LockerverseSdkError,se as createLockerverseCheckout};
1
+ import{A as e,C as t,D as n,E as r,M as i,O as a,S as o,T as s,_ as c,a as l,b as u,c as d,d as f,f as p,g as m,i as h,j as g,k as _,l as v,m as y,n as b,o as x,p as S,r as C,s as w,t as T,v as ee,w as E,x as D,y as O}from"./transport.js";import{n as k,t as A}from"./types.js";const j={development:`pk_test_51O7FkjDHAhgRuLtFHdkXdIe8T5i7rOVaG9PCtDetK3UUVKojVUEKHmQacGzigf9mOX1wz3zSOKoYwFjRcTfML9PU00OjJko2lk`,production:`pk_live_51O7FkjDHAhgRuLtFlzLdxJrwo7F09WCKTlzT9lnBePjOGizWnuijkH9oCkoAddkmBT8ngIuqAPkDiHlPEAH4KXbz00Tm0DaPT4`};function M(e){let t=v(e,`widgetSlug`);return{...t,stripePublishableKey:j[t.environment],widgetSlug:t.resourceSlug,widgetSlugValue:t.resourceSlugValue}}const N=E(t(a({email:t(_()),includeServiceFee:t(p()),promoCode:t(_()),tipCents:t(d(0))}),{})),P=E(a({confirmationToken:x,customFieldAnswers:t(f(h)),email:_(),memberId:t(_()),merchSize:t(s([`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`])),metadata:t(n(_(),_())),phone:t(_())})),F=g([a({amountCents:d(1),productId:x}),a({productId:x,quantity:d(1)})]),I=E(r(f(F),ee(1))),L=s([`one-time`,`monthly`,`annually`]),R=u(d(0)),z={description:w,id:x,inventoryQuantity:R,maxQuantity:R,minimumAmountCents:R,minQuantity:R,name:x,paymentOption:L},B=r(i(`pricingMode`,[o({...z,amountCents:d(0),pricingMode:m(`fixed`)}),o({...z,amountCents:R,pricingMode:m(`custom`)})]),S(({maxQuantity:e,minQuantity:t})=>e===null||t===null||t<=e)),V=o({acceptsDiscounts:t(p(),!1),id:x,product:B,productId:x,slug:x}),H=t(o({memberId:t(p(),!1),merchSize:t(p(),!1),phone:t(p(),!1),promoCode:t(p(),!1),serviceFee:t(p(),!1),shipping:t(p(),!1),tipping:t(p(),!1)}),{}),U=r(o({config:t(o({customFields:l,fields:H})),description:w,id:t(_(),``),name:t(_(),`Lockerverse widget`),pricingPolicy:t(o({currency:t(m(`usd`),`usd`),serviceFeeRateBasisPoints:t(d(0),0)})),products:t(f(V),[]),showCommunityBranding:t(p(),!0),title:w}),e(e=>({...e,config:{customFields:e.config?.customFields??[],fields:{memberId:e.config?.fields?.memberId??!1,merchSize:e.config?.fields?.merchSize??!1,phone:e.config?.fields?.phone??!1,promoCode:e.config?.fields?.promoCode??!1,serviceFee:e.config?.fields?.serviceFee??!1,shipping:e.config?.fields?.shipping??!1,tipping:e.config?.fields?.tipping??!1}},pricingPolicy:e.pricingPolicy??{currency:`usd`,serviceFeeRateBasisPoints:0}}))),W=u(o({percentageOff:r(D(),y(),O(0),c(100)),source:s([`email_list`,`promo_code`])})),G=o({acceptsDiscounts:p(),listingId:x,listingSlug:x,paymentOption:L,pricingMode:s([`fixed`,`custom`]),productId:x,productName:x,quantity:d(1),subtotalCents:d(0),unitAmountCents:d(0)}),K=o({amountCents:d(0),appliedDiscount:W,connectedAccountId:u(x),discountableSubtotalCents:d(0),discountCents:d(0),lineItems:f(G),paymentOption:L,serviceFeeCents:d(0),subtotalCents:d(0),tipCents:d(0),totalCents:d(0)}),q=o({checkoutId:x,checkoutStatus:s([`action_required`,`failed`,`pending`,`success`]),clientSecret:u(_()),paymentReference:x,requiresAction:p(),status:u(_())}),J=E(K),Y=E(q),X=E(U);function Z(e){let{product:t}=e;return{acceptsDiscounts:e.acceptsDiscounts??!1,amountCents:t.amountCents,description:t.description??null,id:t.id,inventoryQuantity:t.inventoryQuantity,listingId:e.id,maximumQuantity:t.maxQuantity,minimumAmountCents:t.minimumAmountCents,minimumQuantity:t.minQuantity,name:t.name,paymentOption:t.paymentOption,pricingMode:t.pricingMode,slug:e.slug}}function te(e,t){let n=e.config?.fields??{};return{payment:{currency:`usd`,publishableKey:t},pricingPolicy:{currency:`usd`,serviceFeeRateBasisPoints:e.pricingPolicy?.serviceFeeRateBasisPoints??0},products:(e.products??[]).map(Z),widget:{customFields:e.config?.customFields??[],description:e.description??null,fields:{memberId:n.memberId??!1,merchSize:n.merchSize??!1,phone:n.phone??!1,promoCode:n.promoCode??!1,serviceFee:n.serviceFee??!1,shipping:n.shipping??!1,tipping:n.tipping??!1},id:e.id??``,name:e.name??`Lockerverse widget`,showCommunityBranding:e.showCommunityBranding??!0,title:e.title??null}}}function ne(e){return $(e)}function re(e){return $(e)}function Q(e){return $(e)}function $(e){return C(structuredClone(e))}function ie(e){let{apiBaseUrl:t,communitySlug:n,communitySlugValue:r,environment:i,fetchImplementation:a,onError:o,requestTimeoutMs:s,sentryDsn:c,stripePublishableKey:l,widgetSlug:u,widgetSlugValue:d}=M(e),f=b({communitySlug:r,environment:i,getContext:()=>({widgetSlug:d}),onError:o,resourceContextName:`lockerverse_widget`,sentryDsn:c}),{requestJson:p}=T(a,f,s),m=`${t}/v2/community/${n}/payment-widgets/${u}/checkout`;function h(e,t,n=`invalid_selection`){throw f(new k({code:n,message:e,operation:t,reportable:!1}))}function g(e,t){return e instanceof k?e:new k({...t,reportable:!0})}function _(e,t,n=!1){let r=g(e,t),i=n&&(r.status===void 0||r.status>=500);throw f(i?new k({code:r.code,message:r.message,operation:r.operation,recoveryRecommended:!0,reportable:r.reportable,...r.status===void 0?{}:{status:r.status}}):r)}function v(e,t){let n;try{n=N(e)}catch{h(`Checkout pricing input is invalid.`,t)}let r=n.email?.trim().toLowerCase(),i=n.promoCode?.trim();return{...r?{email:r}:{},...n.includeServiceFee===void 0?{}:{includeServiceFee:n.includeServiceFee},...i?{promoCode:i}:{},...n.tipCents===void 0?{}:{tipCents:n.tipCents}}}function y(e){(!(e&&typeof e==`object`)||Array.isArray(e))&&h(`Checkout selection is invalid.`,`calculate_total`);let{items:t,...n}=e;try{return{items:I(t),pricing:v(n,`calculate_total`)}}catch(e){if(e instanceof k)throw e;h(`Checkout selection is invalid.`,`calculate_total`)}}function x(e){try{if(!(e&&typeof e==`object`)||Array.isArray(e))throw TypeError(`Invalid quote.`);let t=e;if(t.authoritative!==!0||t.paymentOption!==`one-time`||typeof t.paymentReference!=`string`||t.paymentReference.length===0||t.payment.currency!==`usd`||t.payment.publishableKey!==l)throw TypeError(`Invalid quote.`);let n=J({...t,connectedAccountId:t.payment.connectedAccountId});if(n.paymentOption!==`one-time`)throw TypeError(`Unsupported checkout cadence.`);let{connectedAccountId:r,paymentOption:i,...a}=n;return C({...a,authoritative:!0,payment:{connectedAccountId:r,currency:`usd`,publishableKey:l},paymentOption:`one-time`,paymentReference:t.paymentReference})}catch{h(`Lockerverse payment submission is invalid.`,`submit_payment`,`payment_submit_failed`)}}function S(e){try{if(!(e&&typeof e==`object`)||Array.isArray(e))throw TypeError(`Invalid payment input.`);let{checkout:t,submission:n}=e;if(!(t&&typeof t==`object`)||Array.isArray(t))throw TypeError(`Invalid prepared checkout.`);let r=t,i=I(r.items),a=v(r.pricing,`submit_payment`),o=x(r),s=P(n),c=s.email.trim().toLowerCase();return(!c||c!==a.email)&&h(`Payment email must match the current checkout quote.`,`submit_payment`),{items:i,pricing:a,quote:o,submission:{...s,email:c}}}catch(e){if(e instanceof k)throw e;h(`Lockerverse payment submission is invalid.`,`submit_payment`,`payment_submit_failed`)}}return{async calculateTotal(e){let{items:t,pricing:n}=y(e),r={code:`total_calculation_failed`,message:`Lockerverse returned an invalid checkout total.`,operation:`calculate_total`};try{let e=await p(`${m}/quote`,{body:JSON.stringify({...n,items:t}),headers:{"Content-Type":`application/json`},method:`POST`},J,{...r,message:`Unable to calculate the Lockerverse checkout total because the request failed.`,report:!1},{...r,report:!1});if(!e.ok)throw new k({...r,message:`Unable to calculate the Lockerverse checkout total (${e.response.status}).`,reportable:e.response.status>=500,status:e.response.status});if(e.value.paymentOption!==`one-time`)throw new k({...r,message:`Lockerverse returned an unsupported checkout cadence.`,reportable:!0});let{connectedAccountId:i,paymentOption:a,...o}=e.value;return re(C({...o,authoritative:!0,items:t,payment:{connectedAccountId:i,currency:`usd`,publishableKey:l},paymentOption:`one-time`,paymentReference:globalThis.crypto.randomUUID(),pricing:n}))}catch(e){_(e,r)}},async getPaymentStatus(e){(typeof e!=`string`||!e.trim())&&h(`Provide a payment reference to recover its status.`,`get_payment_status`);let t=e.trim(),n={code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`};try{let e=await p(`${m}/${encodeURIComponent(t)}/status`,void 0,Y,{...n,message:`Unable to recover the Lockerverse payment status because the request failed.`,report:!1},{...n,report:!1});if(!e.ok)throw new k({...n,message:`Unable to recover the Lockerverse payment status (${e.response.status}).`,reportable:e.response.status>=500,status:e.response.status});if(e.value.paymentReference!==t)throw new k({...n,reportable:!0});return Q(e.value)}catch(e){_(e,n)}},async load(){let e={code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`};try{let r=await p(`${t}/v2/community/${n}/payment-widgets/${u}`,void 0,X,{...e,message:`Unable to load Lockerverse widget because the request failed.`,report:!1},{...e,report:!1});if(!r.ok)throw new k({...e,message:`Unable to load Lockerverse widget (${r.response.status}).`,reportable:r.response.status>=500,status:r.response.status});return ne(C(te(r.value,l)))}catch(t){_(t,e)}},async submitPayment(e){let{items:t,pricing:n,quote:r,submission:i}=S(e),a={code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`};try{let e=await p(`${m}/confirm`,{body:JSON.stringify({confirmationToken:i.confirmationToken,customFieldAnswers:i.customFieldAnswers,email:i.email,expectedAmountCents:r.amountCents,expectedAppliedDiscount:r.appliedDiscount,expectedConnectedAccountId:r.payment.connectedAccountId,expectedDiscountableSubtotalCents:r.discountableSubtotalCents,expectedDiscountCents:r.discountCents,expectedServiceFeeCents:r.serviceFeeCents,expectedSubtotalCents:r.subtotalCents,expectedTipCents:r.tipCents,expectedTotalCents:r.totalCents,...n,items:t,memberId:i.memberId,merchSize:i.merchSize,metadata:i.metadata,paymentReference:r.paymentReference,phone:i.phone,quoteContractVersion:1}),headers:{"Content-Type":`application/json`},method:`POST`},Y,{...a,message:`Unable to submit the Lockerverse payment because the request failed.`,report:!1},{...a,report:!1});if(!e.ok)throw new k({...a,message:`Unable to submit the Lockerverse payment (${e.response.status}).`,reportable:e.response.status>=500,status:e.response.status});if(e.value.paymentReference!==r.paymentReference)throw new k({...a,reportable:!0});return Q(e.value)}catch(e){_(e,a,!0)}}}}export{A as LOCKERVERSE_SDK_VERSION,k as LockerverseSdkError,ie as createLockerverseCheckoutClient};
2
2
  //# sourceMappingURL=checkout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkout.js","names":[],"sources":["../src/checkout-environment.ts","../src/checkout-input-schemas.ts","../src/checkout-schemas.ts","../src/pricing.ts","../src/snapshots.ts","../src/checkout.ts"],"sourcesContent":["import { resolveResourceEnvironment } from \"./environment.ts\";\nimport type {\n CreateLockerverseWidgetOptions,\n LockerverseEnvironment,\n} from \"./types.ts\";\n\nconst STRIPE_PUBLISHABLE_KEYS: Record<LockerverseEnvironment, string> = {\n development:\n \"pk_test_51O7FkjDHAhgRuLtFHdkXdIe8T5i7rOVaG9PCtDetK3UUVKojVUEKHmQacGzigf9mOX1wz3zSOKoYwFjRcTfML9PU00OjJko2lk\",\n production:\n \"pk_live_51O7FkjDHAhgRuLtFlzLdxJrwo7F09WCKTlzT9lnBePjOGizWnuijkH9oCkoAddkmBT8ngIuqAPkDiHlPEAH4KXbz00Tm0DaPT4\",\n};\n\nexport function resolveWidgetEnvironment(\n options: CreateLockerverseWidgetOptions\n) {\n const runtime = resolveResourceEnvironment(options, \"widgetSlug\");\n return {\n ...runtime,\n stripePublishableKey: STRIPE_PUBLISHABLE_KEYS[runtime.environment],\n widgetSlug: runtime.resourceSlug,\n widgetSlugValue: runtime.resourceSlugValue,\n };\n}\n","import {\n array,\n boolean,\n optional,\n parser,\n picklist,\n record,\n strictObject,\n string,\n} from \"valibot\";\n\nimport {\n customFieldAnswerSchema,\n nonEmptyStringSchema,\n safeIntegerSchema,\n} from \"./schema-helpers.ts\";\n\nexport const parseCheckoutPricingInput = parser(\n optional(\n strictObject({\n email: optional(string()),\n includeServiceFee: optional(boolean()),\n promoCode: optional(string()),\n tipCents: optional(safeIntegerSchema(0)),\n }),\n {}\n )\n);\n\nexport const parsePaymentSubmission = parser(\n strictObject({\n confirmationToken: nonEmptyStringSchema,\n customFieldAnswers: optional(array(customFieldAnswerSchema)),\n email: string(),\n memberId: optional(string()),\n merchSize: optional(picklist([\"XS\", \"S\", \"M\", \"L\", \"XL\", \"XXL\", \"XXXL\"])),\n metadata: optional(record(string(), string())),\n phone: optional(string()),\n })\n);\n","import {\n array,\n boolean,\n check,\n finite,\n type InferOutput,\n literal,\n maxValue,\n minValue,\n nullable,\n number,\n object,\n optional,\n parser,\n picklist,\n pipe,\n string,\n transform,\n variant,\n} from \"valibot\";\n\nimport {\n customFieldsSchema,\n nonEmptyStringSchema,\n optionalNullableStringSchema,\n safeIntegerSchema,\n} from \"./schema-helpers.ts\";\n\nconst paymentOptionSchema = picklist([\"one-time\", \"monthly\", \"annually\"]);\nconst nullableNonNegativeIntegerSchema = nullable(safeIntegerSchema(0));\n\nconst productBaseEntries = {\n description: optionalNullableStringSchema,\n id: nonEmptyStringSchema,\n inventoryQuantity: nullableNonNegativeIntegerSchema,\n maxQuantity: nullableNonNegativeIntegerSchema,\n minimumAmountCents: nullableNonNegativeIntegerSchema,\n minQuantity: nullableNonNegativeIntegerSchema,\n name: nonEmptyStringSchema,\n paymentOption: paymentOptionSchema,\n};\n\nconst publicProductSchema = pipe(\n variant(\"pricingMode\", [\n object({\n ...productBaseEntries,\n amountCents: safeIntegerSchema(0),\n pricingMode: literal(\"fixed\"),\n }),\n object({\n ...productBaseEntries,\n amountCents: nullableNonNegativeIntegerSchema,\n pricingMode: literal(\"custom\"),\n }),\n ]),\n check(\n ({ maxQuantity, minQuantity }) =>\n maxQuantity === null || minQuantity === null || minQuantity <= maxQuantity\n )\n);\n\nconst productListingSchema = object({\n acceptsDiscounts: optional(boolean(), false),\n id: nonEmptyStringSchema,\n product: publicProductSchema,\n productId: nonEmptyStringSchema,\n slug: nonEmptyStringSchema,\n});\n\nconst widgetFieldsSchema = optional(\n object({\n memberId: optional(boolean(), false),\n merchSize: optional(boolean(), false),\n phone: optional(boolean(), false),\n promoCode: optional(boolean(), false),\n serviceFee: optional(boolean(), false),\n shipping: optional(boolean(), false),\n tipping: optional(boolean(), false),\n }),\n {}\n);\n\nexport const publicWidgetSchema = pipe(\n object({\n config: optional(\n object({\n customFields: customFieldsSchema,\n fields: widgetFieldsSchema,\n })\n ),\n description: optionalNullableStringSchema,\n id: optional(string(), \"\"),\n name: optional(string(), \"Lockerverse widget\"),\n pricingPolicy: optional(\n object({\n currency: optional(literal(\"usd\"), \"usd\"),\n serviceFeeRateBasisPoints: optional(safeIntegerSchema(0), 0),\n })\n ),\n products: optional(array(productListingSchema), []),\n showCommunityBranding: optional(boolean(), true),\n title: optionalNullableStringSchema,\n }),\n transform((widget) => ({\n ...widget,\n config: {\n customFields: widget.config?.customFields ?? [],\n fields: {\n memberId: widget.config?.fields?.memberId ?? false,\n merchSize: widget.config?.fields?.merchSize ?? false,\n phone: widget.config?.fields?.phone ?? false,\n promoCode: widget.config?.fields?.promoCode ?? false,\n serviceFee: widget.config?.fields?.serviceFee ?? false,\n shipping: widget.config?.fields?.shipping ?? false,\n tipping: widget.config?.fields?.tipping ?? false,\n },\n },\n pricingPolicy: widget.pricingPolicy ?? {\n currency: \"usd\" as const,\n serviceFeeRateBasisPoints: 0,\n },\n }))\n);\n\nconst appliedDiscountSchema = nullable(\n object({\n percentageOff: pipe(number(), finite(), minValue(0), maxValue(100)),\n source: picklist([\"email_list\", \"promo_code\"]),\n })\n);\n\nconst checkoutLineItemSchema = object({\n acceptsDiscounts: boolean(),\n listingId: nonEmptyStringSchema,\n listingSlug: nonEmptyStringSchema,\n paymentOption: paymentOptionSchema,\n pricingMode: picklist([\"fixed\", \"custom\"]),\n productId: nonEmptyStringSchema,\n productName: nonEmptyStringSchema,\n quantity: safeIntegerSchema(1),\n subtotalCents: safeIntegerSchema(0),\n unitAmountCents: safeIntegerSchema(0),\n});\n\nexport const checkoutQuoteSchema = object({\n amountCents: safeIntegerSchema(0),\n appliedDiscount: appliedDiscountSchema,\n connectedAccountId: nullable(nonEmptyStringSchema),\n discountableSubtotalCents: safeIntegerSchema(0),\n discountCents: safeIntegerSchema(0),\n lineItems: array(checkoutLineItemSchema),\n paymentOption: paymentOptionSchema,\n serviceFeeCents: safeIntegerSchema(0),\n subtotalCents: safeIntegerSchema(0),\n tipCents: safeIntegerSchema(0),\n totalCents: safeIntegerSchema(0),\n});\n\nexport const paymentResultSchema = object({\n checkoutId: nonEmptyStringSchema,\n checkoutStatus: picklist([\"action_required\", \"failed\", \"pending\", \"success\"]),\n clientSecret: nullable(string()),\n paymentReference: nonEmptyStringSchema,\n requiresAction: boolean(),\n status: nullable(string()),\n});\n\nexport type PublicCheckoutQuote = InferOutput<typeof checkoutQuoteSchema>;\nexport type PublicProductListing = InferOutput<typeof productListingSchema>;\nexport type PublicWidget = InferOutput<typeof publicWidgetSchema>;\n\nexport const parseCheckoutQuote = parser(checkoutQuoteSchema);\nexport const parsePaymentResult = parser(paymentResultSchema);\nexport const parsePublicWidget = parser(publicWidgetSchema);\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutPreview,\n LockerverseCheckoutPricingInput,\n LockerverseSelection,\n} from \"./types.ts\";\n\nconst BASIS_POINTS_PER_WHOLE = 10_000;\n\nfunction assertSafeCents(value: number, message: string) {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new TypeError(message);\n }\n return value;\n}\n\nfunction addCents(left: number, right: number) {\n return assertSafeCents(\n left + right,\n \"The selected checkout total is too large.\"\n );\n}\n\nfunction multiplyCents(value: number, quantity: number) {\n return assertSafeCents(\n value * quantity,\n \"The selected Product quantity produces an unsafe total.\"\n );\n}\n\nfunction calculateBasisPoints(value: number, basisPoints: number) {\n const rounded =\n (BigInt(value) * BigInt(basisPoints) + BigInt(BASIS_POINTS_PER_WHOLE / 2)) /\n BigInt(BASIS_POINTS_PER_WHOLE);\n if (rounded > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new TypeError(\"The selected checkout total is too large.\");\n }\n return Number(rounded);\n}\n\nexport function calculateCheckoutPreview(\n catalog: LockerverseCatalog,\n selection: LockerverseSelection,\n input: LockerverseCheckoutPricingInput\n): LockerverseCheckoutPreview {\n let subtotalCents = 0;\n let discountableSubtotalCents = 0;\n\n for (const item of selection.items) {\n const product = catalog.products.find(\n ({ id, slug }) => id === item.productId && slug === item.productSlug\n );\n if (!product) {\n throw new TypeError(\"The selected Product is no longer available.\");\n }\n if (product.paymentOption !== \"one-time\") {\n throw new TypeError(\n \"Recurring Products are not supported by this SDK checkout yet.\"\n );\n }\n const itemSubtotal =\n \"quantity\" in item\n ? multiplyCents(product.amountCents ?? 0, item.quantity)\n : item.amountCents;\n subtotalCents = addCents(subtotalCents, itemSubtotal);\n if (product.acceptsDiscounts) {\n discountableSubtotalCents = addCents(\n discountableSubtotalCents,\n itemSubtotal\n );\n }\n }\n\n const serviceFeeCents = input.includeServiceFee\n ? calculateBasisPoints(\n subtotalCents,\n catalog.pricingPolicy.serviceFeeRateBasisPoints\n )\n : 0;\n const tipCents = input.tipCents ?? 0;\n const amountCents = addCents(subtotalCents, serviceFeeCents);\n\n return {\n amountCents,\n appliedDiscount: null,\n authoritative: false,\n discountableSubtotalCents,\n discountCents: 0,\n serviceFeeCents,\n subtotalCents,\n tipCents,\n totalCents: addCents(amountCents, tipCents),\n };\n}\n","import type { PublicProductListing, PublicWidget } from \"./checkout-schemas.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\nimport type {\n LockerverseCatalog,\n LockerverseCheckoutTotal,\n LockerversePaymentResult,\n LockerverseProduct,\n} from \"./types.ts\";\n\nfunction mapProduct(listing: PublicProductListing): LockerverseProduct {\n const { product } = listing;\n\n return {\n acceptsDiscounts: listing.acceptsDiscounts ?? false,\n amountCents: product.amountCents,\n description: product.description ?? null,\n id: product.id,\n inventoryQuantity: product.inventoryQuantity,\n listingId: listing.id,\n maximumQuantity: product.maxQuantity,\n minimumAmountCents: product.minimumAmountCents,\n minimumQuantity: product.minQuantity,\n name: product.name,\n paymentOption: product.paymentOption,\n pricingMode: product.pricingMode,\n slug: listing.slug,\n };\n}\n\nexport function createCatalog(\n widget: PublicWidget,\n publishableKey: string\n): LockerverseCatalog {\n const fields = widget.config?.fields ?? {};\n\n return {\n payment: {\n currency: \"usd\",\n publishableKey,\n },\n pricingPolicy: {\n currency: \"usd\",\n serviceFeeRateBasisPoints:\n widget.pricingPolicy?.serviceFeeRateBasisPoints ?? 0,\n },\n products: (widget.products ?? []).map(mapProduct),\n widget: {\n customFields: widget.config?.customFields ?? [],\n description: widget.description ?? null,\n fields: {\n memberId: fields.memberId ?? false,\n merchSize: fields.merchSize ?? false,\n phone: fields.phone ?? false,\n promoCode: fields.promoCode ?? false,\n serviceFee: fields.serviceFee ?? false,\n shipping: fields.shipping ?? false,\n tipping: fields.tipping ?? false,\n },\n id: widget.id ?? \"\",\n name: widget.name ?? \"Lockerverse widget\",\n showCommunityBranding: widget.showCommunityBranding ?? true,\n title: widget.title ?? null,\n },\n };\n}\n\nexport function cloneCatalog(catalog: LockerverseCatalog): LockerverseCatalog {\n return cloneSnapshot(catalog);\n}\n\nexport function cloneCheckoutTotal(\n total: LockerverseCheckoutTotal\n): LockerverseCheckoutTotal {\n return cloneSnapshot(total);\n}\n\nexport function clonePaymentResult(\n paymentResult: LockerversePaymentResult\n): LockerversePaymentResult {\n return cloneSnapshot(paymentResult);\n}\n\nfunction cloneSnapshot<T>(value: T): T {\n return deepFreeze(structuredClone(value));\n}\n","import { resolveWidgetEnvironment } from \"./checkout-environment.ts\";\nimport {\n parseCheckoutPricingInput,\n parsePaymentSubmission,\n} from \"./checkout-input-schemas.ts\";\nimport {\n type PublicCheckoutQuote,\n parseCheckoutQuote,\n parsePaymentResult,\n parsePublicWidget,\n} from \"./checkout-schemas.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\nimport { createSdkErrorReporter } from \"./error-reporting.ts\";\nimport { calculateCheckoutPreview } from \"./pricing.ts\";\nimport {\n cloneCatalog,\n cloneCheckoutTotal,\n clonePaymentResult,\n createCatalog,\n} from \"./snapshots.ts\";\nimport { createStateStore } from \"./state.ts\";\nimport { createTransport } from \"./transport.ts\";\nimport {\n type CreateLockerverseWidgetOptions,\n type LockerverseCatalog,\n type LockerverseCheckoutPreview,\n type LockerverseCheckoutPricingInput,\n type LockerverseCheckoutTotal,\n LockerverseSdkError,\n type LockerverseSdkOperation,\n type LockerverseSelection,\n type LockerverseWidget,\n type LockerverseWidgetState,\n} from \"./types.ts\";\n\nexport function createLockerverseCheckout(\n options: CreateLockerverseWidgetOptions\n): LockerverseWidget {\n const {\n apiBaseUrl,\n communitySlug,\n communitySlugValue,\n environment,\n fetchImplementation,\n onError,\n requestTimeoutMs,\n sentryDsn,\n stripePublishableKey,\n widgetSlug,\n widgetSlugValue,\n } = resolveWidgetEnvironment(options);\n let catalog: LockerverseCatalog | null = null;\n let calculatedTotal: LockerverseCheckoutTotal | null = null;\n let calculatedPricingInput: LockerverseCheckoutPricingInput | null = null;\n let latestPaymentReference: string | null = null;\n let latestPreview: LockerverseCheckoutPreview | null = null;\n let remoteOperationGeneration = 0;\n let stateRevision = 0;\n let submitting = false;\n const selection = new Map<\n string,\n { amountCents: number } | { quantity: number }\n >();\n const stateStore = createStateStore<LockerverseWidgetState>({\n phase: \"idle\",\n selection: deepFreeze({ items: [] }),\n });\n\n function getProduct(productSlug: string) {\n const currentCatalog = catalog;\n const product = currentCatalog\n ? currentCatalog.products.find(({ slug }) => slug === productSlug)\n : undefined;\n\n if (!product) {\n throw new Error(`Lockerverse Product \"${productSlug}\" is unavailable.`);\n }\n\n return product;\n }\n\n const reportError = createSdkErrorReporter({\n communitySlug: communitySlugValue,\n environment,\n getContext: () => ({\n paymentReference: latestPaymentReference,\n widgetSlug: widgetSlugValue,\n }),\n onError,\n resourceContextName: \"lockerverse_widget\",\n sentryDsn,\n });\n\n function invalidSelection(\n message: string,\n operation: LockerverseSdkOperation = \"update_selection\"\n ): never {\n throw reportError(\n new LockerverseSdkError({\n code: \"invalid_selection\",\n message,\n operation,\n reportable: false,\n })\n );\n }\n\n const { requestJson } = createTransport(\n fetchImplementation,\n reportError,\n requestTimeoutMs\n );\n\n function getSelection(): LockerverseSelection {\n const currentCatalog = catalog;\n return deepFreeze({\n items: (currentCatalog ? currentCatalog.products : []).flatMap(\n (product) => {\n const selected = selection.get(product.slug);\n return selected\n ? [\n {\n productId: product.id,\n productSlug: product.slug,\n ...selected,\n },\n ]\n : [];\n }\n ),\n });\n }\n\n function invalidateCalculatedTotal() {\n calculatedTotal = null;\n calculatedPricingInput = null;\n latestPaymentReference = null;\n latestPreview = null;\n }\n\n function ensureSelectionMutable() {\n if (submitting) {\n invalidSelection(\n \"Selection cannot change while a payment is being submitted.\"\n );\n }\n }\n\n function ensureOperationAvailable(operation: LockerverseSdkOperation) {\n if (submitting) {\n invalidSelection(\n \"This operation cannot run while a payment is being submitted.\",\n operation\n );\n }\n }\n\n function reviseState() {\n stateRevision += 1;\n invalidateCalculatedTotal();\n }\n\n function commitReady(preview: LockerverseCheckoutPreview | null = null) {\n if (!catalog) {\n return;\n }\n stateStore.commit({\n catalog,\n phase: \"ready\",\n preview,\n selection: getSelection(),\n });\n }\n\n function commitError(\n error: LockerverseSdkError,\n recoverablePaymentReference: string | null = null\n ) {\n stateStore.commit({\n catalog,\n error,\n phase: \"error\",\n recoverablePaymentReference,\n selection: getSelection(),\n });\n }\n\n function normalizeOperationError(\n error: unknown,\n context: {\n code:\n | \"payment_status_failed\"\n | \"payment_submit_failed\"\n | \"widget_load_failed\";\n message: string;\n operation: \"get_payment_status\" | \"load_widget\" | \"submit_payment\";\n }\n ) {\n return error instanceof LockerverseSdkError\n ? error\n : new LockerverseSdkError({\n ...context,\n reportable: true,\n });\n }\n\n function startRemoteOperation() {\n remoteOperationGeneration += 1;\n return remoteOperationGeneration;\n }\n\n function rejectSupersededRemoteOperation(\n requestedGeneration: number,\n context: {\n code:\n | \"payment_status_failed\"\n | \"total_calculation_failed\"\n | \"widget_load_failed\";\n message: string;\n operation: \"calculate_total\" | \"get_payment_status\" | \"load_widget\";\n },\n shouldReport = true\n ) {\n if (requestedGeneration === remoteOperationGeneration) {\n return;\n }\n\n const error = new LockerverseSdkError({\n ...context,\n reportable: false,\n });\n throw shouldReport ? reportError(error) : error;\n }\n\n function rejectSupersededQuote(\n requestedStateRevision: number,\n requestedRemoteOperationGeneration: number\n ) {\n if (\n requestedStateRevision === stateRevision &&\n requestedRemoteOperationGeneration === remoteOperationGeneration\n ) {\n return;\n }\n\n throw reportError(\n new LockerverseSdkError({\n code: \"total_calculation_failed\",\n message:\n \"This Lockerverse checkout total was superseded. Calculate the total again for the current selection.\",\n operation: \"calculate_total\",\n reportable: false,\n })\n );\n }\n\n function previewTotal(input: LockerverseCheckoutPricingInput = {}) {\n ensureOperationAvailable(\"calculate_total\");\n if (!catalog) {\n throw new Error(\n \"Load the Lockerverse widget before previewing the total.\"\n );\n }\n if (selection.size === 0) {\n invalidSelection(\"Select at least one Product before previewing.\");\n }\n const normalizedInput = normalizePricingInput(catalog, input);\n reviseState();\n\n try {\n const preview = deepFreeze(\n calculateCheckoutPreview(catalog, getSelection(), normalizedInput)\n );\n latestPreview = preview;\n commitReady(preview);\n return preview;\n } catch (error) {\n invalidSelection(\n error instanceof Error ? error.message : \"Unable to preview checkout.\"\n );\n }\n }\n\n function normalizePricingInput(\n currentCatalog: LockerverseCatalog,\n input: LockerverseCheckoutPricingInput\n ): LockerverseCheckoutPricingInput {\n let parsedInput: ReturnType<typeof parseCheckoutPricingInput>;\n try {\n parsedInput = parseCheckoutPricingInput(input);\n } catch {\n invalidSelection(\"Checkout pricing input is invalid.\");\n }\n validatePricingInput(currentCatalog, parsedInput);\n const tipCents = parsedInput.tipCents ?? 0;\n const email = parsedInput.email?.trim().toLowerCase();\n const promoCode = parsedInput.promoCode?.trim();\n return {\n ...(email ? { email } : {}),\n ...(parsedInput.includeServiceFee === undefined\n ? {}\n : { includeServiceFee: parsedInput.includeServiceFee }),\n ...(promoCode ? { promoCode } : {}),\n ...(parsedInput.tipCents === undefined ? {} : { tipCents }),\n };\n }\n\n function validatePricingInput(\n currentCatalog: LockerverseCatalog,\n input: ReturnType<typeof parseCheckoutPricingInput>\n ) {\n const tipCents = input.tipCents ?? 0;\n if (!Number.isSafeInteger(tipCents) || tipCents < 0) {\n invalidSelection(\"Tip must be a non-negative whole number of cents.\");\n }\n if (input.includeServiceFee && !currentCatalog.widget.fields.serviceFee) {\n invalidSelection(\"Service fee is not enabled for this widget.\");\n }\n if (\n input.includeServiceFee &&\n currentCatalog.pricingPolicy.serviceFeeRateBasisPoints === 0\n ) {\n invalidSelection(\n \"Service fee pricing is unavailable. Reload the widget and try again.\"\n );\n }\n if (tipCents > 0 && !currentCatalog.widget.fields.tipping) {\n invalidSelection(\"Tipping is not enabled for this widget.\");\n }\n }\n\n async function calculateTotal(input: LockerverseCheckoutPricingInput = {}) {\n ensureOperationAvailable(\"calculate_total\");\n if (!catalog) {\n throw new Error(\n \"Load the Lockerverse widget before calculating the total.\"\n );\n }\n\n const normalizedInput = normalizePricingInput(catalog, input);\n if (selection.size === 0) {\n invalidSelection(\n \"Select at least one Product before calculating the total.\",\n \"calculate_total\"\n );\n }\n const currentSelection = getSelection();\n const requestedRemoteOperationGeneration = startRemoteOperation();\n const preview = deepFreeze(\n calculateCheckoutPreview(catalog, currentSelection, normalizedInput)\n );\n latestPreview = preview;\n stateStore.commit({\n catalog,\n phase: \"quoting\",\n preview,\n selection: currentSelection,\n });\n const items = currentSelection.items.map(\n ({ productSlug: _productSlug, ...item }) => item\n );\n const requestedStateRevision = stateRevision;\n calculatedTotal = null;\n latestPaymentReference = null;\n const quoteRequest = requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}/checkout/quote`,\n {\n body: JSON.stringify({ ...normalizedInput, items }),\n headers: { \"Content-Type\": \"application/json\" },\n method: \"POST\",\n },\n parseCheckoutQuote,\n {\n code: \"total_calculation_failed\",\n message:\n \"Unable to calculate the Lockerverse checkout total because the request failed.\",\n operation: \"calculate_total\",\n report: false,\n },\n {\n code: \"total_calculation_failed\",\n message: \"Lockerverse returned an invalid checkout total.\",\n operation: \"calculate_total\",\n report: false,\n }\n );\n let quoteResponse: Awaited<typeof quoteRequest>;\n\n try {\n quoteResponse = await quoteRequest;\n } catch (error) {\n rejectSupersededQuote(\n requestedStateRevision,\n requestedRemoteOperationGeneration\n );\n if (error instanceof LockerverseSdkError) {\n commitError(error);\n throw reportError(error);\n }\n throw error;\n }\n\n rejectSupersededQuote(\n requestedStateRevision,\n requestedRemoteOperationGeneration\n );\n\n if (!quoteResponse.ok) {\n const error = new LockerverseSdkError({\n code: \"total_calculation_failed\",\n message: `Unable to calculate the Lockerverse checkout total (${quoteResponse.response.status}).`,\n operation: \"calculate_total\",\n reportable: quoteResponse.response.status >= 500,\n status: quoteResponse.response.status,\n });\n commitError(error);\n throw reportError(error);\n }\n\n let serverTotal: PublicCheckoutQuote;\n try {\n serverTotal = quoteResponse.value;\n if (serverTotal.paymentOption !== \"one-time\") {\n throw new LockerverseSdkError({\n code: \"total_calculation_failed\",\n message: \"Lockerverse returned an unsupported checkout cadence.\",\n operation: \"calculate_total\",\n reportable: true,\n });\n }\n } catch (error) {\n rejectSupersededQuote(\n requestedStateRevision,\n requestedRemoteOperationGeneration\n );\n if (error instanceof LockerverseSdkError) {\n commitError(error);\n throw reportError(error);\n }\n throw error;\n }\n rejectSupersededQuote(\n requestedStateRevision,\n requestedRemoteOperationGeneration\n );\n const paymentReference = globalThis.crypto.randomUUID();\n const {\n connectedAccountId,\n paymentOption: _paymentOption,\n ...total\n } = serverTotal;\n const nextCalculatedTotal = deepFreeze({\n ...total,\n authoritative: true as const,\n payment: {\n ...catalog.payment,\n connectedAccountId,\n },\n paymentOption: \"one-time\" as const,\n paymentReference,\n });\n calculatedTotal = nextCalculatedTotal;\n calculatedPricingInput = deepFreeze({ ...normalizedInput });\n latestPaymentReference = paymentReference;\n stateStore.commit({\n catalog,\n phase: \"quoted\",\n preview,\n quote: nextCalculatedTotal,\n selection: currentSelection,\n });\n return cloneCheckoutTotal(nextCalculatedTotal);\n }\n\n return {\n calculateTotal,\n clear() {\n ensureSelectionMutable();\n selection.clear();\n reviseState();\n commitReady();\n },\n async getPaymentStatus(paymentReference = latestPaymentReference ?? \"\") {\n ensureOperationAvailable(\"get_payment_status\");\n if (!paymentReference) {\n invalidSelection(\n \"Provide a payment reference to recover its status.\",\n \"get_payment_status\"\n );\n }\n const requestedRemoteOperationGeneration = startRemoteOperation();\n const supersededContext = {\n code: \"payment_status_failed\" as const,\n message: \"This Lockerverse payment status request was superseded.\",\n operation: \"get_payment_status\" as const,\n };\n latestPaymentReference = paymentReference;\n const currentSelection = getSelection();\n stateStore.commit({\n catalog,\n paymentReference,\n phase: \"recovering\",\n selection: currentSelection,\n });\n try {\n const statusResponse = await requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}/checkout/${encodeURIComponent(paymentReference)}/status`,\n undefined,\n parsePaymentResult,\n {\n code: \"payment_status_failed\",\n message:\n \"Unable to recover the Lockerverse payment status because the request failed.\",\n operation: \"get_payment_status\",\n report: false,\n },\n {\n code: \"payment_status_failed\",\n message: \"Lockerverse returned an invalid payment status.\",\n operation: \"get_payment_status\",\n report: false,\n }\n );\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext,\n false\n );\n if (!statusResponse.ok) {\n throw new LockerverseSdkError({\n code: \"payment_status_failed\",\n message: `Unable to recover the Lockerverse payment status (${statusResponse.response.status}).`,\n operation: \"get_payment_status\",\n reportable: statusResponse.response.status >= 500,\n status: statusResponse.response.status,\n });\n }\n\n const payment = clonePaymentResult(statusResponse.value);\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext,\n false\n );\n if (payment.paymentReference !== paymentReference) {\n throw new LockerverseSdkError({\n code: \"payment_status_failed\",\n message: \"Lockerverse returned an invalid payment status.\",\n operation: \"get_payment_status\",\n reportable: true,\n });\n }\n stateStore.commit({\n catalog,\n payment,\n phase: \"payment\",\n quote:\n calculatedTotal?.paymentReference === paymentReference\n ? calculatedTotal\n : null,\n selection: currentSelection,\n });\n return clonePaymentResult(payment);\n } catch (error) {\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext\n );\n const sdkError = normalizeOperationError(error, {\n code: \"payment_status_failed\",\n message: \"Lockerverse returned an invalid payment status.\",\n operation: \"get_payment_status\",\n });\n commitError(sdkError, paymentReference);\n throw reportError(sdkError);\n }\n },\n getSelection,\n getState: stateStore.getState,\n async load() {\n ensureOperationAvailable(\"load_widget\");\n const requestedRemoteOperationGeneration = startRemoteOperation();\n const supersededContext = {\n code: \"widget_load_failed\" as const,\n message: \"This Lockerverse widget load was superseded.\",\n operation: \"load_widget\" as const,\n };\n reviseState();\n stateStore.commit({ phase: \"loading\", selection: getSelection() });\n const requestContext = {\n code: \"widget_load_failed\" as const,\n message:\n \"Unable to load Lockerverse widget because the request failed.\",\n operation: \"load_widget\" as const,\n report: false,\n };\n try {\n const widgetResponse = await requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}`,\n undefined,\n parsePublicWidget,\n requestContext,\n {\n code: \"widget_load_failed\",\n message: \"Lockerverse returned an invalid widget catalog.\",\n operation: \"load_widget\",\n report: false,\n }\n );\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext,\n false\n );\n if (!widgetResponse.ok) {\n throw new LockerverseSdkError({\n code: \"widget_load_failed\",\n message: `Unable to load Lockerverse widget (${widgetResponse.response.status}).`,\n operation: \"load_widget\",\n reportable: widgetResponse.response.status >= 500,\n status: widgetResponse.response.status,\n });\n }\n\n const widget = widgetResponse.value;\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext,\n false\n );\n const nextCatalog = deepFreeze(\n createCatalog(widget, stripePublishableKey)\n );\n const catalogResult = cloneCatalog(nextCatalog);\n selection.clear();\n catalog = nextCatalog;\n commitReady();\n\n return catalogResult;\n } catch (error) {\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext\n );\n const sdkError = normalizeOperationError(error, {\n code: \"widget_load_failed\",\n message: \"Lockerverse returned an invalid widget catalog.\",\n operation: \"load_widget\",\n });\n commitError(sdkError);\n throw reportError(sdkError);\n }\n },\n previewTotal,\n remove(productSlug) {\n ensureSelectionMutable();\n selection.delete(productSlug);\n reviseState();\n commitReady();\n },\n setAmount(productSlug, amountCents) {\n ensureSelectionMutable();\n const product = getProduct(productSlug);\n\n if (product.pricingMode !== \"custom\") {\n invalidSelection(\"Fixed-price Products do not accept custom amounts.\");\n }\n if (!Number.isSafeInteger(amountCents) || amountCents <= 0) {\n invalidSelection(\"Product amount must be a positive integer in cents.\");\n }\n if (\n product.minimumAmountCents !== null &&\n amountCents < product.minimumAmountCents\n ) {\n invalidSelection(\n `Product amount must be at least ${product.minimumAmountCents} cents.`\n );\n }\n\n selection.set(productSlug, { amountCents });\n reviseState();\n commitReady();\n },\n setQuantity(productSlug, quantity) {\n ensureSelectionMutable();\n const product = getProduct(productSlug);\n\n if (product.pricingMode !== \"fixed\") {\n invalidSelection(\"Custom-amount Products do not accept quantities.\");\n }\n if (!Number.isSafeInteger(quantity) || quantity <= 0) {\n invalidSelection(\"Product quantity must be a positive integer.\");\n }\n if (\n product.minimumQuantity !== null &&\n quantity < product.minimumQuantity\n ) {\n invalidSelection(\n `Product quantity must be at least ${product.minimumQuantity}.`\n );\n }\n if (\n product.maximumQuantity !== null &&\n quantity > product.maximumQuantity\n ) {\n invalidSelection(\n `Product quantity must not exceed ${product.maximumQuantity}.`\n );\n }\n if (\n product.inventoryQuantity !== null &&\n quantity > product.inventoryQuantity\n ) {\n invalidSelection(\"Requested Product quantity is unavailable.\");\n }\n\n selection.set(productSlug, { quantity });\n reviseState();\n commitReady();\n },\n async submitPayment(submission) {\n if (!(catalog && calculatedTotal && calculatedPricingInput)) {\n invalidSelection(\n \"Calculate the current total before submitting a payment.\",\n \"submit_payment\"\n );\n }\n if (submitting) {\n invalidSelection(\n \"A Lockerverse payment is already being submitted.\",\n \"submit_payment\"\n );\n }\n\n const transactionCatalog = catalog;\n const transactionQuote = calculatedTotal;\n const transactionPricingInput = calculatedPricingInput;\n const transactionSelection = getSelection();\n const transactionPreview =\n latestPreview ??\n calculateCheckoutPreview(\n transactionCatalog,\n transactionSelection,\n transactionPricingInput\n );\n let parsedSubmission: ReturnType<typeof parsePaymentSubmission>;\n try {\n parsedSubmission = parsePaymentSubmission(submission);\n } catch {\n const error = new LockerverseSdkError({\n code: \"payment_submit_failed\",\n message: \"Lockerverse payment submission is invalid.\",\n operation: \"submit_payment\",\n reportable: true,\n });\n commitError(error, transactionQuote.paymentReference);\n // biome-ignore lint/style/useErrorCause: Raw validation errors must not escape the SDK boundary.\n throw reportError(error);\n }\n const normalizedEmail = parsedSubmission.email.trim().toLowerCase();\n if (\n !normalizedEmail ||\n normalizedEmail !== transactionPricingInput.email\n ) {\n invalidSelection(\n \"Payment email must match the current checkout quote.\",\n \"submit_payment\"\n );\n }\n\n const items = transactionSelection.items.map(\n ({ productSlug: _productSlug, ...item }) => item\n );\n startRemoteOperation();\n submitting = true;\n stateStore.commit({\n catalog: transactionCatalog,\n phase: \"submitting\",\n preview: transactionPreview,\n quote: transactionQuote,\n selection: transactionSelection,\n });\n try {\n const confirmationResponse = await requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}/checkout/confirm`,\n {\n body: JSON.stringify({\n confirmationToken: parsedSubmission.confirmationToken,\n customFieldAnswers: parsedSubmission.customFieldAnswers,\n email: normalizedEmail,\n expectedAmountCents: transactionQuote.amountCents,\n expectedAppliedDiscount: transactionQuote.appliedDiscount,\n expectedConnectedAccountId:\n transactionQuote.payment.connectedAccountId,\n expectedDiscountableSubtotalCents:\n transactionQuote.discountableSubtotalCents,\n expectedDiscountCents: transactionQuote.discountCents,\n expectedServiceFeeCents: transactionQuote.serviceFeeCents,\n expectedSubtotalCents: transactionQuote.subtotalCents,\n expectedTipCents: transactionQuote.tipCents,\n expectedTotalCents: transactionQuote.totalCents,\n ...transactionPricingInput,\n items,\n memberId: parsedSubmission.memberId,\n merchSize: parsedSubmission.merchSize,\n metadata: parsedSubmission.metadata,\n paymentReference: transactionQuote.paymentReference,\n phone: parsedSubmission.phone,\n quoteContractVersion: 1,\n }),\n headers: { \"Content-Type\": \"application/json\" },\n method: \"POST\",\n },\n parsePaymentResult,\n {\n code: \"payment_submit_failed\",\n message:\n \"Unable to submit the Lockerverse payment because the request failed.\",\n operation: \"submit_payment\",\n report: false,\n },\n {\n code: \"payment_submit_failed\",\n message: \"Lockerverse returned an invalid payment confirmation.\",\n operation: \"submit_payment\",\n report: false,\n }\n );\n\n if (!confirmationResponse.ok) {\n throw new LockerverseSdkError({\n code: \"payment_submit_failed\",\n message: `Unable to submit the Lockerverse payment (${confirmationResponse.response.status}).`,\n operation: \"submit_payment\",\n reportable: confirmationResponse.response.status >= 500,\n status: confirmationResponse.response.status,\n });\n }\n\n const payment = clonePaymentResult(confirmationResponse.value);\n if (payment.paymentReference !== transactionQuote.paymentReference) {\n throw new LockerverseSdkError({\n code: \"payment_submit_failed\",\n message: \"Lockerverse returned an invalid payment confirmation.\",\n operation: \"submit_payment\",\n reportable: true,\n });\n }\n stateStore.commit({\n catalog: transactionCatalog,\n payment,\n phase: \"payment\",\n quote: transactionQuote,\n selection: transactionSelection,\n });\n return clonePaymentResult(payment);\n } catch (error) {\n const sdkError = normalizeOperationError(error, {\n code: \"payment_submit_failed\",\n message: \"Lockerverse returned an invalid payment confirmation.\",\n operation: \"submit_payment\",\n });\n commitError(sdkError, transactionQuote.paymentReference);\n throw reportError(sdkError);\n } finally {\n submitting = false;\n }\n },\n subscribe: stateStore.subscribe,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"checkout.js","names":[],"sources":["../src/checkout-environment.ts","../src/checkout-input-schemas.ts","../src/checkout-schemas.ts","../src/snapshots.ts","../src/checkout-client.ts"],"sourcesContent":["import { resolveResourceEnvironment } from \"./environment.ts\";\nimport type {\n CreateLockerverseWidgetOptions,\n LockerverseEnvironment,\n} from \"./types.ts\";\n\nconst STRIPE_PUBLISHABLE_KEYS: Record<LockerverseEnvironment, string> = {\n development:\n \"pk_test_51O7FkjDHAhgRuLtFHdkXdIe8T5i7rOVaG9PCtDetK3UUVKojVUEKHmQacGzigf9mOX1wz3zSOKoYwFjRcTfML9PU00OjJko2lk\",\n production:\n \"pk_live_51O7FkjDHAhgRuLtFlzLdxJrwo7F09WCKTlzT9lnBePjOGizWnuijkH9oCkoAddkmBT8ngIuqAPkDiHlPEAH4KXbz00Tm0DaPT4\",\n};\n\nexport function resolveWidgetEnvironment(\n options: CreateLockerverseWidgetOptions\n) {\n const runtime = resolveResourceEnvironment(options, \"widgetSlug\");\n return {\n ...runtime,\n stripePublishableKey: STRIPE_PUBLISHABLE_KEYS[runtime.environment],\n widgetSlug: runtime.resourceSlug,\n widgetSlugValue: runtime.resourceSlugValue,\n };\n}\n","import {\n array,\n boolean,\n minLength,\n optional,\n parser,\n picklist,\n pipe,\n record,\n strictObject,\n string,\n union,\n} from \"valibot\";\n\nimport {\n customFieldAnswerSchema,\n nonEmptyStringSchema,\n safeIntegerSchema,\n} from \"./schema-helpers.ts\";\n\nexport const parseCheckoutPricingInput = parser(\n optional(\n strictObject({\n email: optional(string()),\n includeServiceFee: optional(boolean()),\n promoCode: optional(string()),\n tipCents: optional(safeIntegerSchema(0)),\n }),\n {}\n )\n);\n\nexport const parsePaymentSubmission = parser(\n strictObject({\n confirmationToken: nonEmptyStringSchema,\n customFieldAnswers: optional(array(customFieldAnswerSchema)),\n email: string(),\n memberId: optional(string()),\n merchSize: optional(picklist([\"XS\", \"S\", \"M\", \"L\", \"XL\", \"XXL\", \"XXXL\"])),\n metadata: optional(record(string(), string())),\n phone: optional(string()),\n })\n);\n\nconst checkoutItemSchema = union([\n strictObject({\n amountCents: safeIntegerSchema(1),\n productId: nonEmptyStringSchema,\n }),\n strictObject({\n productId: nonEmptyStringSchema,\n quantity: safeIntegerSchema(1),\n }),\n]);\n\nexport const parseCheckoutItems = parser(\n pipe(array(checkoutItemSchema), minLength(1))\n);\n","import {\n array,\n boolean,\n check,\n finite,\n type InferOutput,\n literal,\n maxValue,\n minValue,\n nullable,\n number,\n object,\n optional,\n parser,\n picklist,\n pipe,\n string,\n transform,\n variant,\n} from \"valibot\";\n\nimport {\n customFieldsSchema,\n nonEmptyStringSchema,\n optionalNullableStringSchema,\n safeIntegerSchema,\n} from \"./schema-helpers.ts\";\n\nconst paymentOptionSchema = picklist([\"one-time\", \"monthly\", \"annually\"]);\nconst nullableNonNegativeIntegerSchema = nullable(safeIntegerSchema(0));\n\nconst productBaseEntries = {\n description: optionalNullableStringSchema,\n id: nonEmptyStringSchema,\n inventoryQuantity: nullableNonNegativeIntegerSchema,\n maxQuantity: nullableNonNegativeIntegerSchema,\n minimumAmountCents: nullableNonNegativeIntegerSchema,\n minQuantity: nullableNonNegativeIntegerSchema,\n name: nonEmptyStringSchema,\n paymentOption: paymentOptionSchema,\n};\n\nconst publicProductSchema = pipe(\n variant(\"pricingMode\", [\n object({\n ...productBaseEntries,\n amountCents: safeIntegerSchema(0),\n pricingMode: literal(\"fixed\"),\n }),\n object({\n ...productBaseEntries,\n amountCents: nullableNonNegativeIntegerSchema,\n pricingMode: literal(\"custom\"),\n }),\n ]),\n check(\n ({ maxQuantity, minQuantity }) =>\n maxQuantity === null || minQuantity === null || minQuantity <= maxQuantity\n )\n);\n\nconst productListingSchema = object({\n acceptsDiscounts: optional(boolean(), false),\n id: nonEmptyStringSchema,\n product: publicProductSchema,\n productId: nonEmptyStringSchema,\n slug: nonEmptyStringSchema,\n});\n\nconst widgetFieldsSchema = optional(\n object({\n memberId: optional(boolean(), false),\n merchSize: optional(boolean(), false),\n phone: optional(boolean(), false),\n promoCode: optional(boolean(), false),\n serviceFee: optional(boolean(), false),\n shipping: optional(boolean(), false),\n tipping: optional(boolean(), false),\n }),\n {}\n);\n\nexport const publicWidgetSchema = pipe(\n object({\n config: optional(\n object({\n customFields: customFieldsSchema,\n fields: widgetFieldsSchema,\n })\n ),\n description: optionalNullableStringSchema,\n id: optional(string(), \"\"),\n name: optional(string(), \"Lockerverse widget\"),\n pricingPolicy: optional(\n object({\n currency: optional(literal(\"usd\"), \"usd\"),\n serviceFeeRateBasisPoints: optional(safeIntegerSchema(0), 0),\n })\n ),\n products: optional(array(productListingSchema), []),\n showCommunityBranding: optional(boolean(), true),\n title: optionalNullableStringSchema,\n }),\n transform((widget) => ({\n ...widget,\n config: {\n customFields: widget.config?.customFields ?? [],\n fields: {\n memberId: widget.config?.fields?.memberId ?? false,\n merchSize: widget.config?.fields?.merchSize ?? false,\n phone: widget.config?.fields?.phone ?? false,\n promoCode: widget.config?.fields?.promoCode ?? false,\n serviceFee: widget.config?.fields?.serviceFee ?? false,\n shipping: widget.config?.fields?.shipping ?? false,\n tipping: widget.config?.fields?.tipping ?? false,\n },\n },\n pricingPolicy: widget.pricingPolicy ?? {\n currency: \"usd\" as const,\n serviceFeeRateBasisPoints: 0,\n },\n }))\n);\n\nconst appliedDiscountSchema = nullable(\n object({\n percentageOff: pipe(number(), finite(), minValue(0), maxValue(100)),\n source: picklist([\"email_list\", \"promo_code\"]),\n })\n);\n\nconst checkoutLineItemSchema = object({\n acceptsDiscounts: boolean(),\n listingId: nonEmptyStringSchema,\n listingSlug: nonEmptyStringSchema,\n paymentOption: paymentOptionSchema,\n pricingMode: picklist([\"fixed\", \"custom\"]),\n productId: nonEmptyStringSchema,\n productName: nonEmptyStringSchema,\n quantity: safeIntegerSchema(1),\n subtotalCents: safeIntegerSchema(0),\n unitAmountCents: safeIntegerSchema(0),\n});\n\nexport const checkoutQuoteSchema = object({\n amountCents: safeIntegerSchema(0),\n appliedDiscount: appliedDiscountSchema,\n connectedAccountId: nullable(nonEmptyStringSchema),\n discountableSubtotalCents: safeIntegerSchema(0),\n discountCents: safeIntegerSchema(0),\n lineItems: array(checkoutLineItemSchema),\n paymentOption: paymentOptionSchema,\n serviceFeeCents: safeIntegerSchema(0),\n subtotalCents: safeIntegerSchema(0),\n tipCents: safeIntegerSchema(0),\n totalCents: safeIntegerSchema(0),\n});\n\nexport const paymentResultSchema = object({\n checkoutId: nonEmptyStringSchema,\n checkoutStatus: picklist([\"action_required\", \"failed\", \"pending\", \"success\"]),\n clientSecret: nullable(string()),\n paymentReference: nonEmptyStringSchema,\n requiresAction: boolean(),\n status: nullable(string()),\n});\n\nexport type PublicCheckoutQuote = InferOutput<typeof checkoutQuoteSchema>;\nexport type PublicProductListing = InferOutput<typeof productListingSchema>;\nexport type PublicWidget = InferOutput<typeof publicWidgetSchema>;\n\nexport const parseCheckoutQuote = parser(checkoutQuoteSchema);\nexport const parsePaymentResult = parser(paymentResultSchema);\nexport const parsePublicWidget = parser(publicWidgetSchema);\n","import type { PublicProductListing, PublicWidget } from \"./checkout-schemas.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\nimport type {\n LockerverseCatalog,\n LockerversePaymentResult,\n LockerversePreparedCheckout,\n LockerverseProduct,\n} from \"./types.ts\";\n\nfunction mapProduct(listing: PublicProductListing): LockerverseProduct {\n const { product } = listing;\n\n return {\n acceptsDiscounts: listing.acceptsDiscounts ?? false,\n amountCents: product.amountCents,\n description: product.description ?? null,\n id: product.id,\n inventoryQuantity: product.inventoryQuantity,\n listingId: listing.id,\n maximumQuantity: product.maxQuantity,\n minimumAmountCents: product.minimumAmountCents,\n minimumQuantity: product.minQuantity,\n name: product.name,\n paymentOption: product.paymentOption,\n pricingMode: product.pricingMode,\n slug: listing.slug,\n };\n}\n\nexport function createCatalog(\n widget: PublicWidget,\n publishableKey: string\n): LockerverseCatalog {\n const fields = widget.config?.fields ?? {};\n\n return {\n payment: {\n currency: \"usd\",\n publishableKey,\n },\n pricingPolicy: {\n currency: \"usd\",\n serviceFeeRateBasisPoints:\n widget.pricingPolicy?.serviceFeeRateBasisPoints ?? 0,\n },\n products: (widget.products ?? []).map(mapProduct),\n widget: {\n customFields: widget.config?.customFields ?? [],\n description: widget.description ?? null,\n fields: {\n memberId: fields.memberId ?? false,\n merchSize: fields.merchSize ?? false,\n phone: fields.phone ?? false,\n promoCode: fields.promoCode ?? false,\n serviceFee: fields.serviceFee ?? false,\n shipping: fields.shipping ?? false,\n tipping: fields.tipping ?? false,\n },\n id: widget.id ?? \"\",\n name: widget.name ?? \"Lockerverse widget\",\n showCommunityBranding: widget.showCommunityBranding ?? true,\n title: widget.title ?? null,\n },\n };\n}\n\nexport function cloneCatalog(catalog: LockerverseCatalog): LockerverseCatalog {\n return cloneSnapshot(catalog);\n}\n\nexport function clonePreparedCheckout(\n checkout: LockerversePreparedCheckout\n): LockerversePreparedCheckout {\n return cloneSnapshot(checkout);\n}\n\nexport function clonePaymentResult(\n paymentResult: LockerversePaymentResult\n): LockerversePaymentResult {\n return cloneSnapshot(paymentResult);\n}\n\nfunction cloneSnapshot<T>(value: T): T {\n return deepFreeze(structuredClone(value));\n}\n","import { resolveWidgetEnvironment } from \"./checkout-environment.ts\";\nimport {\n parseCheckoutItems,\n parseCheckoutPricingInput,\n parsePaymentSubmission,\n} from \"./checkout-input-schemas.ts\";\nimport {\n parseCheckoutQuote,\n parsePaymentResult,\n parsePublicWidget,\n} from \"./checkout-schemas.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\nimport { createSdkErrorReporter } from \"./error-reporting.ts\";\nimport {\n cloneCatalog,\n clonePaymentResult,\n clonePreparedCheckout,\n createCatalog,\n} from \"./snapshots.ts\";\nimport { createTransport } from \"./transport.ts\";\nimport {\n type CreateLockerverseWidgetOptions,\n type LockerverseCheckoutClient,\n type LockerverseCheckoutQuote,\n LockerverseSdkError,\n type LockerverseSdkOperation,\n} from \"./types.ts\";\n\ntype OperationErrorContext = {\n code:\n | \"payment_status_failed\"\n | \"payment_submit_failed\"\n | \"total_calculation_failed\"\n | \"widget_load_failed\";\n message: string;\n operation:\n | \"calculate_total\"\n | \"get_payment_status\"\n | \"load_widget\"\n | \"submit_payment\";\n};\n\nexport function createLockerverseCheckoutClient(\n options: CreateLockerverseWidgetOptions\n): LockerverseCheckoutClient {\n const {\n apiBaseUrl,\n communitySlug,\n communitySlugValue,\n environment,\n fetchImplementation,\n onError,\n requestTimeoutMs,\n sentryDsn,\n stripePublishableKey,\n widgetSlug,\n widgetSlugValue,\n } = resolveWidgetEnvironment(options);\n const reportError = createSdkErrorReporter({\n communitySlug: communitySlugValue,\n environment,\n getContext: () => ({ widgetSlug: widgetSlugValue }),\n onError,\n resourceContextName: \"lockerverse_widget\",\n sentryDsn,\n });\n const { requestJson } = createTransport(\n fetchImplementation,\n reportError,\n requestTimeoutMs\n );\n const checkoutBaseUrl = `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}/checkout`;\n\n function invalidInput(\n message: string,\n operation: LockerverseSdkOperation,\n code: \"invalid_selection\" | \"payment_submit_failed\" = \"invalid_selection\"\n ): never {\n throw reportError(\n new LockerverseSdkError({\n code,\n message,\n operation,\n reportable: false,\n })\n );\n }\n\n function normalizeOperationError(\n error: unknown,\n context: OperationErrorContext\n ) {\n return error instanceof LockerverseSdkError\n ? error\n : new LockerverseSdkError({ ...context, reportable: true });\n }\n\n function failOperation(\n error: unknown,\n context: OperationErrorContext,\n recoveryMayBeRequired = false\n ): never {\n const normalized = normalizeOperationError(error, context);\n const recoveryRecommended =\n recoveryMayBeRequired &&\n (normalized.status === undefined || normalized.status >= 500);\n throw reportError(\n recoveryRecommended\n ? new LockerverseSdkError({\n code: normalized.code,\n message: normalized.message,\n operation: normalized.operation,\n recoveryRecommended: true,\n reportable: normalized.reportable,\n ...(normalized.status === undefined\n ? {}\n : { status: normalized.status }),\n })\n : normalized\n );\n }\n\n function normalizePricingInput(\n input: unknown,\n operation: \"calculate_total\" | \"submit_payment\"\n ) {\n let parsed: ReturnType<typeof parseCheckoutPricingInput>;\n try {\n parsed = parseCheckoutPricingInput(input);\n } catch {\n invalidInput(\"Checkout pricing input is invalid.\", operation);\n }\n const email = parsed.email?.trim().toLowerCase();\n const promoCode = parsed.promoCode?.trim();\n return {\n ...(email ? { email } : {}),\n ...(parsed.includeServiceFee === undefined\n ? {}\n : { includeServiceFee: parsed.includeServiceFee }),\n ...(promoCode ? { promoCode } : {}),\n ...(parsed.tipCents === undefined ? {} : { tipCents: parsed.tipCents }),\n };\n }\n\n function normalizeCalculateTotalInput(input: unknown) {\n if (!(input && typeof input === \"object\") || Array.isArray(input)) {\n invalidInput(\"Checkout selection is invalid.\", \"calculate_total\");\n }\n const { items, ...pricingInput } = input as Record<string, unknown>;\n try {\n return {\n items: parseCheckoutItems(items),\n pricing: normalizePricingInput(pricingInput, \"calculate_total\"),\n };\n } catch (error) {\n if (error instanceof LockerverseSdkError) {\n throw error;\n }\n invalidInput(\"Checkout selection is invalid.\", \"calculate_total\");\n }\n }\n\n function normalizeQuote(input: unknown) {\n try {\n if (!(input && typeof input === \"object\") || Array.isArray(input)) {\n throw new TypeError(\"Invalid quote.\");\n }\n const quoteInput = input as LockerverseCheckoutQuote;\n if (\n quoteInput.authoritative !== true ||\n quoteInput.paymentOption !== \"one-time\" ||\n typeof quoteInput.paymentReference !== \"string\" ||\n quoteInput.paymentReference.length === 0 ||\n quoteInput.payment.currency !== \"usd\" ||\n quoteInput.payment.publishableKey !== stripePublishableKey\n ) {\n throw new TypeError(\"Invalid quote.\");\n }\n const parsed = parseCheckoutQuote({\n ...quoteInput,\n connectedAccountId: quoteInput.payment.connectedAccountId,\n });\n if (parsed.paymentOption !== \"one-time\") {\n throw new TypeError(\"Unsupported checkout cadence.\");\n }\n const {\n connectedAccountId,\n paymentOption: _paymentOption,\n ...quote\n } = parsed;\n return deepFreeze({\n ...quote,\n authoritative: true as const,\n payment: {\n connectedAccountId,\n currency: \"usd\" as const,\n publishableKey: stripePublishableKey,\n },\n paymentOption: \"one-time\" as const,\n paymentReference: quoteInput.paymentReference,\n });\n } catch {\n invalidInput(\n \"Lockerverse payment submission is invalid.\",\n \"submit_payment\",\n \"payment_submit_failed\"\n );\n }\n }\n\n function normalizeSubmitPaymentInput(input: unknown) {\n try {\n if (!(input && typeof input === \"object\") || Array.isArray(input)) {\n throw new TypeError(\"Invalid payment input.\");\n }\n const { checkout, submission: submissionInput } = input as Record<\n string,\n unknown\n >;\n if (\n !(checkout && typeof checkout === \"object\") ||\n Array.isArray(checkout)\n ) {\n throw new TypeError(\"Invalid prepared checkout.\");\n }\n const checkoutInput = checkout as Record<string, unknown>;\n const items = parseCheckoutItems(checkoutInput.items);\n const pricing = normalizePricingInput(\n checkoutInput.pricing,\n \"submit_payment\"\n );\n const quote = normalizeQuote(checkoutInput);\n const submission = parsePaymentSubmission(submissionInput);\n const email = submission.email.trim().toLowerCase();\n if (!email || email !== pricing.email) {\n invalidInput(\n \"Payment email must match the current checkout quote.\",\n \"submit_payment\"\n );\n }\n return {\n items,\n pricing,\n quote,\n submission: { ...submission, email },\n };\n } catch (error) {\n if (error instanceof LockerverseSdkError) {\n throw error;\n }\n invalidInput(\n \"Lockerverse payment submission is invalid.\",\n \"submit_payment\",\n \"payment_submit_failed\"\n );\n }\n }\n\n return {\n async calculateTotal(input) {\n const { items, pricing } = normalizeCalculateTotalInput(input);\n const context = {\n code: \"total_calculation_failed\" as const,\n message: \"Lockerverse returned an invalid checkout total.\",\n operation: \"calculate_total\" as const,\n };\n try {\n const response = await requestJson(\n `${checkoutBaseUrl}/quote`,\n {\n body: JSON.stringify({ ...pricing, items }),\n headers: { \"Content-Type\": \"application/json\" },\n method: \"POST\",\n },\n parseCheckoutQuote,\n {\n ...context,\n message:\n \"Unable to calculate the Lockerverse checkout total because the request failed.\",\n report: false,\n },\n { ...context, report: false }\n );\n if (!response.ok) {\n throw new LockerverseSdkError({\n ...context,\n message: `Unable to calculate the Lockerverse checkout total (${response.response.status}).`,\n reportable: response.response.status >= 500,\n status: response.response.status,\n });\n }\n if (response.value.paymentOption !== \"one-time\") {\n throw new LockerverseSdkError({\n ...context,\n message: \"Lockerverse returned an unsupported checkout cadence.\",\n reportable: true,\n });\n }\n const {\n connectedAccountId,\n paymentOption: _paymentOption,\n ...quote\n } = response.value;\n return clonePreparedCheckout(\n deepFreeze({\n ...quote,\n authoritative: true as const,\n items,\n payment: {\n connectedAccountId,\n currency: \"usd\" as const,\n publishableKey: stripePublishableKey,\n },\n paymentOption: \"one-time\" as const,\n paymentReference: globalThis.crypto.randomUUID(),\n pricing,\n })\n );\n } catch (error) {\n failOperation(error, context);\n }\n },\n async getPaymentStatus(paymentReference) {\n if (typeof paymentReference !== \"string\" || !paymentReference.trim()) {\n invalidInput(\n \"Provide a payment reference to recover its status.\",\n \"get_payment_status\"\n );\n }\n const normalizedReference = paymentReference.trim();\n const context = {\n code: \"payment_status_failed\" as const,\n message: \"Lockerverse returned an invalid payment status.\",\n operation: \"get_payment_status\" as const,\n };\n try {\n const response = await requestJson(\n `${checkoutBaseUrl}/${encodeURIComponent(normalizedReference)}/status`,\n undefined,\n parsePaymentResult,\n {\n ...context,\n message:\n \"Unable to recover the Lockerverse payment status because the request failed.\",\n report: false,\n },\n { ...context, report: false }\n );\n if (!response.ok) {\n throw new LockerverseSdkError({\n ...context,\n message: `Unable to recover the Lockerverse payment status (${response.response.status}).`,\n reportable: response.response.status >= 500,\n status: response.response.status,\n });\n }\n if (response.value.paymentReference !== normalizedReference) {\n throw new LockerverseSdkError({ ...context, reportable: true });\n }\n return clonePaymentResult(response.value);\n } catch (error) {\n failOperation(error, context);\n }\n },\n async load() {\n const context = {\n code: \"widget_load_failed\" as const,\n message: \"Lockerverse returned an invalid widget catalog.\",\n operation: \"load_widget\" as const,\n };\n try {\n const response = await requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}`,\n undefined,\n parsePublicWidget,\n {\n ...context,\n message:\n \"Unable to load Lockerverse widget because the request failed.\",\n report: false,\n },\n { ...context, report: false }\n );\n if (!response.ok) {\n throw new LockerverseSdkError({\n ...context,\n message: `Unable to load Lockerverse widget (${response.response.status}).`,\n reportable: response.response.status >= 500,\n status: response.response.status,\n });\n }\n return cloneCatalog(\n deepFreeze(createCatalog(response.value, stripePublishableKey))\n );\n } catch (error) {\n failOperation(error, context);\n }\n },\n async submitPayment(input) {\n const { items, pricing, quote, submission } =\n normalizeSubmitPaymentInput(input);\n const context = {\n code: \"payment_submit_failed\" as const,\n message: \"Lockerverse returned an invalid payment confirmation.\",\n operation: \"submit_payment\" as const,\n };\n try {\n const response = await requestJson(\n `${checkoutBaseUrl}/confirm`,\n {\n body: JSON.stringify({\n confirmationToken: submission.confirmationToken,\n customFieldAnswers: submission.customFieldAnswers,\n email: submission.email,\n expectedAmountCents: quote.amountCents,\n expectedAppliedDiscount: quote.appliedDiscount,\n expectedConnectedAccountId: quote.payment.connectedAccountId,\n expectedDiscountableSubtotalCents:\n quote.discountableSubtotalCents,\n expectedDiscountCents: quote.discountCents,\n expectedServiceFeeCents: quote.serviceFeeCents,\n expectedSubtotalCents: quote.subtotalCents,\n expectedTipCents: quote.tipCents,\n expectedTotalCents: quote.totalCents,\n ...pricing,\n items,\n memberId: submission.memberId,\n merchSize: submission.merchSize,\n metadata: submission.metadata,\n paymentReference: quote.paymentReference,\n phone: submission.phone,\n quoteContractVersion: 1,\n }),\n headers: { \"Content-Type\": \"application/json\" },\n method: \"POST\",\n },\n parsePaymentResult,\n {\n ...context,\n message:\n \"Unable to submit the Lockerverse payment because the request failed.\",\n report: false,\n },\n { ...context, report: false }\n );\n if (!response.ok) {\n throw new LockerverseSdkError({\n ...context,\n message: `Unable to submit the Lockerverse payment (${response.response.status}).`,\n reportable: response.response.status >= 500,\n status: response.response.status,\n });\n }\n if (response.value.paymentReference !== quote.paymentReference) {\n throw new LockerverseSdkError({ ...context, reportable: true });\n }\n return clonePaymentResult(response.value);\n } catch (error) {\n failOperation(error, context, true);\n }\n },\n };\n}\n"],"mappings":"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"}