@nextblock-cms/ecom 0.22.0 → 0.22.2
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/index.cjs +1 -1
- package/index.es.js +31 -31
- package/lib/components/Checkout.cjs +1 -1
- package/lib/components/Checkout.es.js +2 -1
- package/lib/coupon-server.cjs +1 -1
- package/lib/coupon-server.d.ts +65 -1
- package/lib/coupon-server.es.js +151 -91
- package/lib/coupons.cjs +1 -1
- package/lib/coupons.d.ts +13 -0
- package/lib/coupons.es.js +5 -4
- package/lib/order-access-token.cjs +1 -0
- package/lib/order-access-token.d.ts +2 -0
- package/lib/order-access-token.es.js +18 -0
- package/lib/pages/cms/orders/actions.cjs +3 -3
- package/lib/pages/cms/orders/actions.es.js +48 -26
- package/lib/pages/cms/orders/export-actions.cjs +1 -1
- package/lib/pages/cms/orders/export-actions.d.ts +42 -1
- package/lib/pages/cms/orders/export-actions.es.js +18 -16
- package/lib/pages/cms/orders/server-actions.cjs +1 -1
- package/lib/pages/cms/orders/server-actions.es.js +25 -15
- package/lib/pages/cms/products/actions.cjs +4 -4
- package/lib/pages/cms/products/actions.es.js +44 -41
- package/lib/pages/cms/products/inventory/actions.cjs +2 -2
- package/lib/pages/cms/products/inventory/actions.es.js +23 -23
- package/lib/pages/cms/products/server-actions.cjs +1 -1
- package/lib/pages/cms/products/server-actions.es.js +109 -108
- package/lib/pages/cms/shipping/server-actions.cjs +1 -1
- package/lib/pages/cms/shipping/server-actions.es.js +27 -26
- package/lib/payment-config.cjs +1 -1
- package/lib/payment-config.d.ts +4 -2
- package/lib/payment-config.es.js +73 -72
- package/lib/product-actions.cjs +1 -1
- package/lib/product-actions.es.js +6 -6
- package/lib/providers/checkout-items.cjs +1 -0
- package/lib/providers/checkout-items.d.ts +30 -0
- package/lib/providers/checkout-items.es.js +43 -0
- package/lib/providers/freemius.cjs +1 -1
- package/lib/providers/freemius.d.ts +1 -1
- package/lib/providers/freemius.es.js +166 -144
- package/lib/providers/stripe.cjs +1 -1
- package/lib/providers/stripe.d.ts +1 -1
- package/lib/providers/stripe.es.js +191 -146
- package/lib/server-actions/coupon-actions.cjs +1 -1
- package/lib/server-actions/coupon-actions.d.ts +11 -12
- package/lib/server-actions/coupon-actions.es.js +19 -11
- package/lib/server-actions/require-ecom-role.cjs +1 -0
- package/lib/server-actions/require-ecom-role.d.ts +5825 -0
- package/lib/server-actions/require-ecom-role.es.js +24 -0
- package/lib/server-actions/shipping-actions.cjs +1 -1
- package/lib/server-actions/shipping-actions.es.js +4 -4
- package/lib/server-actions/tax-actions.cjs +1 -1
- package/lib/server-actions/tax-actions.es.js +22 -18
- package/lib/shipping/checkout-shipping-method.cjs +7 -0
- package/lib/shipping/checkout-shipping-method.d.ts +115 -0
- package/lib/shipping/checkout-shipping-method.es.js +167 -0
- package/lib/shipping/resolver.cjs +1 -7
- package/lib/shipping/resolver.d.ts +7 -12
- package/lib/shipping/resolver.es.js +13 -38
- package/package.json +4 -4
- package/server.cjs +1 -1
- package/server.d.ts +1 -0
- package/server.es.js +49 -48
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { isDigitalItem as e } from "../types.es.js";
|
|
2
|
-
import {
|
|
3
|
-
import { getCartLineCouponKey as
|
|
4
|
-
import { getCouponQuote as
|
|
5
|
-
import { countries as
|
|
6
|
-
import {
|
|
7
|
-
import { createInventoryInsufficientError as
|
|
8
|
-
import { STRIPE_TAX_CODE_NONTAXABLE as
|
|
9
|
-
import { normalizeOrderCustomerDetails as
|
|
10
|
-
import { fillMissingUserProfileCheckoutDetails as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
2
|
+
import { getDefaultCurrency as t, normalizePriceMap as n, resolveEffectivePriceForCurrency as r } from "../currency.es.js";
|
|
3
|
+
import { getCartLineCouponKey as i } from "../coupons.es.js";
|
|
4
|
+
import { getCouponQuote as a, getQuoteLineDiscountMap as o, recordCouponRedemption as s } from "../coupon-server.es.js";
|
|
5
|
+
import { countries as c } from "../countries.es.js";
|
|
6
|
+
import { createInvalidShippingMethodError as l, createShippingAddressRequiredError as u, createShippingMethodRequiredError as ee, listEligibleShippingMethods as te, normalizeShippingDestination as ne, resolveCheckoutShippingMethod as re } from "../shipping/checkout-shipping-method.es.js";
|
|
7
|
+
import { createInventoryInsufficientError as ie, createInventoryUnavailableError as ae, getEcommerceInventorySettings as oe } from "../inventory-settings.es.js";
|
|
8
|
+
import { STRIPE_TAX_CODE_NONTAXABLE as d, STRIPE_TAX_CODE_SHIPPING as se, calculateCheckoutTaxes as ce, getStripeTaxCodeForProduct as le } from "../tax-calculation.es.js";
|
|
9
|
+
import { normalizeOrderCustomerDetails as ue } from "../customer.es.js";
|
|
10
|
+
import { fillMissingUserProfileCheckoutDetails as de, upsertDefaultUserAddresses as fe } from "../customer-addresses.es.js";
|
|
11
|
+
import { normalizeCheckoutItems as f } from "./checkout-items.es.js";
|
|
12
|
+
import { buildOrderTaxDetailsFromCalculation as pe } from "../order-tax-details.es.js";
|
|
13
|
+
import { getStripeClient as p } from "../stripe/client.es.js";
|
|
14
|
+
import { createClient as me } from "@supabase/supabase-js";
|
|
14
15
|
//#region src/lib/providers/stripe.ts
|
|
15
|
-
var
|
|
16
|
-
function
|
|
16
|
+
var he = c.map((e) => e.code), m = /* @__PURE__ */ new Set(/* @__PURE__ */ "bg.cs.da.de.el.en.en-GB.es.es-419.et.fi.fil.fr.hr.hu.id.it.ja.ko.lt.lv.ms.mt.nb.nl.pl.pt.pt-BR.ro.ru.sk.sl.sv.th.tr.vi.zh.zh-HK.zh-TW".split("."));
|
|
17
|
+
function h(e) {
|
|
17
18
|
if (e) return {
|
|
18
19
|
line1: e.line1 || void 0,
|
|
19
20
|
line2: e.line2 || void 0,
|
|
@@ -23,7 +24,7 @@ function g(e) {
|
|
|
23
24
|
country: e.country_code || void 0
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
|
-
function
|
|
27
|
+
function ge(e) {
|
|
27
28
|
let t = e?.trim().replace("_", "-");
|
|
28
29
|
if (!t) return;
|
|
29
30
|
let n = [
|
|
@@ -31,18 +32,15 @@ function ue(e) {
|
|
|
31
32
|
t.toLowerCase(),
|
|
32
33
|
t.split("-")[0].toLowerCase()
|
|
33
34
|
];
|
|
34
|
-
for (let e of n) if (
|
|
35
|
+
for (let e of n) if (m.has(e)) return e;
|
|
35
36
|
}
|
|
36
|
-
function
|
|
37
|
-
return u(e.name, e.name_translations || null, t);
|
|
38
|
-
}
|
|
39
|
-
async function fe(e) {
|
|
37
|
+
async function _e(e) {
|
|
40
38
|
if (!e.email) return null;
|
|
41
|
-
let t = await
|
|
39
|
+
let t = await p(), n = h(e.shippingAddress), r = e.shippingAddress?.recipient_name || e.billingAddress?.recipient_name || void 0, i = {
|
|
42
40
|
email: e.email,
|
|
43
41
|
name: e.billingAddress?.recipient_name || e.shippingAddress?.recipient_name || void 0,
|
|
44
42
|
phone: e.phone || void 0,
|
|
45
|
-
address:
|
|
43
|
+
address: h(e.billingAddress),
|
|
46
44
|
metadata: e.userId ? { userId: e.userId } : void 0,
|
|
47
45
|
...n && r ? { shipping: {
|
|
48
46
|
name: r,
|
|
@@ -60,61 +58,75 @@ async function fe(e) {
|
|
|
60
58
|
return console.error("Failed to upsert Stripe customer for checkout prefill:", e), null;
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
|
-
var
|
|
61
|
+
var g = class {
|
|
64
62
|
getProviderName() {
|
|
65
63
|
return "Stripe";
|
|
66
64
|
}
|
|
67
|
-
async createCheckoutSession({ items:
|
|
68
|
-
let
|
|
69
|
-
if (!
|
|
65
|
+
async createCheckoutSession({ items: c, customerEmail: m, customerPhone: h, userId: g, billingAddress: _, shippingAddress: v, shippingMethodId: y, currencyCode: ve, locale: b, couponCode: x, couponContextItems: S }) {
|
|
66
|
+
let ye = await p(), C = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL, w = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
|
67
|
+
if (!C || !w) return console.error("Missing Supabase credentials for checkout (Service Key required)."), {
|
|
70
68
|
error: "Internal Server Error",
|
|
71
69
|
url: null
|
|
72
70
|
};
|
|
73
|
-
let
|
|
74
|
-
if (!
|
|
71
|
+
let T = me(C, w), E = process.env.NEXT_PUBLIC_URL || "http://localhost:4200";
|
|
72
|
+
if (!c?.length) return {
|
|
75
73
|
error: "Cart is empty",
|
|
76
74
|
url: null
|
|
77
75
|
};
|
|
78
|
-
let
|
|
79
|
-
if (
|
|
76
|
+
let D = f(c);
|
|
77
|
+
if (!D.ok) return {
|
|
78
|
+
url: null,
|
|
79
|
+
...D.error
|
|
80
|
+
};
|
|
81
|
+
let O = D.items, k = O;
|
|
82
|
+
if (S && S.length > 0) {
|
|
83
|
+
let e = f(S);
|
|
84
|
+
if (!e.ok) return {
|
|
85
|
+
url: null,
|
|
86
|
+
...e.error
|
|
87
|
+
};
|
|
88
|
+
k = e.items;
|
|
89
|
+
}
|
|
90
|
+
let A = O.some((t) => !e(t)), { data: be, error: j } = await T.from("currencies").select("code, symbol, exchange_rate, is_default, is_active, auto_sync_product_prices, auto_update_exchange_rate, exchange_rate_source, exchange_rate_updated_at, rounding_mode, rounding_increment, rounding_charm_amount").eq("is_active", !0).order("code", { ascending: !0 }), M = be ?? [];
|
|
91
|
+
if (j || M.length === 0) return console.error("Error fetching currencies for checkout:", j), {
|
|
80
92
|
error: "Failed to resolve store currencies",
|
|
81
93
|
url: null
|
|
82
94
|
};
|
|
83
|
-
let
|
|
84
|
-
if (
|
|
95
|
+
let xe = t(M), N = M.find((e) => e.code === (ve || "").toUpperCase()) ?? xe, P = N.code.toLowerCase(), F = await oe(T), Se = O.map((e) => e.product_id), I = O.map((e) => e.variant_id).filter((e) => !!e), { data: L, error: R } = await T.from("products").select("id, title, sku, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at, stock, is_taxable").in("id", Se);
|
|
96
|
+
if (R || !L) return console.error("Error fetching products for validation:", R), {
|
|
85
97
|
error: "Failed to validate product prices",
|
|
86
98
|
url: null
|
|
87
99
|
};
|
|
88
|
-
let { data:
|
|
100
|
+
let { data: Ce, error: we } = I.length ? await T.from("product_variants").select("id, product_id, sku, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at, stock_quantity").in("id", I) : {
|
|
89
101
|
data: [],
|
|
90
102
|
error: null
|
|
91
103
|
};
|
|
92
|
-
if (
|
|
104
|
+
if (we) return console.error("Error fetching variants for validation:", we), {
|
|
93
105
|
error: "Failed to validate product variants",
|
|
94
106
|
url: null
|
|
95
107
|
};
|
|
96
|
-
let
|
|
97
|
-
for (let e of
|
|
98
|
-
let t =
|
|
108
|
+
let z = new Map(L.map((e) => [e.id, e])), B = new Map((Ce || []).map((e) => [e.id, e])), V = /* @__PURE__ */ new Set(), H = /* @__PURE__ */ new Map();
|
|
109
|
+
for (let e of O) {
|
|
110
|
+
let t = z.get(e.product_id);
|
|
99
111
|
if (!t) continue;
|
|
100
|
-
let n = (e.variant_id ?
|
|
101
|
-
n && (
|
|
112
|
+
let n = (e.variant_id ? B.get(e.variant_id) : null)?.sku || t.sku;
|
|
113
|
+
n && (V.add(n), H.set(n, (H.get(n) ?? 0) + e.quantity));
|
|
102
114
|
}
|
|
103
|
-
let { data:
|
|
115
|
+
let { data: Te, error: Ee } = V.size ? await T.from("inventory_items").select("sku, quantity").in("sku", [...V]) : {
|
|
104
116
|
data: [],
|
|
105
117
|
error: null
|
|
106
118
|
};
|
|
107
|
-
if (
|
|
119
|
+
if (Ee) return console.error("Error fetching SKU inventory for validation:", Ee), {
|
|
108
120
|
error: "Failed to validate SKU inventory",
|
|
109
121
|
url: null
|
|
110
122
|
};
|
|
111
|
-
let
|
|
112
|
-
if (
|
|
113
|
-
let e = await
|
|
114
|
-
client:
|
|
115
|
-
code:
|
|
116
|
-
items:
|
|
117
|
-
currencyCode:
|
|
123
|
+
let U = new Map((Te || []).map((e) => [e.sku, Math.max(0, e.quantity ?? 0)])), W = [], De = [], Oe = [], G = 0, K = 0, q = null;
|
|
124
|
+
if (x) {
|
|
125
|
+
let e = await a({
|
|
126
|
+
client: T,
|
|
127
|
+
code: x,
|
|
128
|
+
items: k,
|
|
129
|
+
currencyCode: N.code
|
|
118
130
|
});
|
|
119
131
|
if (!e.success) return {
|
|
120
132
|
error: e.error,
|
|
@@ -124,16 +136,16 @@ var _ = class {
|
|
|
124
136
|
};
|
|
125
137
|
q = e.quote;
|
|
126
138
|
}
|
|
127
|
-
let
|
|
139
|
+
let ke = o(q), Ae = (e) => {
|
|
128
140
|
let t = e.unitAmount * e.quantity, n = Math.max(0, t - e.lineDiscount);
|
|
129
141
|
if (n <= 0) return;
|
|
130
142
|
let r = Math.floor(n / e.quantity), i = n - r * e.quantity, a = (t, n) => {
|
|
131
|
-
n <= 0 || t <= 0 ||
|
|
143
|
+
n <= 0 || t <= 0 || W.push({
|
|
132
144
|
price_data: {
|
|
133
145
|
currency: e.currency,
|
|
134
146
|
product_data: {
|
|
135
147
|
name: e.name,
|
|
136
|
-
tax_code:
|
|
148
|
+
tax_code: le(e.isTaxable),
|
|
137
149
|
metadata: {
|
|
138
150
|
productId: e.productId,
|
|
139
151
|
variantId: e.variantId || ""
|
|
@@ -147,55 +159,55 @@ var _ = class {
|
|
|
147
159
|
};
|
|
148
160
|
a(r, e.quantity - i), a(r + 1, i);
|
|
149
161
|
};
|
|
150
|
-
for (let e of
|
|
151
|
-
let t =
|
|
162
|
+
for (let e of O) {
|
|
163
|
+
let t = z.get(e.product_id);
|
|
152
164
|
if (!t) return console.warn(`Product ${e.product_id} not found in DB.`), {
|
|
153
165
|
url: null,
|
|
154
|
-
...
|
|
166
|
+
...ae(e.title)
|
|
155
167
|
};
|
|
156
|
-
let
|
|
157
|
-
prices:
|
|
168
|
+
let a = r({
|
|
169
|
+
prices: n(t.prices),
|
|
158
170
|
salePrices: t.sale_prices || {},
|
|
159
171
|
fallbackPrice: t.price,
|
|
160
172
|
fallbackSalePrice: t.sale_price,
|
|
161
173
|
saleStartAt: t.sale_start_at,
|
|
162
174
|
saleEndAt: t.sale_end_at,
|
|
163
175
|
scheduledPrice: t.scheduled_price,
|
|
164
|
-
scheduledPrices:
|
|
176
|
+
scheduledPrices: n(t.scheduled_prices),
|
|
165
177
|
scheduledPriceAt: t.scheduled_price_at,
|
|
166
|
-
currencyCode:
|
|
167
|
-
currencies:
|
|
168
|
-
}), o =
|
|
178
|
+
currencyCode: N.code,
|
|
179
|
+
currencies: M
|
|
180
|
+
}), o = a.sale_price ?? a.price, s = t.title, c = null;
|
|
169
181
|
if (e.variant_id) {
|
|
170
|
-
let
|
|
171
|
-
if (!
|
|
182
|
+
let i = B.get(e.variant_id);
|
|
183
|
+
if (!i || i.product_id !== e.product_id) return {
|
|
172
184
|
url: null,
|
|
173
|
-
...
|
|
185
|
+
...ae(e.title)
|
|
174
186
|
};
|
|
175
|
-
let a =
|
|
176
|
-
if (
|
|
187
|
+
let a = H.get(i.sku) ?? e.quantity, l = U.has(i.sku) ? U.get(i.sku) ?? 0 : Math.max(0, i.stock_quantity ?? 0);
|
|
188
|
+
if (F.trackQuantities && a > l) return {
|
|
177
189
|
url: null,
|
|
178
|
-
...
|
|
190
|
+
...ie(e.title, l)
|
|
179
191
|
};
|
|
180
|
-
let u =
|
|
181
|
-
prices:
|
|
182
|
-
salePrices:
|
|
183
|
-
fallbackPrice:
|
|
184
|
-
fallbackSalePrice:
|
|
185
|
-
saleStartAt:
|
|
186
|
-
saleEndAt:
|
|
187
|
-
scheduledPrice:
|
|
188
|
-
scheduledPrices:
|
|
189
|
-
scheduledPriceAt:
|
|
190
|
-
currencyCode:
|
|
191
|
-
currencies:
|
|
192
|
+
let u = r({
|
|
193
|
+
prices: n(i.prices),
|
|
194
|
+
salePrices: i.sale_prices || {},
|
|
195
|
+
fallbackPrice: i.price,
|
|
196
|
+
fallbackSalePrice: i.sale_price,
|
|
197
|
+
saleStartAt: i.sale_start_at,
|
|
198
|
+
saleEndAt: i.sale_end_at,
|
|
199
|
+
scheduledPrice: i.scheduled_price,
|
|
200
|
+
scheduledPrices: n(i.scheduled_prices),
|
|
201
|
+
scheduledPriceAt: i.scheduled_price_at,
|
|
202
|
+
currencyCode: N.code,
|
|
203
|
+
currencies: M
|
|
192
204
|
});
|
|
193
|
-
o = u.sale_price ?? u.price, c =
|
|
205
|
+
o = u.sale_price ?? u.price, c = i.id, s = e.variant_label ? `${t.title} - ${e.variant_label}` : `${t.title} - ${i.sku}`;
|
|
194
206
|
} else {
|
|
195
|
-
let n =
|
|
196
|
-
if (
|
|
207
|
+
let n = H.get(t.sku) ?? e.quantity, r = U.has(t.sku) ? U.get(t.sku) ?? 0 : Math.max(0, t.stock ?? 0);
|
|
208
|
+
if (F.trackQuantities && n > r) return {
|
|
197
209
|
url: null,
|
|
198
|
-
...
|
|
210
|
+
...ie(e.title, r)
|
|
199
211
|
};
|
|
200
212
|
}
|
|
201
213
|
let l = t.is_taxable ?? !0;
|
|
@@ -203,22 +215,22 @@ var _ = class {
|
|
|
203
215
|
error: "A product variation produced an invalid price.",
|
|
204
216
|
url: null
|
|
205
217
|
};
|
|
206
|
-
let u = Math.min(o * e.quantity,
|
|
207
|
-
|
|
218
|
+
let u = Math.min(o * e.quantity, ke.get(i(e)) ?? 0);
|
|
219
|
+
Ae({
|
|
208
220
|
name: s,
|
|
209
|
-
currency:
|
|
221
|
+
currency: P,
|
|
210
222
|
productId: t.id,
|
|
211
223
|
variantId: c,
|
|
212
224
|
isTaxable: l,
|
|
213
225
|
unitAmount: o,
|
|
214
226
|
quantity: e.quantity,
|
|
215
227
|
lineDiscount: u
|
|
216
|
-
}), G += o * e.quantity, K += u,
|
|
228
|
+
}), G += o * e.quantity, K += u, Oe.push({
|
|
217
229
|
product_id: t.id,
|
|
218
230
|
quantity: e.quantity,
|
|
219
231
|
price_at_purchase: o,
|
|
220
232
|
variant_id: c
|
|
221
|
-
}),
|
|
233
|
+
}), De.push({
|
|
222
234
|
product_id: t.id,
|
|
223
235
|
quantity: e.quantity,
|
|
224
236
|
unit_amount: o,
|
|
@@ -226,37 +238,66 @@ var _ = class {
|
|
|
226
238
|
is_taxable: l
|
|
227
239
|
});
|
|
228
240
|
}
|
|
229
|
-
if (
|
|
241
|
+
if (W.length === 0 && K >= G) return {
|
|
230
242
|
error: "This coupon would reduce the Stripe order to zero. Use a smaller discount for Stripe checkout.",
|
|
231
243
|
errorKey: "ecommerce.coupon_zero_total_not_supported",
|
|
232
244
|
errorStatus: 400,
|
|
233
245
|
url: null
|
|
234
246
|
};
|
|
235
|
-
if (
|
|
247
|
+
if (W.length === 0) return {
|
|
236
248
|
error: "No valid items in cart",
|
|
237
249
|
url: null
|
|
238
250
|
};
|
|
239
251
|
let J = 0, Y = null;
|
|
240
|
-
if (
|
|
241
|
-
let
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
252
|
+
if (A) {
|
|
253
|
+
let e = ne({
|
|
254
|
+
country: v?.country_code,
|
|
255
|
+
state: v?.state,
|
|
256
|
+
postal_code: v?.postal_code
|
|
257
|
+
});
|
|
258
|
+
if (!e) return {
|
|
259
|
+
url: null,
|
|
260
|
+
...u()
|
|
245
261
|
};
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
262
|
+
let t = {
|
|
263
|
+
destination: e,
|
|
264
|
+
cartTotal: Math.max(0, G - K),
|
|
265
|
+
currencies: M,
|
|
266
|
+
currencyCode: N.code
|
|
267
|
+
};
|
|
268
|
+
if (y) {
|
|
269
|
+
let e = await re(T, {
|
|
270
|
+
...t,
|
|
271
|
+
methodId: y,
|
|
272
|
+
languageCode: b
|
|
273
|
+
});
|
|
274
|
+
if (!e.ok) return e.reason === "load_failed" ? (console.error("Failed to load shipping method:", e.error), {
|
|
275
|
+
error: "Failed to load shipping method",
|
|
276
|
+
url: null
|
|
277
|
+
}) : (console.warn(`Checkout rejected shipping method ${y}: ${e.reason}`), {
|
|
278
|
+
url: null,
|
|
279
|
+
...l()
|
|
280
|
+
});
|
|
281
|
+
J = e.method.amount, Y = e.method.name;
|
|
282
|
+
} else {
|
|
283
|
+
let e = await te(T, t);
|
|
284
|
+
if (!e.ok) return console.error("Failed to load shipping methods:", e.error), {
|
|
285
|
+
error: "Failed to load shipping method",
|
|
286
|
+
url: null
|
|
287
|
+
};
|
|
288
|
+
if (e.methods.length > 0) return {
|
|
289
|
+
url: null,
|
|
290
|
+
...ee()
|
|
291
|
+
};
|
|
292
|
+
}
|
|
252
293
|
}
|
|
253
|
-
let
|
|
294
|
+
let je = A ? v ?? _ : _, X;
|
|
254
295
|
try {
|
|
255
|
-
X = await
|
|
256
|
-
items:
|
|
296
|
+
X = await ce(T, {
|
|
297
|
+
items: De,
|
|
257
298
|
destination: {
|
|
258
|
-
country_code:
|
|
259
|
-
state:
|
|
299
|
+
country_code: je?.country_code,
|
|
300
|
+
state: je?.state
|
|
260
301
|
}
|
|
261
302
|
});
|
|
262
303
|
} catch (e) {
|
|
@@ -265,12 +306,12 @@ var _ = class {
|
|
|
265
306
|
url: null
|
|
266
307
|
};
|
|
267
308
|
}
|
|
268
|
-
J > 0 && Y &&
|
|
309
|
+
J > 0 && Y && W.push({
|
|
269
310
|
price_data: {
|
|
270
|
-
currency:
|
|
311
|
+
currency: P,
|
|
271
312
|
product_data: {
|
|
272
313
|
name: Y,
|
|
273
|
-
tax_code: X.enabled && X.mode === "automatic" ?
|
|
314
|
+
tax_code: X.enabled && X.mode === "automatic" ? se : d
|
|
274
315
|
},
|
|
275
316
|
tax_behavior: "exclusive",
|
|
276
317
|
unit_amount: J
|
|
@@ -278,39 +319,39 @@ var _ = class {
|
|
|
278
319
|
quantity: 1
|
|
279
320
|
});
|
|
280
321
|
let Z = X.enabled && X.mode === "manual" && !X.isPendingExternalCalculation ? X.amount : 0;
|
|
281
|
-
Z > 0 &&
|
|
322
|
+
Z > 0 && W.push({
|
|
282
323
|
price_data: {
|
|
283
|
-
currency:
|
|
324
|
+
currency: P,
|
|
284
325
|
product_data: {
|
|
285
326
|
name: "Tax",
|
|
286
|
-
tax_code:
|
|
327
|
+
tax_code: d
|
|
287
328
|
},
|
|
288
329
|
tax_behavior: "exclusive",
|
|
289
330
|
unit_amount: Z
|
|
290
331
|
},
|
|
291
332
|
quantity: 1
|
|
292
333
|
});
|
|
293
|
-
let
|
|
294
|
-
email:
|
|
334
|
+
let Me = ue({
|
|
335
|
+
email: m,
|
|
295
336
|
phone: h,
|
|
296
337
|
name: _?.recipient_name,
|
|
297
338
|
billing: _,
|
|
298
339
|
shipping: v
|
|
299
|
-
}),
|
|
340
|
+
}), Ne = N.code, Pe = pe({
|
|
300
341
|
calculation: X,
|
|
301
342
|
subtotal: G,
|
|
302
343
|
shippingTotal: J,
|
|
303
344
|
total: Math.max(0, G - K) + J + Z,
|
|
304
|
-
currency:
|
|
305
|
-
}),
|
|
345
|
+
currency: Ne
|
|
346
|
+
}), Fe = Math.max(0, G - K) + J + Z, { data: Ie, error: Le } = await T.from("orders").insert({
|
|
306
347
|
status: "pending",
|
|
307
|
-
total:
|
|
308
|
-
currency:
|
|
309
|
-
exchange_rate_at_purchase:
|
|
348
|
+
total: Fe,
|
|
349
|
+
currency: Ne,
|
|
350
|
+
exchange_rate_at_purchase: N.exchange_rate,
|
|
310
351
|
subtotal: G,
|
|
311
352
|
shipping_total: J,
|
|
312
353
|
tax_total: Z,
|
|
313
|
-
tax_details:
|
|
354
|
+
tax_details: Pe,
|
|
314
355
|
coupon_id: q?.couponId ?? null,
|
|
315
356
|
coupon_code: q?.code ?? null,
|
|
316
357
|
discount_total: K,
|
|
@@ -324,88 +365,92 @@ var _ = class {
|
|
|
324
365
|
} : null,
|
|
325
366
|
provider: "stripe",
|
|
326
367
|
user_id: g,
|
|
327
|
-
customer_details:
|
|
368
|
+
customer_details: Me
|
|
328
369
|
}).select("id").single();
|
|
329
|
-
if (
|
|
370
|
+
if (Le || !Ie) return console.error("Failed to create pending order:", Le), {
|
|
330
371
|
error: "Failed to initiate order",
|
|
331
372
|
url: null
|
|
332
373
|
};
|
|
333
|
-
let Q =
|
|
374
|
+
let Q = Ie.id, { error: Re } = await T.from("order_items").insert(Oe.map((e) => ({
|
|
334
375
|
order_id: Q,
|
|
335
376
|
product_id: e.product_id,
|
|
336
377
|
variant_id: e.variant_id ?? null,
|
|
337
378
|
quantity: e.quantity,
|
|
338
379
|
price_at_purchase: e.price_at_purchase
|
|
339
380
|
})));
|
|
340
|
-
if (
|
|
381
|
+
if (Re) return console.error("Failed to insert order items:", Re), await T.from("orders").update({ status: "failed" }).eq("id", Q), {
|
|
341
382
|
error: "Failed to record order items",
|
|
342
383
|
url: null
|
|
343
384
|
};
|
|
344
385
|
if (g) try {
|
|
345
|
-
await
|
|
386
|
+
await fe({
|
|
346
387
|
userId: g,
|
|
347
388
|
billingAddress: _,
|
|
348
389
|
shippingAddress: v,
|
|
349
|
-
client:
|
|
350
|
-
}), await
|
|
390
|
+
client: T
|
|
391
|
+
}), await de({
|
|
351
392
|
userId: g,
|
|
352
393
|
fullName: _?.recipient_name ?? v?.recipient_name ?? null,
|
|
353
394
|
phone: h,
|
|
354
|
-
client:
|
|
395
|
+
client: T
|
|
355
396
|
});
|
|
356
397
|
} catch (e) {
|
|
357
398
|
console.error("Failed to sync checkout profile defaults before checkout:", e);
|
|
358
399
|
}
|
|
359
|
-
q && await
|
|
360
|
-
client:
|
|
400
|
+
if (q && !(await s({
|
|
401
|
+
client: T,
|
|
361
402
|
quote: q,
|
|
362
403
|
orderId: Q,
|
|
363
404
|
provider: "stripe",
|
|
364
405
|
discountTotal: K,
|
|
365
406
|
userId: g,
|
|
366
|
-
customerEmail:
|
|
407
|
+
customerEmail: m,
|
|
367
408
|
metadata: {
|
|
368
|
-
currency:
|
|
409
|
+
currency: N.code,
|
|
369
410
|
subtotal: G,
|
|
370
411
|
shipping_total: J,
|
|
371
412
|
tax_total: Z
|
|
372
413
|
}
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
|
|
414
|
+
})).success) return await T.from("orders").update({ status: "failed" }).eq("id", Q), {
|
|
415
|
+
url: null,
|
|
416
|
+
error: "Coupon is no longer available.",
|
|
417
|
+
errorKey: "ecommerce.coupon_invalid"
|
|
418
|
+
};
|
|
419
|
+
let $ = await _e({
|
|
420
|
+
email: m,
|
|
376
421
|
phone: h,
|
|
377
422
|
userId: g,
|
|
378
423
|
billingAddress: _,
|
|
379
424
|
shippingAddress: v
|
|
380
425
|
});
|
|
381
426
|
try {
|
|
382
|
-
let e = await
|
|
427
|
+
let e = await ye.checkout.sessions.create({
|
|
383
428
|
mode: "payment",
|
|
384
|
-
success_url: `${
|
|
385
|
-
cancel_url: `${
|
|
386
|
-
locale:
|
|
387
|
-
line_items:
|
|
429
|
+
success_url: `${E}/checkout/success?session_id={CHECKOUT_SESSION_ID}`,
|
|
430
|
+
cancel_url: `${E}/checkout`,
|
|
431
|
+
locale: ge(b),
|
|
432
|
+
line_items: W,
|
|
388
433
|
automatic_tax: X.enabled && X.mode === "automatic" ? { enabled: !0 } : void 0,
|
|
389
434
|
billing_address_collection: "auto",
|
|
390
435
|
customer: $ || void 0,
|
|
391
|
-
customer_email: $ ? void 0 :
|
|
436
|
+
customer_email: $ ? void 0 : m || void 0,
|
|
392
437
|
customer_creation: $ ? void 0 : "if_required",
|
|
393
438
|
customer_update: $ ? {
|
|
394
439
|
name: "auto",
|
|
395
440
|
address: "auto",
|
|
396
441
|
shipping: "auto"
|
|
397
442
|
} : void 0,
|
|
398
|
-
shipping_address_collection:
|
|
443
|
+
shipping_address_collection: A ? { allowed_countries: he } : void 0,
|
|
399
444
|
metadata: {
|
|
400
445
|
orderId: Q,
|
|
401
446
|
taxMode: X.mode,
|
|
402
|
-
currencyCode:
|
|
447
|
+
currencyCode: N.code,
|
|
403
448
|
couponCode: q?.code || ""
|
|
404
449
|
}
|
|
405
|
-
}), { error: t } = await
|
|
450
|
+
}), { error: t } = await T.from("orders").update({ stripe_session_id: e.id }).eq("id", Q);
|
|
406
451
|
return t && console.error("Failed to save Stripe session ID on order:", t), { url: e.url };
|
|
407
452
|
} catch (e) {
|
|
408
|
-
return console.error("Stripe session creation failed:", e), await
|
|
453
|
+
return console.error("Stripe session creation failed:", e), await T.from("orders").update({ status: "failed" }).eq("id", Q), e?.name === "StripeNotConfiguredError" || e?.type === "StripeAuthenticationError" ? {
|
|
409
454
|
error: "This store is not able to take payments right now. Please contact the seller to complete your purchase.",
|
|
410
455
|
errorKey: "ecommerce.checkout_payments_unavailable",
|
|
411
456
|
errorStatus: 503,
|
|
@@ -419,4 +464,4 @@ var _ = class {
|
|
|
419
464
|
}
|
|
420
465
|
};
|
|
421
466
|
//#endregion
|
|
422
|
-
export {
|
|
467
|
+
export { g as StripeProvider };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use server";const e=require("../coupon-server.cjs");let
|
|
1
|
+
"use server";const e=require("../coupons.cjs"),t=require("../coupon-server.cjs");let n=require("next/headers"),r=require("@nextblock-cms/db/server");async function i(i){try{let a=await(0,n.headers)();if(!t.consumeCouponValidationToken(t.resolveCouponValidationThrottleKey(a)))return{success:!1,error:e.COUPON_THROTTLED_ERROR_MESSAGE,errorKey:e.COUPON_THROTTLED_ERROR_KEY};let o=(0,r.getServiceRoleSupabaseClient)();return await t.getCouponQuote({client:o,code:i.code,items:Array.isArray(i.items)?i.items:[],currencyCode:i.currencyCode})}catch(e){return console.error(`Failed to validate coupon:`,e),{success:!1,error:`We couldn't validate this coupon. Try again.`,errorKey:`ecommerce.coupon_validation_failed`}}}exports.getCouponQuoteAction=i;
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { CartItem } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Public coupon validation for the cart and checkout forms.
|
|
4
|
+
*
|
|
5
|
+
* Reachable by anyone (a server action is a POST endpoint dispatched by id, no session
|
|
6
|
+
* needed) and it reads with the service-role client, so it is the only way a visitor can ask
|
|
7
|
+
* "does this code exist?". Two things keep that from being an enumeration oracle:
|
|
8
|
+
* `getCouponQuote` answers every unusable code with the same message, and this action spends a
|
|
9
|
+
* per-client token before it touches the database. The bucket is in-memory and best-effort
|
|
10
|
+
* (see coupon-server.ts); the uniform reply is what makes a slow probe also an unreliable one.
|
|
11
|
+
*/
|
|
2
12
|
export declare function getCouponQuoteAction(input: {
|
|
3
13
|
code?: string | null;
|
|
4
14
|
items: CartItem[];
|
|
5
15
|
currencyCode?: string | null;
|
|
6
|
-
}): Promise<
|
|
7
|
-
success: true;
|
|
8
|
-
quote: import('../coupons').CouponQuote;
|
|
9
|
-
} | {
|
|
10
|
-
success: false;
|
|
11
|
-
error: string;
|
|
12
|
-
errorKey?: string;
|
|
13
|
-
} | {
|
|
14
|
-
success: false;
|
|
15
|
-
error: any;
|
|
16
|
-
errorKey: string;
|
|
17
|
-
}>;
|
|
16
|
+
}): Promise<import('../coupons').CouponQuoteResult>;
|
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
"use server";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { COUPON_THROTTLED_ERROR_KEY as e, COUPON_THROTTLED_ERROR_MESSAGE as t } from "../coupons.es.js";
|
|
3
|
+
import { consumeCouponValidationToken as n, getCouponQuote as r, resolveCouponValidationThrottleKey as i } from "../coupon-server.es.js";
|
|
4
|
+
import { headers as a } from "next/headers";
|
|
5
|
+
import { getServiceRoleSupabaseClient as o } from "@nextblock-cms/db/server";
|
|
4
6
|
//#region src/lib/server-actions/coupon-actions.ts
|
|
5
|
-
async function
|
|
7
|
+
async function s(s) {
|
|
6
8
|
try {
|
|
7
|
-
let
|
|
8
|
-
return
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
let c = await a();
|
|
10
|
+
if (!n(i(c))) return {
|
|
11
|
+
success: !1,
|
|
12
|
+
error: t,
|
|
13
|
+
errorKey: e
|
|
14
|
+
};
|
|
15
|
+
let l = o();
|
|
16
|
+
return await r({
|
|
17
|
+
client: l,
|
|
18
|
+
code: s.code,
|
|
19
|
+
items: Array.isArray(s.items) ? s.items : [],
|
|
20
|
+
currencyCode: s.currencyCode
|
|
13
21
|
});
|
|
14
22
|
} catch (e) {
|
|
15
23
|
return console.error("Failed to validate coupon:", e), {
|
|
16
24
|
success: !1,
|
|
17
|
-
error:
|
|
25
|
+
error: "We couldn't validate this coupon. Try again.",
|
|
18
26
|
errorKey: "ecommerce.coupon_validation_failed"
|
|
19
27
|
};
|
|
20
28
|
}
|
|
21
29
|
}
|
|
22
30
|
//#endregion
|
|
23
|
-
export {
|
|
31
|
+
export { s as getCouponQuoteAction };
|