@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 +21 -0
- package/README.md +77 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +265 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +218 -0
- package/dist/server.d.ts +218 -0
- package/dist/server.js +236 -0
- package/dist/server.js.map +1 -0
- package/package.json +9 -3
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
|
-
|
|
3
|
+
Production checkout SDK for Throttle storefront integrations.
|
|
4
4
|
|
|
5
|
-
|
|
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
|
|
30
|
-
|
|
31
|
-
| `sessionId`
|
|
32
|
-
| `parentOrigin` | `string`
|
|
33
|
-
| `baseUrl`
|
|
34
|
-
| `theme`
|
|
35
|
-
| `onSucceeded`
|
|
36
|
-
| `onFailed`
|
|
37
|
-
| `onCancelled`
|
|
38
|
-
| `onTelemetry`
|
|
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`
|
|
43
|
-
|
|
44
|
-
| `mounted`
|
|
45
|
-
| `ready`
|
|
46
|
-
| `processing`
|
|
47
|
-
| `succeeded`
|
|
48
|
-
| `failed`
|
|
49
|
-
| `cancelled`
|
|
50
|
-
| `step_changed` | `sessionId`, `step`, `timestamp`
|
|
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
|
|
119
|
+
Emits CJS, ESM, and TypeScript declarations for both the browser entrypoint and
|
|
120
|
+
`@usethrottle/checkout-sdk/server`.
|
package/dist/index.cjs.map
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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":[]}
|
package/dist/server.cjs
ADDED
|
@@ -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":"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","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 };
|
package/dist/server.d.ts
ADDED
|
@@ -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.
|
|
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.
|
|
30
|
+
"@usethrottle/checkout-react": "1.0.1"
|
|
25
31
|
},
|
|
26
32
|
"devDependencies": {
|
|
27
33
|
"@testing-library/react": "^16.0.0",
|