@usethrottle/checkout-sdk 1.0.0 → 1.0.2

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/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # @usethrottle/checkout-sdk
2
+
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Expose customer Net-N payment terms in the generated API client and republish the public SDK package set.
8
+ - Updated dependencies
9
+ - @usethrottle/checkout-react@1.0.1
10
+
11
+ ## 1.0.1
12
+
13
+ ### Patch Changes
14
+
15
+ - Add a server-safe checkout client for checkout session creation/completion, Gr4vy embed token minting, checkout URL helpers, and order/payment reads.
16
+
17
+ ## 1.0.0
18
+
19
+ ### Major Changes
20
+
21
+ - Ship the React checkout wrapper with iframe lifecycle telemetry, idempotent terminal events, and brand theming.
package/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # @usethrottle/checkout-sdk
2
2
 
3
- Throttle Checkout SDK Phase 1.
3
+ Production checkout SDK for Throttle storefront integrations.
4
4
 
5
- Wraps `@usethrottle/checkout-react` with idempotency, telemetry, and brand theming.
5
+ Use the server entrypoint from backend routes to create sessions, mint embed tokens,
6
+ and read orders/payments. Use the React wrapper in the browser when you want
7
+ idempotent terminal callbacks, telemetry, and brand theming on top of
8
+ `@usethrottle/checkout-react`.
6
9
 
7
10
  ## Install
8
11
 
@@ -21,33 +24,83 @@ import { ThrottleCheckout } from '@usethrottle/checkout-sdk';
21
24
  theme={{ primary: '#ff6600', logo: 'https://shop.example.com/logo.png' }}
22
25
  onSucceeded={({ orderId }) => router.push(`/orders/${orderId}`)}
23
26
  onTelemetry={(event) => analytics.track(event.type, event)}
24
- />
27
+ />;
25
28
  ```
26
29
 
30
+ ## Server quickstart
31
+
32
+ Use the server export from backend routes only. It keeps your Throttle API key
33
+ out of the browser and unwraps both `{ data }` envelopes and direct responses.
34
+
35
+ ```ts
36
+ import {
37
+ buildCheckoutEmbedUrl,
38
+ buildCheckoutHostedUrl,
39
+ createCheckoutClient,
40
+ } from '@usethrottle/checkout-sdk/server';
41
+
42
+ const checkout = createCheckoutClient({
43
+ apiKey: process.env.THROTTLE_API_KEY!,
44
+ baseUrl: process.env.THROTTLE_BASE_URL,
45
+ });
46
+
47
+ const session = await checkout.createSession({
48
+ storeId: process.env.THROTTLE_STORE_ID!,
49
+ cartId: 'cart_123',
50
+ returnUrl: 'https://shop.example.com/checkout/success',
51
+ cancelUrl: 'https://shop.example.com/cart',
52
+ collect: { shippingAddress: true, billingAddress: false },
53
+ });
54
+
55
+ const embedUrl = buildCheckoutEmbedUrl({
56
+ checkoutOrigin: 'https://checkout.usethrottle.dev',
57
+ sessionId: session.sessionId,
58
+ parentOrigin: 'https://shop.example.com',
59
+ mode: 'payment-only',
60
+ });
61
+
62
+ const hostedUrl = buildCheckoutHostedUrl({
63
+ checkoutOrigin: 'https://checkout.usethrottle.dev',
64
+ sessionId: session.sessionId,
65
+ });
66
+ ```
67
+
68
+ ### Server methods
69
+
70
+ | Method | Endpoint | Description |
71
+ | ----------------------------- | --------------------------------------------- | --------------------------------------------------------- |
72
+ | `createSession(input)` | `POST /api/v1/checkout/sessions` | Creates a cart-backed hosted/embed checkout session. |
73
+ | `completeSession(id, input)` | `POST /api/v1/checkout/sessions/:id/complete` | Completes a checkout session from server-side proxy mode. |
74
+ | `createEmbedToken(input)` | `POST /api/v1/checkout-sessions/embed-token` | Mints a Gr4vy Embed token for proxy-mode card capture. |
75
+ | `getOrder(id)` | `GET /api/v1/orders/:id` | Reads public-safe order totals/status. |
76
+ | `listOrderPayments(id)` | `GET /api/v1/orders/:id/payments` | Lists payments for an order. |
77
+ | `listPaymentTransactions(id)` | `GET /api/v1/payments/:id/transactions` | Lists transactions for a payment. |
78
+ | `getOrderWithPayments(id)` | Combined reads | Fetches an order, payments, and transactions together. |
79
+
27
80
  ## Props
28
81
 
29
- | Prop | Type | Required | Description |
30
- |------|------|----------|-------------|
31
- | `sessionId` | `string` | Yes | Throttle checkout session id (`cs_*`) |
32
- | `parentOrigin` | `string` | No | Origin of the page mounting the embed |
33
- | `baseUrl` | `string` | No | Override the hosted checkout URL (default: `https://throttle-checkout.vercel.app`) |
34
- | `theme` | `BrandTheme` | No | Brand colour + logo forwarded to hosted page |
35
- | `onSucceeded` | `(args) => void` | No | Called once on successful payment |
36
- | `onFailed` | `(args) => void` | No | Called once on terminal payment failure |
37
- | `onCancelled` | `() => void` | No | Called when the user cancels |
38
- | `onTelemetry` | `(event) => void` | No | Receives every lifecycle event |
82
+ | Prop | Type | Required | Description |
83
+ | -------------- | ----------------- | -------- | ------------------------------------------------------------------------------ |
84
+ | `sessionId` | `string` | Yes | Throttle checkout session id (`cs_*`) |
85
+ | `parentOrigin` | `string` | No | Origin of the page mounting the embed |
86
+ | `baseUrl` | `string` | No | Override the hosted checkout URL (default: `https://checkout.usethrottle.dev`) |
87
+ | `theme` | `BrandTheme` | No | Brand colour + logo forwarded to hosted page |
88
+ | `onSucceeded` | `(args) => void` | No | Called once on successful payment |
89
+ | `onFailed` | `(args) => void` | No | Called once on terminal payment failure |
90
+ | `onCancelled` | `() => void` | No | Called when the user cancels |
91
+ | `onTelemetry` | `(event) => void` | No | Receives every lifecycle event |
39
92
 
40
93
  ## Telemetry events
41
94
 
42
- | `event.type` | Additional payload | Description |
43
- |---|---|---|
44
- | `mounted` | `sessionId`, `timestamp` | Component mounted in the DOM |
45
- | `ready` | `sessionId`, `timestamp` | Hosted iframe fully loaded |
46
- | `processing` | `sessionId`, `timestamp` | Payment authorization in-flight |
47
- | `succeeded` | `sessionId`, `orderId`, `paymentId`, `timestamp` | Payment completed successfully |
48
- | `failed` | `sessionId`, `code`, `message`, `timestamp` | Terminal payment failure |
49
- | `cancelled` | `sessionId`, `timestamp` | User cancelled checkout |
50
- | `step_changed` | `sessionId`, `step`, `timestamp` | Checkout step navigation (full embed only) |
95
+ | `event.type` | Additional payload | Description |
96
+ | -------------- | ------------------------------------------------ | ------------------------------------------ |
97
+ | `mounted` | `sessionId`, `timestamp` | Component mounted in the DOM |
98
+ | `ready` | `sessionId`, `timestamp` | Hosted iframe fully loaded |
99
+ | `processing` | `sessionId`, `timestamp` | Payment authorization in-flight |
100
+ | `succeeded` | `sessionId`, `orderId`, `paymentId`, `timestamp` | Payment completed successfully |
101
+ | `failed` | `sessionId`, `code`, `message`, `timestamp` | Terminal payment failure |
102
+ | `cancelled` | `sessionId`, `timestamp` | User cancelled checkout |
103
+ | `step_changed` | `sessionId`, `step`, `timestamp` | Checkout step navigation (full embed only) |
51
104
 
52
105
  ## Idempotency
53
106
 
@@ -63,4 +116,5 @@ import { ThrottleCheckout } from '@usethrottle/checkout-sdk';
63
116
  pnpm --filter @usethrottle/checkout-sdk build
