@sazito/checkout 0.1.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.
@@ -0,0 +1,376 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { Cart, Invoice, ApplicableShippingMethods, InvoiceItem, ShippingRate, PaymentMethod, Order } from '@sazito/client-sdk';
4
+
5
+ /**
6
+ * Checkout domain types.
7
+ *
8
+ * The package re-exports the SDK data models (camelCase) and layers
9
+ * checkout-specific state, config, events and effects on top.
10
+ */
11
+
12
+ /** How a discount code changes the order. */
13
+ type DiscountKind = 'percentage' | 'fixed_amount' | 'free_shipping' | 'unknown';
14
+ /**
15
+ * A successfully applied discount code with its detected type. The API only
16
+ * reports discount codes as totals on the invoice, so the type is inferred by
17
+ * `classifyAppliedDiscount` (selectors) — `unknown` when nothing measurable
18
+ * changed yet (e.g. a free-shipping code applied before a rate is selected).
19
+ */
20
+ interface AppliedDiscount {
21
+ code: string;
22
+ kind: DiscountKind;
23
+ /** Amount taken off the items total by this code. */
24
+ amount: number;
25
+ /** Percentage discounts only: the detected integer percent. */
26
+ percent?: number;
27
+ /** Shipping cost removed by the code. */
28
+ shippingSaved?: number;
29
+ }
30
+ /** Regions are not re-exported by the SDK top level; mirror the shape here. */
31
+ interface CheckoutCity {
32
+ id: number;
33
+ name: string;
34
+ latitude: number;
35
+ longitude: number;
36
+ }
37
+ interface CheckoutRegion {
38
+ id: number;
39
+ name: string;
40
+ cities: CheckoutCity[];
41
+ }
42
+ type CheckoutLocale = 'fa' | 'en';
43
+ type CheckoutDirection = 'rtl' | 'ltr';
44
+ /** Interactive steps in order. `result` is the terminal post-payment screen. */
45
+ type CheckoutStep = 'cart' | 'shipping' | 'payment' | 'result';
46
+ /** Coarse engine status used to drive spinners / disabled states. */
47
+ type CheckoutStatus = 'idle' | 'bootstrapping' | 'working' | 'redirecting' | 'polling' | 'error';
48
+ type CheckoutResultStatus = 'success' | 'failed' | 'pending' | 'stock_violated';
49
+ interface CheckoutTheme {
50
+ /** Primary accent (buttons, active states). CSS color. */
51
+ accent?: string;
52
+ /** Foreground used on top of the accent. CSS color. */
53
+ accentForeground?: string;
54
+ /** Soft accent surface used for selected rows and focus-adjacent states. */
55
+ accentSoft?: string;
56
+ /** Checkout page background. */
57
+ background?: string;
58
+ /** Primary text color. */
59
+ foreground?: string;
60
+ /** Muted surface background. */
61
+ muted?: string;
62
+ /** Secondary text color. */
63
+ mutedForeground?: string;
64
+ /** Borders and dividers. */
65
+ border?: string;
66
+ /** Form, product, and shipping card background. */
67
+ card?: string;
68
+ /** Order-summary sidebar background. */
69
+ summaryBackground?: string;
70
+ /** Error and destructive-state color. */
71
+ danger?: string;
72
+ /** Success and completed-state color. */
73
+ success?: string;
74
+ /** Base corner radius in px. */
75
+ radius?: number;
76
+ /** Font family. Defaults to `inherit` so the host font flows through. */
77
+ fontFamily?: string;
78
+ }
79
+ /** Seed credentials so checkout can attach to an already-built cart. */
80
+ interface CheckoutCredentials {
81
+ cart?: {
82
+ id?: number;
83
+ identifier: string;
84
+ };
85
+ invoice?: {
86
+ id: number;
87
+ identifier: string;
88
+ };
89
+ }
90
+ interface CheckoutConfig {
91
+ locale?: CheckoutLocale;
92
+ direction?: CheckoutDirection;
93
+ theme?: CheckoutTheme;
94
+ /** URL for the "continue shopping" / back-to-store action. */
95
+ continueShoppingUrl?: string;
96
+ /** URL the gateway returns to after payment. Defaults to current URL. */
97
+ returnUrl?: string;
98
+ /** Pending-payment poll interval in ms (default 15000). */
99
+ pollIntervalMs?: number;
100
+ /** Currency label override (defaults per-locale). */
101
+ currencyLabel?: string;
102
+ onEvent?: (event: CheckoutEvent) => void;
103
+ }
104
+ /** The guest contact + address form. */
105
+ interface AddressFormValues {
106
+ firstName: string;
107
+ lastName: string;
108
+ mobilePhone: string;
109
+ email: string;
110
+ phoneNumber: string;
111
+ regionId: number | null;
112
+ cityId: number | null;
113
+ postalCode: string;
114
+ address: string;
115
+ description: string;
116
+ }
117
+ /**
118
+ * A shippable group: a set of invoice items shipped together, with the rates
119
+ * the customer can switch between and the currently selected rate.
120
+ */
121
+ interface ShippingGroup {
122
+ key: string;
123
+ title: string;
124
+ itemIds: Array<number | string>;
125
+ items: InvoiceItem[];
126
+ rates: ShippingRate[];
127
+ selectedRateId: number | null;
128
+ }
129
+ interface CheckoutResult {
130
+ status: CheckoutResultStatus;
131
+ order?: Order;
132
+ message?: string;
133
+ }
134
+ interface CheckoutError {
135
+ message: string;
136
+ code?: CheckoutErrorCode;
137
+ status?: number;
138
+ step?: CheckoutStep;
139
+ }
140
+ type CheckoutErrorCode = 'no_cart' | 'no_invoice' | 'min_basket' | 'rate_limited' | 'cart_invalid' | 'invoice_locked' | 'stock_violated' | 'shipping_required' | 'address_required' | 'payment_failed' | 'network' | 'validation' | 'unknown';
141
+ /** Per-region async flags so the UI can show targeted spinners. */
142
+ interface CheckoutFlags {
143
+ bootstrapping: boolean;
144
+ updatingCart: boolean;
145
+ savingAddress: boolean;
146
+ loadingShipping: boolean;
147
+ selectingRate: boolean;
148
+ applyingDiscount: boolean;
149
+ loadingPayments: boolean;
150
+ placingOrder: boolean;
151
+ }
152
+ interface CheckoutState {
153
+ step: CheckoutStep;
154
+ status: CheckoutStatus;
155
+ locale: CheckoutLocale;
156
+ direction: CheckoutDirection;
157
+ cart: Cart | null;
158
+ invoice: Invoice | null;
159
+ regions: CheckoutRegion[];
160
+ addressForm: AddressFormValues;
161
+ /** Shop-level requirement loaded from the checkout configuration. */
162
+ postalCodeMandatory: boolean;
163
+ /** Shop-level requirement loaded from the checkout configuration. */
164
+ emailMandatory: boolean;
165
+ /** Whether the saved address on the invoice matches the current form. */
166
+ addressDirty: boolean;
167
+ applicable: ApplicableShippingMethods | null;
168
+ shippingGroups: ShippingGroup[];
169
+ paymentMethods: PaymentMethod[];
170
+ selectedPaymentMethodId: number | null;
171
+ discountCode: string;
172
+ appliedDiscountCode: string | null;
173
+ /** Type + saved amounts of the applied code; null when no code is applied. */
174
+ appliedDiscount: AppliedDiscount | null;
175
+ /** Inline error for the discount field; not shown in the global banner. */
176
+ discountError: string | null;
177
+ result: CheckoutResult | null;
178
+ error: CheckoutError | null;
179
+ flags: CheckoutFlags;
180
+ }
181
+ type CheckoutEventName = 'checkout_viewed' | 'step_viewed' | 'address_submitted' | 'shipping_rate_selected' | 'discount_applied' | 'discount_removed' | 'payment_method_selected' | 'payment_initiated' | 'payment_succeeded' | 'payment_failed' | 'payment_pending';
182
+ interface CheckoutEvent {
183
+ name: CheckoutEventName;
184
+ step?: CheckoutStep;
185
+ value?: number;
186
+ metadata?: Record<string, unknown>;
187
+ timestamp: number;
188
+ }
189
+ /**
190
+ * Side-effects the pure engine asks the host to perform. The default browser
191
+ * executor handles all of these; a host may override (SSR / native / tests).
192
+ */
193
+ type CheckoutEffect = {
194
+ type: 'redirect';
195
+ url: string;
196
+ } | {
197
+ type: 'post-form';
198
+ url: string;
199
+ fields: Record<string, string>;
200
+ } | {
201
+ type: 'emit';
202
+ event: CheckoutEvent;
203
+ };
204
+ type CheckoutEffectExecutor = (effect: CheckoutEffect) => void;
205
+ /** Public command surface exposed to UI bindings. */
206
+ interface CheckoutActions {
207
+ /** Load cart + invoice and derive initial state. */
208
+ start(): Promise<void>;
209
+ goToStep(step: CheckoutStep): void;
210
+ next(): Promise<void>;
211
+ back(): void;
212
+ /** Cart review edits — update a line quantity or remove a line. */
213
+ updateItemQuantity(cartProductId: number | string, variantId: number, quantity: number): Promise<void>;
214
+ removeItem(cartProductId: number | string, variantId: number): Promise<void>;
215
+ setAddressField<K extends keyof AddressFormValues>(key: K, value: AddressFormValues[K]): void;
216
+ submitAddress(): Promise<boolean>;
217
+ selectShippingRate(groupKey: string, rateId: number): Promise<void>;
218
+ setDiscountCode(code: string): void;
219
+ applyDiscount(): Promise<void>;
220
+ removeDiscount(): Promise<void>;
221
+ selectPaymentMethod(id: number): void;
222
+ placeOrder(): Promise<void>;
223
+ /** Resolve a return from the payment gateway (query params from the URL). */
224
+ resolvePaymentReturn(params: Record<string, string>): Promise<void>;
225
+ reset(): void;
226
+ }
227
+
228
+ interface CheckoutEngine {
229
+ getState(): CheckoutState;
230
+ subscribe(listener: () => void): () => void;
231
+ actions: CheckoutActions;
232
+ setEffectExecutor(executor: CheckoutEffectExecutor): void;
233
+ destroy(): void;
234
+ }
235
+
236
+ /**
237
+ * UI strings (fa/en) and domain label helpers (payment gateways, shipping).
238
+ */
239
+
240
+ interface Strings {
241
+ stepCart: string;
242
+ stepShipping: string;
243
+ stepPayment: string;
244
+ stepReview: string;
245
+ stepResult: string;
246
+ /** Mobile header title for the shipping step. */
247
+ stepShippingInfo: string;
248
+ /** Mobile header progress, e.g. "مرحله ۲ از ۳" / "Step 2 of 3". */
249
+ stepOf: (current: string, total: string) => string;
250
+ next: string;
251
+ placeOrder: string;
252
+ saveShippingDetails: string;
253
+ continueToPayment: string;
254
+ finalizeOrder: string;
255
+ finishPurchase: string;
256
+ back: string;
257
+ continueShopping: string;
258
+ orderSummary: string;
259
+ subtotal: string;
260
+ shipping: string;
261
+ discount: string;
262
+ credit: string;
263
+ vat: string;
264
+ total: string;
265
+ totalAmount: string;
266
+ free: string;
267
+ quantity: string;
268
+ optional: string;
269
+ cartTitle: string;
270
+ cartEmpty: string;
271
+ cartEmptyHint: string;
272
+ remove: string;
273
+ itemDiscount: (amount: string) => string;
274
+ yourSavings: string;
275
+ contactInfo: string;
276
+ firstName: string;
277
+ lastName: string;
278
+ mobilePhone: string;
279
+ email: string;
280
+ phoneNumber: string;
281
+ region: string;
282
+ city: string;
283
+ postalCode: string;
284
+ addressLine: string;
285
+ description: string;
286
+ selectRegion: string;
287
+ selectCity: string;
288
+ shippingMethod: string;
289
+ shippingMethods: string;
290
+ shippingMethodsHint: string;
291
+ digitalNoShipping: string;
292
+ errorRequired: string;
293
+ errorMobilePhone: string;
294
+ errorEmail: string;
295
+ changeTo: string;
296
+ productCount: (n: string) => string;
297
+ paymentMethod: string;
298
+ discountCode: string;
299
+ discountPlaceholder: string;
300
+ apply: string;
301
+ applied: string;
302
+ discountPercentOff: (percent: string) => string;
303
+ discountAmountOff: (amount: string) => string;
304
+ discountFreeShipping: string;
305
+ reviewTitle: string;
306
+ reviewContact: string;
307
+ reviewAddress: string;
308
+ reviewShipping: string;
309
+ reviewPayment: string;
310
+ payNow: string;
311
+ edit: string;
312
+ paymentSuccess: string;
313
+ paymentFailed: string;
314
+ paymentPending: string;
315
+ paymentPendingHint: string;
316
+ orderNumber: string;
317
+ tryAgain: string;
318
+ loading: string;
319
+ processing: string;
320
+ redirecting: string;
321
+ }
322
+
323
+ /**
324
+ * Pure derivations over invoice / shipping data: shipping groups, summary
325
+ * lines, address form mapping and validation. No SDK calls, no side-effects.
326
+ */
327
+
328
+ type SummaryLineKey = 'subtotal' | 'discount' | 'shipping' | 'credit' | 'vat';
329
+ interface SummaryLine {
330
+ key: SummaryLineKey;
331
+ amount: number;
332
+ negative?: boolean;
333
+ free?: boolean;
334
+ /** Discount line only: amount as a percentage of subtotal (rounded). */
335
+ percent?: number;
336
+ }
337
+ interface CheckoutSummary {
338
+ lines: SummaryLine[];
339
+ total: number;
340
+ }
341
+
342
+ interface CheckoutProviderProps {
343
+ /** Override the SazitoProvider client for this checkout instance only. */
344
+ client?: unknown;
345
+ credentials?: CheckoutCredentials;
346
+ config?: CheckoutConfig;
347
+ autoStart?: boolean;
348
+ children: ReactNode;
349
+ }
350
+ declare function CheckoutProvider({ client: clientProp, credentials, config, autoStart, children }: CheckoutProviderProps): react_jsx_runtime.JSX.Element;
351
+
352
+ interface UseCheckout {
353
+ state: CheckoutState;
354
+ actions: CheckoutActions;
355
+ /** Localized UI strings. */
356
+ t: Strings;
357
+ /** Format an amount with the currency label for the active locale. */
358
+ money(value: number): string;
359
+ /** Like `money`, but renders 0 as "Free". */
360
+ price(value: number): string;
361
+ summary: CheckoutSummary;
362
+ digitalItems: InvoiceItem[];
363
+ }
364
+ declare function useCheckout(): UseCheckout;
365
+
366
+ declare function useCheckoutEngine(): CheckoutEngine;
367
+
368
+ interface SazitoProviderProps {
369
+ client: unknown;
370
+ children: ReactNode;
371
+ }
372
+ declare function SazitoProvider({ client, children }: SazitoProviderProps): react_jsx_runtime.JSX.Element;
373
+ declare function useSazitoClient(): unknown;
374
+
375
+ export { CheckoutProvider, SazitoProvider, useCheckout, useCheckoutEngine, useSazitoClient };
376
+ export type { CheckoutProviderProps, SazitoProviderProps, UseCheckout };
@@ -0,0 +1,7 @@
1
+ 'use client';
2
+ export { C as CheckoutProvider, S as SazitoProvider, u as useCheckout, a as useCheckoutEngine, b as useSazitoClient } from '../chunks/use-checkout-E0O8HsSs.js';
3
+ import 'react/jsx-runtime';
4
+ import 'react';
5
+ import '../chunks/labels-ChywPk2i.js';
6
+ import '@sazito/client-sdk';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}