omni-sync-sdk 0.14.3 → 0.16.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/README.md CHANGED
@@ -16,6 +16,39 @@ yarn add omni-sync-sdk
16
16
 
17
17
  ---
18
18
 
19
+ ## Quick Reference - Helper Functions
20
+
21
+ The SDK exports these utility functions for common UI tasks:
22
+
23
+ | Function | Purpose | Example |
24
+ | ---------------------------------------------- | -------------------------------------- | ---------------------------------------------- |
25
+ | `formatPrice(amount, currency?, locale?)` | Format prices for display | `formatPrice(99.99, 'USD')` → `$99.99` |
26
+ | `getPriceDisplay(amount, currency?, locale?)` | Alias for `formatPrice` | Same as above |
27
+ | `getDescriptionContent(product)` | Get product description (HTML or text) | `getDescriptionContent(product)` |
28
+ | `isHtmlDescription(product)` | Check if description is HTML | `isHtmlDescription(product)` → `true/false` |
29
+ | `getStockStatus(variant)` | Get human-readable stock status | `getStockStatus(variant)` → `"In Stock"` |
30
+ | `isCouponApplicableToProduct(coupon, product)` | Check if coupon applies | `isCouponApplicableToProduct(coupon, product)` |
31
+
32
+ ```typescript
33
+ import {
34
+ formatPrice,
35
+ getPriceDisplay, // Alias for formatPrice
36
+ getDescriptionContent,
37
+ getStockStatus,
38
+ } from 'omni-sync-sdk';
39
+
40
+ // Format price for display
41
+ const priceText = formatPrice(product.basePrice, 'USD'); // "$99.99"
42
+
43
+ // Get product description (handles HTML vs plain text)
44
+ const description = getDescriptionContent(product);
45
+
46
+ // Get stock status text
47
+ const stockText = getStockStatus(product.variants[0]); // "In Stock", "Low Stock", "Out of Stock"
48
+ ```
49
+
50
+ ---
51
+
19
52
  ## ⚠️ CRITICAL: Payment Integration Required!
20
53
 
21
54
  **Your store will NOT work without payment integration.** The store owner has already configured payment providers (Stripe/PayPal) - you just need to implement the payment page.
@@ -1349,9 +1382,74 @@ if (error) {
1349
1382
  }
1350
1383
  ```
1351
1384
 
1352
- #### Check Payment Status
1385
+ #### After Payment: Success Page Pattern (Recommended)
1386
+
1387
+ **Important:** Orders are created asynchronously via webhook after Stripe confirms payment.
1388
+ This typically takes 1-5 seconds, but can vary. Follow these best practices:
1389
+
1390
+ **Option 1: Optimistic Success Page (Recommended - Used by Amazon, Shopify, AliExpress)**
1391
+
1392
+ Show success immediately without waiting for orderId. This is the industry standard:
1393
+
1394
+ ```typescript
1395
+ // In your payment form, after stripe.confirmPayment() succeeds:
1396
+ const { error } = await stripe.confirmPayment({
1397
+ elements,
1398
+ confirmParams: {
1399
+ return_url: `${window.location.origin}/checkout/success?checkout_id=${checkout.id}`,
1400
+ },
1401
+ });
1402
+
1403
+ // On /checkout/success page - show confirmation IMMEDIATELY:
1404
+ export default function CheckoutSuccessPage() {
1405
+ const checkoutId = new URLSearchParams(window.location.search).get('checkout_id');
1406
+
1407
+ return (
1408
+ <div className="text-center py-12">
1409
+ <h1 className="text-2xl font-bold text-green-600">Payment Received!</h1>
1410
+ <p className="mt-4">Your order is being processed.</p>
1411
+ <p className="mt-2 text-gray-600">
1412
+ Confirmation #{checkoutId?.slice(-8).toUpperCase()}
1413
+ </p>
1414
+ <p className="mt-4">A confirmation email will be sent shortly.</p>
1415
+ <a href="/orders" className="mt-6 inline-block text-blue-600">
1416
+ View Your Orders →
1417
+ </a>
1418
+ </div>
1419
+ );
1420
+ }
1421
+ ```
1422
+
1423
+ **Option 2: Wait for Order (For SPAs that need orderId)**
1424
+
1425
+ Use `waitForOrder()` to poll in the background with exponential backoff:
1426
+
1427
+ ```typescript
1428
+ // After payment succeeds, wait for order creation (max 30 seconds)
1429
+ const result = await omni.waitForOrder(checkout.id, {
1430
+ maxWaitMs: 30000, // 30 seconds max
1431
+ onPollAttempt: (attempt, status) => {
1432
+ console.log(`Checking order status... (attempt ${attempt})`);
1433
+ },
1434
+ onOrderReady: (status) => {
1435
+ // Called immediately when order is created
1436
+ console.log('Order ready:', status.orderNumber);
1437
+ },
1438
+ });
1439
+
1440
+ if (result.success) {
1441
+ // Order was created within timeout
1442
+ window.location.href = `/orders/${result.status.orderId}`;
1443
+ } else {
1444
+ // Order not created yet - show optimistic success anyway
1445
+ // The email will be sent when order is ready
1446
+ showSuccessMessage('Payment received! Order confirmation coming soon.');
1447
+ }
1448
+ ```
1449
+
1450
+ **Option 3: Simple Status Check (Single poll)**
1353
1451
 
1354
- After redirect or for polling:
1452
+ For simple use cases where you just want to check once:
1355
1453
 
1356
1454
  ```typescript
1357
1455
  const status = await omni.getPaymentStatus(checkout.id);
@@ -1359,17 +1457,27 @@ const status = await omni.getPaymentStatus(checkout.id);
1359
1457
  // Returns:
1360
1458
  // {
1361
1459
  // checkoutId: 'checkout_xxx',
1362
- // status: 'succeeded' | 'pending' | 'failed',
1363
- // orderId: 'order_xxx', // Only if payment succeeded
1364
- // orderNumber: 'ORD-123', // Only if payment succeeded
1460
+ // status: 'succeeded' | 'pending' | 'failed' | 'canceled',
1461
+ // orderId: 'order_xxx', // Only if order was created
1462
+ // orderNumber: 'ORD-123', // Only if order was created
1365
1463
  // error: 'Payment declined' // Only if payment failed
1366
1464
  // }
1367
1465
 