64
117
  ```
65
118
 
66
- Emits CJS (`dist/index.cjs`), ESM (`dist/index.js`), and TypeScript declarations (`dist/index.d.ts`).
119
+ Emits CJS, ESM, and TypeScript declarations for both the browser entrypoint and
120
+ `@usethrottle/checkout-sdk/server`.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/ThrottleCheckout.tsx"],"sourcesContent":["export { ThrottleCheckout } from './ThrottleCheckout.js';\nexport type { BrandTheme, TelemetryEvent, ThrottleCheckoutProps } from './types.js';\n","import { useCallback, useEffect, useRef } from 'react';\nimport { PaymentEmbed } from '@usethrottle/checkout-react';\nimport type { ThrottleCheckoutProps, TelemetryEvent } from './types.js';\n\n/**\n * ThrottleCheckout — Phase 1 platform SDK wrapper.\n *\n * Wraps `<PaymentEmbed>` from `@usethrottle/checkout-react` and adds:\n * 1. Idempotency — settledRef ensures `onSucceeded` / `onFailed` fire at most once\n * per component lifetime, even if the iframe sends duplicate events.\n * 2. Telemetry — `onTelemetry` callback receives every lifecycle event with a\n * typed payload so merchants can pipe to Datadog / Segment / etc.\n * 3. Brand theming — `theme.primary` + `theme.logo` are forwarded to the underlying\n * `<PaymentEmbed>` which appends them as URL query params on the\n * hosted checkout iframe src.\n */\nexport function ThrottleCheckout({\n sessionId,\n parentOrigin = '',\n baseUrl,\n theme,\n onSucceeded,\n onFailed,\n onCancelled,\n onTelemetry,\n}: ThrottleCheckoutProps): JSX.Element {\n // Idempotency guard — once a terminal event (success or failure) fires,\n // all subsequent duplicate events from the iframe are silently dropped.\n const settledRef = useRef(false);\n\n const emit = useCallback(\n (event: TelemetryEvent) => {\n onTelemetry?.(event);\n },\n [onTelemetry],\n );\n\n // Fire \"mounted\" telemetry once on initial render.\n useEffect(() => {\n emit({ type: 'mounted', sessionId, timestamp: Date.now() });\n // intentionally only on mount — sessionId identity change re-mounts anyway\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleReady = useCallback(() => {\n emit({ type: 'ready', sessionId, timestamp: Date.now() });\n }, [emit, sessionId]);\n\n const handleProcessing = useCallback(() => {\n emit({ type: 'processing', sessionId, timestamp: Date.now() });\n }, [emit, sessionId]);\n\n const handleSucceeded = useCallback(\n ({ orderId, paymentId }: { orderId: string; paymentId: string }) => {\n if (settledRef.current) return;\n settledRef.current = true;\n emit({ type: 'succeeded', sessionId, orderId, paymentId, timestamp: Date.now() });\n onSucceeded?.({ orderId, paymentId });\n },\n [emit, sessionId, onSucceeded],\n );\n\n const handleFailed = useCallback(\n ({ code, message }: { code: string; message: string }) => {\n if (settledRef.current) return;\n settledRef.current = true;\n emit({ type: 'failed', sessionId, code, message, timestamp: Date.now() });\n onFailed?.({ code, message });\n },\n [emit, sessionId, onFailed],\n );\n\n const handleCanceled = useCallback(() => {\n emit({ type: 'cancelled', sessionId, timestamp: Date.now() });\n onCancelled?.();\n }, [emit, sessionId, onCancelled]);\n\n return (\n <PaymentEmbed\n sessionId={sessionId}\n parentOrigin={parentOrigin}\n {...(baseUrl !== undefined ? { baseUrl } : {})}\n primary={theme?.primary}\n logo={theme?.logo}\n onReady={handleReady}\n onProcessing={handleProcessing}\n onSucceeded={handleSucceeded}\n onFailed={handleFailed}\n onCanceled={handleCanceled}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAA+C;AAC/C,4BAA6B;AA6EzB;AA9DG,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AAGrC,QAAM,iBAAa,qBAAO,KAAK;AAE/B,QAAM,WAAO;AAAA,IACX,CAAC,UAA0B;AACzB,oBAAc,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAGA,8BAAU,MAAM;AACd,SAAK,EAAE,MAAM,WAAW,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAG5D,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAc,0BAAY,MAAM;AACpC,SAAK,EAAE,MAAM,SAAS,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAC1D,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB,QAAM,uBAAmB,0BAAY,MAAM;AACzC,SAAK,EAAE,MAAM,cAAc,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAC/D,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB,QAAM,sBAAkB;AAAA,IACtB,CAAC,EAAE,SAAS,UAAU,MAA8C;AAClE,UAAI,WAAW,QAAS;AACxB,iBAAW,UAAU;AACrB,WAAK,EAAE,MAAM,aAAa,WAAW,SAAS,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAChF,oBAAc,EAAE,SAAS,UAAU,CAAC;AAAA,IACtC;AAAA,IACA,CAAC,MAAM,WAAW,WAAW;AAAA,EAC/B;AAEA,QAAM,mBAAe;AAAA,IACnB,CAAC,EAAE,MAAM,QAAQ,MAAyC;AACxD,UAAI,WAAW,QAAS;AACxB,iBAAW,UAAU;AACrB,WAAK,EAAE,MAAM,UAAU,WAAW,MAAM,SAAS,WAAW,KAAK,IAAI,EAAE,CAAC;AACxE,iBAAW,EAAE,MAAM,QAAQ,CAAC;AAAA,IAC9B;AAAA,IACA,CAAC,MAAM,WAAW,QAAQ;AAAA,EAC5B;AAEA,QAAM,qBAAiB,0BAAY,MAAM;AACvC,SAAK,EAAE,MAAM,aAAa,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAC5D,kBAAc;AAAA,EAChB,GAAG,CAAC,MAAM,WAAW,WAAW,CAAC;AAEjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACC,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC5C,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO;AAAA,MACb,SAAS;AAAA,MACT,cAAc;AAAA,MACd,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA;AAAA,EACd;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/ThrottleCheckout.tsx"],"sourcesContent":["export { ThrottleCheckout } from './ThrottleCheckout.js';\nexport type { BrandTheme, TelemetryEvent, ThrottleCheckoutProps } from './types.js';\n","import { useCallback, useEffect, useRef } from 'react';\nimport { PaymentEmbed } from '@usethrottle/checkout-react';\nimport type { ThrottleCheckoutProps, TelemetryEvent } from './types.js';\n\n/**\n * ThrottleCheckout — Phase 1 platform SDK wrapper.\n *\n * Wraps `<PaymentEmbed>` from `@usethrottle/checkout-react` and adds:\n * 1. Idempotency — settledRef ensures `onSucceeded` / `onFailed` fire at most once\n * per component lifetime, even if the iframe sends duplicate events.\n * 2. Telemetry — `onTelemetry` callback receives every lifecycle event with a\n * typed payload so workspaces can pipe to Datadog / Segment / etc.\n * 3. Brand theming — `theme.primary` + `theme.logo` are forwarded to the underlying\n * `<PaymentEmbed>` which appends them as URL query params on the\n * hosted checkout iframe src.\n */\nexport function ThrottleCheckout({\n sessionId,\n parentOrigin = '',\n baseUrl,\n theme,\n onSucceeded,\n onFailed,\n onCancelled,\n onTelemetry,\n}: ThrottleCheckoutProps): JSX.Element {\n // Idempotency guard — once a terminal event (success or failure) fires,\n // all subsequent duplicate events from the iframe are silently dropped.\n const settledRef = useRef(false);\n\n const emit = useCallback(\n (event: TelemetryEvent) => {\n onTelemetry?.(event);\n },\n [onTelemetry],\n );\n\n // Fire \"mounted\" telemetry once on initial render.\n useEffect(() => {\n emit({ type: 'mounted', sessionId, timestamp: Date.now() });\n // intentionally only on mount — sessionId identity change re-mounts anyway\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleReady = useCallback(() => {\n emit({ type: 'ready', sessionId, timestamp: Date.now() });\n }, [emit, sessionId]);\n\n const handleProcessing = useCallback(() => {\n emit({ type: 'processing', sessionId, timestamp: Date.now() });\n }, [emit, sessionId]);\n\n const handleSucceeded = useCallback(\n ({ orderId, paymentId }: { orderId: string; paymentId: string }) => {\n if (settledRef.current) return;\n settledRef.current = true;\n emit({ type: 'succeeded', sessionId, orderId, paymentId, timestamp: Date.now() });\n onSucceeded?.({ orderId, paymentId });\n },\n [emit, sessionId, onSucceeded],\n );\n\n const handleFailed = useCallback(\n ({ code, message }: { code: string; message: string }) => {\n if (settledRef.current) return;\n settledRef.current = true;\n emit({ type: 'failed', sessionId, code, message, timestamp: Date.now() });\n onFailed?.({ code, message });\n },\n [emit, sessionId, onFailed],\n );\n\n const handleCanceled = useCallback(() => {\n emit({ type: 'cancelled', sessionId, timestamp: Date.now() });\n onCancelled?.();\n }, [emit, sessionId, onCancelled]);\n\n return (\n <PaymentEmbed\n sessionId={sessionId}\n parentOrigin={parentOrigin}\n {...(baseUrl !== undefined ? { baseUrl } : {})}\n primary={theme?.primary}\n logo={theme?.logo}\n onReady={handleReady}\n onProcessing={handleProcessing}\n onSucceeded={handleSucceeded}\n onFailed={handleFailed}\n onCanceled={handleCanceled}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAA+C;AAC/C,4BAA6B;AA6EzB;AA9DG,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AAGrC,QAAM,iBAAa,qBAAO,KAAK;AAE/B,QAAM,WAAO;AAAA,IACX,CAAC,UAA0B;AACzB,oBAAc,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAGA,8BAAU,MAAM;AACd,SAAK,EAAE,MAAM,WAAW,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAG5D,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAc,0BAAY,MAAM;AACpC,SAAK,EAAE,MAAM,SAAS,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAC1D,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB,QAAM,uBAAmB,0BAAY,MAAM;AACzC,SAAK,EAAE,MAAM,cAAc,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAC/D,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB,QAAM,sBAAkB;AAAA,IACtB,CAAC,EAAE,SAAS,UAAU,MAA8C;AAClE,UAAI,WAAW,QAAS;AACxB,iBAAW,UAAU;AACrB,WAAK,EAAE,MAAM,aAAa,WAAW,SAAS,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAChF,oBAAc,EAAE,SAAS,UAAU,CAAC;AAAA,IACtC;AAAA,IACA,CAAC,MAAM,WAAW,WAAW;AAAA,EAC/B;AAEA,QAAM,mBAAe;AAAA,IACnB,CAAC,EAAE,MAAM,QAAQ,MAAyC;AACxD,UAAI,WAAW,QAAS;AACxB,iBAAW,UAAU;AACrB,WAAK,EAAE,MAAM,UAAU,WAAW,MAAM,SAAS,WAAW,KAAK,IAAI,EAAE,CAAC;AACxE,iBAAW,EAAE,MAAM,QAAQ,CAAC;AAAA,IAC9B;AAAA,IACA,CAAC,MAAM,WAAW,QAAQ;AAAA,EAC5B;AAEA,QAAM,qBAAiB,0BAAY,MAAM;AACvC,SAAK,EAAE,MAAM,aAAa,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAC5D,kBAAc;AAAA,EAChB,GAAG,CAAC,MAAM,WAAW,WAAW,CAAC;AAEjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACC,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC5C,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO;AAAA,MACb,SAAS;AAAA,MACT,cAAc;AAAA,MACd,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA;AAAA,EACd;AAEJ;","names":[]}
package/dist/index.d.cts CHANGED
@@ -76,7 +76,7 @@ interface ThrottleCheckoutProps {
76
76
  * 1. Idempotency — settledRef ensures `onSucceeded` / `onFailed` fire at most once
77
77
  * per component lifetime, even if the iframe sends duplicate events.
78
78
  * 2. Telemetry — `onTelemetry` callback receives every lifecycle event with a
79
- * typed payload so merchants can pipe to Datadog / Segment / etc.
79
+ * typed payload so workspaces can pipe to Datadog / Segment / etc.
80
80
  * 3. Brand theming — `theme.primary` + `theme.logo` are forwarded to the underlying
81
81
  * `<PaymentEmbed>` which appends them as URL query params on the
82
82
  * hosted checkout iframe src.
package/dist/index.d.ts CHANGED
@@ -76,7 +76,7 @@ interface ThrottleCheckoutProps {
76
76
  * 1. Idempotency — settledRef ensures `onSucceeded` / `onFailed` fire at most once
77
77
  * per component lifetime, even if the iframe sends duplicate events.
78
78
  * 2. Telemetry — `onTelemetry` callback receives every lifecycle event with a
79
- * typed payload so merchants can pipe to Datadog / Segment / etc.
79
+ * typed payload so workspaces can pipe to Datadog / Segment / etc.
80
80
  * 3. Brand theming — `theme.primary` + `theme.logo` are forwarded to the underlying
81
81
  * `<PaymentEmbed>` which appends them as URL query params on the
82
82
  * hosted checkout iframe src.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ThrottleCheckout.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { PaymentEmbed } from '@usethrottle/checkout-react';\nimport type { ThrottleCheckoutProps, TelemetryEvent } from './types.js';\n\n/**\n * ThrottleCheckout — Phase 1 platform SDK wrapper.\n *\n * Wraps `<PaymentEmbed>` from `@usethrottle/checkout-react` and adds:\n * 1. Idempotency — settledRef ensures `onSucceeded` / `onFailed` fire at most once\n * per component lifetime, even if the iframe sends duplicate events.\n * 2. Telemetry — `onTelemetry` callback receives every lifecycle event with a\n * typed payload so merchants can pipe to Datadog / Segment / etc.\n * 3. Brand theming — `theme.primary` + `theme.logo` are forwarded to the underlying\n * `<PaymentEmbed>` which appends them as URL query params on the\n * hosted checkout iframe src.\n */\nexport function ThrottleCheckout({\n sessionId,\n parentOrigin = '',\n baseUrl,\n theme,\n onSucceeded,\n onFailed,\n onCancelled,\n onTelemetry,\n}: ThrottleCheckoutProps): JSX.Element {\n // Idempotency guard — once a terminal event (success or failure) fires,\n // all subsequent duplicate events from the iframe are silently dropped.\n const settledRef = useRef(false);\n\n const emit = useCallback(\n (event: TelemetryEvent) => {\n onTelemetry?.(event);\n },\n [onTelemetry],\n );\n\n // Fire \"mounted\" telemetry once on initial render.\n useEffect(() => {\n emit({ type: 'mounted', sessionId, timestamp: Date.now() });\n // intentionally only on mount — sessionId identity change re-mounts anyway\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleReady = useCallback(() => {\n emit({ type: 'ready', sessionId, timestamp: Date.now() });\n }, [emit, sessionId]);\n\n const handleProcessing = useCallback(() => {\n emit({ type: 'processing', sessionId, timestamp: Date.now() });\n }, [emit, sessionId]);\n\n const handleSucceeded = useCallback(\n ({ orderId, paymentId }: { orderId: string; paymentId: string }) => {\n if (settledRef.current) return;\n settledRef.current = true;\n emit({ type: 'succeeded', sessionId, orderId, paymentId, timestamp: Date.now() });\n onSucceeded?.({ orderId, paymentId });\n },\n [emit, sessionId, onSucceeded],\n );\n\n const handleFailed = useCallback(\n ({ code, message }: { code: string; message: string }) => {\n if (settledRef.current) return;\n settledRef.current = true;\n emit({ type: 'failed', sessionId, code, message, timestamp: Date.now() });\n onFailed?.({ code, message });\n },\n [emit, sessionId, onFailed],\n );\n\n const handleCanceled = useCallback(() => {\n emit({ type: 'cancelled', sessionId, timestamp: Date.now() });\n onCancelled?.();\n }, [emit, sessionId, onCancelled]);\n\n return (\n <PaymentEmbed\n sessionId={sessionId}\n parentOrigin={parentOrigin}\n {...(baseUrl !== undefined ? { baseUrl } : {})}\n primary={theme?.primary}\n logo={theme?.logo}\n onReady={handleReady}\n onProcessing={handleProcessing}\n onSucceeded={handleSucceeded}\n onFailed={handleFailed}\n onCanceled={handleCanceled}\n />\n );\n}\n"],"mappings":";AAAA,SAAS,aAAa,WAAW,cAAc;AAC/C,SAAS,oBAAoB;AA6EzB;AA9DG,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AAGrC,QAAM,aAAa,OAAO,KAAK;AAE/B,QAAM,OAAO;AAAA,IACX,CAAC,UAA0B;AACzB,oBAAc,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAGA,YAAU,MAAM;AACd,SAAK,EAAE,MAAM,WAAW,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAG5D,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,YAAY,MAAM;AACpC,SAAK,EAAE,MAAM,SAAS,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAC1D,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB,QAAM,mBAAmB,YAAY,MAAM;AACzC,SAAK,EAAE,MAAM,cAAc,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAC/D,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB,QAAM,kBAAkB;AAAA,IACtB,CAAC,EAAE,SAAS,UAAU,MAA8C;AAClE,UAAI,WAAW,QAAS;AACxB,iBAAW,UAAU;AACrB,WAAK,EAAE,MAAM,aAAa,WAAW,SAAS,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAChF,oBAAc,EAAE,SAAS,UAAU,CAAC;AAAA,IACtC;AAAA,IACA,CAAC,MAAM,WAAW,WAAW;AAAA,EAC/B;AAEA,QAAM,eAAe;AAAA,IACnB,CAAC,EAAE,MAAM,QAAQ,MAAyC;AACxD,UAAI,WAAW,QAAS;AACxB,iBAAW,UAAU;AACrB,WAAK,EAAE,MAAM,UAAU,WAAW,MAAM,SAAS,WAAW,KAAK,IAAI,EAAE,CAAC;AACxE,iBAAW,EAAE,MAAM,QAAQ,CAAC;AAAA,IAC9B;AAAA,IACA,CAAC,MAAM,WAAW,QAAQ;AAAA,EAC5B;AAEA,QAAM,iBAAiB,YAAY,MAAM;AACvC,SAAK,EAAE,MAAM,aAAa,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAC5D,kBAAc;AAAA,EAChB,GAAG,CAAC,MAAM,WAAW,WAAW,CAAC;AAEjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACC,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC5C,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO;AAAA,MACb,SAAS;AAAA,MACT,cAAc;AAAA,MACd,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA;AAAA,EACd;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../src/ThrottleCheckout.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { PaymentEmbed } from '@usethrottle/checkout-react';\nimport type { ThrottleCheckoutProps, TelemetryEvent } from './types.js';\n\n/**\n * ThrottleCheckout — Phase 1 platform SDK wrapper.\n *\n * Wraps `<PaymentEmbed>` from `@usethrottle/checkout-react` and adds:\n * 1. Idempotency — settledRef ensures `onSucceeded` / `onFailed` fire at most once\n * per component lifetime, even if the iframe sends duplicate events.\n * 2. Telemetry — `onTelemetry` callback receives every lifecycle event with a\n * typed payload so workspaces can pipe to Datadog / Segment / etc.\n * 3. Brand theming — `theme.primary` + `theme.logo` are forwarded to the underlying\n * `<PaymentEmbed>` which appends them as URL query params on the\n * hosted checkout iframe src.\n */\nexport function ThrottleCheckout({\n sessionId,\n parentOrigin = '',\n baseUrl,\n theme,\n onSucceeded,\n onFailed,\n onCancelled,\n onTelemetry,\n}: ThrottleCheckoutProps): JSX.Element {\n // Idempotency guard — once a terminal event (success or failure) fires,\n // all subsequent duplicate events from the iframe are silently dropped.\n const settledRef = useRef(false);\n\n const emit = useCallback(\n (event: TelemetryEvent) => {\n onTelemetry?.(event);\n },\n [onTelemetry],\n );\n\n // Fire \"mounted\" telemetry once on initial render.\n useEffect(() => {\n emit({ type: 'mounted', sessionId, timestamp: Date.now() });\n // intentionally only on mount — sessionId identity change re-mounts anyway\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleReady = useCallback(() => {\n emit({ type: 'ready', sessionId, timestamp: Date.now() });\n }, [emit, sessionId]);\n\n const handleProcessing = useCallback(() => {\n emit({ type: 'processing', sessionId, timestamp: Date.now() });\n }, [emit, sessionId]);\n\n const handleSucceeded = useCallback(\n ({ orderId, paymentId }: { orderId: string; paymentId: string }) => {\n if (settledRef.current) return;\n settledRef.current = true;\n emit({ type: 'succeeded', sessionId, orderId, paymentId, timestamp: Date.now() });\n onSucceeded?.({ orderId, paymentId });\n },\n [emit, sessionId, onSucceeded],\n );\n\n const handleFailed = useCallback(\n ({ code, message }: { code: string; message: string }) => {\n if (settledRef.current) return;\n settledRef.current = true;\n emit({ type: 'failed', sessionId, code, message, timestamp: Date.now() });\n onFailed?.({ code, message });\n },\n [emit, sessionId, onFailed],\n );\n\n const handleCanceled = useCallback(() => {\n emit({ type: 'cancelled', sessionId, timestamp: Date.now() });\n onCancelled?.();\n }, [emit, sessionId, onCancelled]);\n\n return (\n <PaymentEmbed\n sessionId={sessionId}\n parentOrigin={parentOrigin}\n {...(baseUrl !== undefined ? { baseUrl } : {})}\n primary={theme?.primary}\n logo={theme?.logo}\n onReady={handleReady}\n onProcessing={handleProcessing}\n onSucceeded={handleSucceeded}\n onFailed={handleFailed}\n onCanceled={handleCanceled}\n />\n );\n}\n"],"mappings":";AAAA,SAAS,aAAa,WAAW,cAAc;AAC/C,SAAS,oBAAoB;AA6EzB;AA9DG,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AAGrC,QAAM,aAAa,OAAO,KAAK;AAE/B,QAAM,OAAO;AAAA,IACX,CAAC,UAA0B;AACzB,oBAAc,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAGA,YAAU,MAAM;AACd,SAAK,EAAE,MAAM,WAAW,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAG5D,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,YAAY,MAAM;AACpC,SAAK,EAAE,MAAM,SAAS,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAC1D,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB,QAAM,mBAAmB,YAAY,MAAM;AACzC,SAAK,EAAE,MAAM,cAAc,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EAC/D,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB,QAAM,kBAAkB;AAAA,IACtB,CAAC,EAAE,SAAS,UAAU,MAA8C;AAClE,UAAI,WAAW,QAAS;AACxB,iBAAW,UAAU;AACrB,WAAK,EAAE,MAAM,aAAa,WAAW,SAAS,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAChF,oBAAc,EAAE,SAAS,UAAU,CAAC;AAAA,IACtC;AAAA,IACA,CAAC,MAAM,WAAW,WAAW;AAAA,EAC/B;AAEA,QAAM,eAAe;AAAA,IACnB,CAAC,EAAE,MAAM,QAAQ,MAAyC;AACxD,UAAI,WAAW,QAAS;AACxB,iBAAW,UAAU;AACrB,WAAK,EAAE,MAAM,UAAU,WAAW,MAAM,SAAS,WAAW,KAAK,IAAI,EAAE,CAAC;AACxE,iBAAW,EAAE,MAAM,QAAQ,CAAC;AAAA,IAC9B;AAAA,IACA,CAAC,MAAM,WAAW,QAAQ;AAAA,EAC5B;AAEA,QAAM,iBAAiB,YAAY,MAAM;AACvC,SAAK,EAAE,MAAM,aAAa,WAAW,WAAW,KAAK,IAAI,EAAE,CAAC;AAC5D,kBAAc;AAAA,EAChB,GAAG,CAAC,MAAM,WAAW,WAAW,CAAC;AAEjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACC,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC5C,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO;AAAA,MACb,SAAS;AAAA,MACT,cAAc;AAAA,MACd,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY;AAAA;AAAA,EACd;AAEJ;","names":[]}
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/server.ts
21
+ var server_exports = {};
22
+ __export(server_exports, {
23
+ CheckoutClient: () => CheckoutClient,
24
+ ThrottleCheckoutError: () => ThrottleCheckoutError,
25
+ buildCheckoutEmbedUrl: () => buildCheckoutEmbedUrl,
26
+ buildCheckoutHostedUrl: () => buildCheckoutHostedUrl,
27
+ createCheckoutClient: () => createCheckoutClient
28
+ });
29
+ module.exports = __toCommonJS(server_exports);
30
+ var ThrottleCheckoutError = class extends Error {
31
+ constructor(args) {
32
+ super(args.message);
33
+ this.name = "ThrottleCheckoutError";
34
+ this.code = args.code;
35
+ this.statusCode = args.statusCode;
36
+ this.details = args.details;
37
+ this.body = args.body;
38
+ }
39
+ };
40
+ var CheckoutClient = class {
41
+ constructor(opts) {
42
+ if (!opts.apiKey) throw new Error("CheckoutClient: apiKey is required");
43
+ const fetchImpl = opts.fetch ?? globalThis.fetch;
44
+ if (!fetchImpl) throw new Error("CheckoutClient: fetch is required");
45
+ this.apiKey = opts.apiKey;
46
+ this.baseUrl = (opts.baseUrl ?? "https://api.usethrottle.dev").replace(/\/+$/, "");
47
+ this.fetchImpl = fetchImpl;
48
+ this.timeoutMs = opts.timeoutMs ?? 3e4;
49
+ }
50
+ async request(method, path, body) {
51
+ const envelope = await this.requestEnvelope(method, path, body);
52
+ if (Object.prototype.hasOwnProperty.call(envelope, "data")) {
53
+ return envelope.data;
54
+ }
55
+ return envelope;
56
+ }
57
+ async requestEnvelope(method, path, body) {
58
+ const ctrl = new AbortController();
59
+ const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
60
+ try {
61
+ const res = await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), {
62
+ method,
63
+ headers: {
64
+ "content-type": "application/json",
65
+ "x-api-key": this.apiKey
66
+ },
67
+ body: body !== void 0 ? JSON.stringify(body) : void 0,
68
+ signal: ctrl.signal
69
+ });
70
+ if (res.status === 204) return { data: void 0 };
71
+ const json = await res.json().catch(() => ({}));
72
+ if (!res.ok) {
73
+ throw new ThrottleCheckoutError({
74
+ code: json.error?.code ?? "unknown_error",
75
+ message: json.error?.message ?? `HTTP ${res.status}`,
76
+ statusCode: res.status,
77
+ details: json.error?.details,
78
+ body: json
79
+ });
80
+ }
81
+ return json;
82
+ } finally {
83
+ clearTimeout(timer);
84
+ }
85
+ }
86
+ async createSession(input) {
87
+ const data = await this.request("POST", "/api/v1/checkout/sessions", input);
88
+ return normalizeCheckoutSession(data);
89
+ }
90
+ async completeSession(sessionId, input) {
91
+ const data = await this.request(
92
+ "POST",
93
+ `/api/v1/checkout/sessions/${encodeURIComponent(sessionId)}/complete`,
94
+ input
95
+ );
96
+ return normalizeCompleteResult(data);
97
+ }
98
+ async createEmbedToken(input) {
99
+ const data = await this.request("POST", "/api/v1/checkout-sessions/embed-token", input);
100
+ return normalizeEmbedToken(data);
101
+ }
102
+ async getOrder(orderId) {
103
+ const data = await this.request("GET", `/api/v1/orders/${encodeURIComponent(orderId)}`);
104
+ return normalizeOrder(data);
105
+ }
106
+ async listOrderPayments(orderId) {
107
+ const data = await this.request(
108
+ "GET",
109
+ `/api/v1/orders/${encodeURIComponent(orderId)}/payments`
110
+ );
111
+ return (data ?? []).map(normalizePayment);
112
+ }
113
+ async listPaymentTransactions(paymentId) {
114
+ const data = await this.request(
115
+ "GET",
116
+ `/api/v1/payments/${encodeURIComponent(paymentId)}/transactions`
117
+ );
118
+ return (data ?? []).map(normalizeTransaction);
119
+ }
120
+ async getOrderWithPayments(orderId) {
121
+ const order = await this.getOrder(orderId);
122
+ const payments = await this.listOrderPayments(orderId);
123
+ return {
124
+ ...order,
125
+ payments: await Promise.all(
126
+ payments.map(async (payment) => ({
127
+ ...payment,
128
+ transactions: payment.id ? await this.listPaymentTransactions(payment.id) : []
129
+ }))
130
+ )
131
+ };
132
+ }
133
+ };
134
+ function createCheckoutClient(opts) {
135
+ return new CheckoutClient(opts);
136
+ }
137
+ function buildCheckoutHostedUrl(options) {
138
+ const route = options.route ?? "s";
139
+ const base = (options.checkoutOrigin ?? "https://checkout.usethrottle.dev").replace(/\/+$/, "");
140
+ return `${base}/${route}/${encodeURIComponent(options.sessionId)}`;
141
+ }
142
+ function buildCheckoutEmbedUrl(options) {
143
+ const baseUrl = buildCheckoutHostedUrl({
144
+ checkoutOrigin: options.checkoutOrigin,
145
+ sessionId: options.sessionId,
146
+ route: options.route ?? "c"
147
+ });
148
+ const params = new URLSearchParams({
149
+ embed: "1",
150
+ mode: options.mode ?? "payment-only",
151
+ ...options.parentOrigin ? { parentOrigin: options.parentOrigin.replace(/\/+$/, "") } : {}
152
+ });
153
+ if (options.primary) params.set("primary", options.primary);
154
+ if (options.logo) params.set("logo", options.logo);
155
+ return `${baseUrl}?${params.toString()}`;
156
+ }
157
+ function toAbsoluteUrl(baseUrl, path) {
158
+ if (/^https?:\/\//i.test(path)) return path;
159
+ return `${baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
160
+ }
161
+ function normalizeCheckoutSession(raw) {
162
+ const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;
163
+ return {
164
+ ...raw,
165
+ id: optionalString(raw?.id),
166
+ sessionId: requiredString(sessionId, "checkoutSession.sessionId"),
167
+ checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url) ?? void 0,
168
+ hostedUrl: optionalString(raw?.hostedUrl ?? raw?.hosted_url) ?? void 0,
169
+ embedUrl: optionalString(raw?.embedUrl ?? raw?.embed_url) ?? void 0,
170
+ embedToken: optionalString(raw?.embedToken ?? raw?.embed_token) ?? void 0,
171
+ expiresAt: optionalString(raw?.expiresAt ?? raw?.expires_at) ?? void 0
172
+ };
173
+ }
174
+ function normalizeCompleteResult(raw) {
175
+ const orderId = raw?.orderId ?? raw?.order_id ?? raw?.id;
176
+ return {
177
+ ...raw,
178
+ orderId: requiredString(orderId, "checkoutComplete.orderId"),
179
+ orderNumber: optionalString(raw?.orderNumber ?? raw?.order_number) ?? void 0,
180
+ paymentId: optionalString(raw?.paymentId ?? raw?.payment_id) ?? void 0,
181
+ total: optionalNumber(raw?.total),
182
+ currency: optionalString(raw?.currency) ?? void 0,
183
+ status: optionalString(raw?.status) ?? void 0,
184
+ paymentStatus: optionalString(raw?.paymentStatus ?? raw?.payment_status) ?? void 0
185
+ };
186
+ }
187
+ function normalizeEmbedToken(raw) {
188
+ return {
189
+ ...raw,
190
+ embedToken: requiredString(raw?.embedToken ?? raw?.embed_token, "embedToken.embedToken"),
191
+ checkoutSessionId: requiredString(
192
+ raw?.checkoutSessionId ?? raw?.checkout_session_id,
193
+ "embedToken.checkoutSessionId"
194
+ ),
195
+ amount: Number(raw?.amount ?? 0),
196
+ currency: optionalString(raw?.currency) ?? "USD",
197
+ hostedUrl: optionalString(raw?.hostedUrl ?? raw?.hosted_url) ?? void 0,
198
+ embedUrl: optionalString(raw?.embedUrl ?? raw?.embed_url) ?? void 0,
199
+ gr4vyId: optionalString(raw?.gr4vyId ?? raw?.gr4vy_id) ?? void 0,
200
+ merchantAccountId: optionalString(raw?.merchantAccountId ?? raw?.merchant_account_id) ?? void 0
201
+ };
202
+ }
203
+ function normalizeOrder(raw) {
204
+ return {
205
+ ...raw,
206
+ id: requiredString(raw?.id, "order.id"),
207
+ orderNumber: optionalString(raw?.orderNumber ?? raw?.order_number) ?? void 0,
208
+ status: optionalString(raw?.status) ?? "processing",
209
+ paymentStatus: optionalString(raw?.paymentStatus ?? raw?.payment_status),
210
+ currency: optionalString(raw?.currency) ?? "USD",
211
+ subtotal: Number(raw?.subtotal ?? 0),
212
+ taxTotal: Number(raw?.taxTotal ?? raw?.tax_total ?? 0),
213
+ shippingTotal: Number(raw?.shippingTotal ?? raw?.shipping_total ?? 0),
214
+ total: Number(raw?.total ?? 0),
215
+ metadata: objectOrUndefined(raw?.metadata)
216
+ };
217
+ }
218
+ function normalizePayment(raw) {
219
+ return {
220
+ ...raw,
221
+ id: requiredString(raw?.id, "payment.id"),
222
+ orderId: optionalString(raw?.orderId ?? raw?.order_id) ?? void 0,
223
+ processor: optionalString(raw?.processor) ?? void 0,
224
+ processorTransactionId: optionalString(raw?.processorTransactionId ?? raw?.processor_transaction_id) ?? void 0,
225
+ amount: optionalNumber(raw?.amount),
226
+ currency: optionalString(raw?.currency) ?? void 0,
227
+ status: optionalString(raw?.status) ?? void 0,
228
+ method: optionalString(raw?.method) ?? void 0,
229
+ createdAt: optionalString(raw?.createdAt ?? raw?.created_at) ?? void 0
230
+ };
231
+ }
232
+ function normalizeTransaction(raw) {
233
+ return {
234
+ ...raw,
235
+ id: requiredString(raw?.id, "transaction.id"),
236
+ paymentId: optionalString(raw?.paymentId ?? raw?.payment_id) ?? void 0,
237
+ type: optionalString(raw?.type) ?? void 0,
238
+ amount: optionalNumber(raw?.amount),
239
+ currency: optionalString(raw?.currency) ?? void 0,
240
+ status: optionalString(raw?.status) ?? void 0,
241
+ createdAt: optionalString(raw?.createdAt ?? raw?.created_at) ?? void 0
242
+ };
243
+ }
244
+ function requiredString(value, label) {
245
+ if (typeof value === "string" && value.length > 0) return value;
246
+ throw new Error(`Invalid Throttle response: missing ${label}`);
247
+ }
248
+ function optionalString(value) {
249
+ return typeof value === "string" && value.length > 0 ? value : null;
250
+ }
251
+ function optionalNumber(value) {
252
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
253
+ }
254
+ function objectOrUndefined(value) {
255
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
256
+ }
257
+ // Annotate the CommonJS export names for ESM import in node:
258
+ 0 && (module.exports = {
259
+ CheckoutClient,
260
+ ThrottleCheckoutError,
261
+ buildCheckoutEmbedUrl,
262
+ buildCheckoutHostedUrl,
263
+ createCheckoutClient
264
+ });
265
+ //# sourceMappingURL=server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["export type PaymentMethod = 'net30' | 'card' | 'gr4vy';\nexport type SubscriptionInterval = 'weekly' | 'monthly' | 'quarterly' | 'yearly';\nexport type CheckoutEmbedMode = 'checkout-full' | 'payment-only';\nexport type CheckoutEmbedRoute = 'c' | 's';\n\nexport interface CheckoutClientOptions {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n}\n\nexport interface CheckoutAddress {\n firstName: string;\n lastName: string;\n company?: string;\n addressLine1: string;\n addressLine2?: string;\n city: string;\n stateProvince: string;\n postalCode: string;\n countryCode: string;\n phone?: string;\n}\n\nexport interface CheckoutCustomerAddressInput {\n firstName?: string;\n lastName?: string;\n phone?: string;\n addressLine1?: string;\n addressLine2?: string;\n city?: string;\n state?: string;\n postalCode?: string;\n country?: string;\n}\n\nexport interface CheckoutCustomerInput {\n customerId?: string;\n externalCustomerId?: string;\n email?: string;\n firstName?: string;\n lastName?: string;\n phone?: string;\n shippingAddress?: CheckoutCustomerAddressInput;\n billingAddress?: CheckoutCustomerAddressInput;\n metadata?: Record<string, unknown>;\n}\n\nexport interface RecurringIntentInput {\n plan: string;\n interval: SubscriptionInterval;\n amount?: number;\n trialDays?: number;\n planName?: string;\n create?: 'auto' | 'manual';\n}\n\nexport interface CheckoutCollectInput {\n shippingAddress?: boolean;\n billingAddress?: boolean;\n}\n\nexport interface CreateCheckoutSessionInput {\n storeId: string;\n cartId?: string;\n externalCartId?: string;\n customerEmail?: string;\n customer?: CheckoutCustomerInput;\n returnUrl: string;\n cancelUrl: string;\n allowedMethods?: string[];\n recurring?: RecurringIntentInput;\n collect?: CheckoutCollectInput;\n metadata?: Record<string, unknown>;\n discountCode?: string;\n}\n\nexport interface CheckoutSession {\n sessionId: string;\n id?: string;\n checkoutUrl?: string;\n hostedUrl?: string;\n embedUrl?: string;\n embedToken?: string;\n expiresAt?: string;\n [key: string]: unknown;\n}\n\nexport interface Net30Acceptance {\n termsHash: string;\n acceptedAt: string;\n companyName: string;\n billingEmail: string;\n}\n\nexport interface CompleteCheckoutSessionInput {\n email?: string;\n shippingAddress?: CheckoutAddress;\n billingAddress?: CheckoutAddress;\n billingSameAsShipping?: boolean;\n paymentMethod: PaymentMethod;\n netDays?: number;\n termsAccepted?: boolean;\n termsSnapshot?: string;\n invoiceNumber?: string;\n net30Acceptance?: Net30Acceptance;\n paymentToken?: string;\n gr4vyCheckoutSessionId?: string;\n gr4vyTransactionId?: string;\n}\n\nexport interface CompleteCheckoutSessionResult {\n orderId: string;\n orderNumber?: string;\n paymentId?: string;\n total?: number;\n currency?: string;\n status?: string;\n paymentStatus?: string;\n [key: string]: unknown;\n}\n\nexport interface CreateEmbedTokenInput {\n externalCartId?: string;\n amount: number;\n currency: string;\n country?: string;\n allowedMethods?: string[];\n}\n\nexport interface CreateEmbedTokenResult {\n embedToken: string;\n checkoutSessionId: string;\n amount: number;\n currency: string;\n hostedUrl?: string;\n embedUrl?: string;\n gr4vyId?: string;\n merchantAccountId?: string;\n [key: string]: unknown;\n}\n\nexport interface CheckoutOrder {\n id: string;\n orderNumber?: string;\n status: string;\n paymentStatus: string | null;\n currency: string;\n subtotal: number;\n taxTotal: number;\n shippingTotal: number;\n total: number;\n metadata?: Record<string, unknown>;\n payments?: CheckoutPayment[];\n [key: string]: unknown;\n}\n\nexport interface CheckoutPayment {\n id: string;\n orderId?: string;\n processor?: string;\n processorTransactionId?: string | null;\n amount?: number;\n currency?: string;\n status?: string;\n method?: string;\n createdAt?: string;\n transactions?: CheckoutPaymentTransaction[];\n [key: string]: unknown;\n}\n\nexport interface CheckoutPaymentTransaction {\n id: string;\n paymentId?: string;\n type?: string;\n amount?: number;\n currency?: string;\n status?: string;\n createdAt?: string;\n [key: string]: unknown;\n}\n\nexport interface BuildCheckoutUrlOptions {\n checkoutOrigin?: string;\n sessionId: string;\n parentOrigin?: string;\n mode?: CheckoutEmbedMode;\n route?: CheckoutEmbedRoute;\n primary?: string;\n logo?: string;\n}\n\nexport interface ThrottleEnvelope<T> {\n data?: T;\n meta?: Record<string, unknown>;\n error?: {\n code?: string;\n message?: string;\n details?: unknown;\n };\n}\n\nexport class ThrottleCheckoutError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly details?: unknown;\n readonly body?: unknown;\n\n constructor(args: {\n code: string;\n message: string;\n statusCode: number;\n details?: unknown;\n body?: unknown;\n }) {\n super(args.message);\n this.name = 'ThrottleCheckoutError';\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n this.body = args.body;\n }\n}\n\nexport class CheckoutClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly timeoutMs: number;\n\n constructor(opts: CheckoutClientOptions) {\n if (!opts.apiKey) throw new Error('CheckoutClient: apiKey is required');\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('CheckoutClient: fetch is required');\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const envelope = await this.requestEnvelope<T>(method, path, body);\n if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {\n return envelope.data as T;\n }\n return envelope as T;\n }\n\n async requestEnvelope<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n\n try {\n const res = await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), {\n method,\n headers: {\n 'content-type': 'application/json',\n 'x-api-key': this.apiKey,\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: ctrl.signal,\n });\n\n if (res.status === 204) return { data: undefined as T };\n\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) {\n throw new ThrottleCheckoutError({\n code: json.error?.code ?? 'unknown_error',\n message: json.error?.message ?? `HTTP ${res.status}`,\n statusCode: res.status,\n details: json.error?.details,\n body: json,\n });\n }\n return json;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async createSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout/sessions', input);\n return normalizeCheckoutSession(data);\n }\n\n async completeSession(\n sessionId: string,\n input: CompleteCheckoutSessionInput,\n ): Promise<CompleteCheckoutSessionResult> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/checkout/sessions/${encodeURIComponent(sessionId)}/complete`,\n input,\n );\n return normalizeCompleteResult(data);\n }\n\n async createEmbedToken(input: CreateEmbedTokenInput): Promise<CreateEmbedTokenResult> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout-sessions/embed-token', input);\n return normalizeEmbedToken(data);\n }\n\n async getOrder(orderId: string): Promise<CheckoutOrder> {\n const data = await this.request<unknown>('GET', `/api/v1/orders/${encodeURIComponent(orderId)}`);\n return normalizeOrder(data);\n }\n\n async listOrderPayments(orderId: string): Promise<CheckoutPayment[]> {\n const data = await this.request<unknown[]>(\n 'GET',\n `/api/v1/orders/${encodeURIComponent(orderId)}/payments`,\n );\n return (data ?? []).map(normalizePayment);\n }\n\n async listPaymentTransactions(paymentId: string): Promise<CheckoutPaymentTransaction[]> {\n const data = await this.request<unknown[]>(\n 'GET',\n `/api/v1/payments/${encodeURIComponent(paymentId)}/transactions`,\n );\n return (data ?? []).map(normalizeTransaction);\n }\n\n async getOrderWithPayments(orderId: string): Promise<CheckoutOrder> {\n const order = await this.getOrder(orderId);\n const payments = await this.listOrderPayments(orderId);\n return {\n ...order,\n payments: await Promise.all(\n payments.map(async (payment) => ({\n ...payment,\n transactions: payment.id ? await this.listPaymentTransactions(payment.id) : [],\n })),\n ),\n };\n }\n}\n\nexport function createCheckoutClient(opts: CheckoutClientOptions): CheckoutClient {\n return new CheckoutClient(opts);\n}\n\nexport function buildCheckoutHostedUrl(options: BuildCheckoutUrlOptions): string {\n const route = options.route ?? 's';\n const base = (options.checkoutOrigin ?? 'https://checkout.usethrottle.dev').replace(/\\/+$/, '');\n return `${base}/${route}/${encodeURIComponent(options.sessionId)}`;\n}\n\nexport function buildCheckoutEmbedUrl(options: BuildCheckoutUrlOptions): string {\n const baseUrl = buildCheckoutHostedUrl({\n checkoutOrigin: options.checkoutOrigin,\n sessionId: options.sessionId,\n route: options.route ?? 'c',\n });\n const params = new URLSearchParams({\n embed: '1',\n mode: options.mode ?? 'payment-only',\n ...(options.parentOrigin ? { parentOrigin: options.parentOrigin.replace(/\\/+$/, '') } : {}),\n });\n if (options.primary) params.set('primary', options.primary);\n if (options.logo) params.set('logo', options.logo);\n return `${baseUrl}?${params.toString()}`;\n}\n\nfunction toAbsoluteUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n}\n\nfunction normalizeCheckoutSession(raw: any): CheckoutSession {\n const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;\n return {\n ...raw,\n id: optionalString(raw?.id),\n sessionId: requiredString(sessionId, 'checkoutSession.sessionId'),\n checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url) ?? undefined,\n hostedUrl: optionalString(raw?.hostedUrl ?? raw?.hosted_url) ?? undefined,\n embedUrl: optionalString(raw?.embedUrl ?? raw?.embed_url) ?? undefined,\n embedToken: optionalString(raw?.embedToken ?? raw?.embed_token) ?? undefined,\n expiresAt: optionalString(raw?.expiresAt ?? raw?.expires_at) ?? undefined,\n };\n}\n\nfunction normalizeCompleteResult(raw: any): CompleteCheckoutSessionResult {\n const orderId = raw?.orderId ?? raw?.order_id ?? raw?.id;\n return {\n ...raw,\n orderId: requiredString(orderId, 'checkoutComplete.orderId'),\n orderNumber: optionalString(raw?.orderNumber ?? raw?.order_number) ?? undefined,\n paymentId: optionalString(raw?.paymentId ?? raw?.payment_id) ?? undefined,\n total: optionalNumber(raw?.total),\n currency: optionalString(raw?.currency) ?? undefined,\n status: optionalString(raw?.status) ?? undefined,\n paymentStatus: optionalString(raw?.paymentStatus ?? raw?.payment_status) ?? undefined,\n };\n}\n\nfunction normalizeEmbedToken(raw: any): CreateEmbedTokenResult {\n return {\n ...raw,\n embedToken: requiredString(raw?.embedToken ?? raw?.embed_token, 'embedToken.embedToken'),\n checkoutSessionId: requiredString(\n raw?.checkoutSessionId ?? raw?.checkout_session_id,\n 'embedToken.checkoutSessionId',\n ),\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n hostedUrl: optionalString(raw?.hostedUrl ?? raw?.hosted_url) ?? undefined,\n embedUrl: optionalString(raw?.embedUrl ?? raw?.embed_url) ?? undefined,\n gr4vyId: optionalString(raw?.gr4vyId ?? raw?.gr4vy_id) ?? undefined,\n merchantAccountId:\n optionalString(raw?.merchantAccountId ?? raw?.merchant_account_id) ?? undefined,\n };\n}\n\nfunction normalizeOrder(raw: any): CheckoutOrder {\n return {\n ...raw,\n id: requiredString(raw?.id, 'order.id'),\n orderNumber: optionalString(raw?.orderNumber ?? raw?.order_number) ?? undefined,\n status: optionalString(raw?.status) ?? 'processing',\n paymentStatus: optionalString(raw?.paymentStatus ?? raw?.payment_status),\n currency: optionalString(raw?.currency) ?? 'USD',\n subtotal: Number(raw?.subtotal ?? 0),\n taxTotal: Number(raw?.taxTotal ?? raw?.tax_total ?? 0),\n shippingTotal: Number(raw?.shippingTotal ?? raw?.shipping_total ?? 0),\n total: Number(raw?.total ?? 0),\n metadata: objectOrUndefined(raw?.metadata),\n };\n}\n\nfunction normalizePayment(raw: any): CheckoutPayment {\n return {\n ...raw,\n id: requiredString(raw?.id, 'payment.id'),\n orderId: optionalString(raw?.orderId ?? raw?.order_id) ?? undefined,\n processor: optionalString(raw?.processor) ?? undefined,\n processorTransactionId:\n optionalString(raw?.processorTransactionId ?? raw?.processor_transaction_id) ?? undefined,\n amount: optionalNumber(raw?.amount),\n currency: optionalString(raw?.currency) ?? undefined,\n status: optionalString(raw?.status) ?? undefined,\n method: optionalString(raw?.method) ?? undefined,\n createdAt: optionalString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n };\n}\n\nfunction normalizeTransaction(raw: any): CheckoutPaymentTransaction {\n return {\n ...raw,\n id: requiredString(raw?.id, 'transaction.id'),\n paymentId: optionalString(raw?.paymentId ?? raw?.payment_id) ?? undefined,\n type: optionalString(raw?.type) ?? undefined,\n amount: optionalNumber(raw?.amount),\n currency: optionalString(raw?.currency) ?? undefined,\n status: optionalString(raw?.status) ?? undefined,\n createdAt: optionalString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n };\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalString(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null;\n}\n\nfunction optionalNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction objectOrUndefined(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2MO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAM/C,YAAY,MAMT;AACD,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AACjB,SAAK,aAAa,KAAK;AACvB,SAAK,UAAU,KAAK;AACpB,SAAK,OAAO,KAAK;AAAA,EACnB;AACF;AAEO,IAAM,iBAAN,MAAqB;AAAA,EAM1B,YAAY,MAA6B;AACvC,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,oCAAoC;AACtE,UAAM,YAAY,KAAK,SAAS,WAAW;AAC3C,QAAI,CAAC,UAAW,OAAM,IAAI,MAAM,mCAAmC;AACnE,SAAK,SAAS,KAAK;AACnB,SAAK,WAAW,KAAK,WAAW,+BAA+B,QAAQ,QAAQ,EAAE;AACjF,SAAK,YAAY;AACjB,SAAK,YAAY,KAAK,aAAa;AAAA,EACrC;AAAA,EAEA,MAAM,QAAqB,QAAgB,MAAc,MAA4B;AACnF,UAAM,WAAW,MAAM,KAAK,gBAAmB,QAAQ,MAAM,IAAI;AACjE,QAAI,OAAO,UAAU,eAAe,KAAK,UAAU,MAAM,GAAG;AAC1D,aAAO,SAAS;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBACJ,QACA,MACA,MAC8B;AAC9B,UAAM,OAAO,IAAI,gBAAgB;AACjC,UAAM,QAAQ,WAAW,MAAM,KAAK,MAAM,GAAG,KAAK,SAAS;AAE3D,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,UAAU,cAAc,KAAK,SAAS,IAAI,GAAG;AAAA,QAClE;AAAA,QACA,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,aAAa,KAAK;AAAA,QACpB;AAAA,QACA,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,QAClD,QAAQ,KAAK;AAAA,MACf,CAAC;AAED,UAAI,IAAI,WAAW,IAAK,QAAO,EAAE,MAAM,OAAe;AAEtD,YAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC/C,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,IAAI,sBAAsB;AAAA,UAC9B,MAAM,KAAK,OAAO,QAAQ;AAAA,UAC1B,SAAS,KAAK,OAAO,WAAW,QAAQ,IAAI,MAAM;AAAA,UAClD,YAAY,IAAI;AAAA,UAChB,SAAS,KAAK,OAAO;AAAA,UACrB,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,OAA6D;AAC/E,UAAM,OAAO,MAAM,KAAK,QAAiB,QAAQ,6BAA6B,KAAK;AACnF,WAAO,yBAAyB,IAAI;AAAA,EACtC;AAAA,EAEA,MAAM,gBACJ,WACA,OACwC;AACxC,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,6BAA6B,mBAAmB,SAAS,CAAC;AAAA,MAC1D;AAAA,IACF;AACA,WAAO,wBAAwB,IAAI;AAAA,EACrC;AAAA,EAEA,MAAM,iBAAiB,OAA+D;AACpF,UAAM,OAAO,MAAM,KAAK,QAAiB,QAAQ,yCAAyC,KAAK;AAC/F,WAAO,oBAAoB,IAAI;AAAA,EACjC;AAAA,EAEA,MAAM,SAAS,SAAyC;AACtD,UAAM,OAAO,MAAM,KAAK,QAAiB,OAAO,kBAAkB,mBAAmB,OAAO,CAAC,EAAE;AAC/F,WAAO,eAAe,IAAI;AAAA,EAC5B;AAAA,EAEA,MAAM,kBAAkB,SAA6C;AACnE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,kBAAkB,mBAAmB,OAAO,CAAC;AAAA,IAC/C;AACA,YAAQ,QAAQ,CAAC,GAAG,IAAI,gBAAgB;AAAA,EAC1C;AAAA,EAEA,MAAM,wBAAwB,WAA0D;AACtF,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,oBAAoB,mBAAmB,SAAS,CAAC;AAAA,IACnD;AACA,YAAQ,QAAQ,CAAC,GAAG,IAAI,oBAAoB;AAAA,EAC9C;AAAA,EAEA,MAAM,qBAAqB,SAAyC;AAClE,UAAM,QAAQ,MAAM,KAAK,SAAS,OAAO;AACzC,UAAM,WAAW,MAAM,KAAK,kBAAkB,OAAO;AACrD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,MAAM,QAAQ;AAAA,QACtB,SAAS,IAAI,OAAO,aAAa;AAAA,UAC/B,GAAG;AAAA,UACH,cAAc,QAAQ,KAAK,MAAM,KAAK,wBAAwB,QAAQ,EAAE,IAAI,CAAC;AAAA,QAC/E,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,qBAAqB,MAA6C;AAChF,SAAO,IAAI,eAAe,IAAI;AAChC;AAEO,SAAS,uBAAuB,SAA0C;AAC/E,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,QAAQ,QAAQ,kBAAkB,oCAAoC,QAAQ,QAAQ,EAAE;AAC9F,SAAO,GAAG,IAAI,IAAI,KAAK,IAAI,mBAAmB,QAAQ,SAAS,CAAC;AAClE;AAEO,SAAS,sBAAsB,SAA0C;AAC9E,QAAM,UAAU,uBAAuB;AAAA,IACrC,gBAAgB,QAAQ;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,OAAO,QAAQ,SAAS;AAAA,EAC1B,CAAC;AACD,QAAM,SAAS,IAAI,gBAAgB;AAAA,IACjC,OAAO;AAAA,IACP,MAAM,QAAQ,QAAQ;AAAA,IACtB,GAAI,QAAQ,eAAe,EAAE,cAAc,QAAQ,aAAa,QAAQ,QAAQ,EAAE,EAAE,IAAI,CAAC;AAAA,EAC3F,CAAC;AACD,MAAI,QAAQ,QAAS,QAAO,IAAI,WAAW,QAAQ,OAAO;AAC1D,MAAI,QAAQ,KAAM,QAAO,IAAI,QAAQ,QAAQ,IAAI;AACjD,SAAO,GAAG,OAAO,IAAI,OAAO,SAAS,CAAC;AACxC;AAEA,SAAS,cAAc,SAAiB,MAAsB;AAC5D,MAAI,gBAAgB,KAAK,IAAI,EAAG,QAAO;AACvC,SAAO,GAAG,OAAO,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AAC9D;AAEA,SAAS,yBAAyB,KAA2B;AAC3D,QAAM,YAAY,KAAK,aAAa,KAAK,cAAc,KAAK;AAC5D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,eAAe,KAAK,EAAE;AAAA,IAC1B,WAAW,eAAe,WAAW,2BAA2B;AAAA,IAChE,aAAa,eAAe,KAAK,eAAe,KAAK,YAAY,KAAK;AAAA,IACtE,WAAW,eAAe,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,IAChE,UAAU,eAAe,KAAK,YAAY,KAAK,SAAS,KAAK;AAAA,IAC7D,YAAY,eAAe,KAAK,cAAc,KAAK,WAAW,KAAK;AAAA,IACnE,WAAW,eAAe,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,EAClE;AACF;AAEA,SAAS,wBAAwB,KAAyC;AACxE,QAAM,UAAU,KAAK,WAAW,KAAK,YAAY,KAAK;AACtD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,eAAe,SAAS,0BAA0B;AAAA,IAC3D,aAAa,eAAe,KAAK,eAAe,KAAK,YAAY,KAAK;AAAA,IACtE,WAAW,eAAe,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,IAChE,OAAO,eAAe,KAAK,KAAK;AAAA,IAChC,UAAU,eAAe,KAAK,QAAQ,KAAK;AAAA,IAC3C,QAAQ,eAAe,KAAK,MAAM,KAAK;AAAA,IACvC,eAAe,eAAe,KAAK,iBAAiB,KAAK,cAAc,KAAK;AAAA,EAC9E;AACF;AAEA,SAAS,oBAAoB,KAAkC;AAC7D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,YAAY,eAAe,KAAK,cAAc,KAAK,aAAa,uBAAuB;AAAA,IACvF,mBAAmB;AAAA,MACjB,KAAK,qBAAqB,KAAK;AAAA,MAC/B;AAAA,IACF;AAAA,IACA,QAAQ,OAAO,KAAK,UAAU,CAAC;AAAA,IAC/B,UAAU,eAAe,KAAK,QAAQ,KAAK;AAAA,IAC3C,WAAW,eAAe,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,IAChE,UAAU,eAAe,KAAK,YAAY,KAAK,SAAS,KAAK;AAAA,IAC7D,SAAS,eAAe,KAAK,WAAW,KAAK,QAAQ,KAAK;AAAA,IAC1D,mBACE,eAAe,KAAK,qBAAqB,KAAK,mBAAmB,KAAK;AAAA,EAC1E;AACF;AAEA,SAAS,eAAe,KAAyB;AAC/C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,eAAe,KAAK,IAAI,UAAU;AAAA,IACtC,aAAa,eAAe,KAAK,eAAe,KAAK,YAAY,KAAK;AAAA,IACtE,QAAQ,eAAe,KAAK,MAAM,KAAK;AAAA,IACvC,eAAe,eAAe,KAAK,iBAAiB,KAAK,cAAc;AAAA,IACvE,UAAU,eAAe,KAAK,QAAQ,KAAK;AAAA,IAC3C,UAAU,OAAO,KAAK,YAAY,CAAC;AAAA,IACnC,UAAU,OAAO,KAAK,YAAY,KAAK,aAAa,CAAC;AAAA,IACrD,eAAe,OAAO,KAAK,iBAAiB,KAAK,kBAAkB,CAAC;AAAA,IACpE,OAAO,OAAO,KAAK,SAAS,CAAC;AAAA,IAC7B,UAAU,kBAAkB,KAAK,QAAQ;AAAA,EAC3C;AACF;AAEA,SAAS,iBAAiB,KAA2B;AACnD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,eAAe,KAAK,IAAI,YAAY;AAAA,IACxC,SAAS,eAAe,KAAK,WAAW,KAAK,QAAQ,KAAK;AAAA,IAC1D,WAAW,eAAe,KAAK,SAAS,KAAK;AAAA,IAC7C,wBACE,eAAe,KAAK,0BAA0B,KAAK,wBAAwB,KAAK;AAAA,IAClF,QAAQ,eAAe,KAAK,MAAM;AAAA,IAClC,UAAU,eAAe,KAAK,QAAQ,KAAK;AAAA,IAC3C,QAAQ,eAAe,KAAK,MAAM,KAAK;AAAA,IACvC,QAAQ,eAAe,KAAK,MAAM,KAAK;AAAA,IACvC,WAAW,eAAe,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,EAClE;AACF;AAEA,SAAS,qBAAqB,KAAsC;AAClE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,eAAe,KAAK,IAAI,gBAAgB;AAAA,IAC5C,WAAW,eAAe,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,IAChE,MAAM,eAAe,KAAK,IAAI,KAAK;AAAA,IACnC,QAAQ,eAAe,KAAK,MAAM;AAAA,IAClC,UAAU,eAAe,KAAK,QAAQ,KAAK;AAAA,IAC3C,QAAQ,eAAe,KAAK,MAAM,KAAK;AAAA,IACvC,WAAW,eAAe,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,EAClE;AACF;AAEA,SAAS,eAAe,OAAgB,OAAuB;AAC7D,MAAI,OAAO,UAAU,YAAY,MAAM,SAAS,EAAG,QAAO;AAC1D,QAAM,IAAI,MAAM,sCAAsC,KAAK,EAAE;AAC/D;AAEA,SAAS,eAAe,OAA+B;AACrD,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAEA,SAAS,eAAe,OAAoC;AAC1D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE;AAEA,SAAS,kBAAkB,OAAqD;AAC9E,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC5D,QACD;AACN;","names":[]}
@@ -0,0 +1,218 @@
1
+ type PaymentMethod = 'net30' | 'card' | 'gr4vy';
2
+ type SubscriptionInterval = 'weekly' | 'monthly' | 'quarterly' | 'yearly';
3
+ type CheckoutEmbedMode = 'checkout-full' | 'payment-only';
4
+ type CheckoutEmbedRoute = 'c' | 's';
5
+ interface CheckoutClientOptions {
6
+ apiKey: string;
7
+ baseUrl?: string;
8
+ fetch?: typeof globalThis.fetch;
9
+ timeoutMs?: number;
10
+ }
11
+ interface CheckoutAddress {
12
+ firstName: string;
13
+ lastName: string;
14
+ company?: string;
15
+ addressLine1: string;
16
+ addressLine2?: string;
17
+ city: string;
18
+ stateProvince: string;
19
+ postalCode: string;
20
+ countryCode: string;
21
+ phone?: string;
22
+ }
23
+ interface CheckoutCustomerAddressInput {
24
+ firstName?: string;
25
+ lastName?: string;
26
+ phone?: string;
27
+ addressLine1?: string;
28
+ addressLine2?: string;
29
+ city?: string;
30
+ state?: string;
31
+ postalCode?: string;
32
+ country?: string;
33
+ }
34
+ interface CheckoutCustomerInput {
35
+ customerId?: string;
36
+ externalCustomerId?: string;
37
+ email?: string;
38
+ firstName?: string;
39
+ lastName?: string;
40
+ phone?: string;
41
+ shippingAddress?: CheckoutCustomerAddressInput;
42
+ billingAddress?: CheckoutCustomerAddressInput;
43
+ metadata?: Record<string, unknown>;
44
+ }
45
+ interface RecurringIntentInput {
46
+ plan: string;
47
+ interval: SubscriptionInterval;
48
+ amount?: number;
49
+ trialDays?: number;
50
+ planName?: string;
51
+ create?: 'auto' | 'manual';
52
+ }
53
+ interface CheckoutCollectInput {
54
+ shippingAddress?: boolean;
55
+ billingAddress?: boolean;
56
+ }
57
+ interface CreateCheckoutSessionInput {
58
+ storeId: string;
59
+ cartId?: string;
60
+ externalCartId?: string;
61
+ customerEmail?: string;
62
+ customer?: CheckoutCustomerInput;
63
+ returnUrl: string;
64
+ cancelUrl: string;
65
+ allowedMethods?: string[];
66
+ recurring?: RecurringIntentInput;
67
+ collect?: CheckoutCollectInput;
68
+ metadata?: Record<string, unknown>;
69
+ discountCode?: string;
70
+ }
71
+ interface CheckoutSession {
72
+ sessionId: string;
73
+ id?: string;
74
+ checkoutUrl?: string;
75
+ hostedUrl?: string;
76
+ embedUrl?: string;
77
+ embedToken?: string;
78
+ expiresAt?: string;
79
+ [key: string]: unknown;
80
+ }
81
+ interface Net30Acceptance {
82
+ termsHash: string;
83
+ acceptedAt: string;
84
+ companyName: string;
85
+ billingEmail: string;
86
+ }
87
+ interface CompleteCheckoutSessionInput {
88
+ email?: string;
89
+ shippingAddress?: CheckoutAddress;
90
+ billingAddress?: CheckoutAddress;
91
+ billingSameAsShipping?: boolean;
92
+ paymentMethod: PaymentMethod;
93
+ netDays?: number;
94
+ termsAccepted?: boolean;
95
+ termsSnapshot?: string;
96
+ invoiceNumber?: string;
97
+ net30Acceptance?: Net30Acceptance;
98
+ paymentToken?: string;
99
+ gr4vyCheckoutSessionId?: string;
100
+ gr4vyTransactionId?: string;
101
+ }
102
+ interface CompleteCheckoutSessionResult {
103
+ orderId: string;
104
+ orderNumber?: string;
105
+ paymentId?: string;
106
+ total?: number;
107
+ currency?: string;
108
+ status?: string;
109
+ paymentStatus?: string;
110
+ [key: string]: unknown;
111
+ }
112
+ interface CreateEmbedTokenInput {
113
+ externalCartId?: string;
114
+ amount: number;
115
+ currency: string;
116
+ country?: string;
117
+ allowedMethods?: string[];
118
+ }
119
+ interface CreateEmbedTokenResult {
120
+ embedToken: string;
121
+ checkoutSessionId: string;
122
+ amount: number;
123
+ currency: string;
124
+ hostedUrl?: string;
125
+ embedUrl?: string;
126
+ gr4vyId?: string;
127
+ merchantAccountId?: string;
128
+ [key: string]: unknown;
129
+ }
130
+ interface CheckoutOrder {
131
+ id: string;
132
+ orderNumber?: string;
133
+ status: string;
134
+ paymentStatus: string | null;
135
+ currency: string;
136
+ subtotal: number;
137
+ taxTotal: number;
138
+ shippingTotal: number;
139
+ total: number;
140
+ metadata?: Record<string, unknown>;
141
+ payments?: CheckoutPayment[];
142
+ [key: string]: unknown;
143
+ }
144
+ interface CheckoutPayment {
145
+ id: string;
146
+ orderId?: string;
147
+ processor?: string;
148
+ processorTransactionId?: string | null;
149
+ amount?: number;
150
+ currency?: string;
151
+ status?: string;
152
+ method?: string;
153
+ createdAt?: string;
154
+ transactions?: CheckoutPaymentTransaction[];
155
+ [key: string]: unknown;
156
+ }
157
+ interface CheckoutPaymentTransaction {
158
+ id: string;
159
+ paymentId?: string;
160
+ type?: string;
161
+ amount?: number;
162
+ currency?: string;
163
+ status?: string;
164
+ createdAt?: string;
165
+ [key: string]: unknown;
166
+ }
167
+ interface BuildCheckoutUrlOptions {
168
+ checkoutOrigin?: string;
169
+ sessionId: string;
170
+ parentOrigin?: string;
171
+ mode?: CheckoutEmbedMode;
172
+ route?: CheckoutEmbedRoute;
173
+ primary?: string;
174
+ logo?: string;
175
+ }
176
+ interface ThrottleEnvelope<T> {
177
+ data?: T;
178
+ meta?: Record<string, unknown>;
179
+ error?: {
180
+ code?: string;
181
+ message?: string;
182
+ details?: unknown;
183
+ };
184
+ }
185
+ declare class ThrottleCheckoutError extends Error {
186
+ readonly code: string;
187
+ readonly statusCode: number;
188
+ readonly details?: unknown;
189
+ readonly body?: unknown;
190
+ constructor(args: {
191
+ code: string;
192
+ message: string;
193
+ statusCode: number;
194
+ details?: unknown;
195
+ body?: unknown;
196
+ });
197
+ }
198
+ declare class CheckoutClient {
199
+ private readonly apiKey;
200
+ private readonly baseUrl;
201
+ private readonly fetchImpl;
202
+ private readonly timeoutMs;
203
+ constructor(opts: CheckoutClientOptions);
204
+ request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
205
+ requestEnvelope<T = unknown>(method: string, path: string, body?: unknown): Promise<ThrottleEnvelope<T>>;
206
+ createSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession>;
207
+ completeSession(sessionId: string, input: CompleteCheckoutSessionInput): Promise<CompleteCheckoutSessionResult>;
208
+ createEmbedToken(input: CreateEmbedTokenInput): Promise<CreateEmbedTokenResult>;
209
+ getOrder(orderId: string): Promise<CheckoutOrder>;
210
+ listOrderPayments(orderId: string): Promise<CheckoutPayment[]>;
211
+ listPaymentTransactions(paymentId: string): Promise<CheckoutPaymentTransaction[]>;
212
+ getOrderWithPayments(orderId: string): Promise<CheckoutOrder>;
213
+ }
214
+ declare function createCheckoutClient(opts: CheckoutClientOptions): CheckoutClient;
215
+ declare function buildCheckoutHostedUrl(options: BuildCheckoutUrlOptions): string;
216
+ declare function buildCheckoutEmbedUrl(options: BuildCheckoutUrlOptions): string;
217
+
218
+ export { type BuildCheckoutUrlOptions, type CheckoutAddress, CheckoutClient, type CheckoutClientOptions, type CheckoutCollectInput, type CheckoutCustomerAddressInput, type CheckoutCustomerInput, type CheckoutEmbedMode, type CheckoutEmbedRoute, type CheckoutOrder, type CheckoutPayment, type CheckoutPaymentTransaction, type CheckoutSession, type CompleteCheckoutSessionInput, type CompleteCheckoutSessionResult, type CreateCheckoutSessionInput, type CreateEmbedTokenInput, type CreateEmbedTokenResult, type Net30Acceptance, type PaymentMethod, type RecurringIntentInput, type SubscriptionInterval, ThrottleCheckoutError, type ThrottleEnvelope, buildCheckoutEmbedUrl, buildCheckoutHostedUrl, createCheckoutClient };
@@ -0,0 +1,218 @@
1
+ type PaymentMethod = 'net30' | 'card' | 'gr4vy';
2
+ type SubscriptionInterval = 'weekly' | 'monthly' | 'quarterly' | 'yearly';
3
+ type CheckoutEmbedMode = 'checkout-full' | 'payment-only';
4
+ type CheckoutEmbedRoute = 'c' | 's';
5
+ interface CheckoutClientOptions {
6
+ apiKey: string;
7
+ baseUrl?: string;
8
+ fetch?: typeof globalThis.fetch;
9
+ timeoutMs?: number;
10
+ }
11
+ interface CheckoutAddress {
12
+ firstName: string;
13
+ lastName: string;
14
+ company?: string;
15
+ addressLine1: string;
16
+ addressLine2?: string;
17
+ city: string;
18
+ stateProvince: string;
19
+ postalCode: string;
20
+ countryCode: string;
21
+ phone?: string;
22
+ }
23
+ interface CheckoutCustomerAddressInput {
24
+ firstName?: string;
25
+ lastName?: string;
26
+ phone?: string;
27
+ addressLine1?: string;
28
+ addressLine2?: string;
29
+ city?: string;
30
+ state?: string;
31
+ postalCode?: string;
32
+ country?: string;
33
+ }
34
+ interface CheckoutCustomerInput {
35
+ customerId?: string;
36
+ externalCustomerId?: string;
37
+ email?: string;
38
+ firstName?: string;
39
+ lastName?: string;
40
+ phone?: string;
41
+ shippingAddress?: CheckoutCustomerAddressInput;
42
+ billingAddress?: CheckoutCustomerAddressInput;
43
+ metadata?: Record<string, unknown>;
44
+ }
45
+ interface RecurringIntentInput {
46
+ plan: string;
47
+ interval: SubscriptionInterval;
48
+ amount?: number;
49
+ trialDays?: number;
50
+ planName?: string;
51
+ create?: 'auto' | 'manual';
52
+ }
53
+ interface CheckoutCollectInput {
54
+ shippingAddress?: boolean;
55
+ billingAddress?: boolean;
56
+ }
57
+ interface CreateCheckoutSessionInput {
58
+ storeId: string;
59
+ cartId?: string;
60
+ externalCartId?: string;
61
+ customerEmail?: string;
62
+ customer?: CheckoutCustomerInput;
63
+ returnUrl: string;
64
+ cancelUrl: string;
65
+ allowedMethods?: string[];
66
+ recurring?: RecurringIntentInput;
67
+ collect?: CheckoutCollectInput;
68
+ metadata?: Record<string, unknown>;
69
+ discountCode?: string;
70
+ }
71
+ interface CheckoutSession {
72
+ sessionId: string;
73
+ id?: string;
74
+ checkoutUrl?: string;
75
+ hostedUrl?: string;
76
+ embedUrl?: string;
77
+ embedToken?: string;
78
+ expiresAt?: string;
79
+ [key: string]: unknown;
80
+ }
81
+ interface Net30Acceptance {
82
+ termsHash: string;
83
+ acceptedAt: string;
84
+ companyName: string;
85
+ billingEmail: string;
86
+ }
87
+ interface CompleteCheckoutSessionInput {
88
+ email?: string;
89
+ shippingAddress?: CheckoutAddress;
90
+ billingAddress?: CheckoutAddress;
91
+ billingSameAsShipping?: boolean;
92
+ paymentMethod: PaymentMethod;
93
+ netDays?: number;
94
+ termsAccepted?: boolean;
95
+ termsSnapshot?: string;
96
+ invoiceNumber?: string;
97
+ net30Acceptance?: Net30Acceptance;
98
+ paymentToken?: string;
99
+ gr4vyCheckoutSessionId?: string;
100
+ gr4vyTransactionId?: string;
101
+ }
102
+ interface CompleteCheckoutSessionResult {
103
+ orderId: string;
104
+ orderNumber?: string;
105
+ paymentId?: string;
106
+ total?: number;
107
+ currency?: string;
108
+ status?: string;
109
+ paymentStatus?: string;
110
+ [key: string]: unknown;
111
+ }
112
+ interface CreateEmbedTokenInput {
113
+ externalCartId?: string;
114
+ amount: number;
115
+ currency: string;
116
+ country?: string;
117
+ allowedMethods?: string[];
118
+ }
119
+ interface CreateEmbedTokenResult {
120
+ embedToken: string;
121
+ checkoutSessionId: string;
122
+ amount: number;
123
+ currency: string;
124
+ hostedUrl?: string;
125
+ embedUrl?: string;
126
+ gr4vyId?: string;
127
+ merchantAccountId?: string;
128
+ [key: string]: unknown;
129
+ }
130
+ interface CheckoutOrder {
131
+ id: string;
132
+ orderNumber?: string;
133
+ status: string;
134
+ paymentStatus: string | null;
135
+ currency: string;
136
+ subtotal: number;
137
+ taxTotal: number;
138
+ shippingTotal: number;
139
+ total: number;
140
+ metadata?: Record<string, unknown>;
141
+ payments?: CheckoutPayment[];
142
+ [key: string]: unknown;
143
+ }
144
+ interface CheckoutPayment {
145
+ id: string;
146
+ orderId?: string;
147
+ processor?: string;
148
+ processorTransactionId?: string | null;
149
+ amount?: number;
150
+ currency?: string;
151
+ status?: string;
152
+ method?: string;
153
+ createdAt?: string;
154
+ transactions?: CheckoutPaymentTransaction[];
155
+ [key: string]: unknown;
156
+ }
157
+ interface CheckoutPaymentTransaction {
158
+ id: string;
159
+ paymentId?: string;
160
+ type?: string;
161
+ amount?: number;
162
+ currency?: string;
163
+ status?: string;
164
+ createdAt?: string;
165
+ [key: string]: unknown;
166
+ }
167
+ interface BuildCheckoutUrlOptions {
168
+ checkoutOrigin?: string;
169
+ sessionId: string;
170
+ parentOrigin?: string;
171
+ mode?: CheckoutEmbedMode;
172
+ route?: CheckoutEmbedRoute;
173
+ primary?: string;
174
+ logo?: string;
175
+ }
176
+ interface ThrottleEnvelope<T> {
177
+ data?: T;
178
+ meta?: Record<string, unknown>;
179
+ error?: {
180
+ code?: string;
181
+ message?: string;
182
+ details?: unknown;
183
+ };
184
+ }
185
+ declare class ThrottleCheckoutError extends Error {
186
+ readonly code: string;
187
+ readonly statusCode: number;
188
+ readonly details?: unknown;
189
+ readonly body?: unknown;
190
+ constructor(args: {
191
+ code: string;
192
+ message: string;
193
+ statusCode: number;
194
+ details?: unknown;
195
+ body?: unknown;
196
+ });
197
+ }
198
+ declare class CheckoutClient {
199
+ private readonly apiKey;
200
+ private readonly baseUrl;
201
+ private readonly fetchImpl;
202
+ private readonly timeoutMs;
203
+ constructor(opts: CheckoutClientOptions);
204
+ request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
205
+ requestEnvelope<T = unknown>(method: string, path: string, body?: unknown): Promise<ThrottleEnvelope<T>>;
206
+ createSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession>;
207
+ completeSession(sessionId: string, input: CompleteCheckoutSessionInput): Promise<CompleteCheckoutSessionResult>;
208
+ createEmbedToken(input: CreateEmbedTokenInput): Promise<CreateEmbedTokenResult>;
209
+ getOrder(orderId: string): Promise<CheckoutOrder>;
210
+ listOrderPayments(orderId: string): Promise<CheckoutPayment[]>;
211
+ listPaymentTransactions(paymentId: string): Promise<CheckoutPaymentTransaction[]>;
212
+ getOrderWithPayments(orderId: string): Promise<CheckoutOrder>;
213
+ }
214
+ declare function createCheckoutClient(opts: CheckoutClientOptions): CheckoutClient;
215
+ declare function buildCheckoutHostedUrl(options: BuildCheckoutUrlOptions): string;
216
+ declare function buildCheckoutEmbedUrl(options: BuildCheckoutUrlOptions): string;
217
+
218
+ export { type BuildCheckoutUrlOptions, type CheckoutAddress, CheckoutClient, type CheckoutClientOptions, type CheckoutCollectInput, type CheckoutCustomerAddressInput, type CheckoutCustomerInput, type CheckoutEmbedMode, type CheckoutEmbedRoute, type CheckoutOrder, type CheckoutPayment, type CheckoutPaymentTransaction, type CheckoutSession, type CompleteCheckoutSessionInput, type CompleteCheckoutSessionResult, type CreateCheckoutSessionInput, type CreateEmbedTokenInput, type CreateEmbedTokenResult, type Net30Acceptance, type PaymentMethod, type RecurringIntentInput, type SubscriptionInterval, ThrottleCheckoutError, type ThrottleEnvelope, buildCheckoutEmbedUrl, buildCheckoutHostedUrl, createCheckoutClient };
package/dist/server.js ADDED
@@ -0,0 +1,236 @@
1
+ // src/server.ts
2
+ var ThrottleCheckoutError = class extends Error {
3
+ constructor(args) {
4
+ super(args.message);
5
+ this.name = "ThrottleCheckoutError";
6
+ this.code = args.code;
7
+ this.statusCode = args.statusCode;
8
+ this.details = args.details;
9
+ this.body = args.body;
10
+ }
11
+ };
12
+ var CheckoutClient = class {
13
+ constructor(opts) {
14
+ if (!opts.apiKey) throw new Error("CheckoutClient: apiKey is required");
15
+ const fetchImpl = opts.fetch ?? globalThis.fetch;
16
+ if (!fetchImpl) throw new Error("CheckoutClient: fetch is required");
17
+ this.apiKey = opts.apiKey;
18
+ this.baseUrl = (opts.baseUrl ?? "https://api.usethrottle.dev").replace(/\/+$/, "");
19
+ this.fetchImpl = fetchImpl;
20
+ this.timeoutMs = opts.timeoutMs ?? 3e4;
21
+ }
22
+ async request(method, path, body) {
23
+ const envelope = await this.requestEnvelope(method, path, body);
24
+ if (Object.prototype.hasOwnProperty.call(envelope, "data")) {
25
+ return envelope.data;
26
+ }
27
+ return envelope;
28
+ }
29
+ async requestEnvelope(method, path, body) {
30
+ const ctrl = new AbortController();
31
+ const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
32
+ try {
33
+ const res = await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), {
34
+ method,
35
+ headers: {
36
+ "content-type": "application/json",
37
+ "x-api-key": this.apiKey
38
+ },
39
+ body: body !== void 0 ? JSON.stringify(body) : void 0,
40
+ signal: ctrl.signal
41
+ });
42
+ if (res.status === 204) return { data: void 0 };
43
+ const json = await res.json().catch(() => ({}));
44
+ if (!res.ok) {
45
+ throw new ThrottleCheckoutError({
46
+ code: json.error?.code ?? "unknown_error",
47
+ message: json.error?.message ?? `HTTP ${res.status}`,
48
+ statusCode: res.status,
49
+ details: json.error?.details,
50
+ body: json
51
+ });
52
+ }
53
+ return json;
54
+ } finally {
55
+ clearTimeout(timer);
56
+ }
57
+ }
58
+ async createSession(input) {
59
+ const data = await this.request("POST", "/api/v1/checkout/sessions", input);
60
+ return normalizeCheckoutSession(data);
61
+ }
62
+ async completeSession(sessionId, input) {
63
+ const data = await this.request(
64
+ "POST",
65
+ `/api/v1/checkout/sessions/${encodeURIComponent(sessionId)}/complete`,
66
+ input
67
+ );
68
+ return normalizeCompleteResult(data);
69
+ }
70
+ async createEmbedToken(input) {
71
+ const data = await this.request("POST", "/api/v1/checkout-sessions/embed-token", input);
72
+ return normalizeEmbedToken(data);
73
+ }
74
+ async getOrder(orderId) {
75
+ const data = await this.request("GET", `/api/v1/orders/${encodeURIComponent(orderId)}`);
76
+ return normalizeOrder(data);
77
+ }
78
+ async listOrderPayments(orderId) {
79
+ const data = await this.request(
80
+ "GET",
81
+ `/api/v1/orders/${encodeURIComponent(orderId)}/payments`
82
+ );
83
+ return (data ?? []).map(normalizePayment);
84
+ }
85
+ async listPaymentTransactions(paymentId) {
86
+ const data = await this.request(
87
+ "GET",
88
+ `/api/v1/payments/${encodeURIComponent(paymentId)}/transactions`
89
+ );
90
+ return (data ?? []).map(normalizeTransaction);
91
+ }
92
+ async getOrderWithPayments(orderId) {
93
+ const order = await this.getOrder(orderId);
94
+ const payments = await this.listOrderPayments(orderId);
95
+ return {
96
+ ...order,
97
+ payments: await Promise.all(
98
+ payments.map(async (payment) => ({
99
+ ...payment,
100
+ transactions: payment.id ? await this.listPaymentTransactions(payment.id) : []
101
+ }))
102
+ )
103
+ };
104
+ }
105
+ };
106
+ function createCheckoutClient(opts) {
107
+ return new CheckoutClient(opts);
108
+ }
109
+ function buildCheckoutHostedUrl(options) {
110
+ const route = options.route ?? "s";
111
+ const base = (options.checkoutOrigin ?? "https://checkout.usethrottle.dev").replace(/\/+$/, "");
112
+ return `${base}/${route}/${encodeURIComponent(options.sessionId)}`;
113
+ }
114
+ function buildCheckoutEmbedUrl(options) {
115
+ const baseUrl = buildCheckoutHostedUrl({
116
+ checkoutOrigin: options.checkoutOrigin,
117
+ sessionId: options.sessionId,
118
+ route: options.route ?? "c"
119
+ });
120
+ const params = new URLSearchParams({
121
+ embed: "1",
122
+ mode: options.mode ?? "payment-only",
123
+ ...options.parentOrigin ? { parentOrigin: options.parentOrigin.replace(/\/+$/, "") } : {}
124
+ });
125
+ if (options.primary) params.set("primary", options.primary);
126
+ if (options.logo) params.set("logo", options.logo);
127
+ return `${baseUrl}?${params.toString()}`;
128
+ }
129
+ function toAbsoluteUrl(baseUrl, path) {
130
+ if (/^https?:\/\//i.test(path)) return path;
131
+ return `${baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
132
+ }
133
+ function normalizeCheckoutSession(raw) {
134
+ const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;
135
+ return {
136
+ ...raw,
137
+ id: optionalString(raw?.id),
138
+ sessionId: requiredString(sessionId, "checkoutSession.sessionId"),
139
+ checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url) ?? void 0,
140
+ hostedUrl: optionalString(raw?.hostedUrl ?? raw?.hosted_url) ?? void 0,
141
+ embedUrl: optionalString(raw?.embedUrl ?? raw?.embed_url) ?? void 0,
142
+ embedToken: optionalString(raw?.embedToken ?? raw?.embed_token) ?? void 0,
143
+ expiresAt: optionalString(raw?.expiresAt ?? raw?.expires_at) ?? void 0
144
+ };
145
+ }
146
+ function normalizeCompleteResult(raw) {
147
+ const orderId = raw?.orderId ?? raw?.order_id ?? raw?.id;
148
+ return {
149
+ ...raw,
150
+ orderId: requiredString(orderId, "checkoutComplete.orderId"),
151
+ orderNumber: optionalString(raw?.orderNumber ?? raw?.order_number) ?? void 0,
152
+ paymentId: optionalString(raw?.paymentId ?? raw?.payment_id) ?? void 0,
153
+ total: optionalNumber(raw?.total),
154
+ currency: optionalString(raw?.currency) ?? void 0,
155
+ status: optionalString(raw?.status) ?? void 0,
156
+ paymentStatus: optionalString(raw?.paymentStatus ?? raw?.payment_status) ?? void 0
157
+ };
158
+ }
159
+ function normalizeEmbedToken(raw) {
160
+ return {
161
+ ...raw,
162
+ embedToken: requiredString(raw?.embedToken ?? raw?.embed_token, "embedToken.embedToken"),
163
+ checkoutSessionId: requiredString(
164
+ raw?.checkoutSessionId ?? raw?.checkout_session_id,
165
+ "embedToken.checkoutSessionId"
166
+ ),
167
+ amount: Number(raw?.amount ?? 0),
168
+ currency: optionalString(raw?.currency) ?? "USD",
169
+ hostedUrl: optionalString(raw?.hostedUrl ?? raw?.hosted_url) ?? void 0,
170
+ embedUrl: optionalString(raw?.embedUrl ?? raw?.embed_url) ?? void 0,
171
+ gr4vyId: optionalString(raw?.gr4vyId ?? raw?.gr4vy_id) ?? void 0,
172
+ merchantAccountId: optionalString(raw?.merchantAccountId ?? raw?.merchant_account_id) ?? void 0
173
+ };
174
+ }
175
+ function normalizeOrder(raw) {
176
+ return {
177
+ ...raw,
178
+ id: requiredString(raw?.id, "order.id"),
179
+ orderNumber: optionalString(raw?.orderNumber ?? raw?.order_number) ?? void 0,
180
+ status: optionalString(raw?.status) ?? "processing",
181
+ paymentStatus: optionalString(raw?.paymentStatus ?? raw?.payment_status),
182
+ currency: optionalString(raw?.currency) ?? "USD",
183
+ subtotal: Number(raw?.subtotal ?? 0),
184
+ taxTotal: Number(raw?.taxTotal ?? raw?.tax_total ?? 0),
185
+ shippingTotal: Number(raw?.shippingTotal ?? raw?.shipping_total ?? 0),
186
+ total: Number(raw?.total ?? 0),
187
+ metadata: objectOrUndefined(raw?.metadata)
188
+ };
189
+ }
190
+ function normalizePayment(raw) {
191
+ return {
192
+ ...raw,
193
+ id: requiredString(raw?.id, "payment.id"),
194
+ orderId: optionalString(raw?.orderId ?? raw?.order_id) ?? void 0,
195
+ processor: optionalString(raw?.processor) ?? void 0,
196
+ processorTransactionId: optionalString(raw?.processorTransactionId ?? raw?.processor_transaction_id) ?? void 0,
197
+ amount: optionalNumber(raw?.amount),
198
+ currency: optionalString(raw?.currency) ?? void 0,
199
+ status: optionalString(raw?.status) ?? void 0,
200
+ method: optionalString(raw?.method) ?? void 0,
201
+ createdAt: optionalString(raw?.createdAt ?? raw?.created_at) ?? void 0
202
+ };
203
+ }
204
+ function normalizeTransaction(raw) {
205
+ return {
206
+ ...raw,
207
+ id: requiredString(raw?.id, "transaction.id"),
208
+ paymentId: optionalString(raw?.paymentId ?? raw?.payment_id) ?? void 0,
209
+ type: optionalString(raw?.type) ?? void 0,
210
+ amount: optionalNumber(raw?.amount),
211
+ currency: optionalString(raw?.currency) ?? void 0,
212
+ status: optionalString(raw?.status) ?? void 0,
213
+ createdAt: optionalString(raw?.createdAt ?? raw?.created_at) ?? void 0
214
+ };
215
+ }
216
+ function requiredString(value, label) {
217
+ if (typeof value === "string" && value.length > 0) return value;
218
+ throw new Error(`Invalid Throttle response: missing ${label}`);
219
+ }
220
+ function optionalString(value) {
221
+ return typeof value === "string" && value.length > 0 ? value : null;
222
+ }
223
+ function optionalNumber(value) {
224
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
225
+ }
226
+ function objectOrUndefined(value) {
227
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
228
+ }
229
+ export {
230
+ CheckoutClient,
231
+ ThrottleCheckoutError,
232
+ buildCheckoutEmbedUrl,
233
+ buildCheckoutHostedUrl,
234
+ createCheckoutClient
235
+ };
236
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["export type PaymentMethod = 'net30' | 'card' | 'gr4vy';\nexport type SubscriptionInterval = 'weekly' | 'monthly' | 'quarterly' | 'yearly';\nexport type CheckoutEmbedMode = 'checkout-full' | 'payment-only';\nexport type CheckoutEmbedRoute = 'c' | 's';\n\nexport interface CheckoutClientOptions {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n timeoutMs?: number;\n}\n\nexport interface CheckoutAddress {\n firstName: string;\n lastName: string;\n company?: string;\n addressLine1: string;\n addressLine2?: string;\n city: string;\n stateProvince: string;\n postalCode: string;\n countryCode: string;\n phone?: string;\n}\n\nexport interface CheckoutCustomerAddressInput {\n firstName?: string;\n lastName?: string;\n phone?: string;\n addressLine1?: string;\n addressLine2?: string;\n city?: string;\n state?: string;\n postalCode?: string;\n country?: string;\n}\n\nexport interface CheckoutCustomerInput {\n customerId?: string;\n externalCustomerId?: string;\n email?: string;\n firstName?: string;\n lastName?: string;\n phone?: string;\n shippingAddress?: CheckoutCustomerAddressInput;\n billingAddress?: CheckoutCustomerAddressInput;\n metadata?: Record<string, unknown>;\n}\n\nexport interface RecurringIntentInput {\n plan: string;\n interval: SubscriptionInterval;\n amount?: number;\n trialDays?: number;\n planName?: string;\n create?: 'auto' | 'manual';\n}\n\nexport interface CheckoutCollectInput {\n shippingAddress?: boolean;\n billingAddress?: boolean;\n}\n\nexport interface CreateCheckoutSessionInput {\n storeId: string;\n cartId?: string;\n externalCartId?: string;\n customerEmail?: string;\n customer?: CheckoutCustomerInput;\n returnUrl: string;\n cancelUrl: string;\n allowedMethods?: string[];\n recurring?: RecurringIntentInput;\n collect?: CheckoutCollectInput;\n metadata?: Record<string, unknown>;\n discountCode?: string;\n}\n\nexport interface CheckoutSession {\n sessionId: string;\n id?: string;\n checkoutUrl?: string;\n hostedUrl?: string;\n embedUrl?: string;\n embedToken?: string;\n expiresAt?: string;\n [key: string]: unknown;\n}\n\nexport interface Net30Acceptance {\n termsHash: string;\n acceptedAt: string;\n companyName: string;\n billingEmail: string;\n}\n\nexport interface CompleteCheckoutSessionInput {\n email?: string;\n shippingAddress?: CheckoutAddress;\n billingAddress?: CheckoutAddress;\n billingSameAsShipping?: boolean;\n paymentMethod: PaymentMethod;\n netDays?: number;\n termsAccepted?: boolean;\n termsSnapshot?: string;\n invoiceNumber?: string;\n net30Acceptance?: Net30Acceptance;\n paymentToken?: string;\n gr4vyCheckoutSessionId?: string;\n gr4vyTransactionId?: string;\n}\n\nexport interface CompleteCheckoutSessionResult {\n orderId: string;\n orderNumber?: string;\n paymentId?: string;\n total?: number;\n currency?: string;\n status?: string;\n paymentStatus?: string;\n [key: string]: unknown;\n}\n\nexport interface CreateEmbedTokenInput {\n externalCartId?: string;\n amount: number;\n currency: string;\n country?: string;\n allowedMethods?: string[];\n}\n\nexport interface CreateEmbedTokenResult {\n embedToken: string;\n checkoutSessionId: string;\n amount: number;\n currency: string;\n hostedUrl?: string;\n embedUrl?: string;\n gr4vyId?: string;\n merchantAccountId?: string;\n [key: string]: unknown;\n}\n\nexport interface CheckoutOrder {\n id: string;\n orderNumber?: string;\n status: string;\n paymentStatus: string | null;\n currency: string;\n subtotal: number;\n taxTotal: number;\n shippingTotal: number;\n total: number;\n metadata?: Record<string, unknown>;\n payments?: CheckoutPayment[];\n [key: string]: unknown;\n}\n\nexport interface CheckoutPayment {\n id: string;\n orderId?: string;\n processor?: string;\n processorTransactionId?: string | null;\n amount?: number;\n currency?: string;\n status?: string;\n method?: string;\n createdAt?: string;\n transactions?: CheckoutPaymentTransaction[];\n [key: string]: unknown;\n}\n\nexport interface CheckoutPaymentTransaction {\n id: string;\n paymentId?: string;\n type?: string;\n amount?: number;\n currency?: string;\n status?: string;\n createdAt?: string;\n [key: string]: unknown;\n}\n\nexport interface BuildCheckoutUrlOptions {\n checkoutOrigin?: string;\n sessionId: string;\n parentOrigin?: string;\n mode?: CheckoutEmbedMode;\n route?: CheckoutEmbedRoute;\n primary?: string;\n logo?: string;\n}\n\nexport interface ThrottleEnvelope<T> {\n data?: T;\n meta?: Record<string, unknown>;\n error?: {\n code?: string;\n message?: string;\n details?: unknown;\n };\n}\n\nexport class ThrottleCheckoutError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly details?: unknown;\n readonly body?: unknown;\n\n constructor(args: {\n code: string;\n message: string;\n statusCode: number;\n details?: unknown;\n body?: unknown;\n }) {\n super(args.message);\n this.name = 'ThrottleCheckoutError';\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n this.body = args.body;\n }\n}\n\nexport class CheckoutClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly timeoutMs: number;\n\n constructor(opts: CheckoutClientOptions) {\n if (!opts.apiKey) throw new Error('CheckoutClient: apiKey is required');\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('CheckoutClient: fetch is required');\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const envelope = await this.requestEnvelope<T>(method, path, body);\n if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {\n return envelope.data as T;\n }\n return envelope as T;\n }\n\n async requestEnvelope<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n\n try {\n const res = await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), {\n method,\n headers: {\n 'content-type': 'application/json',\n 'x-api-key': this.apiKey,\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: ctrl.signal,\n });\n\n if (res.status === 204) return { data: undefined as T };\n\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) {\n throw new ThrottleCheckoutError({\n code: json.error?.code ?? 'unknown_error',\n message: json.error?.message ?? `HTTP ${res.status}`,\n statusCode: res.status,\n details: json.error?.details,\n body: json,\n });\n }\n return json;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async createSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout/sessions', input);\n return normalizeCheckoutSession(data);\n }\n\n async completeSession(\n sessionId: string,\n input: CompleteCheckoutSessionInput,\n ): Promise<CompleteCheckoutSessionResult> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/checkout/sessions/${encodeURIComponent(sessionId)}/complete`,\n input,\n );\n return normalizeCompleteResult(data);\n }\n\n async createEmbedToken(input: CreateEmbedTokenInput): Promise<CreateEmbedTokenResult> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout-sessions/embed-token', input);\n return normalizeEmbedToken(data);\n }\n\n async getOrder(orderId: string): Promise<CheckoutOrder> {\n const data = await this.request<unknown>('GET', `/api/v1/orders/${encodeURIComponent(orderId)}`);\n return normalizeOrder(data);\n }\n\n async listOrderPayments(orderId: string): Promise<CheckoutPayment[]> {\n const data = await this.request<unknown[]>(\n 'GET',\n `/api/v1/orders/${encodeURIComponent(orderId)}/payments`,\n );\n return (data ?? []).map(normalizePayment);\n }\n\n async listPaymentTransactions(paymentId: string): Promise<CheckoutPaymentTransaction[]> {\n const data = await this.request<unknown[]>(\n 'GET',\n `/api/v1/payments/${encodeURIComponent(paymentId)}/transactions`,\n );\n return (data ?? []).map(normalizeTransaction);\n }\n\n async getOrderWithPayments(orderId: string): Promise<CheckoutOrder> {\n const order = await this.getOrder(orderId);\n const payments = await this.listOrderPayments(orderId);\n return {\n ...order,\n payments: await Promise.all(\n payments.map(async (payment) => ({\n ...payment,\n transactions: payment.id ? await this.listPaymentTransactions(payment.id) : [],\n })),\n ),\n };\n }\n}\n\nexport function createCheckoutClient(opts: CheckoutClientOptions): CheckoutClient {\n return new CheckoutClient(opts);\n}\n\nexport function buildCheckoutHostedUrl(options: BuildCheckoutUrlOptions): string {\n const route = options.route ?? 's';\n const base = (options.checkoutOrigin ?? 'https://checkout.usethrottle.dev').replace(/\\/+$/, '');\n return `${base}/${route}/${encodeURIComponent(options.sessionId)}`;\n}\n\nexport function buildCheckoutEmbedUrl(options: BuildCheckoutUrlOptions): string {\n const baseUrl = buildCheckoutHostedUrl({\n checkoutOrigin: options.checkoutOrigin,\n sessionId: options.sessionId,\n route: options.route ?? 'c',\n });\n const params = new URLSearchParams({\n embed: '1',\n mode: options.mode ?? 'payment-only',\n ...(options.parentOrigin ? { parentOrigin: options.parentOrigin.replace(/\\/+$/, '') } : {}),\n });\n if (options.primary) params.set('primary', options.primary);\n if (options.logo) params.set('logo', options.logo);\n return `${baseUrl}?${params.toString()}`;\n}\n\nfunction toAbsoluteUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n}\n\nfunction normalizeCheckoutSession(raw: any): CheckoutSession {\n const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;\n return {\n ...raw,\n id: optionalString(raw?.id),\n sessionId: requiredString(sessionId, 'checkoutSession.sessionId'),\n checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url) ?? undefined,\n hostedUrl: optionalString(raw?.hostedUrl ?? raw?.hosted_url) ?? undefined,\n embedUrl: optionalString(raw?.embedUrl ?? raw?.embed_url) ?? undefined,\n embedToken: optionalString(raw?.embedToken ?? raw?.embed_token) ?? undefined,\n expiresAt: optionalString(raw?.expiresAt ?? raw?.expires_at) ?? undefined,\n };\n}\n\nfunction normalizeCompleteResult(raw: any): CompleteCheckoutSessionResult {\n const orderId = raw?.orderId ?? raw?.order_id ?? raw?.id;\n return {\n ...raw,\n orderId: requiredString(orderId, 'checkoutComplete.orderId'),\n orderNumber: optionalString(raw?.orderNumber ?? raw?.order_number) ?? undefined,\n paymentId: optionalString(raw?.paymentId ?? raw?.payment_id) ?? undefined,\n total: optionalNumber(raw?.total),\n currency: optionalString(raw?.currency) ?? undefined,\n status: optionalString(raw?.status) ?? undefined,\n paymentStatus: optionalString(raw?.paymentStatus ?? raw?.payment_status) ?? undefined,\n };\n}\n\nfunction normalizeEmbedToken(raw: any): CreateEmbedTokenResult {\n return {\n ...raw,\n embedToken: requiredString(raw?.embedToken ?? raw?.embed_token, 'embedToken.embedToken'),\n checkoutSessionId: requiredString(\n raw?.checkoutSessionId ?? raw?.checkout_session_id,\n 'embedToken.checkoutSessionId',\n ),\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n hostedUrl: optionalString(raw?.hostedUrl ?? raw?.hosted_url) ?? undefined,\n embedUrl: optionalString(raw?.embedUrl ?? raw?.embed_url) ?? undefined,\n gr4vyId: optionalString(raw?.gr4vyId ?? raw?.gr4vy_id) ?? undefined,\n merchantAccountId:\n optionalString(raw?.merchantAccountId ?? raw?.merchant_account_id) ?? undefined,\n };\n}\n\nfunction normalizeOrder(raw: any): CheckoutOrder {\n return {\n ...raw,\n id: requiredString(raw?.id, 'order.id'),\n orderNumber: optionalString(raw?.orderNumber ?? raw?.order_number) ?? undefined,\n status: optionalString(raw?.status) ?? 'processing',\n paymentStatus: optionalString(raw?.paymentStatus ?? raw?.payment_status),\n currency: optionalString(raw?.currency) ?? 'USD',\n subtotal: Number(raw?.subtotal ?? 0),\n taxTotal: Number(raw?.taxTotal ?? raw?.tax_total ?? 0),\n shippingTotal: Number(raw?.shippingTotal ?? raw?.shipping_total ?? 0),\n total: Number(raw?.total ?? 0),\n metadata: objectOrUndefined(raw?.metadata),\n };\n}\n\nfunction normalizePayment(raw: any): CheckoutPayment {\n return {\n ...raw,\n id: requiredString(raw?.id, 'payment.id'),\n orderId: optionalString(raw?.orderId ?? raw?.order_id) ?? undefined,\n processor: optionalString(raw?.processor) ?? undefined,\n processorTransactionId:\n optionalString(raw?.processorTransactionId ?? raw?.processor_transaction_id) ?? undefined,\n amount: optionalNumber(raw?.amount),\n currency: optionalString(raw?.currency) ?? undefined,\n status: optionalString(raw?.status) ?? undefined,\n method: optionalString(raw?.method) ?? undefined,\n createdAt: optionalString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n };\n}\n\nfunction normalizeTransaction(raw: any): CheckoutPaymentTransaction {\n return {\n ...raw,\n id: requiredString(raw?.id, 'transaction.id'),\n paymentId: optionalString(raw?.paymentId ?? raw?.payment_id) ?? undefined,\n type: optionalString(raw?.type) ?? undefined,\n amount: optionalNumber(raw?.amount),\n currency: optionalString(raw?.currency) ?? undefined,\n status: optionalString(raw?.status) ?? undefined,\n createdAt: optionalString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n };\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalString(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null;\n}\n\nfunction optionalNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction objectOrUndefined(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usethrottle/checkout-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -10,18 +10,24 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "import": "./dist/index.js",
12
12
  "require": "./dist/index.cjs"
13
+ },
14
+ "./server": {
15
+ "types": "./dist/server.d.ts",
16
+ "import": "./dist/server.js",
17
+ "require": "./dist/server.cjs"
13
18
  }
14
19
  },
15
20
  "files": [
16
21
  "dist",
17
- "README.md"
22
+ "README.md",
23
+ "CHANGELOG.md"
18
24
  ],
19
25
  "peerDependencies": {
20
26
  "react": ">=18 <20",
21
27
  "react-dom": ">=18 <20"
22
28
  },
23
29
  "dependencies": {
24
- "@usethrottle/checkout-react": "1.0.0"
30
+ "@usethrottle/checkout-react": "1.0.1"
25
31
  },
26
32
  "devDependencies": {
27
33
  "@testing-library/react": "^16.0.0",