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 +114 -6
- package/dist/index.d.mts +131 -10
- package/dist/index.d.ts +131 -10
- package/dist/index.js +116 -3
- package/dist/index.mjs +115 -3
- package/package.json +76 -76
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
|
-
####
|
|
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
|
-
|
|
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
|
|
1364
|
-
// orderNumber: 'ORD-123', // Only if
|
|
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.
|
|
1268
|
-
* 2.
|
|
1269
|
-
* 3.
|
|
1270
|
-
*
|
|
1271
|
-
*
|
|
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
|
-
|
|
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.
|
|
1268
|
-
* 2.
|
|
1269
|
-
* 3.
|
|
1270
|
-
*
|
|
1271
|
-
*
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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.
|
|
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
|
+
}
|