@techninja/staticart 0.1.7 → 0.1.9
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/api/checkout.js +11 -6
- package/api/lib/stripe.js +8 -1
- package/docs/staticart/CUSTOMIZATION.md +57 -0
- package/package.json +1 -1
- package/src/assets/staticart_logo.png +0 -0
- package/src/components/organisms/product-grid/product-grid.js +1 -1
- package/src/store/Product.js +1 -1
- package/vendor/components/organisms/product-grid/product-grid.js +1 -1
- package/vendor/store/Product.js +1 -1
package/api/checkout.js
CHANGED
|
@@ -51,12 +51,17 @@ export async function handler(event) {
|
|
|
51
51
|
config: cfg,
|
|
52
52
|
});
|
|
53
53
|
const url = await createCheckoutSession({
|
|
54
|
-
items: items.map((i) =>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
items: items.map((i) => {
|
|
55
|
+
const p = productData.find((pd) => pd.sku === i.sku);
|
|
56
|
+
return {
|
|
57
|
+
sku: i.sku,
|
|
58
|
+
name: i.name,
|
|
59
|
+
price: i.price,
|
|
60
|
+
currency: i.currency || cfg.store?.currency || 'usd',
|
|
61
|
+
quantity: i.quantity,
|
|
62
|
+
metadata: p?.metadata || {},
|
|
63
|
+
};
|
|
64
|
+
}),
|
|
60
65
|
successUrl,
|
|
61
66
|
cancelUrl,
|
|
62
67
|
shipping: { type: 'flat', amount: shippingAmount, displayName: shippingSummary || '' },
|
package/api/lib/stripe.js
CHANGED
|
@@ -21,7 +21,7 @@ export function getStripe() {
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* @typedef {Object} CheckoutOptions
|
|
24
|
-
* @property {Array<{name: string, price: number, currency: string, quantity: number}>} items
|
|
24
|
+
* @property {Array<{name: string, price: number, currency: string, quantity: number, sku?: string, metadata?: any}>} items
|
|
25
25
|
* @property {string} successUrl
|
|
26
26
|
* @property {string} cancelUrl
|
|
27
27
|
* @property {{type: string, amount?: number, displayName?: string}} [shipping]
|
|
@@ -78,6 +78,13 @@ export async function createCheckoutSession(opts) {
|
|
|
78
78
|
];
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
const itemsMeta = opts.items.map((i) => ({
|
|
82
|
+
sku: i.sku || '',
|
|
83
|
+
quantity: i.quantity,
|
|
84
|
+
metadata: i.metadata || {},
|
|
85
|
+
}));
|
|
86
|
+
params.metadata = { items: JSON.stringify(itemsMeta) };
|
|
87
|
+
|
|
81
88
|
const session = await getStripe().checkout.sessions.create(params);
|
|
82
89
|
return session.url;
|
|
83
90
|
}
|
|
@@ -61,3 +61,60 @@ npx clearstack update # re-vendor + sync docs
|
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
Your config, tokens, products, and overrides are never touched.
|
|
64
|
+
|
|
65
|
+
## Shipping Types
|
|
66
|
+
|
|
67
|
+
StatiCart supports three shipping modes via `staticart.config.json`:
|
|
68
|
+
|
|
69
|
+
### Flat Rate
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{ "shipping": { "type": "flat", "amount": 499 } }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Tiered (by cart subtotal + product class)
|
|
76
|
+
|
|
77
|
+
See the demo store config for a full example with `classes`, `regions`,
|
|
78
|
+
and `tiers`.
|
|
79
|
+
|
|
80
|
+
### Custom (external API)
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{ "shipping": { "type": "custom" } }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Create `api/lib/shipping-custom.js` exporting:
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
export async function calculateShipping(ctx) {
|
|
90
|
+
// ctx.items — cart items with metadata
|
|
91
|
+
// ctx.country — ISO country code
|
|
92
|
+
// ctx.config — full staticart.config.json
|
|
93
|
+
return amountInCents;
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The platform calls this automatically when `shipping.type` is `"custom"`.
|
|
98
|
+
|
|
99
|
+
## Stock Convention
|
|
100
|
+
|
|
101
|
+
- `stock > 0` — finite inventory, decremented on purchase
|
|
102
|
+
- `stock: 0` — out of stock, hidden from catalog
|
|
103
|
+
- `stock: -1` — unlimited / dropship (always in stock, never decremented)
|
|
104
|
+
|
|
105
|
+
Use `stock: -1` for print-on-demand or dropshipped products.
|
|
106
|
+
|
|
107
|
+
## Post-Checkout Fulfillment
|
|
108
|
+
|
|
109
|
+
To add fulfillment logic after a successful payment, import your module
|
|
110
|
+
in `api/webhook.js` and call it after the order is recorded:
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
import { fulfillOrder } from './lib/fulfillment.js';
|
|
114
|
+
|
|
115
|
+
// Inside handleCheckoutCompleted, after putItem:
|
|
116
|
+
const result = await fulfillOrder({ orderId, email, items, session });
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Item metadata (from `products.json`) is passed through the Stripe session
|
|
120
|
+
and available in the webhook's `items` array.
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -72,7 +72,7 @@ export default define({
|
|
|
72
72
|
return html`<p>${t('general.loading')}</p>`;
|
|
73
73
|
const filtered = /** @type {any[]} */ (products).filter(
|
|
74
74
|
(p) =>
|
|
75
|
-
p.stock
|
|
75
|
+
p.stock !== 0 &&
|
|
76
76
|
(!category ||
|
|
77
77
|
(Array.isArray(p.category)
|
|
78
78
|
? p.category.includes(category)
|
package/src/store/Product.js
CHANGED
|
@@ -69,7 +69,7 @@ const Product = {
|
|
|
69
69
|
const products = await fetchProducts();
|
|
70
70
|
const p = /** @type {any} */ (params) || {};
|
|
71
71
|
let filtered = products.filter((item) => item.active);
|
|
72
|
-
if (!p.showOutOfStock) filtered = filtered.filter((item) => item.stock
|
|
72
|
+
if (!p.showOutOfStock) filtered = filtered.filter((item) => item.stock !== 0);
|
|
73
73
|
if (p.category) {
|
|
74
74
|
filtered = filtered.filter((item) =>
|
|
75
75
|
Array.isArray(item.category)
|
|
@@ -72,7 +72,7 @@ export default define({
|
|
|
72
72
|
return html`<p>${t('general.loading')}</p>`;
|
|
73
73
|
const filtered = /** @type {any[]} */ (products).filter(
|
|
74
74
|
(p) =>
|
|
75
|
-
p.stock
|
|
75
|
+
p.stock !== 0 &&
|
|
76
76
|
(!category ||
|
|
77
77
|
(Array.isArray(p.category)
|
|
78
78
|
? p.category.includes(category)
|
package/vendor/store/Product.js
CHANGED
|
@@ -69,7 +69,7 @@ const Product = {
|
|
|
69
69
|
const products = await fetchProducts();
|
|
70
70
|
const p = /** @type {any} */ (params) || {};
|
|
71
71
|
let filtered = products.filter((item) => item.active);
|
|
72
|
-
if (!p.showOutOfStock) filtered = filtered.filter((item) => item.stock
|
|
72
|
+
if (!p.showOutOfStock) filtered = filtered.filter((item) => item.stock !== 0);
|
|
73
73
|
if (p.category) {
|
|
74
74
|
filtered = filtered.filter((item) =>
|
|
75
75
|
Array.isArray(item.category)
|