torque-checkout 3.1.0 → 3.2.0

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/dist/nextjs.js CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var crypto = require('crypto');
3
4
  var server = require('next/server');
4
5
  var index = require('./index.js');
5
6
 
@@ -18,7 +19,7 @@ var index = require('./index.js');
18
19
  *
19
20
  * @example
20
21
  * ```ts
21
- * // app/api/checkout/route.ts
22
+ * // app/api/checkout-session/route.ts (path is your choice)
22
23
  * import { generateCheckoutUrl } from 'torque-checkout/nextjs'
23
24
  *
24
25
  * export async function POST(request: Request) {
@@ -42,7 +43,7 @@ async function generateCheckoutUrl(cart, config) {
42
43
  *
43
44
  * @example
44
45
  * ```ts
45
- * // app/api/checkout/route.ts
46
+ * // app/api/checkout-session/route.ts (path is your choice)
46
47
  * import { handleCheckoutRequest } from 'torque-checkout/nextjs'
47
48
  *
48
49
  * export const POST = handleCheckoutRequest({
@@ -101,11 +102,18 @@ function handleCheckoutRequest(options = {}) {
101
102
  function handleWebhook(options = {}) {
102
103
  return async (request) => {
103
104
  try {
104
- const event = await request.json();
105
- // Verify webhook secret if provided
105
+ const rawBody = await request.text();
106
+ let event;
107
+ try {
108
+ event = JSON.parse(rawBody);
109
+ }
110
+ catch {
111
+ return server.NextResponse.json({ error: 'Invalid JSON' }, { status: 400 });
112
+ }
113
+ // Verify HMAC-SHA256 of raw body (same pattern as Suby-style signed webhooks)
106
114
  if (options.secret) {
107
115
  const signature = request.headers.get('x-torque-signature');
108
- if (!signature || !verifyWebhookSignature(event, signature, options.secret)) {
116
+ if (!verifyTorqueWebhookSignature(rawBody, signature, options.secret)) {
109
117
  return server.NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
110
118
  }
111
119
  }
@@ -138,17 +146,20 @@ function handleWebhook(options = {}) {
138
146
  };
139
147
  }
140
148
  /**
141
- * Verify webhook signature
142
- * @internal
149
+ * Verify `X-Torque-Signature` (or raw hex) against HMAC-SHA256 of the **raw** webhook body.
150
+ * Accepts `hex`, `sha256=<hex>`, or `v1=<hex>` (Suby-style prefix).
143
151
  */
144
- function verifyWebhookSignature(event, signature, secret) {
145
- // Simple signature verification - implement HMAC verification in production
146
- // This is a placeholder - implement proper crypto verification
152
+ function verifyTorqueWebhookSignature(rawBody, signatureHeader, secret) {
153
+ if (!signatureHeader || !secret)
154
+ return false;
155
+ const expectedHex = crypto.createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex');
156
+ const normalized = signatureHeader.trim().replace(/^(sha256|v1)=/i, '');
147
157
  try {
148
- const payload = JSON.stringify(event);
149
- // In production, use crypto.createHmac('sha256', secret).update(payload).digest('hex')
150
- // and compare with signature
151
- return true; // Placeholder
158
+ const a = Buffer.from(normalized, 'hex');
159
+ const b = Buffer.from(expectedHex, 'hex');
160
+ if (a.length !== b.length)
161
+ return false;
162
+ return crypto.timingSafeEqual(a, b);
152
163
  }
153
164
  catch {
154
165
  return false;
@@ -182,4 +193,5 @@ exports.generateCheckoutUrl = generateCheckoutUrl;
182
193
  exports.getOrderStatus = getOrderStatus;
183
194
  exports.handleCheckoutRequest = handleCheckoutRequest;
184
195
  exports.handleWebhook = handleWebhook;
196
+ exports.verifyTorqueWebhookSignature = verifyTorqueWebhookSignature;
185
197
  //# sourceMappingURL=nextjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs.js","sources":["../src/nextjs.ts"],"sourcesContent":["/**\n * Next.js Server-Side Utilities\n * Server-side helpers for Next.js App Router and Pages Router\n * \n * @requires next >= 13.0.0\n */\n\n// Type-only imports for better compatibility\nimport type { NextRequest } from 'next/server'\nimport { NextResponse } from 'next/server'\nimport {\n TorqueCheckout,\n createTorqueCheckout,\n createTorqueCheckoutFromEnv,\n type TorqueConfig,\n type CartData,\n type OrderStatus,\n type TorqueCheckoutError\n} from './index'\n\n// ============================================================================\n// Server-Side Checkout Helper\n// ============================================================================\n\n/**\n * Generate checkout URL on the server\n * Use this in Next.js API routes or Server Components\n * \n * @example\n * ```ts\n * // app/api/checkout/route.ts\n * import { generateCheckoutUrl } from 'torque-checkout/nextjs'\n * \n * export async function POST(request: Request) {\n * const cart = await request.json()\n * const url = await generateCheckoutUrl(cart, {\n * businessId: process.env.TORQUE_BUSINESS_ID!,\n * apiKey: process.env.TORQUE_API_KEY!\n * })\n * return Response.json({ checkoutUrl: url })\n * }\n * ```\n */\nexport async function generateCheckoutUrl(\n cart: CartData,\n config?: TorqueConfig\n): Promise<string> {\n const torque = config \n ? createTorqueCheckout(config)\n : createTorqueCheckoutFromEnv()\n\n return torque.generateCartCheckoutUrl(cart)\n}\n\n// ============================================================================\n// API Route Handler Helpers\n// ============================================================================\n\nexport interface CheckoutApiHandlerOptions {\n config?: TorqueConfig\n onSuccess?: (checkoutUrl: string, cart: CartData) => Promise<void> | void\n onError?: (error: TorqueCheckoutError, cart: CartData) => Promise<void> | void\n}\n\n/**\n * Next.js API route handler for generating checkout URLs\n * \n * @example\n * ```ts\n * // app/api/checkout/route.ts\n * import { handleCheckoutRequest } from 'torque-checkout/nextjs'\n * \n * export const POST = handleCheckoutRequest({\n * onSuccess: async (url, cart) => {\n * // Log checkout generation\n * console.log('Checkout generated:', url)\n * }\n * })\n * ```\n */\nexport function handleCheckoutRequest(options: CheckoutApiHandlerOptions = {}) {\n return async (request: NextRequest) => {\n try {\n const cart: CartData = await request.json()\n\n const torque = options.config\n ? createTorqueCheckout(options.config)\n : createTorqueCheckoutFromEnv()\n\n const checkoutUrl = await torque.generateCartCheckoutUrl(cart)\n\n await options.onSuccess?.(checkoutUrl, cart)\n\n return NextResponse.json({\n success: true,\n checkoutUrl,\n expiresAt: new Date(Date.now() + (cart.options?.expiresIn || 24 * 60 * 60 * 1000)).toISOString()\n })\n } catch (error) {\n const torqueError = error instanceof Error && 'code' in error\n ? error as TorqueCheckoutError\n : new Error(error instanceof Error ? error.message : 'Unknown error') as TorqueCheckoutError\n\n await options.onError?.(torqueError, {} as CartData)\n\n return NextResponse.json(\n {\n success: false,\n error: torqueError.message,\n code: torqueError.code || 'UNKNOWN_ERROR'\n },\n { status: torqueError.statusCode || 500 }\n )\n }\n }\n}\n\n// ============================================================================\n// Webhook Handler\n// ============================================================================\n\nexport interface WebhookEvent {\n type: 'order.created' | 'order.completed' | 'order.failed' | 'subscription.created' | 'subscription.cancelled'\n orderId?: string\n subscriptionId?: string\n data: any\n timestamp: number\n}\n\nexport interface WebhookHandlerOptions {\n secret?: string\n onOrderCreated?: (event: WebhookEvent) => Promise<void> | void\n onOrderCompleted?: (event: WebhookEvent) => Promise<void> | void\n onOrderFailed?: (event: WebhookEvent) => Promise<void> | void\n onSubscriptionCreated?: (event: WebhookEvent) => Promise<void> | void\n onSubscriptionCancelled?: (event: WebhookEvent) => Promise<void> | void\n}\n\n/**\n * Next.js API route handler for webhook events\n * \n * @example\n * ```ts\n * // app/api/webhooks/torque/route.ts\n * import { handleWebhook } from 'torque-checkout/nextjs'\n * \n * export const POST = handleWebhook({\n * secret: process.env.TORQUE_WEBHOOK_SECRET,\n * onOrderCompleted: async (event) => {\n * // Fulfill order\n * await fulfillOrder(event.orderId!)\n * }\n * })\n * ```\n */\nexport function handleWebhook(options: WebhookHandlerOptions = {}) {\n return async (request: NextRequest) => {\n try {\n const event: WebhookEvent = await request.json()\n\n // Verify webhook secret if provided\n if (options.secret) {\n const signature = request.headers.get('x-torque-signature')\n if (!signature || !verifyWebhookSignature(event, signature, options.secret)) {\n return NextResponse.json(\n { error: 'Invalid signature' },\n { status: 401 }\n )\n }\n }\n\n // Route to appropriate handler\n switch (event.type) {\n case 'order.created':\n await options.onOrderCreated?.(event)\n break\n case 'order.completed':\n await options.onOrderCompleted?.(event)\n break\n case 'order.failed':\n await options.onOrderFailed?.(event)\n break\n case 'subscription.created':\n await options.onSubscriptionCreated?.(event)\n break\n case 'subscription.cancelled':\n await options.onSubscriptionCancelled?.(event)\n break\n default:\n console.warn('Unknown webhook event type:', event.type)\n }\n\n return NextResponse.json({ received: true })\n } catch (error) {\n console.error('Webhook handler error:', error)\n return NextResponse.json(\n { error: 'Webhook processing failed' },\n { status: 500 }\n )\n }\n }\n}\n\n/**\n * Verify webhook signature\n * @internal\n */\nfunction verifyWebhookSignature(event: WebhookEvent, signature: string, secret: string): boolean {\n // Simple signature verification - implement HMAC verification in production\n // This is a placeholder - implement proper crypto verification\n try {\n const payload = JSON.stringify(event)\n // In production, use crypto.createHmac('sha256', secret).update(payload).digest('hex')\n // and compare with signature\n return true // Placeholder\n } catch {\n return false\n }\n}\n\n// ============================================================================\n// Order Status Helper\n// ============================================================================\n\n/**\n * Get order status on the server\n * \n * @example\n * ```ts\n * // app/api/orders/[orderId]/route.ts\n * import { getOrderStatus } from 'torque-checkout/nextjs'\n * \n * export async function GET(request: Request, { params }: { params: { orderId: string } }) {\n * const status = await getOrderStatus(params.orderId)\n * return Response.json(status)\n * }\n * ```\n */\nexport async function getOrderStatus(\n orderId: string,\n config?: TorqueConfig\n): Promise<OrderStatus> {\n const torque = config\n ? createTorqueCheckout(config)\n : createTorqueCheckoutFromEnv()\n\n return torque.getOrderStatus(orderId)\n}\n\n"],"names":["createTorqueCheckout","createTorqueCheckoutFromEnv","NextResponse"],"mappings":"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"}
1
+ {"version":3,"file":"nextjs.js","sources":["../src/nextjs.ts"],"sourcesContent":["/**\n * Next.js Server-Side Utilities\n * Server-side helpers for Next.js App Router and Pages Router\n * \n * @requires next >= 13.0.0\n */\n\nimport { createHmac, timingSafeEqual } from 'crypto'\n// Type-only imports for better compatibility\nimport type { NextRequest } from 'next/server'\nimport { NextResponse } from 'next/server'\nimport {\n TorqueCheckout,\n createTorqueCheckout,\n createTorqueCheckoutFromEnv,\n type TorqueConfig,\n type CartData,\n type OrderStatus,\n type TorqueCheckoutError\n} from './index'\n\n// ============================================================================\n// Server-Side Checkout Helper\n// ============================================================================\n\n/**\n * Generate checkout URL on the server\n * Use this in Next.js API routes or Server Components\n * \n * @example\n * ```ts\n * // app/api/checkout-session/route.ts (path is your choice)\n * import { generateCheckoutUrl } from 'torque-checkout/nextjs'\n * \n * export async function POST(request: Request) {\n * const cart = await request.json()\n * const url = await generateCheckoutUrl(cart, {\n * businessId: process.env.TORQUE_BUSINESS_ID!,\n * apiKey: process.env.TORQUE_API_KEY!\n * })\n * return Response.json({ checkoutUrl: url })\n * }\n * ```\n */\nexport async function generateCheckoutUrl(\n cart: CartData,\n config?: TorqueConfig\n): Promise<string> {\n const torque = config \n ? createTorqueCheckout(config)\n : createTorqueCheckoutFromEnv()\n\n return torque.generateCartCheckoutUrl(cart)\n}\n\n// ============================================================================\n// API Route Handler Helpers\n// ============================================================================\n\nexport interface CheckoutApiHandlerOptions {\n config?: TorqueConfig\n onSuccess?: (checkoutUrl: string, cart: CartData) => Promise<void> | void\n onError?: (error: TorqueCheckoutError, cart: CartData) => Promise<void> | void\n}\n\n/**\n * Next.js API route handler for generating checkout URLs\n * \n * @example\n * ```ts\n * // app/api/checkout-session/route.ts (path is your choice)\n * import { handleCheckoutRequest } from 'torque-checkout/nextjs'\n * \n * export const POST = handleCheckoutRequest({\n * onSuccess: async (url, cart) => {\n * // Log checkout generation\n * console.log('Checkout generated:', url)\n * }\n * })\n * ```\n */\nexport function handleCheckoutRequest(options: CheckoutApiHandlerOptions = {}) {\n return async (request: NextRequest) => {\n try {\n const cart: CartData = await request.json()\n\n const torque = options.config\n ? createTorqueCheckout(options.config)\n : createTorqueCheckoutFromEnv()\n\n const checkoutUrl = await torque.generateCartCheckoutUrl(cart)\n\n await options.onSuccess?.(checkoutUrl, cart)\n\n return NextResponse.json({\n success: true,\n checkoutUrl,\n expiresAt: new Date(Date.now() + (cart.options?.expiresIn || 24 * 60 * 60 * 1000)).toISOString()\n })\n } catch (error) {\n const torqueError = error instanceof Error && 'code' in error\n ? error as TorqueCheckoutError\n : new Error(error instanceof Error ? error.message : 'Unknown error') as TorqueCheckoutError\n\n await options.onError?.(torqueError, {} as CartData)\n\n return NextResponse.json(\n {\n success: false,\n error: torqueError.message,\n code: torqueError.code || 'UNKNOWN_ERROR'\n },\n { status: torqueError.statusCode || 500 }\n )\n }\n }\n}\n\n// ============================================================================\n// Webhook Handler\n// ============================================================================\n\nexport interface WebhookEvent {\n type: 'order.created' | 'order.completed' | 'order.failed' | 'subscription.created' | 'subscription.cancelled'\n orderId?: string\n subscriptionId?: string\n data: any\n timestamp: number\n}\n\nexport interface WebhookHandlerOptions {\n secret?: string\n onOrderCreated?: (event: WebhookEvent) => Promise<void> | void\n onOrderCompleted?: (event: WebhookEvent) => Promise<void> | void\n onOrderFailed?: (event: WebhookEvent) => Promise<void> | void\n onSubscriptionCreated?: (event: WebhookEvent) => Promise<void> | void\n onSubscriptionCancelled?: (event: WebhookEvent) => Promise<void> | void\n}\n\n/**\n * Next.js API route handler for webhook events\n * \n * @example\n * ```ts\n * // app/api/webhooks/torque/route.ts\n * import { handleWebhook } from 'torque-checkout/nextjs'\n * \n * export const POST = handleWebhook({\n * secret: process.env.TORQUE_WEBHOOK_SECRET,\n * onOrderCompleted: async (event) => {\n * // Fulfill order\n * await fulfillOrder(event.orderId!)\n * }\n * })\n * ```\n */\nexport function handleWebhook(options: WebhookHandlerOptions = {}) {\n return async (request: NextRequest) => {\n try {\n const rawBody = await request.text()\n let event: WebhookEvent\n try {\n event = JSON.parse(rawBody) as WebhookEvent\n } catch {\n return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 })\n }\n\n // Verify HMAC-SHA256 of raw body (same pattern as Suby-style signed webhooks)\n if (options.secret) {\n const signature = request.headers.get('x-torque-signature')\n if (!verifyTorqueWebhookSignature(rawBody, signature, options.secret)) {\n return NextResponse.json(\n { error: 'Invalid signature' },\n { status: 401 }\n )\n }\n }\n\n // Route to appropriate handler\n switch (event.type) {\n case 'order.created':\n await options.onOrderCreated?.(event)\n break\n case 'order.completed':\n await options.onOrderCompleted?.(event)\n break\n case 'order.failed':\n await options.onOrderFailed?.(event)\n break\n case 'subscription.created':\n await options.onSubscriptionCreated?.(event)\n break\n case 'subscription.cancelled':\n await options.onSubscriptionCancelled?.(event)\n break\n default:\n console.warn('Unknown webhook event type:', event.type)\n }\n\n return NextResponse.json({ received: true })\n } catch (error) {\n console.error('Webhook handler error:', error)\n return NextResponse.json(\n { error: 'Webhook processing failed' },\n { status: 500 }\n )\n }\n }\n}\n\n/**\n * Verify `X-Torque-Signature` (or raw hex) against HMAC-SHA256 of the **raw** webhook body.\n * Accepts `hex`, `sha256=<hex>`, or `v1=<hex>` (Suby-style prefix).\n */\nexport function verifyTorqueWebhookSignature(\n rawBody: string,\n signatureHeader: string | null,\n secret: string\n): boolean {\n if (!signatureHeader || !secret) return false\n const expectedHex = createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex')\n const normalized = signatureHeader.trim().replace(/^(sha256|v1)=/i, '')\n try {\n const a = Buffer.from(normalized, 'hex')\n const b = Buffer.from(expectedHex, 'hex')\n if (a.length !== b.length) return false\n return timingSafeEqual(a, b)\n } catch {\n return false\n }\n}\n\n// ============================================================================\n// Order Status Helper\n// ============================================================================\n\n/**\n * Get order status on the server\n * \n * @example\n * ```ts\n * // app/api/orders/[orderId]/route.ts\n * import { getOrderStatus } from 'torque-checkout/nextjs'\n * \n * export async function GET(request: Request, { params }: { params: { orderId: string } }) {\n * const status = await getOrderStatus(params.orderId)\n * return Response.json(status)\n * }\n * ```\n */\nexport async function getOrderStatus(\n orderId: string,\n config?: TorqueConfig\n): Promise<OrderStatus> {\n const torque = config\n ? createTorqueCheckout(config)\n : createTorqueCheckoutFromEnv()\n\n return torque.getOrderStatus(orderId)\n}\n\n"],"names":["createTorqueCheckout","createTorqueCheckoutFromEnv","NextResponse","createHmac","timingSafeEqual"],"mappings":"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"}
package/dist/react.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * React Hooks for Torque Checkout
3
3
  * Client-side React hooks for seamless Next.js integration
4
4
  */
5
- import { type TorqueConfig, type CartData, type CartItem, type CustomerData, type CartOptions, type OrderStatus, type CartValidation, type TorqueCheckoutError } from './index';
5
+ import { type TorqueConfig, type CartData, type CartItem, type CustomerData, type CartOptions, type CheckoutSession, type OrderStatus, type CartValidation, type TorqueCheckoutError } from './index';
6
6
  export interface UseTorqueCheckoutOptions {
7
7
  config?: TorqueConfig;
8
8
  autoRedirect?: boolean;
@@ -11,6 +11,8 @@ export interface UseTorqueCheckoutOptions {
11
11
  }
12
12
  export interface UseTorqueCheckoutReturn {
13
13
  generateCheckout: (cart: CartData) => Promise<string | null>;
14
+ /** Full session (URL + cartSummary + expiresAt) — use for merchant return URL & analytics. */
15
+ requestCheckoutSession: (cart: CartData) => Promise<CheckoutSession | null>;
14
16
  generateProductCheckout: (productId: string, quantity?: number, customer?: CustomerData, options?: CartOptions) => Promise<string | null>;
15
17
  generateSubscriptionCheckout: (productId: string, paymentPlanId: string, customer?: CustomerData, options?: CartOptions) => Promise<string | null>;
16
18
  validateCart: (cart: CartData) => Promise<CartValidation>;
package/dist/react.esm.js CHANGED
@@ -75,6 +75,29 @@ function useTorqueCheckout(options = {}) {
75
75
  return handleError(err);
76
76
  }
77
77
  }, [torque, handleError, handleSuccess]);
78
+ const requestCheckoutSession = useCallback(async (cart) => {
79
+ if (!torque) {
80
+ const err = new Error('TorqueCheckout not initialized');
81
+ return handleError(err);
82
+ }
83
+ setIsLoading(true);
84
+ setError(null);
85
+ try {
86
+ const session = await torque.requestCheckoutSession(cart);
87
+ setIsLoading(false);
88
+ setCheckoutUrl(session.checkoutUrl);
89
+ setError(null);
90
+ options.onSuccess?.(session.checkoutUrl);
91
+ if (options.autoRedirect) {
92
+ window.location.href = session.checkoutUrl;
93
+ }
94
+ return session;
95
+ }
96
+ catch (err) {
97
+ setIsLoading(false);
98
+ return handleError(err);
99
+ }
100
+ }, [torque, handleError, options]);
78
101
  const generateProductCheckout = useCallback(async (productId, quantity = 1, customer, options) => {
79
102
  if (!torque) {
80
103
  const err = new Error('TorqueCheckout not initialized');
@@ -157,6 +180,7 @@ function useTorqueCheckout(options = {}) {
157
180
  }, [torque, handleError]);
158
181
  return {
159
182
  generateCheckout,
183
+ requestCheckoutSession,
160
184
  generateProductCheckout,
161
185
  generateSubscriptionCheckout,
162
186
  validateCart,
@@ -1 +1 @@
1
- {"version":3,"file":"react.esm.js","sources":["../src/react.tsx"],"sourcesContent":["/**\n * React Hooks for Torque Checkout\n * Client-side React hooks for seamless Next.js integration\n */\n\n'use client'\n\nimport { useState, useCallback, useMemo } from 'react'\nimport {\n TorqueCheckout,\n createTorqueCheckout,\n createTorqueCheckoutFromEnv,\n type TorqueConfig,\n type CartData,\n type CartItem,\n type CustomerData,\n type CartOptions,\n type CheckoutResponse,\n type OrderStatus,\n type CartValidation,\n type Subscription,\n type CreateSubscriptionData,\n type TorqueCheckoutError\n} from './index'\n\n// ============================================================================\n// Hook: useTorqueCheckout\n// ============================================================================\n\nexport interface UseTorqueCheckoutOptions {\n config?: TorqueConfig\n autoRedirect?: boolean\n onSuccess?: (checkoutUrl: string) => void\n onError?: (error: TorqueCheckoutError) => void\n}\n\nexport interface UseTorqueCheckoutReturn {\n generateCheckout: (cart: CartData) => Promise<string | null>\n generateProductCheckout: (productId: string, quantity?: number, customer?: CustomerData, options?: CartOptions) => Promise<string | null>\n generateSubscriptionCheckout: (productId: string, paymentPlanId: string, customer?: CustomerData, options?: CartOptions) => Promise<string | null>\n validateCart: (cart: CartData) => Promise<CartValidation>\n getOrderStatus: (orderId: string) => Promise<OrderStatus | null>\n isLoading: boolean\n error: TorqueCheckoutError | null\n checkoutUrl: string | null\n}\n\n/**\n * React hook for Torque Checkout\n * \n * @example\n * ```tsx\n * const { generateCheckout, isLoading } = useTorqueCheckout({\n * config: {\n * businessId: 'your_business_id',\n * apiKey: 'your_api_key'\n * }\n * })\n * \n * const handleCheckout = async () => {\n * const url = await generateCheckout({\n * items: [{ productId: 'prod_123', quantity: 1 }],\n * customer: { email: 'customer@example.com' }\n * })\n * }\n * ```\n */\nexport function useTorqueCheckout(options: UseTorqueCheckoutOptions = {}): UseTorqueCheckoutReturn {\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<TorqueCheckoutError | null>(null)\n const [checkoutUrl, setCheckoutUrl] = useState<string | null>(null)\n\n const torque = useMemo(() => {\n if (options.config) {\n return createTorqueCheckout(options.config)\n }\n try {\n return createTorqueCheckoutFromEnv()\n } catch (err) {\n console.warn('Failed to create TorqueCheckout from env vars:', err)\n return null\n }\n }, [options.config])\n\n const handleError = useCallback((err: unknown) => {\n const error = err instanceof Error && 'code' in err \n ? err as TorqueCheckoutError \n : new Error(err instanceof Error ? err.message : 'Unknown error') as TorqueCheckoutError\n \n setError(error)\n options.onError?.(error)\n return null\n }, [options])\n\n const handleSuccess = useCallback((url: string) => {\n setCheckoutUrl(url)\n setError(null)\n options.onSuccess?.(url)\n \n if (options.autoRedirect) {\n window.location.href = url\n }\n \n return url\n }, [options])\n\n const generateCheckout = useCallback(async (cart: CartData): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized. Provide config or set TORQUE_BUSINESS_ID and TORQUE_API_KEY environment variables.') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateCartCheckoutUrl(cart)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const generateProductCheckout = useCallback(async (\n productId: string,\n quantity: number = 1,\n customer?: CustomerData,\n options?: CartOptions\n ): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateProductCheckoutUrl(productId, quantity, customer, options)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const generateSubscriptionCheckout = useCallback(async (\n productId: string,\n paymentPlanId: string,\n customer?: CustomerData,\n options?: CartOptions\n ): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateSubscriptionCheckoutUrl(productId, paymentPlanId, customer, options)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const validateCart = useCallback(async (cart: CartData): Promise<CartValidation> => {\n if (!torque) {\n return {\n valid: false,\n errors: ['TorqueCheckout not initialized'],\n warnings: [],\n estimatedTotal: 0\n }\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const validation = await torque.validateCart(cart)\n setIsLoading(false)\n return validation\n } catch (err) {\n setIsLoading(false)\n const error = err instanceof Error && 'code' in err \n ? err as TorqueCheckoutError \n : new Error(err instanceof Error ? err.message : 'Validation failed') as TorqueCheckoutError\n setError(error)\n return {\n valid: false,\n errors: [error.message],\n warnings: [],\n estimatedTotal: 0\n }\n }\n }, [torque])\n\n const getOrderStatus = useCallback(async (orderId: string): Promise<OrderStatus | null> => {\n if (!torque) {\n return handleError(new Error('TorqueCheckout not initialized') as TorqueCheckoutError)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const status = await torque.getOrderStatus(orderId)\n setIsLoading(false)\n return status\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError])\n\n return {\n generateCheckout,\n generateProductCheckout,\n generateSubscriptionCheckout,\n validateCart,\n getOrderStatus,\n isLoading,\n error,\n checkoutUrl\n }\n}\n\n// ============================================================================\n// Hook: useCart\n// ============================================================================\n\nexport interface UseCartReturn {\n items: CartItem[]\n addItem: (item: CartItem) => void\n removeItem: (productId: string, variant?: string) => void\n updateQuantity: (productId: string, quantity: number, variant?: string) => void\n clearCart: () => void\n getTotal: () => number\n getItemCount: () => number\n}\n\n/**\n * React hook for managing shopping cart state\n * \n * @example\n * ```tsx\n * const { items, addItem, removeItem, getTotal } = useCart()\n * \n * <button onClick={() => addItem({ productId: 'prod_123', quantity: 1 })}>\n * Add to Cart\n * </button>\n * ```\n */\nexport function useCart(): UseCartReturn {\n const [items, setItems] = useState<CartItem[]>([])\n\n const addItem = useCallback((item: CartItem) => {\n setItems(prev => {\n const existingIndex = prev.findIndex(\n i => i.productId === item.productId && i.variant === item.variant\n )\n \n if (existingIndex >= 0) {\n const updated = [...prev]\n updated[existingIndex] = {\n ...updated[existingIndex],\n quantity: updated[existingIndex].quantity + item.quantity\n }\n return updated\n }\n \n return [...prev, item]\n })\n }, [])\n\n const removeItem = useCallback((productId: string, variant?: string) => {\n setItems(prev => prev.filter(\n item => !(item.productId === productId && item.variant === variant)\n ))\n }, [])\n\n const updateQuantity = useCallback((productId: string, quantity: number, variant?: string) => {\n if (quantity <= 0) {\n removeItem(productId, variant)\n return\n }\n\n setItems(prev => prev.map(item => \n item.productId === productId && item.variant === variant\n ? { ...item, quantity }\n : item\n ))\n }, [removeItem])\n\n const clearCart = useCallback(() => {\n setItems([])\n }, [])\n\n const getTotal = useCallback(() => {\n // Note: Prices come from Torque product database, not from cart items\n // This function returns 0 as prices are only available after checkout URL generation\n // Use the cartSummary from generateCartCheckoutUrl response for accurate totals\n console.warn('getTotal() returns 0 because prices come from Torque product database. Use cartSummary from checkout URL generation for accurate totals.')\n return 0\n }, [items])\n\n const getItemCount = useCallback(() => {\n return items.reduce((count, item) => count + item.quantity, 0)\n }, [items])\n\n return {\n items,\n addItem,\n removeItem,\n updateQuantity,\n clearCart,\n getTotal,\n getItemCount\n }\n}\n\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react.esm.js","sources":["../src/react.tsx"],"sourcesContent":["/**\n * React Hooks for Torque Checkout\n * Client-side React hooks for seamless Next.js integration\n */\n\n'use client'\n\nimport { useState, useCallback, useMemo } from 'react'\nimport {\n TorqueCheckout,\n createTorqueCheckout,\n createTorqueCheckoutFromEnv,\n type TorqueConfig,\n type CartData,\n type CartItem,\n type CustomerData,\n type CartOptions,\n type CheckoutSession,\n type OrderStatus,\n type CartValidation,\n type Subscription,\n type CreateSubscriptionData,\n type TorqueCheckoutError\n} from './index'\n\n// ============================================================================\n// Hook: useTorqueCheckout\n// ============================================================================\n\nexport interface UseTorqueCheckoutOptions {\n config?: TorqueConfig\n autoRedirect?: boolean\n onSuccess?: (checkoutUrl: string) => void\n onError?: (error: TorqueCheckoutError) => void\n}\n\nexport interface UseTorqueCheckoutReturn {\n generateCheckout: (cart: CartData) => Promise<string | null>\n /** Full session (URL + cartSummary + expiresAt) — use for merchant return URL & analytics. */\n requestCheckoutSession: (cart: CartData) => Promise<CheckoutSession | null>\n generateProductCheckout: (productId: string, quantity?: number, customer?: CustomerData, options?: CartOptions) => Promise<string | null>\n generateSubscriptionCheckout: (productId: string, paymentPlanId: string, customer?: CustomerData, options?: CartOptions) => Promise<string | null>\n validateCart: (cart: CartData) => Promise<CartValidation>\n getOrderStatus: (orderId: string) => Promise<OrderStatus | null>\n isLoading: boolean\n error: TorqueCheckoutError | null\n checkoutUrl: string | null\n}\n\n/**\n * React hook for Torque Checkout\n * \n * @example\n * ```tsx\n * const { generateCheckout, isLoading } = useTorqueCheckout({\n * config: {\n * businessId: 'your_business_id',\n * apiKey: 'your_api_key'\n * }\n * })\n * \n * const handleCheckout = async () => {\n * const url = await generateCheckout({\n * items: [{ productId: 'prod_123', quantity: 1 }],\n * customer: { email: 'customer@example.com' }\n * })\n * }\n * ```\n */\nexport function useTorqueCheckout(options: UseTorqueCheckoutOptions = {}): UseTorqueCheckoutReturn {\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<TorqueCheckoutError | null>(null)\n const [checkoutUrl, setCheckoutUrl] = useState<string | null>(null)\n\n const torque = useMemo(() => {\n if (options.config) {\n return createTorqueCheckout(options.config)\n }\n try {\n return createTorqueCheckoutFromEnv()\n } catch (err) {\n console.warn('Failed to create TorqueCheckout from env vars:', err)\n return null\n }\n }, [options.config])\n\n const handleError = useCallback((err: unknown) => {\n const error = err instanceof Error && 'code' in err \n ? err as TorqueCheckoutError \n : new Error(err instanceof Error ? err.message : 'Unknown error') as TorqueCheckoutError\n \n setError(error)\n options.onError?.(error)\n return null\n }, [options])\n\n const handleSuccess = useCallback((url: string) => {\n setCheckoutUrl(url)\n setError(null)\n options.onSuccess?.(url)\n \n if (options.autoRedirect) {\n window.location.href = url\n }\n \n return url\n }, [options])\n\n const generateCheckout = useCallback(async (cart: CartData): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized. Provide config or set TORQUE_BUSINESS_ID and TORQUE_API_KEY environment variables.') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateCartCheckoutUrl(cart)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const requestCheckoutSession = useCallback(async (cart: CartData): Promise<CheckoutSession | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const session = await torque.requestCheckoutSession(cart)\n setIsLoading(false)\n setCheckoutUrl(session.checkoutUrl)\n setError(null)\n options.onSuccess?.(session.checkoutUrl)\n if (options.autoRedirect) {\n window.location.href = session.checkoutUrl\n }\n return session\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, options])\n\n const generateProductCheckout = useCallback(async (\n productId: string,\n quantity: number = 1,\n customer?: CustomerData,\n options?: CartOptions\n ): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateProductCheckoutUrl(productId, quantity, customer, options)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const generateSubscriptionCheckout = useCallback(async (\n productId: string,\n paymentPlanId: string,\n customer?: CustomerData,\n options?: CartOptions\n ): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateSubscriptionCheckoutUrl(productId, paymentPlanId, customer, options)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const validateCart = useCallback(async (cart: CartData): Promise<CartValidation> => {\n if (!torque) {\n return {\n valid: false,\n errors: ['TorqueCheckout not initialized'],\n warnings: [],\n estimatedTotal: 0\n }\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const validation = await torque.validateCart(cart)\n setIsLoading(false)\n return validation\n } catch (err) {\n setIsLoading(false)\n const error = err instanceof Error && 'code' in err \n ? err as TorqueCheckoutError \n : new Error(err instanceof Error ? err.message : 'Validation failed') as TorqueCheckoutError\n setError(error)\n return {\n valid: false,\n errors: [error.message],\n warnings: [],\n estimatedTotal: 0\n }\n }\n }, [torque])\n\n const getOrderStatus = useCallback(async (orderId: string): Promise<OrderStatus | null> => {\n if (!torque) {\n return handleError(new Error('TorqueCheckout not initialized') as TorqueCheckoutError)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const status = await torque.getOrderStatus(orderId)\n setIsLoading(false)\n return status\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError])\n\n return {\n generateCheckout,\n requestCheckoutSession,\n generateProductCheckout,\n generateSubscriptionCheckout,\n validateCart,\n getOrderStatus,\n isLoading,\n error,\n checkoutUrl\n }\n}\n\n// ============================================================================\n// Hook: useCart\n// ============================================================================\n\nexport interface UseCartReturn {\n items: CartItem[]\n addItem: (item: CartItem) => void\n removeItem: (productId: string, variant?: string) => void\n updateQuantity: (productId: string, quantity: number, variant?: string) => void\n clearCart: () => void\n getTotal: () => number\n getItemCount: () => number\n}\n\n/**\n * React hook for managing shopping cart state\n * \n * @example\n * ```tsx\n * const { items, addItem, removeItem, getTotal } = useCart()\n * \n * <button onClick={() => addItem({ productId: 'prod_123', quantity: 1 })}>\n * Add to Cart\n * </button>\n * ```\n */\nexport function useCart(): UseCartReturn {\n const [items, setItems] = useState<CartItem[]>([])\n\n const addItem = useCallback((item: CartItem) => {\n setItems(prev => {\n const existingIndex = prev.findIndex(\n i => i.productId === item.productId && i.variant === item.variant\n )\n \n if (existingIndex >= 0) {\n const updated = [...prev]\n updated[existingIndex] = {\n ...updated[existingIndex],\n quantity: updated[existingIndex].quantity + item.quantity\n }\n return updated\n }\n \n return [...prev, item]\n })\n }, [])\n\n const removeItem = useCallback((productId: string, variant?: string) => {\n setItems(prev => prev.filter(\n item => !(item.productId === productId && item.variant === variant)\n ))\n }, [])\n\n const updateQuantity = useCallback((productId: string, quantity: number, variant?: string) => {\n if (quantity <= 0) {\n removeItem(productId, variant)\n return\n }\n\n setItems(prev => prev.map(item => \n item.productId === productId && item.variant === variant\n ? { ...item, quantity }\n : item\n ))\n }, [removeItem])\n\n const clearCart = useCallback(() => {\n setItems([])\n }, [])\n\n const getTotal = useCallback(() => {\n // Note: Prices come from Torque product database, not from cart items\n // This function returns 0 as prices are only available after checkout URL generation\n // Use the cartSummary from generateCartCheckoutUrl response for accurate totals\n console.warn('getTotal() returns 0 because prices come from Torque product database. Use cartSummary from checkout URL generation for accurate totals.')\n return 0\n }, [items])\n\n const getItemCount = useCallback(() => {\n return items.reduce((count, item) => count + item.quantity, 0)\n }, [items])\n\n return {\n items,\n addItem,\n removeItem,\n updateQuantity,\n clearCart,\n getTotal,\n getItemCount\n }\n}\n\n"],"names":[],"mappings":"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"}
package/dist/react.js CHANGED
@@ -77,6 +77,29 @@ function useTorqueCheckout(options = {}) {
77
77
  return handleError(err);
78
78
  }
79
79
  }, [torque, handleError, handleSuccess]);
80
+ const requestCheckoutSession = react.useCallback(async (cart) => {
81
+ if (!torque) {
82
+ const err = new Error('TorqueCheckout not initialized');
83
+ return handleError(err);
84
+ }
85
+ setIsLoading(true);
86
+ setError(null);
87
+ try {
88
+ const session = await torque.requestCheckoutSession(cart);
89
+ setIsLoading(false);
90
+ setCheckoutUrl(session.checkoutUrl);
91
+ setError(null);
92
+ options.onSuccess?.(session.checkoutUrl);
93
+ if (options.autoRedirect) {
94
+ window.location.href = session.checkoutUrl;
95
+ }
96
+ return session;
97
+ }
98
+ catch (err) {
99
+ setIsLoading(false);
100
+ return handleError(err);
101
+ }
102
+ }, [torque, handleError, options]);
80
103
  const generateProductCheckout = react.useCallback(async (productId, quantity = 1, customer, options) => {
81
104
  if (!torque) {
82
105
  const err = new Error('TorqueCheckout not initialized');
@@ -159,6 +182,7 @@ function useTorqueCheckout(options = {}) {
159
182
  }, [torque, handleError]);
160
183
  return {
161
184
  generateCheckout,
185
+ requestCheckoutSession,
162
186
  generateProductCheckout,
163
187
  generateSubscriptionCheckout,
164
188
  validateCart,
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sources":["../src/react.tsx"],"sourcesContent":["/**\n * React Hooks for Torque Checkout\n * Client-side React hooks for seamless Next.js integration\n */\n\n'use client'\n\nimport { useState, useCallback, useMemo } from 'react'\nimport {\n TorqueCheckout,\n createTorqueCheckout,\n createTorqueCheckoutFromEnv,\n type TorqueConfig,\n type CartData,\n type CartItem,\n type CustomerData,\n type CartOptions,\n type CheckoutResponse,\n type OrderStatus,\n type CartValidation,\n type Subscription,\n type CreateSubscriptionData,\n type TorqueCheckoutError\n} from './index'\n\n// ============================================================================\n// Hook: useTorqueCheckout\n// ============================================================================\n\nexport interface UseTorqueCheckoutOptions {\n config?: TorqueConfig\n autoRedirect?: boolean\n onSuccess?: (checkoutUrl: string) => void\n onError?: (error: TorqueCheckoutError) => void\n}\n\nexport interface UseTorqueCheckoutReturn {\n generateCheckout: (cart: CartData) => Promise<string | null>\n generateProductCheckout: (productId: string, quantity?: number, customer?: CustomerData, options?: CartOptions) => Promise<string | null>\n generateSubscriptionCheckout: (productId: string, paymentPlanId: string, customer?: CustomerData, options?: CartOptions) => Promise<string | null>\n validateCart: (cart: CartData) => Promise<CartValidation>\n getOrderStatus: (orderId: string) => Promise<OrderStatus | null>\n isLoading: boolean\n error: TorqueCheckoutError | null\n checkoutUrl: string | null\n}\n\n/**\n * React hook for Torque Checkout\n * \n * @example\n * ```tsx\n * const { generateCheckout, isLoading } = useTorqueCheckout({\n * config: {\n * businessId: 'your_business_id',\n * apiKey: 'your_api_key'\n * }\n * })\n * \n * const handleCheckout = async () => {\n * const url = await generateCheckout({\n * items: [{ productId: 'prod_123', quantity: 1 }],\n * customer: { email: 'customer@example.com' }\n * })\n * }\n * ```\n */\nexport function useTorqueCheckout(options: UseTorqueCheckoutOptions = {}): UseTorqueCheckoutReturn {\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<TorqueCheckoutError | null>(null)\n const [checkoutUrl, setCheckoutUrl] = useState<string | null>(null)\n\n const torque = useMemo(() => {\n if (options.config) {\n return createTorqueCheckout(options.config)\n }\n try {\n return createTorqueCheckoutFromEnv()\n } catch (err) {\n console.warn('Failed to create TorqueCheckout from env vars:', err)\n return null\n }\n }, [options.config])\n\n const handleError = useCallback((err: unknown) => {\n const error = err instanceof Error && 'code' in err \n ? err as TorqueCheckoutError \n : new Error(err instanceof Error ? err.message : 'Unknown error') as TorqueCheckoutError\n \n setError(error)\n options.onError?.(error)\n return null\n }, [options])\n\n const handleSuccess = useCallback((url: string) => {\n setCheckoutUrl(url)\n setError(null)\n options.onSuccess?.(url)\n \n if (options.autoRedirect) {\n window.location.href = url\n }\n \n return url\n }, [options])\n\n const generateCheckout = useCallback(async (cart: CartData): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized. Provide config or set TORQUE_BUSINESS_ID and TORQUE_API_KEY environment variables.') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateCartCheckoutUrl(cart)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const generateProductCheckout = useCallback(async (\n productId: string,\n quantity: number = 1,\n customer?: CustomerData,\n options?: CartOptions\n ): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateProductCheckoutUrl(productId, quantity, customer, options)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const generateSubscriptionCheckout = useCallback(async (\n productId: string,\n paymentPlanId: string,\n customer?: CustomerData,\n options?: CartOptions\n ): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateSubscriptionCheckoutUrl(productId, paymentPlanId, customer, options)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const validateCart = useCallback(async (cart: CartData): Promise<CartValidation> => {\n if (!torque) {\n return {\n valid: false,\n errors: ['TorqueCheckout not initialized'],\n warnings: [],\n estimatedTotal: 0\n }\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const validation = await torque.validateCart(cart)\n setIsLoading(false)\n return validation\n } catch (err) {\n setIsLoading(false)\n const error = err instanceof Error && 'code' in err \n ? err as TorqueCheckoutError \n : new Error(err instanceof Error ? err.message : 'Validation failed') as TorqueCheckoutError\n setError(error)\n return {\n valid: false,\n errors: [error.message],\n warnings: [],\n estimatedTotal: 0\n }\n }\n }, [torque])\n\n const getOrderStatus = useCallback(async (orderId: string): Promise<OrderStatus | null> => {\n if (!torque) {\n return handleError(new Error('TorqueCheckout not initialized') as TorqueCheckoutError)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const status = await torque.getOrderStatus(orderId)\n setIsLoading(false)\n return status\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError])\n\n return {\n generateCheckout,\n generateProductCheckout,\n generateSubscriptionCheckout,\n validateCart,\n getOrderStatus,\n isLoading,\n error,\n checkoutUrl\n }\n}\n\n// ============================================================================\n// Hook: useCart\n// ============================================================================\n\nexport interface UseCartReturn {\n items: CartItem[]\n addItem: (item: CartItem) => void\n removeItem: (productId: string, variant?: string) => void\n updateQuantity: (productId: string, quantity: number, variant?: string) => void\n clearCart: () => void\n getTotal: () => number\n getItemCount: () => number\n}\n\n/**\n * React hook for managing shopping cart state\n * \n * @example\n * ```tsx\n * const { items, addItem, removeItem, getTotal } = useCart()\n * \n * <button onClick={() => addItem({ productId: 'prod_123', quantity: 1 })}>\n * Add to Cart\n * </button>\n * ```\n */\nexport function useCart(): UseCartReturn {\n const [items, setItems] = useState<CartItem[]>([])\n\n const addItem = useCallback((item: CartItem) => {\n setItems(prev => {\n const existingIndex = prev.findIndex(\n i => i.productId === item.productId && i.variant === item.variant\n )\n \n if (existingIndex >= 0) {\n const updated = [...prev]\n updated[existingIndex] = {\n ...updated[existingIndex],\n quantity: updated[existingIndex].quantity + item.quantity\n }\n return updated\n }\n \n return [...prev, item]\n })\n }, [])\n\n const removeItem = useCallback((productId: string, variant?: string) => {\n setItems(prev => prev.filter(\n item => !(item.productId === productId && item.variant === variant)\n ))\n }, [])\n\n const updateQuantity = useCallback((productId: string, quantity: number, variant?: string) => {\n if (quantity <= 0) {\n removeItem(productId, variant)\n return\n }\n\n setItems(prev => prev.map(item => \n item.productId === productId && item.variant === variant\n ? { ...item, quantity }\n : item\n ))\n }, [removeItem])\n\n const clearCart = useCallback(() => {\n setItems([])\n }, [])\n\n const getTotal = useCallback(() => {\n // Note: Prices come from Torque product database, not from cart items\n // This function returns 0 as prices are only available after checkout URL generation\n // Use the cartSummary from generateCartCheckoutUrl response for accurate totals\n console.warn('getTotal() returns 0 because prices come from Torque product database. Use cartSummary from checkout URL generation for accurate totals.')\n return 0\n }, [items])\n\n const getItemCount = useCallback(() => {\n return items.reduce((count, item) => count + item.quantity, 0)\n }, [items])\n\n return {\n items,\n addItem,\n removeItem,\n updateQuantity,\n clearCart,\n getTotal,\n getItemCount\n }\n}\n\n"],"names":["useState","useMemo","createTorqueCheckout","createTorqueCheckoutFromEnv","useCallback"],"mappings":"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"}
1
+ {"version":3,"file":"react.js","sources":["../src/react.tsx"],"sourcesContent":["/**\n * React Hooks for Torque Checkout\n * Client-side React hooks for seamless Next.js integration\n */\n\n'use client'\n\nimport { useState, useCallback, useMemo } from 'react'\nimport {\n TorqueCheckout,\n createTorqueCheckout,\n createTorqueCheckoutFromEnv,\n type TorqueConfig,\n type CartData,\n type CartItem,\n type CustomerData,\n type CartOptions,\n type CheckoutSession,\n type OrderStatus,\n type CartValidation,\n type Subscription,\n type CreateSubscriptionData,\n type TorqueCheckoutError\n} from './index'\n\n// ============================================================================\n// Hook: useTorqueCheckout\n// ============================================================================\n\nexport interface UseTorqueCheckoutOptions {\n config?: TorqueConfig\n autoRedirect?: boolean\n onSuccess?: (checkoutUrl: string) => void\n onError?: (error: TorqueCheckoutError) => void\n}\n\nexport interface UseTorqueCheckoutReturn {\n generateCheckout: (cart: CartData) => Promise<string | null>\n /** Full session (URL + cartSummary + expiresAt) — use for merchant return URL & analytics. */\n requestCheckoutSession: (cart: CartData) => Promise<CheckoutSession | null>\n generateProductCheckout: (productId: string, quantity?: number, customer?: CustomerData, options?: CartOptions) => Promise<string | null>\n generateSubscriptionCheckout: (productId: string, paymentPlanId: string, customer?: CustomerData, options?: CartOptions) => Promise<string | null>\n validateCart: (cart: CartData) => Promise<CartValidation>\n getOrderStatus: (orderId: string) => Promise<OrderStatus | null>\n isLoading: boolean\n error: TorqueCheckoutError | null\n checkoutUrl: string | null\n}\n\n/**\n * React hook for Torque Checkout\n * \n * @example\n * ```tsx\n * const { generateCheckout, isLoading } = useTorqueCheckout({\n * config: {\n * businessId: 'your_business_id',\n * apiKey: 'your_api_key'\n * }\n * })\n * \n * const handleCheckout = async () => {\n * const url = await generateCheckout({\n * items: [{ productId: 'prod_123', quantity: 1 }],\n * customer: { email: 'customer@example.com' }\n * })\n * }\n * ```\n */\nexport function useTorqueCheckout(options: UseTorqueCheckoutOptions = {}): UseTorqueCheckoutReturn {\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<TorqueCheckoutError | null>(null)\n const [checkoutUrl, setCheckoutUrl] = useState<string | null>(null)\n\n const torque = useMemo(() => {\n if (options.config) {\n return createTorqueCheckout(options.config)\n }\n try {\n return createTorqueCheckoutFromEnv()\n } catch (err) {\n console.warn('Failed to create TorqueCheckout from env vars:', err)\n return null\n }\n }, [options.config])\n\n const handleError = useCallback((err: unknown) => {\n const error = err instanceof Error && 'code' in err \n ? err as TorqueCheckoutError \n : new Error(err instanceof Error ? err.message : 'Unknown error') as TorqueCheckoutError\n \n setError(error)\n options.onError?.(error)\n return null\n }, [options])\n\n const handleSuccess = useCallback((url: string) => {\n setCheckoutUrl(url)\n setError(null)\n options.onSuccess?.(url)\n \n if (options.autoRedirect) {\n window.location.href = url\n }\n \n return url\n }, [options])\n\n const generateCheckout = useCallback(async (cart: CartData): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized. Provide config or set TORQUE_BUSINESS_ID and TORQUE_API_KEY environment variables.') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateCartCheckoutUrl(cart)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const requestCheckoutSession = useCallback(async (cart: CartData): Promise<CheckoutSession | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const session = await torque.requestCheckoutSession(cart)\n setIsLoading(false)\n setCheckoutUrl(session.checkoutUrl)\n setError(null)\n options.onSuccess?.(session.checkoutUrl)\n if (options.autoRedirect) {\n window.location.href = session.checkoutUrl\n }\n return session\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, options])\n\n const generateProductCheckout = useCallback(async (\n productId: string,\n quantity: number = 1,\n customer?: CustomerData,\n options?: CartOptions\n ): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateProductCheckoutUrl(productId, quantity, customer, options)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const generateSubscriptionCheckout = useCallback(async (\n productId: string,\n paymentPlanId: string,\n customer?: CustomerData,\n options?: CartOptions\n ): Promise<string | null> => {\n if (!torque) {\n const err = new Error('TorqueCheckout not initialized') as TorqueCheckoutError\n return handleError(err)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const url = await torque.generateSubscriptionCheckoutUrl(productId, paymentPlanId, customer, options)\n setIsLoading(false)\n return handleSuccess(url)\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError, handleSuccess])\n\n const validateCart = useCallback(async (cart: CartData): Promise<CartValidation> => {\n if (!torque) {\n return {\n valid: false,\n errors: ['TorqueCheckout not initialized'],\n warnings: [],\n estimatedTotal: 0\n }\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const validation = await torque.validateCart(cart)\n setIsLoading(false)\n return validation\n } catch (err) {\n setIsLoading(false)\n const error = err instanceof Error && 'code' in err \n ? err as TorqueCheckoutError \n : new Error(err instanceof Error ? err.message : 'Validation failed') as TorqueCheckoutError\n setError(error)\n return {\n valid: false,\n errors: [error.message],\n warnings: [],\n estimatedTotal: 0\n }\n }\n }, [torque])\n\n const getOrderStatus = useCallback(async (orderId: string): Promise<OrderStatus | null> => {\n if (!torque) {\n return handleError(new Error('TorqueCheckout not initialized') as TorqueCheckoutError)\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const status = await torque.getOrderStatus(orderId)\n setIsLoading(false)\n return status\n } catch (err) {\n setIsLoading(false)\n return handleError(err)\n }\n }, [torque, handleError])\n\n return {\n generateCheckout,\n requestCheckoutSession,\n generateProductCheckout,\n generateSubscriptionCheckout,\n validateCart,\n getOrderStatus,\n isLoading,\n error,\n checkoutUrl\n }\n}\n\n// ============================================================================\n// Hook: useCart\n// ============================================================================\n\nexport interface UseCartReturn {\n items: CartItem[]\n addItem: (item: CartItem) => void\n removeItem: (productId: string, variant?: string) => void\n updateQuantity: (productId: string, quantity: number, variant?: string) => void\n clearCart: () => void\n getTotal: () => number\n getItemCount: () => number\n}\n\n/**\n * React hook for managing shopping cart state\n * \n * @example\n * ```tsx\n * const { items, addItem, removeItem, getTotal } = useCart()\n * \n * <button onClick={() => addItem({ productId: 'prod_123', quantity: 1 })}>\n * Add to Cart\n * </button>\n * ```\n */\nexport function useCart(): UseCartReturn {\n const [items, setItems] = useState<CartItem[]>([])\n\n const addItem = useCallback((item: CartItem) => {\n setItems(prev => {\n const existingIndex = prev.findIndex(\n i => i.productId === item.productId && i.variant === item.variant\n )\n \n if (existingIndex >= 0) {\n const updated = [...prev]\n updated[existingIndex] = {\n ...updated[existingIndex],\n quantity: updated[existingIndex].quantity + item.quantity\n }\n return updated\n }\n \n return [...prev, item]\n })\n }, [])\n\n const removeItem = useCallback((productId: string, variant?: string) => {\n setItems(prev => prev.filter(\n item => !(item.productId === productId && item.variant === variant)\n ))\n }, [])\n\n const updateQuantity = useCallback((productId: string, quantity: number, variant?: string) => {\n if (quantity <= 0) {\n removeItem(productId, variant)\n return\n }\n\n setItems(prev => prev.map(item => \n item.productId === productId && item.variant === variant\n ? { ...item, quantity }\n : item\n ))\n }, [removeItem])\n\n const clearCart = useCallback(() => {\n setItems([])\n }, [])\n\n const getTotal = useCallback(() => {\n // Note: Prices come from Torque product database, not from cart items\n // This function returns 0 as prices are only available after checkout URL generation\n // Use the cartSummary from generateCartCheckoutUrl response for accurate totals\n console.warn('getTotal() returns 0 because prices come from Torque product database. Use cartSummary from checkout URL generation for accurate totals.')\n return 0\n }, [items])\n\n const getItemCount = useCallback(() => {\n return items.reduce((count, item) => count + item.quantity, 0)\n }, [items])\n\n return {\n items,\n addItem,\n removeItem,\n updateQuantity,\n clearCart,\n getTotal,\n getItemCount\n }\n}\n\n"],"names":["useState","useMemo","createTorqueCheckout","createTorqueCheckoutFromEnv","useCallback"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "torque-checkout",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "Official Torque checkout SDK for seamless eCommerce integrations with Next.js",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -32,10 +32,9 @@
32
32
  "scripts": {
33
33
  "build": "rollup -c",
34
34
  "dev": "rollup -c -w",
35
- "test": "jest",
36
35
  "lint": "eslint src --ext .ts,.tsx",
37
36
  "clean": "rimraf dist",
38
- "prepublishOnly": "npm run clean && npm run build"
37
+ "prepublishOnly": "yarn clean && yarn build"
39
38
  },
40
39
  "keywords": [
41
40
  "torque",
@@ -68,7 +67,6 @@
68
67
  "@typescript-eslint/eslint-plugin": "^6.0.0",
69
68
  "@typescript-eslint/parser": "^6.0.0",
70
69
  "eslint": "^8.0.0",
71
- "jest": "^29.0.0",
72
70
  "rimraf": "^5.0.0",
73
71
  "rollup": "^4.0.0",
74
72
  "typescript": "^5.0.0"