1368
- if (status.status === 'succeeded') {
1466
+ if (status.status === 'succeeded' && status.orderId) {
1369
1467
  window.location.href = `/order-confirmation/${status.orderId}`;
1468
+ } else if (status.status === 'succeeded') {
1469
+ // Payment succeeded but order not created yet
1470
+ showMessage('Payment received, processing your order...');
1471
+ } else if (status.status === 'failed') {
1472
+ showError(status.error || 'Payment failed');
1370
1473
  }
1371
1474
  ```
1372
1475
 
1476
+ > **Why Optimistic Success?** Stripe webhooks typically arrive within 1-5 seconds,
1477
+ > but network issues can cause delays. Major e-commerce platforms (Amazon, Shopify)
1478
+ > show success immediately and send order details via email. This provides better UX
1479
+ > than making customers wait on a loading screen.
1480
+
1373
1481
  #### Complete Checkout with Payment Example
1374
1482
 
1375
1483
  ```typescript
package/dist/index.d.mts CHANGED
@@ -1263,12 +1263,13 @@ interface ShippingRate {
1263
1263
  /**
1264
1264
  * Represents a checkout session for completing a purchase.
1265
1265
  *
1266
- * **Checkout Flow:**
1267
- * 1. Create checkout from cart: `createCheckout({ cartId })`
1268
- * 2. Set customer info: `setCheckoutCustomer(id, { email, ... })`
1269
- * 3. Set shipping address: `setShippingAddress(id, address)` - returns available rates
1270
- * 4. Select shipping method: `selectShippingMethod(id, rateId)`
1271
- * 5. Complete checkout: `completeCheckout(id)` - creates the order
1266
+ * **Simplified Checkout Flow (3 steps):**
1267
+ * 1. Set shipping address (includes email): `setShippingAddress(id, { email, ...address })` - returns rates
1268
+ * 2. Select shipping method: `selectShippingMethod(id, rateId)`
1269
+ * 3. Pay with Stripe: `createPaymentIntent(id)` → `stripe.confirmPayment()` Order created automatically!
1270
+ *
1271
+ * **Note:** Order is created automatically via webhook when payment succeeds.
1272
+ * No need to call `completeCheckout()` - it happens automatically.
1272
1273
  *
1273
1274
  * **IMPORTANT: Price fields are strings**
1274
1275
  * All monetary fields (subtotal, discountAmount, shippingAmount, taxAmount, total)
@@ -1367,7 +1368,13 @@ interface SetCheckoutCustomerDto {
1367
1368
  phone?: string;
1368
1369
  acceptsMarketing?: boolean;
1369
1370
  }
1371
+ /**
1372
+ * Shipping address with customer email (required for checkout).
1373
+ * Email is included here to simplify the checkout flow - no need for separate setCheckoutCustomer call.
1374
+ */
1370
1375
  interface SetShippingAddressDto {
1376
+ /** Customer email (required) - used for order confirmation */
1377
+ email: string;
1371
1378
  firstName: string;
1372
1379
  lastName: string;
1373
1380
  company?: string;
@@ -1378,8 +1385,23 @@ interface SetShippingAddressDto {
1378
1385
  postalCode: string;
1379
1386
  country: string;
1380
1387
  phone?: string;
1388
+ /** Whether customer accepts marketing emails */
1389
+ acceptsMarketing?: boolean;
1381
1390
  }
1382
- interface SetBillingAddressDto extends SetShippingAddressDto {
1391
+ /**
1392
+ * Billing address (email not required - already set in shipping address)
1393
+ */
1394
+ interface SetBillingAddressDto {
1395
+ firstName: string;
1396
+ lastName: string;
1397
+ company?: string;
1398
+ line1: string;
1399
+ line2?: string;
1400
+ city: string;
1401
+ region?: string;
1402
+ postalCode: string;
1403
+ country: string;
1404
+ phone?: string;
1383
1405
  sameAsShipping?: boolean;
1384
1406
  }
1385
1407
  interface SelectShippingMethodDto {
@@ -1774,6 +1796,46 @@ interface PaymentStatus {
1774
1796
  /** Payment intent ID from provider */
1775
1797
  paymentIntentId?: string;
1776
1798
  }
1799
+ /**
1800
+ * Options for waitForOrder method.
1801
+ * Used when polling for order creation after payment.
1802
+ */
1803
+ interface WaitForOrderOptions {
1804
+ /**
1805
+ * Maximum time to wait in milliseconds.
1806
+ * Default: 30000 (30 seconds)
1807
+ */
1808
+ maxWaitMs?: number;
1809
+ /**
1810
+ * Initial delay between polls in milliseconds.
1811
+ * Uses exponential backoff: 1s → 2s → 4s → 8s...
1812
+ * Default: 1000 (1 second)
1813
+ */
1814
+ initialDelayMs?: number;
1815
+ /**
1816
+ * Callback fired when order is ready.
1817
+ * Useful for updating UI without awaiting the full promise.
1818
+ */
1819
+ onOrderReady?: (status: PaymentStatus) => void;
1820
+ /**
1821
+ * Callback fired on each poll attempt.
1822
+ * Useful for showing loading progress.
1823
+ */
1824
+ onPollAttempt?: (attempt: number, status: PaymentStatus) => void;
1825
+ }
1826
+ /**
1827
+ * Result from waitForOrder method.
1828
+ */
1829
+ interface WaitForOrderResult {
1830
+ /** Whether the order was created within the timeout */
1831
+ success: boolean;
1832
+ /** Final payment status */
1833
+ status: PaymentStatus;
1834
+ /** Number of poll attempts made */
1835
+ attempts: number;
1836
+ /** Total time waited in milliseconds */
1837
+ waitedMs: number;
1838
+ }
1777
1839
  /**
1778
1840
  * When inventory is reserved for customers.
1779
1841
  * Configured per vibe-coded connection by the store owner.
@@ -2965,12 +3027,16 @@ declare class OmniSyncClient {
2965
3027
  */
2966
3028
  setCheckoutCustomer(checkoutId: string, data: SetCheckoutCustomerDto): Promise<Checkout>;
2967
3029
  /**
2968
- * Set shipping address on checkout
2969
- * Returns the checkout and available shipping rates for the address
3030
+ * Set shipping address on checkout (includes customer email).
3031
+ * Returns the checkout and available shipping rates for the address.
3032
+ *
3033
+ * **This is the first step of the simplified checkout flow.**
3034
+ * Email is required and will be used for order confirmation.
2970
3035
  *
2971
3036
  * @example
2972
3037
  * ```typescript
2973
3038
  * const { checkout, rates } = await omni.setShippingAddress('checkout_123', {
3039
+ * email: 'customer@example.com', // Required!
2974
3040
  * firstName: 'John',
2975
3041
  * lastName: 'Doe',
2976
3042
  * line1: '123 Main St',
@@ -3161,6 +3227,61 @@ declare class OmniSyncClient {
3161
3227
  * ```
3162
3228
  */
3163
3229
  getPaymentStatus(checkoutId: string): Promise<PaymentStatus>;
3230
+ /**
3231
+ * Wait for order creation after payment.
3232
+ *
3233
+ * **Important:** This is an optional utility for SPA apps that want to update the UI
3234
+ * when the order is ready. For most use cases, you should show a success message
3235
+ * immediately after payment and let the customer check their email or orders page.
3236
+ *
3237
+ * **Best Practice (Optimistic Success Page):**
3238
+ * ```typescript
3239
+ * // After stripe.confirmPayment() succeeds, redirect to success page immediately
3240
+ * // Don't wait for orderId - show confirmation with checkoutId
3241
+ * window.location.href = `/checkout/success?checkout_id=${checkoutId}`;
3242
+ *
3243
+ * // On success page, show "Payment received!" immediately
3244
+ * // The order confirmation email will be sent automatically
3245
+ * ```
3246
+ *
3247
+ * **When to use waitForOrder:**
3248
+ * - SPA apps that want to show the order number without page reload
3249
+ * - Apps that need the orderId for analytics or tracking
3250
+ *
3251
+ * **Vibe-coded mode only** - requires connectionId
3252
+ *
3253
+ * @param checkoutId - The checkout ID to wait for order creation
3254
+ * @param options - Polling options (maxWaitMs, initialDelayMs, callbacks)
3255
+ * @returns Result with success status, final payment status, and timing info
3256
+ *
3257
+ * @example
3258
+ * ```typescript
3259
+ * // Basic usage - wait up to 30 seconds
3260
+ * const result = await omni.waitForOrder(checkoutId);
3261
+ *
3262
+ * if (result.success) {
3263
+ * console.log('Order created:', result.status.orderNumber);
3264
+ * } else {
3265
+ * // Order not created yet - show success message anyway
3266
+ * console.log('Payment received, order is being processed...');
3267
+ * }
3268
+ * ```
3269
+ *
3270
+ * @example
3271
+ * ```typescript
3272
+ * // With progress callback for UI updates
3273
+ * const result = await omni.waitForOrder(checkoutId, {
3274
+ * maxWaitMs: 20000,
3275
+ * onPollAttempt: (attempt, status) => {
3276
+ * setLoadingMessage(`Confirming order... (attempt ${attempt})`);
3277
+ * },
3278
+ * onOrderReady: (status) => {
3279
+ * toast.success(`Order ${status.orderNumber} confirmed!`);
3280
+ * },
3281
+ * });
3282
+ * ```
3283
+ */
3284
+ waitForOrder(checkoutId: string, options?: WaitForOrderOptions): Promise<WaitForOrderResult>;
3164
3285
  private readonly LOCAL_CART_KEY;
3165
3286
  /**
3166
3287
  * Check if localStorage is available (browser environment)
@@ -3628,4 +3749,4 @@ declare function isWebhookEventType(event: WebhookEvent, type: WebhookEventType)
3628
3749
  */
3629
3750
  declare function createWebhookHandler(handlers: Partial<Record<WebhookEventType, (event: WebhookEvent) => Promise<void>>>): (payload: unknown) => Promise<void>;
3630
3751
 
3631
- export { type AddToCartDto, type AppliedDiscount, type ApplyCouponDto, type BulkInventoryResponse, type BulkSaveVariantsDto, type BulkSaveVariantsResponse, type BulkVariantInput, type Cart, type CartItem, type CartStatus, type CategorySuggestion, type Checkout, type CheckoutAddress, type CheckoutLineItem, type CheckoutStatus, type CompleteCheckoutResponse, type CompleteDraftDto, type ConnectorPlatform, type Coupon, type CouponCreateResponse, type CouponQueryParams, type CouponStatus, type CouponType, type CouponValidationWarning, type CreateAddressDto, type CreateCheckoutDto, type CreateCouponDto, type CreateCustomApiDto, type CreateCustomerDto, type CreateGuestOrderDto, type CreateOrderDto, type CreateProductDto, type CreateRefundDto, type CreateVariantDto, type CustomApiAuthType, type CustomApiConnectionStatus, type CustomApiCredentials, type CustomApiIntegration, type CustomApiSyncConfig, type CustomApiSyncDirection, type CustomApiTestResult, type Customer, type CustomerAddress, type CustomerAuthResponse, type CustomerOAuthProvider, type CustomerProfile, type CustomerQueryParams, type DraftLineItem, type EditInventoryDto, type EmailVerificationResponse, type FormatPriceOptions, type FulfillOrderDto, type GuestCheckoutStartResponse, type GuestOrderResponse, type InsufficientStockError, type InventoryInfo, type InventorySyncStatus, type LocalCart, type LocalCartItem, type MergeCartsDto, type OAuthAuthorizeResponse, type OAuthCallbackResponse, type OAuthConnection, type OAuthConnectionsResponse, type OAuthProvidersResponse, type OmniSyncApiError, OmniSyncClient, type OmniSyncClientOptions, OmniSyncError, type Order, type OrderAddress, type OrderCustomer, type OrderItem, type OrderQueryParams, type OrderStatus, type PaginatedResponse, type PaymentConfig, type PaymentIntent, type PaymentProviderConfig, type PaymentProvidersConfig, type PaymentStatus, type PlatformCouponCapabilities, type Product, type ProductAttributeInput, type ProductImage, type ProductQueryParams, type ProductSuggestion, type ProductVariant, type PublishProductResponse, type ReconcileInventoryResponse, type Refund, type RefundLineItem, type RefundLineItemResponse, type RefundType, type RegisterCustomerDto, type SearchSuggestions, type SelectShippingMethodDto, type SendInvoiceDto, type SetBillingAddressDto, type SetCheckoutCustomerDto, type SetShippingAddressDto, type SetShippingAddressResponse, type ShippingLine, type ShippingRate, type StockAvailabilityRequest, type StockAvailabilityResponse, type StockAvailabilityResult, type StoreInfo, type SyncJob, type UpdateAddressDto, type UpdateCartItemDto, type UpdateCouponDto, type UpdateCustomApiDto, type UpdateCustomerDto, type UpdateDraftDto, type UpdateInventoryDto, type UpdateOrderDto, type UpdateOrderShippingDto, type UpdateProductDto, type UpdateVariantDto, type UpdateVariantInventoryDto, type VariantInventoryResponse, type VariantPlatformOverlay, type VariantStatus, type WebhookEvent, type WebhookEventType, createWebhookHandler, formatPrice, getDescriptionContent, getStockStatus, isCouponApplicableToProduct, isHtmlDescription, isWebhookEventType, parseWebhookEvent, verifyWebhook };
3752
+ export { type AddToCartDto, type AppliedDiscount, type ApplyCouponDto, type BulkInventoryResponse, type BulkSaveVariantsDto, type BulkSaveVariantsResponse, type BulkVariantInput, type Cart, type CartItem, type CartStatus, type CategorySuggestion, type Checkout, type CheckoutAddress, type CheckoutLineItem, type CheckoutStatus, type CompleteCheckoutResponse, type CompleteDraftDto, type ConnectorPlatform, type Coupon, type CouponCreateResponse, type CouponQueryParams, type CouponStatus, type CouponType, type CouponValidationWarning, type CreateAddressDto, type CreateCheckoutDto, type CreateCouponDto, type CreateCustomApiDto, type CreateCustomerDto, type CreateGuestOrderDto, type CreateOrderDto, type CreateProductDto, type CreateRefundDto, type CreateVariantDto, type CustomApiAuthType, type CustomApiConnectionStatus, type CustomApiCredentials, type CustomApiIntegration, type CustomApiSyncConfig, type CustomApiSyncDirection, type CustomApiTestResult, type Customer, type CustomerAddress, type CustomerAuthResponse, type CustomerOAuthProvider, type CustomerProfile, type CustomerQueryParams, type DraftLineItem, type EditInventoryDto, type EmailVerificationResponse, type FormatPriceOptions, type FulfillOrderDto, type GuestCheckoutStartResponse, type GuestOrderResponse, type InsufficientStockError, type InventoryInfo, type InventorySyncStatus, type LocalCart, type LocalCartItem, type MergeCartsDto, type OAuthAuthorizeResponse, type OAuthCallbackResponse, type OAuthConnection, type OAuthConnectionsResponse, type OAuthProvidersResponse, type OmniSyncApiError, OmniSyncClient, type OmniSyncClientOptions, OmniSyncError, type Order, type OrderAddress, type OrderCustomer, type OrderItem, type OrderQueryParams, type OrderStatus, type PaginatedResponse, type PaymentConfig, type PaymentIntent, type PaymentProviderConfig, type PaymentProvidersConfig, type PaymentStatus, type PlatformCouponCapabilities, type Product, type ProductAttributeInput, type ProductImage, type ProductQueryParams, type ProductSuggestion, type ProductVariant, type PublishProductResponse, type ReconcileInventoryResponse, type Refund, type RefundLineItem, type RefundLineItemResponse, type RefundType, type RegisterCustomerDto, type SearchSuggestions, type SelectShippingMethodDto, type SendInvoiceDto, type SetBillingAddressDto, type SetCheckoutCustomerDto, type SetShippingAddressDto, type SetShippingAddressResponse, type ShippingLine, type ShippingRate, type StockAvailabilityRequest, type StockAvailabilityResponse, type StockAvailabilityResult, type StoreInfo, type SyncJob, type UpdateAddressDto, type UpdateCartItemDto, type UpdateCouponDto, type UpdateCustomApiDto, type UpdateCustomerDto, type UpdateDraftDto, type UpdateInventoryDto, type UpdateOrderDto, type UpdateOrderShippingDto, type UpdateProductDto, type UpdateVariantDto, type UpdateVariantInventoryDto, type VariantInventoryResponse, type VariantPlatformOverlay, type VariantStatus, type WaitForOrderOptions, type WaitForOrderResult, type WebhookEvent, type WebhookEventType, createWebhookHandler, formatPrice, getDescriptionContent, formatPrice as getPriceDisplay, getStockStatus, isCouponApplicableToProduct, isHtmlDescription, isWebhookEventType, parseWebhookEvent, verifyWebhook };
package/dist/index.d.ts CHANGED
@@ -1263,12 +1263,13 @@ interface ShippingRate {
1263
1263
  /**
1264
1264
  * Represents a checkout session for completing a purchase.
1265
1265
  *
1266
- * **Checkout Flow:**
1267
- * 1. Create checkout from cart: `createCheckout({ cartId })`
1268
- * 2. Set customer info: `setCheckoutCustomer(id, { email, ... })`
1269
- * 3. Set shipping address: `setShippingAddress(id, address)` - returns available rates
1270
- * 4. Select shipping method: `selectShippingMethod(id, rateId)`
1271
- * 5. Complete checkout: `completeCheckout(id)` - creates the order
1266
+ * **Simplified Checkout Flow (3 steps):**
1267
+ * 1. Set shipping address (includes email): `setShippingAddress(id, { email, ...address })` - returns rates
1268
+ * 2. Select shipping method: `selectShippingMethod(id, rateId)`
1269
+ * 3. Pay with Stripe: `createPaymentIntent(id)` → `stripe.confirmPayment()` Order created automatically!
1270
+ *
1271
+ * **Note:** Order is created automatically via webhook when payment succeeds.
1272
+ * No need to call `completeCheckout()` - it happens automatically.
1272
1273
  *
1273
1274
  * **IMPORTANT: Price fields are strings**
1274
1275
  * All monetary fields (subtotal, discountAmount, shippingAmount, taxAmount, total)
@@ -1367,7 +1368,13 @@ interface SetCheckoutCustomerDto {
1367
1368
  phone?: string;
1368
1369
  acceptsMarketing?: boolean;
1369
1370
  }
1371
+ /**
1372
+ * Shipping address with customer email (required for checkout).
1373
+ * Email is included here to simplify the checkout flow - no need for separate setCheckoutCustomer call.
1374
+ */
1370
1375
  interface SetShippingAddressDto {
1376
+ /** Customer email (required) - used for order confirmation */
1377
+ email: string;
1371
1378
  firstName: string;
1372
1379
  lastName: string;
1373
1380
  company?: string;
@@ -1378,8 +1385,23 @@ interface SetShippingAddressDto {
1378
1385
  postalCode: string;
1379
1386
  country: string;
1380
1387
  phone?: string;
1388
+ /** Whether customer accepts marketing emails */
1389
+ acceptsMarketing?: boolean;
1381
1390
  }
1382
- interface SetBillingAddressDto extends SetShippingAddressDto {
1391
+ /**
1392
+ * Billing address (email not required - already set in shipping address)
1393
+ */
1394
+ interface SetBillingAddressDto {
1395
+ firstName: string;
1396
+ lastName: string;
1397
+ company?: string;
1398
+ line1: string;
1399
+ line2?: string;
1400
+ city: string;
1401
+ region?: string;
1402
+ postalCode: string;
1403
+ country: string;
1404
+ phone?: string;
1383
1405
  sameAsShipping?: boolean;
1384
1406
  }
1385
1407
  interface SelectShippingMethodDto {
@@ -1774,6 +1796,46 @@ interface PaymentStatus {
1774
1796
  /** Payment intent ID from provider */
1775
1797
  paymentIntentId?: string;
1776
1798
  }
1799
+ /**
1800
+ * Options for waitForOrder method.
1801
+ * Used when polling for order creation after payment.
1802
+ */
1803
+ interface WaitForOrderOptions {
1804
+ /**
1805
+ * Maximum time to wait in milliseconds.
1806
+ * Default: 30000 (30 seconds)
1807
+ */
1808
+ maxWaitMs?: number;
1809
+ /**
1810
+ * Initial delay between polls in milliseconds.
1811
+ * Uses exponential backoff: 1s → 2s → 4s → 8s...
1812
+ * Default: 1000 (1 second)
1813
+ */
1814
+ initialDelayMs?: number;
1815
+ /**
1816
+ * Callback fired when order is ready.
1817
+ * Useful for updating UI without awaiting the full promise.
1818
+ */
1819
+ onOrderReady?: (status: PaymentStatus) => void;
1820
+ /**
1821
+ * Callback fired on each poll attempt.
1822
+ * Useful for showing loading progress.
1823
+ */
1824
+ onPollAttempt?: (attempt: number, status: PaymentStatus) => void;
1825
+ }
1826
+ /**
1827
+ * Result from waitForOrder method.
1828
+ */
1829
+ interface WaitForOrderResult {
1830
+ /** Whether the order was created within the timeout */
1831
+ success: boolean;
1832
+ /** Final payment status */
1833
+ status: PaymentStatus;
1834
+ /** Number of poll attempts made */
1835
+ attempts: number;
1836
+ /** Total time waited in milliseconds */
1837
+ waitedMs: number;
1838
+ }
1777
1839
  /**
1778
1840
  * When inventory is reserved for customers.
1779
1841
  * Configured per vibe-coded connection by the store owner.
@@ -2965,12 +3027,16 @@ declare class OmniSyncClient {
2965
3027
  */
2966
3028
  setCheckoutCustomer(checkoutId: string, data: SetCheckoutCustomerDto): Promise<Checkout>;
2967
3029
  /**
2968
- * Set shipping address on checkout
2969
- * Returns the checkout and available shipping rates for the address
3030
+ * Set shipping address on checkout (includes customer email).
3031
+ * Returns the checkout and available shipping rates for the address.
3032
+ *
3033
+ * **This is the first step of the simplified checkout flow.**
3034
+ * Email is required and will be used for order confirmation.
2970
3035
  *
2971
3036
  * @example
2972
3037
  * ```typescript
2973
3038
  * const { checkout, rates } = await omni.setShippingAddress('checkout_123', {
3039
+ * email: 'customer@example.com', // Required!
2974
3040
  * firstName: 'John',
2975
3041
  * lastName: 'Doe',
2976
3042
  * line1: '123 Main St',
@@ -3161,6 +3227,61 @@ declare class OmniSyncClient {
3161
3227
  * ```
3162
3228
  */
3163
3229
  getPaymentStatus(checkoutId: string): Promise<PaymentStatus>;
3230
+ /**
3231
+ * Wait for order creation after payment.
3232
+ *
3233
+ * **Important:** This is an optional utility for SPA apps that want to update the UI
3234
+ * when the order is ready. For most use cases, you should show a success message
3235
+ * immediately after payment and let the customer check their email or orders page.
3236
+ *
3237
+ * **Best Practice (Optimistic Success Page):**
3238
+ * ```typescript
3239
+ * // After stripe.confirmPayment() succeeds, redirect to success page immediately
3240
+ * // Don't wait for orderId - show confirmation with checkoutId
3241
+ * window.location.href = `/checkout/success?checkout_id=${checkoutId}`;
3242
+ *
3243
+ * // On success page, show "Payment received!" immediately
3244
+ * // The order confirmation email will be sent automatically
3245
+ * ```
3246
+ *
3247
+ * **When to use waitForOrder:**
3248
+ * - SPA apps that want to show the order number without page reload
3249
+ * - Apps that need the orderId for analytics or tracking
3250
+ *
3251
+ * **Vibe-coded mode only** - requires connectionId
3252
+ *
3253
+ * @param checkoutId - The checkout ID to wait for order creation
3254
+ * @param options - Polling options (maxWaitMs, initialDelayMs, callbacks)
3255
+ * @returns Result with success status, final payment status, and timing info
3256
+ *
3257
+ * @example
3258
+ * ```typescript
3259
+ * // Basic usage - wait up to 30 seconds
3260
+ * const result = await omni.waitForOrder(checkoutId);
3261
+ *
3262
+ * if (result.success) {
3263
+ * console.log('Order created:', result.status.orderNumber);
3264
+ * } else {
3265
+ * // Order not created yet - show success message anyway
3266
+ * console.log('Payment received, order is being processed...');
3267
+ * }
3268
+ * ```
3269
+ *
3270
+ * @example
3271
+ * ```typescript
3272
+ * // With progress callback for UI updates
3273
+ * const result = await omni.waitForOrder(checkoutId, {
3274
+ * maxWaitMs: 20000,
3275
+ * onPollAttempt: (attempt, status) => {
3276
+ * setLoadingMessage(`Confirming order... (attempt ${attempt})`);
3277
+ * },
3278
+ * onOrderReady: (status) => {
3279
+ * toast.success(`Order ${status.orderNumber} confirmed!`);
3280
+ * },
3281
+ * });
3282
+ * ```
3283
+ */
3284
+ waitForOrder(checkoutId: string, options?: WaitForOrderOptions): Promise<WaitForOrderResult>;
3164
3285
  private readonly LOCAL_CART_KEY;
3165
3286
  /**
3166
3287
  * Check if localStorage is available (browser environment)
@@ -3628,4 +3749,4 @@ declare function isWebhookEventType(event: WebhookEvent, type: WebhookEventType)
3628
3749
  */
3629
3750
  declare function createWebhookHandler(handlers: Partial<Record<WebhookEventType, (event: WebhookEvent) => Promise<void>>>): (payload: unknown) => Promise<void>;
3630
3751
 
3631
- export { type AddToCartDto, type AppliedDiscount, type ApplyCouponDto, type BulkInventoryResponse, type BulkSaveVariantsDto, type BulkSaveVariantsResponse, type BulkVariantInput, type Cart, type CartItem, type CartStatus, type CategorySuggestion, type Checkout, type CheckoutAddress, type CheckoutLineItem, type CheckoutStatus, type CompleteCheckoutResponse, type CompleteDraftDto, type ConnectorPlatform, type Coupon, type CouponCreateResponse, type CouponQueryParams, type CouponStatus, type CouponType, type CouponValidationWarning, type CreateAddressDto, type CreateCheckoutDto, type CreateCouponDto, type CreateCustomApiDto, type CreateCustomerDto, type CreateGuestOrderDto, type CreateOrderDto, type CreateProductDto, type CreateRefundDto, type CreateVariantDto, type CustomApiAuthType, type CustomApiConnectionStatus, type CustomApiCredentials, type CustomApiIntegration, type CustomApiSyncConfig, type CustomApiSyncDirection, type CustomApiTestResult, type Customer, type CustomerAddress, type CustomerAuthResponse, type CustomerOAuthProvider, type CustomerProfile, type CustomerQueryParams, type DraftLineItem, type EditInventoryDto, type EmailVerificationResponse, type FormatPriceOptions, type FulfillOrderDto, type GuestCheckoutStartResponse, type GuestOrderResponse, type InsufficientStockError, type InventoryInfo, type InventorySyncStatus, type LocalCart, type LocalCartItem, type MergeCartsDto, type OAuthAuthorizeResponse, type OAuthCallbackResponse, type OAuthConnection, type OAuthConnectionsResponse, type OAuthProvidersResponse, type OmniSyncApiError, OmniSyncClient, type OmniSyncClientOptions, OmniSyncError, type Order, type OrderAddress, type OrderCustomer, type OrderItem, type OrderQueryParams, type OrderStatus, type PaginatedResponse, type PaymentConfig, type PaymentIntent, type PaymentProviderConfig, type PaymentProvidersConfig, type PaymentStatus, type PlatformCouponCapabilities, type Product, type ProductAttributeInput, type ProductImage, type ProductQueryParams, type ProductSuggestion, type ProductVariant, type PublishProductResponse, type ReconcileInventoryResponse, type Refund, type RefundLineItem, type RefundLineItemResponse, type RefundType, type RegisterCustomerDto, type SearchSuggestions, type SelectShippingMethodDto, type SendInvoiceDto, type SetBillingAddressDto, type SetCheckoutCustomerDto, type SetShippingAddressDto, type SetShippingAddressResponse, type ShippingLine, type ShippingRate, type StockAvailabilityRequest, type StockAvailabilityResponse, type StockAvailabilityResult, type StoreInfo, type SyncJob, type UpdateAddressDto, type UpdateCartItemDto, type UpdateCouponDto, type UpdateCustomApiDto, type UpdateCustomerDto, type UpdateDraftDto, type UpdateInventoryDto, type UpdateOrderDto, type UpdateOrderShippingDto, type UpdateProductDto, type UpdateVariantDto, type UpdateVariantInventoryDto, type VariantInventoryResponse, type VariantPlatformOverlay, type VariantStatus, type WebhookEvent, type WebhookEventType, createWebhookHandler, formatPrice, getDescriptionContent, getStockStatus, isCouponApplicableToProduct, isHtmlDescription, isWebhookEventType, parseWebhookEvent, verifyWebhook };
3752
+ export { type AddToCartDto, type AppliedDiscount, type ApplyCouponDto, type BulkInventoryResponse, type BulkSaveVariantsDto, type BulkSaveVariantsResponse, type BulkVariantInput, type Cart, type CartItem, type CartStatus, type CategorySuggestion, type Checkout, type CheckoutAddress, type CheckoutLineItem, type CheckoutStatus, type CompleteCheckoutResponse, type CompleteDraftDto, type ConnectorPlatform, type Coupon, type CouponCreateResponse, type CouponQueryParams, type CouponStatus, type CouponType, type CouponValidationWarning, type CreateAddressDto, type CreateCheckoutDto, type CreateCouponDto, type CreateCustomApiDto, type CreateCustomerDto, type CreateGuestOrderDto, type CreateOrderDto, type CreateProductDto, type CreateRefundDto, type CreateVariantDto, type CustomApiAuthType, type CustomApiConnectionStatus, type CustomApiCredentials, type CustomApiIntegration, type CustomApiSyncConfig, type CustomApiSyncDirection, type CustomApiTestResult, type Customer, type CustomerAddress, type CustomerAuthResponse, type CustomerOAuthProvider, type CustomerProfile, type CustomerQueryParams, type DraftLineItem, type EditInventoryDto, type EmailVerificationResponse, type FormatPriceOptions, type FulfillOrderDto, type GuestCheckoutStartResponse, type GuestOrderResponse, type InsufficientStockError, type InventoryInfo, type InventorySyncStatus, type LocalCart, type LocalCartItem, type MergeCartsDto, type OAuthAuthorizeResponse, type OAuthCallbackResponse, type OAuthConnection, type OAuthConnectionsResponse, type OAuthProvidersResponse, type OmniSyncApiError, OmniSyncClient, type OmniSyncClientOptions, OmniSyncError, type Order, type OrderAddress, type OrderCustomer, type OrderItem, type OrderQueryParams, type OrderStatus, type PaginatedResponse, type PaymentConfig, type PaymentIntent, type PaymentProviderConfig, type PaymentProvidersConfig, type PaymentStatus, type PlatformCouponCapabilities, type Product, type ProductAttributeInput, type ProductImage, type ProductQueryParams, type ProductSuggestion, type ProductVariant, type PublishProductResponse, type ReconcileInventoryResponse, type Refund, type RefundLineItem, type RefundLineItemResponse, type RefundType, type RegisterCustomerDto, type SearchSuggestions, type SelectShippingMethodDto, type SendInvoiceDto, type SetBillingAddressDto, type SetCheckoutCustomerDto, type SetShippingAddressDto, type SetShippingAddressResponse, type ShippingLine, type ShippingRate, type StockAvailabilityRequest, type StockAvailabilityResponse, type StockAvailabilityResult, type StoreInfo, type SyncJob, type UpdateAddressDto, type UpdateCartItemDto, type UpdateCouponDto, type UpdateCustomApiDto, type UpdateCustomerDto, type UpdateDraftDto, type UpdateInventoryDto, type UpdateOrderDto, type UpdateOrderShippingDto, type UpdateProductDto, type UpdateVariantDto, type UpdateVariantInventoryDto, type VariantInventoryResponse, type VariantPlatformOverlay, type VariantStatus, type WaitForOrderOptions, type WaitForOrderResult, type WebhookEvent, type WebhookEventType, createWebhookHandler, formatPrice, getDescriptionContent, formatPrice as getPriceDisplay, getStockStatus, isCouponApplicableToProduct, isHtmlDescription, isWebhookEventType, parseWebhookEvent, verifyWebhook };
package/dist/index.js CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  createWebhookHandler: () => createWebhookHandler,
26
26
  formatPrice: () => formatPrice,
27
27
  getDescriptionContent: () => getDescriptionContent,
28
+ getPriceDisplay: () => formatPrice,
28
29
  getStockStatus: () => getStockStatus,
29
30
  isCouponApplicableToProduct: () => isCouponApplicableToProduct,
30
31
  isHtmlDescription: () => isHtmlDescription,
@@ -1897,12 +1898,16 @@ var OmniSyncClient = class {
1897
1898
  return this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/customer`, data);
1898
1899
  }
1899
1900
  /**
1900
- * Set shipping address on checkout
1901
- * Returns the checkout and available shipping rates for the address
1901
+ * Set shipping address on checkout (includes customer email).
1902
+ * Returns the checkout and available shipping rates for the address.
1903
+ *
1904
+ * **This is the first step of the simplified checkout flow.**
1905
+ * Email is required and will be used for order confirmation.
1902
1906
  *
1903
1907
  * @example
1904
1908
  * ```typescript
1905
1909
  * const { checkout, rates } = await omni.setShippingAddress('checkout_123', {
1910
+ * email: 'customer@example.com', // Required!
1906
1911
  * firstName: 'John',
1907
1912
  * lastName: 'Doe',
1908
1913
  * line1: '123 Main St',
@@ -2215,6 +2220,109 @@ var OmniSyncClient = class {
2215
2220
  }
2216
2221
  return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/payment-status`);
2217
2222
  }
2223
+ /**
2224
+ * Wait for order creation after payment.
2225
+ *
2226
+ * **Important:** This is an optional utility for SPA apps that want to update the UI
2227
+ * when the order is ready. For most use cases, you should show a success message
2228
+ * immediately after payment and let the customer check their email or orders page.
2229
+ *
2230
+ * **Best Practice (Optimistic Success Page):**
2231
+ * ```typescript
2232
+ * // After stripe.confirmPayment() succeeds, redirect to success page immediately
2233
+ * // Don't wait for orderId - show confirmation with checkoutId
2234
+ * window.location.href = `/checkout/success?checkout_id=${checkoutId}`;
2235
+ *
2236
+ * // On success page, show "Payment received!" immediately
2237
+ * // The order confirmation email will be sent automatically
2238
+ * ```
2239
+ *
2240
+ * **When to use waitForOrder:**
2241
+ * - SPA apps that want to show the order number without page reload
2242
+ * - Apps that need the orderId for analytics or tracking
2243
+ *
2244
+ * **Vibe-coded mode only** - requires connectionId
2245
+ *
2246
+ * @param checkoutId - The checkout ID to wait for order creation
2247
+ * @param options - Polling options (maxWaitMs, initialDelayMs, callbacks)
2248
+ * @returns Result with success status, final payment status, and timing info
2249
+ *
2250
+ * @example
2251
+ * ```typescript
2252
+ * // Basic usage - wait up to 30 seconds
2253
+ * const result = await omni.waitForOrder(checkoutId);
2254
+ *
2255
+ * if (result.success) {
2256
+ * console.log('Order created:', result.status.orderNumber);
2257
+ * } else {
2258
+ * // Order not created yet - show success message anyway
2259
+ * console.log('Payment received, order is being processed...');
2260
+ * }
2261
+ * ```
2262
+ *
2263
+ * @example
2264
+ * ```typescript
2265
+ * // With progress callback for UI updates
2266
+ * const result = await omni.waitForOrder(checkoutId, {
2267
+ * maxWaitMs: 20000,
2268
+ * onPollAttempt: (attempt, status) => {
2269
+ * setLoadingMessage(`Confirming order... (attempt ${attempt})`);
2270
+ * },
2271
+ * onOrderReady: (status) => {
2272
+ * toast.success(`Order ${status.orderNumber} confirmed!`);
2273
+ * },
2274
+ * });
2275
+ * ```
2276
+ */
2277
+ async waitForOrder(checkoutId, options) {
2278
+ if (!this.isVibeCodedMode()) {
2279
+ throw new OmniSyncError(
2280
+ "waitForOrder is only available in vibe-coded mode (use connectionId)",
2281
+ 400
2282
+ );
2283
+ }
2284
+ const maxWaitMs = options?.maxWaitMs ?? 3e4;
2285
+ const initialDelayMs = options?.initialDelayMs ?? 1e3;
2286
+ const startTime = Date.now();
2287
+ let attempts = 0;
2288
+ let currentDelay = initialDelayMs;
2289
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2290
+ while (Date.now() - startTime < maxWaitMs) {
2291
+ attempts++;
2292
+ const status = await this.getPaymentStatus(checkoutId);
2293
+ options?.onPollAttempt?.(attempts, status);
2294
+ if (status.status === "failed" || status.status === "canceled") {
2295
+ return {
2296
+ success: false,
2297
+ status,
2298
+ attempts,
2299
+ waitedMs: Date.now() - startTime
2300
+ };
2301
+ }
2302
+ if (status.status === "succeeded" && status.orderId) {
2303
+ options?.onOrderReady?.(status);
2304
+ return {
2305
+ success: true,
2306
+ status,
2307
+ attempts,
2308
+ waitedMs: Date.now() - startTime
2309
+ };
2310
+ }
2311
+ const remainingTime = maxWaitMs - (Date.now() - startTime);
2312
+ const sleepTime = Math.min(currentDelay, remainingTime, 8e3);
2313
+ if (sleepTime > 0) {
2314
+ await sleep(sleepTime);
2315
+ currentDelay = Math.min(currentDelay * 2, 8e3);
2316
+ }
2317
+ }
2318
+ const finalStatus = await this.getPaymentStatus(checkoutId);
2319
+ return {
2320
+ success: finalStatus.status === "succeeded" && !!finalStatus.orderId,
2321
+ status: finalStatus,
2322
+ attempts,
2323
+ waitedMs: Date.now() - startTime
2324
+ };
2325
+ }
2218
2326
  /**
2219
2327
  * Check if localStorage is available (browser environment)
2220
2328
  */
@@ -2449,7 +2557,11 @@ var OmniSyncClient = class {
2449
2557
  const trackingResult = await this.startGuestCheckout();
2450
2558
  if (trackingResult.tracked) {
2451
2559
  await this.updateGuestCheckoutAddress(trackingResult.checkoutId, {
2452
- shippingAddress: cart.shippingAddress,
2560
+ shippingAddress: {
2561
+ ...cart.shippingAddress,
2562
+ email: cart.customer.email
2563
+ // Already validated above
2564
+ },
2453
2565
  billingAddress: cart.billingAddress
2454
2566
  });
2455
2567
  const orderResult = await this.completeGuestCheckout(trackingResult.checkoutId, {
@@ -3110,6 +3222,7 @@ function isCouponApplicableToProduct(coupon, productId, productCategoryIds) {
3110
3222
  createWebhookHandler,
3111
3223
  formatPrice,
3112
3224
  getDescriptionContent,
3225
+ getPriceDisplay,
3113
3226
  getStockStatus,
3114
3227
  isCouponApplicableToProduct,
3115
3228
  isHtmlDescription,
package/dist/index.mjs CHANGED
@@ -1868,12 +1868,16 @@ var OmniSyncClient = class {
1868
1868
  return this.adminRequest("PATCH", `/api/v1/checkout/${checkoutId}/customer`, data);
1869
1869
  }
1870
1870
  /**
1871
- * Set shipping address on checkout
1872
- * Returns the checkout and available shipping rates for the address
1871
+ * Set shipping address on checkout (includes customer email).
1872
+ * Returns the checkout and available shipping rates for the address.
1873
+ *
1874
+ * **This is the first step of the simplified checkout flow.**
1875
+ * Email is required and will be used for order confirmation.
1873
1876
  *
1874
1877
  * @example
1875
1878
  * ```typescript
1876
1879
  * const { checkout, rates } = await omni.setShippingAddress('checkout_123', {
1880
+ * email: 'customer@example.com', // Required!
1877
1881
  * firstName: 'John',
1878
1882
  * lastName: 'Doe',
1879
1883
  * line1: '123 Main St',
@@ -2186,6 +2190,109 @@ var OmniSyncClient = class {
2186
2190
  }
2187
2191
  return this.vibeCodedRequest("GET", `/checkout/${checkoutId}/payment-status`);
2188
2192
  }
2193
+ /**
2194
+ * Wait for order creation after payment.
2195
+ *
2196
+ * **Important:** This is an optional utility for SPA apps that want to update the UI
2197
+ * when the order is ready. For most use cases, you should show a success message
2198
+ * immediately after payment and let the customer check their email or orders page.
2199
+ *
2200
+ * **Best Practice (Optimistic Success Page):**
2201
+ * ```typescript
2202
+ * // After stripe.confirmPayment() succeeds, redirect to success page immediately
2203
+ * // Don't wait for orderId - show confirmation with checkoutId
2204
+ * window.location.href = `/checkout/success?checkout_id=${checkoutId}`;
2205
+ *
2206
+ * // On success page, show "Payment received!" immediately
2207
+ * // The order confirmation email will be sent automatically
2208
+ * ```
2209
+ *
2210
+ * **When to use waitForOrder:**
2211
+ * - SPA apps that want to show the order number without page reload
2212
+ * - Apps that need the orderId for analytics or tracking
2213
+ *
2214
+ * **Vibe-coded mode only** - requires connectionId
2215
+ *
2216
+ * @param checkoutId - The checkout ID to wait for order creation
2217
+ * @param options - Polling options (maxWaitMs, initialDelayMs, callbacks)
2218
+ * @returns Result with success status, final payment status, and timing info
2219
+ *
2220
+ * @example
2221
+ * ```typescript
2222
+ * // Basic usage - wait up to 30 seconds
2223
+ * const result = await omni.waitForOrder(checkoutId);
2224
+ *
2225
+ * if (result.success) {
2226
+ * console.log('Order created:', result.status.orderNumber);
2227
+ * } else {
2228
+ * // Order not created yet - show success message anyway
2229
+ * console.log('Payment received, order is being processed...');
2230
+ * }
2231
+ * ```
2232
+ *
2233
+ * @example
2234
+ * ```typescript
2235
+ * // With progress callback for UI updates
2236
+ * const result = await omni.waitForOrder(checkoutId, {
2237
+ * maxWaitMs: 20000,
2238
+ * onPollAttempt: (attempt, status) => {
2239
+ * setLoadingMessage(`Confirming order... (attempt ${attempt})`);
2240
+ * },
2241
+ * onOrderReady: (status) => {
2242
+ * toast.success(`Order ${status.orderNumber} confirmed!`);
2243
+ * },
2244
+ * });
2245
+ * ```
2246
+ */
2247
+ async waitForOrder(checkoutId, options) {
2248
+ if (!this.isVibeCodedMode()) {
2249
+ throw new OmniSyncError(
2250
+ "waitForOrder is only available in vibe-coded mode (use connectionId)",
2251
+ 400
2252
+ );
2253
+ }
2254
+ const maxWaitMs = options?.maxWaitMs ?? 3e4;
2255
+ const initialDelayMs = options?.initialDelayMs ?? 1e3;
2256
+ const startTime = Date.now();
2257
+ let attempts = 0;
2258
+ let currentDelay = initialDelayMs;
2259
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2260
+ while (Date.now() - startTime < maxWaitMs) {
2261
+ attempts++;
2262
+ const status = await this.getPaymentStatus(checkoutId);
2263
+ options?.onPollAttempt?.(attempts, status);
2264
+ if (status.status === "failed" || status.status === "canceled") {
2265
+ return {
2266
+ success: false,
2267
+ status,
2268
+ attempts,
2269
+ waitedMs: Date.now() - startTime
2270
+ };
2271
+ }
2272
+ if (status.status === "succeeded" && status.orderId) {
2273
+ options?.onOrderReady?.(status);
2274
+ return {
2275
+ success: true,
2276
+ status,
2277
+ attempts,
2278
+ waitedMs: Date.now() - startTime
2279
+ };
2280
+ }
2281
+ const remainingTime = maxWaitMs - (Date.now() - startTime);
2282
+ const sleepTime = Math.min(currentDelay, remainingTime, 8e3);
2283
+ if (sleepTime > 0) {
2284
+ await sleep(sleepTime);
2285
+ currentDelay = Math.min(currentDelay * 2, 8e3);
2286
+ }
2287
+ }
2288
+ const finalStatus = await this.getPaymentStatus(checkoutId);
2289
+ return {
2290
+ success: finalStatus.status === "succeeded" && !!finalStatus.orderId,
2291
+ status: finalStatus,
2292
+ attempts,
2293
+ waitedMs: Date.now() - startTime
2294
+ };
2295
+ }
2189
2296
  /**
2190
2297
  * Check if localStorage is available (browser environment)
2191
2298
  */
@@ -2420,7 +2527,11 @@ var OmniSyncClient = class {
2420
2527
  const trackingResult = await this.startGuestCheckout();
2421
2528
  if (trackingResult.tracked) {
2422
2529
  await this.updateGuestCheckoutAddress(trackingResult.checkoutId, {
2423
- shippingAddress: cart.shippingAddress,
2530
+ shippingAddress: {
2531
+ ...cart.shippingAddress,
2532
+ email: cart.customer.email
2533
+ // Already validated above
2534
+ },
2424
2535
  billingAddress: cart.billingAddress
2425
2536
  });
2426
2537
  const orderResult = await this.completeGuestCheckout(trackingResult.checkoutId, {
@@ -3080,6 +3191,7 @@ export {
3080
3191
  createWebhookHandler,
3081
3192
  formatPrice,
3082
3193
  getDescriptionContent,
3194
+ formatPrice as getPriceDisplay,
3083
3195
  getStockStatus,
3084
3196
  isCouponApplicableToProduct,
3085
3197
  isHtmlDescription,
package/package.json CHANGED
@@ -1,76 +1,76 @@
1
- {
2
- "name": "omni-sync-sdk",
3
- "version": "0.14.3",
4
- "description": "Official SDK for building e-commerce storefronts with OmniSync Platform. Perfect for vibe-coded sites, AI-built stores (Cursor, Lovable, v0), and custom storefronts.",
5
- "main": "dist/index.js",
6
- "module": "dist/index.mjs",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "require": "./dist/index.js",
12
- "import": "./dist/index.mjs"
13
- }
14
- },
15
- "files": [
16
- "dist",
17
- "README.md"
18
- ],
19
- "scripts": {
20
- "build": "tsup src/index.ts --format cjs,esm --dts",
21
- "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
22
- "lint": "eslint \"src/**/*.ts\"",
23
- "test": "vitest run",
24
- "test:watch": "vitest",
25
- "prepublishOnly": "pnpm build"
26
- },
27
- "keywords": [
28
- "omni-sync",
29
- "e-commerce",
30
- "ecommerce",
31
- "sdk",
32
- "vibe-coding",
33
- "vibe-coded",
34
- "ai-commerce",
35
- "storefront",
36
- "headless-commerce",
37
- "multi-platform",
38
- "shopify",
39
- "tiktok",
40
- "cursor",
41
- "lovable",
42
- "v0",
43
- "cart",
44
- "checkout",
45
- "products",
46
- "sync"
47
- ],
48
- "author": "Omni-Sync Platform",
49
- "license": "MIT",
50
- "repository": {
51
- "type": "git",
52
- "url": "https://github.com/omni-sync/omni-sync-platform.git",
53
- "directory": "packages/sdk"
54
- },
55
- "homepage": "https://omni-sync.com",
56
- "bugs": {
57
- "url": "https://github.com/omni-sync/omni-sync-platform/issues"
58
- },
59
- "devDependencies": {
60
- "@types/node": "^25.0.3",
61
- "@typescript-eslint/eslint-plugin": "^8.50.1",
62
- "@typescript-eslint/parser": "^8.50.1",
63
- "eslint": "^9.39.2",
64
- "tsup": "^8.0.0",
65
- "typescript": "^5.3.0",
66
- "vitest": "^1.0.0"
67
- },
68
- "peerDependencies": {
69
- "typescript": ">=4.7.0"
70
- },
71
- "peerDependenciesMeta": {
72
- "typescript": {
73
- "optional": true
74
- }
75
- }
76
- }
1
+ {
2
+ "name": "omni-sync-sdk",
3
+ "version": "0.16.0",
4
+ "description": "Official SDK for building e-commerce storefronts with OmniSync Platform. Perfect for vibe-coded sites, AI-built stores (Cursor, Lovable, v0), and custom storefronts.",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "require": "./dist/index.js",
12
+ "import": "./dist/index.mjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format cjs,esm --dts",
21
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
22
+ "lint": "eslint \"src/**/*.ts\"",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "prepublishOnly": "pnpm build"
26
+ },
27
+ "keywords": [
28
+ "omni-sync",
29
+ "e-commerce",
30
+ "ecommerce",
31
+ "sdk",
32
+ "vibe-coding",
33
+ "vibe-coded",
34
+ "ai-commerce",
35
+ "storefront",
36
+ "headless-commerce",
37
+ "multi-platform",
38
+ "shopify",
39
+ "tiktok",
40
+ "cursor",
41
+ "lovable",
42
+ "v0",
43
+ "cart",
44
+ "checkout",
45
+ "products",
46
+ "sync"
47
+ ],
48
+ "author": "Omni-Sync Platform",
49
+ "license": "MIT",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://github.com/omni-sync/omni-sync-platform.git",
53
+ "directory": "packages/sdk"
54
+ },
55
+ "homepage": "https://omni-sync.com",
56
+ "bugs": {
57
+ "url": "https://github.com/omni-sync/omni-sync-platform/issues"
58
+ },
59
+ "devDependencies": {
60
+ "@types/node": "^25.0.3",
61
+ "@typescript-eslint/eslint-plugin": "^8.50.1",
62
+ "@typescript-eslint/parser": "^8.50.1",
63
+ "eslint": "^9.39.2",
64
+ "tsup": "^8.0.0",
65
+ "typescript": "^5.3.0",
66
+ "vitest": "^1.0.0"
67
+ },
68
+ "peerDependencies": {
69
+ "typescript": ">=4.7.0"
70
+ },
71
+ "peerDependenciesMeta": {
72
+ "typescript": {
73
+ "optional": true
74
+ }
75
+ }
76
+ }