omni-sync-sdk 0.21.8 → 0.22.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/AI_BUILDER_PROMPT.md +59 -15
- package/README.md +4379 -4270
- package/dist/index.d.mts +237 -31
- package/dist/index.d.ts +237 -31
- package/dist/index.js +230 -35
- package/dist/index.mjs +227 -35
- package/package.json +1 -1
package/AI_BUILDER_PROMPT.md
CHANGED
|
@@ -30,7 +30,7 @@ if (omni.isCustomerLoggedIn()) {
|
|
|
30
30
|
| **Guest** | localStorage | `startGuestCheckout()` | `result.checkoutId` |
|
|
31
31
|
| **Logged-in** | Server | `createCheckout({ cartId })` | `checkout.id` |
|
|
32
32
|
|
|
33
|
-
### Rule 2: Clear Cart After
|
|
33
|
+
### Rule 2: Complete Checkout & Clear Cart After Payment!
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
36
|
// On /checkout/success page - MUST DO THIS!
|
|
@@ -38,14 +38,21 @@ export default function CheckoutSuccessPage() {
|
|
|
38
38
|
const checkoutId = new URLSearchParams(window.location.search).get('checkout_id');
|
|
39
39
|
|
|
40
40
|
useEffect(() => {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
if (checkoutId) {
|
|
42
|
+
// ⚠️ CRITICAL: This sends the order to the server AND clears the cart!
|
|
43
|
+
// handlePaymentSuccess() only clears the local cart - it does NOT create the order!
|
|
44
|
+
omni.completeGuestCheckout(checkoutId);
|
|
45
|
+
}
|
|
43
46
|
}, []);
|
|
44
47
|
|
|
45
48
|
return <div>Thank you for your order!</div>;
|
|
46
49
|
}
|
|
47
50
|
```
|
|
48
51
|
|
|
52
|
+
> **WARNING:** Do NOT use `handlePaymentSuccess()` to complete an order. It only clears
|
|
53
|
+
> the local cart (localStorage) and does NOT communicate with the server.
|
|
54
|
+
> Always use `completeGuestCheckout()` after payment succeeds.
|
|
55
|
+
|
|
49
56
|
### Rule 3: Never Hardcode Products!
|
|
50
57
|
|
|
51
58
|
```typescript
|
|
@@ -193,7 +200,7 @@ const handleCheckout = async () => {
|
|
|
193
200
|
**Why this matters:**
|
|
194
201
|
|
|
195
202
|
- Users can buy some items now, leave others for later
|
|
196
|
-
- After payment, `
|
|
203
|
+
- After payment, `completeGuestCheckout()` sends the order and only removes purchased items
|
|
197
204
|
- Remaining items stay in cart for future purchase
|
|
198
205
|
|
|
199
206
|
**⚠️ Order Summary on Checkout Page - Use checkout.lineItems!**
|
|
@@ -323,7 +330,7 @@ if (error) {
|
|
|
323
330
|
// If no error, Stripe redirects to success page
|
|
324
331
|
```
|
|
325
332
|
|
|
326
|
-
### Step 5: Success Page (Clear Cart!)
|
|
333
|
+
### Step 5: Success Page (Complete Order & Clear Cart!)
|
|
327
334
|
|
|
328
335
|
```typescript
|
|
329
336
|
// /checkout/success/page.tsx
|
|
@@ -333,19 +340,25 @@ import { omni } from '@/lib/omni-sync';
|
|
|
333
340
|
|
|
334
341
|
export default function CheckoutSuccessPage() {
|
|
335
342
|
const [orderNumber, setOrderNumber] = useState<string>();
|
|
343
|
+
const [loading, setLoading] = useState(true);
|
|
336
344
|
|
|
337
345
|
useEffect(() => {
|
|
338
346
|
const checkoutId = new URLSearchParams(window.location.search).get('checkout_id');
|
|
339
347
|
|
|
340
|
-
// ⚠️ CRITICAL: Clear the cart!
|
|
341
|
-
omni.handlePaymentSuccess(checkoutId);
|
|
342
|
-
|
|
343
|
-
// Optional: Get order details
|
|
344
348
|
if (checkoutId) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
+
// ⚠️ CRITICAL: Complete the order on the server AND clear the cart!
|
|
350
|
+
// Do NOT use handlePaymentSuccess() - it only clears localStorage!
|
|
351
|
+
omni.completeGuestCheckout(checkoutId).then(result => {
|
|
352
|
+
setOrderNumber(result.orderNumber);
|
|
353
|
+
setLoading(false);
|
|
354
|
+
}).catch(() => {
|
|
355
|
+
// Order may already be completed (e.g., page refresh) - check status
|
|
356
|
+
omni.getPaymentStatus(checkoutId).then(status => {
|
|
357
|
+
if (status.orderNumber) {
|
|
358
|
+
setOrderNumber(status.orderNumber);
|
|
359
|
+
}
|
|
360
|
+
setLoading(false);
|
|
361
|
+
});
|
|
349
362
|
});
|
|
350
363
|
}
|
|
351
364
|
}, []);
|
|
@@ -353,6 +366,7 @@ export default function CheckoutSuccessPage() {
|
|
|
353
366
|
return (
|
|
354
367
|
<div className="text-center py-12">
|
|
355
368
|
<h1 className="text-2xl font-bold text-green-600">Thank you for your order!</h1>
|
|
369
|
+
{loading && <p className="mt-2">Processing your order...</p>}
|
|
356
370
|
{orderNumber && <p className="mt-2">Order #{orderNumber}</p>}
|
|
357
371
|
<p className="mt-4">A confirmation email will be sent shortly.</p>
|
|
358
372
|
</div>
|
|
@@ -372,7 +386,7 @@ const result = await omni.startGuestCheckout({
|
|
|
372
386
|
selectedIndices: [0, 2], // Buy items at index 0 and 2 only
|
|
373
387
|
});
|
|
374
388
|
|
|
375
|
-
// After payment,
|
|
389
|
+
// After payment, completeGuestCheckout() sends the order AND removes only those items!
|
|
376
390
|
// Other items stay in cart.
|
|
377
391
|
```
|
|
378
392
|
|
|
@@ -399,6 +413,34 @@ const suggestions = await omni.getSearchSuggestions('blue', 5);
|
|
|
399
413
|
|
|
400
414
|
---
|
|
401
415
|
|
|
416
|
+
## Product Custom Fields (Metafields)
|
|
417
|
+
|
|
418
|
+
Products may have custom fields defined by the store owner (e.g., "Material", "Care Instructions", "Warranty").
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
import { getProductMetafield, getProductMetafieldValue } from 'omni-sync-sdk';
|
|
422
|
+
|
|
423
|
+
// Access metafields on a product
|
|
424
|
+
const product = await omni.getProductBySlug('blue-shirt');
|
|
425
|
+
|
|
426
|
+
// Get all custom fields
|
|
427
|
+
product.metafields?.forEach((field) => {
|
|
428
|
+
console.log(`${field.definitionName}: ${field.value}`);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
// Get specific field by key
|
|
432
|
+
const material = getProductMetafieldValue(product, 'material');
|
|
433
|
+
const careInstructions = getProductMetafield(product, 'care_instructions');
|
|
434
|
+
|
|
435
|
+
// Get available metafield definitions (schema)
|
|
436
|
+
const { definitions } = await omni.getPublicMetafieldDefinitions();
|
|
437
|
+
// Use definitions to build dynamic UI (filters, forms, etc.)
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
> **Tip:** `metafields` may be empty if the store hasn't defined custom fields. Always use optional chaining.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
402
444
|
## Customer Authentication
|
|
403
445
|
|
|
404
446
|
```typescript
|
|
@@ -456,7 +498,7 @@ setCustomerToken(token);
|
|
|
456
498
|
- [ ] **Product Detail** (`/products/[slug]`) - Use `getProductBySlug(slug)`
|
|
457
499
|
- [ ] **Cart** (`/cart`) - Show items, quantities, totals
|
|
458
500
|
- [ ] **Checkout** (`/checkout`) - Address → Shipping → Payment
|
|
459
|
-
- [ ] **Success** (`/checkout/success`) - **Must call `
|
|
501
|
+
- [ ] **Success** (`/checkout/success`) - **Must call `completeGuestCheckout()`!**
|
|
460
502
|
- [ ] **Login** (`/login`) - Email/password + social buttons
|
|
461
503
|
- [ ] **Register** (`/register`) - Registration form
|
|
462
504
|
- [ ] **Account** (`/account`) - Profile + order history
|
|
@@ -475,6 +517,8 @@ item.name (in cart) item.product.name
|
|
|
475
517
|
response.url (OAuth) response.authorizationUrl
|
|
476
518
|
providers.forEach (OAuth) response.providers.forEach
|
|
477
519
|
status === 'completed' status === 'succeeded'
|
|
520
|
+
product.metafields.name product.metafields[0].definitionName
|
|
521
|
+
product.metafields.key product.metafields[0].definitionKey
|
|
478
522
|
```
|
|
479
523
|
|
|
480
524
|
---
|