@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 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
- name: i.name,
56
- price: i.price,
57
- currency: i.currency || cfg.store?.currency || 'usd',
58
- quantity: i.quantity,
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techninja/staticart",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "StatiCart — a full-featured e-commerce platform built 99% on static hosting",
5
5
  "repository": {
6
6
  "type": "git",
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 > 0 &&
75
+ p.stock !== 0 &&
76
76
  (!category ||
77
77
  (Array.isArray(p.category)
78
78
  ? p.category.includes(category)
@@ -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 > 0);
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 > 0 &&
75
+ p.stock !== 0 &&
76
76
  (!category ||
77
77
  (Array.isArray(p.category)
78
78
  ? p.category.includes(category)
@@ -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 > 0);
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)