@nextblock-cms/ecom 0.10.2 → 0.10.3
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/lib/components/CustomerProfileForm.cjs.js +1 -1
- package/lib/components/CustomerProfileForm.es.js +162 -159
- package/lib/freemius-coupons.cjs.js +1 -1
- package/lib/freemius-coupons.es.js +51 -49
- package/lib/pages/cms/payments/PaymentsClient.cjs.js +1 -1
- package/lib/pages/cms/payments/PaymentsClient.d.ts +4 -1
- package/lib/pages/cms/payments/PaymentsClient.es.js +255 -127
- package/lib/pages/cms/payments/PaymentsPage.cjs.js +1 -1
- package/lib/pages/cms/payments/PaymentsPage.es.js +20 -16
- package/lib/pages/cms/payments/actions.cjs.js +1 -1
- package/lib/pages/cms/payments/actions.d.ts +1 -0
- package/lib/pages/cms/payments/actions.es.js +41 -13
- package/lib/pages/cms/payments/queries.cjs.js +1 -1
- package/lib/pages/cms/payments/queries.es.js +13 -24
- package/lib/payment-config.cjs.js +1 -0
- package/lib/payment-config.d.ts +57 -0
- package/lib/payment-config.es.js +137 -0
- package/lib/providers/freemius.cjs.js +2 -2
- package/lib/providers/freemius.es.js +108 -107
- package/lib/providers/stripe.cjs.js +1 -1
- package/lib/providers/stripe.es.js +167 -167
- package/lib/stripe/checkout.cjs.js +1 -1
- package/lib/stripe/checkout.es.js +14 -14
- package/lib/stripe/client.cjs.js +1 -1
- package/lib/stripe/client.d.ts +1 -1
- package/lib/stripe/client.es.js +8 -5
- package/lib/stripe/order-sync.cjs.js +1 -1
- package/lib/stripe/order-sync.es.js +50 -50
- package/lib/stripe/webhooks.cjs.js +1 -1
- package/lib/stripe/webhooks.es.js +12 -10
- package/package.json +4 -4
- package/server.cjs.js +1 -1
- package/server.d.ts +1 -0
- package/server.es.js +188 -178
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createClient as
|
|
3
|
-
import { countries as
|
|
4
|
-
import { normalizeOrderCustomerDetails as
|
|
5
|
-
import { getCouponQuote as be, getQuoteLineDiscountMap as
|
|
6
|
-
import { getCartLineCouponKey as
|
|
7
|
-
import { upsertDefaultUserAddresses as
|
|
8
|
-
import { getEcommerceInventorySettings as
|
|
9
|
-
import { calculateCheckoutTaxes as
|
|
10
|
-
import { getDefaultCurrency as
|
|
11
|
-
import { buildOrderTaxDetailsFromCalculation as
|
|
12
|
-
import { isDigitalItem as
|
|
13
|
-
import { resolveTranslatedText as
|
|
14
|
-
const
|
|
1
|
+
import { getStripeClient as _e } from "../stripe/client.es.js";
|
|
2
|
+
import { createClient as Pe } from "@supabase/supabase-js";
|
|
3
|
+
import { countries as qe } from "../countries.es.js";
|
|
4
|
+
import { normalizeOrderCustomerDetails as we } from "../customer.es.js";
|
|
5
|
+
import { getCouponQuote as be, getQuoteLineDiscountMap as Te, recordCouponRedemption as Ae } from "../coupon-server.es.js";
|
|
6
|
+
import { getCartLineCouponKey as Ie } from "../coupons.es.js";
|
|
7
|
+
import { upsertDefaultUserAddresses as De, fillMissingUserProfileCheckoutDetails as Ue } from "../customer-addresses.es.js";
|
|
8
|
+
import { getEcommerceInventorySettings as Le, createInventoryUnavailableError as se, createInventoryInsufficientError as ue } from "../inventory-settings.es.js";
|
|
9
|
+
import { calculateCheckoutTaxes as Me, STRIPE_TAX_CODE_SHIPPING as Fe, STRIPE_TAX_CODE_NONTAXABLE as le, getStripeTaxCodeForProduct as Re } from "../tax-calculation.es.js";
|
|
10
|
+
import { getDefaultCurrency as Ne, resolveEffectivePriceForCurrency as de, normalizePriceMap as I, convertMinorUnitAmount as Be } from "../currency.es.js";
|
|
11
|
+
import { buildOrderTaxDetailsFromCalculation as Oe } from "../order-tax-details.es.js";
|
|
12
|
+
import { isDigitalItem as Ke } from "../types.es.js";
|
|
13
|
+
import { resolveTranslatedText as Qe } from "../variation-utils.es.js";
|
|
14
|
+
const ze = qe.map((r) => r.code), $e = /* @__PURE__ */ new Set([
|
|
15
15
|
"bg",
|
|
16
16
|
"cs",
|
|
17
17
|
"da",
|
|
@@ -52,7 +52,7 @@ const Qe = Pe.map((r) => r.code), ze = /* @__PURE__ */ new Set([
|
|
|
52
52
|
"zh-HK",
|
|
53
53
|
"zh-TW"
|
|
54
54
|
]);
|
|
55
|
-
function
|
|
55
|
+
function pe(r) {
|
|
56
56
|
if (r)
|
|
57
57
|
return {
|
|
58
58
|
line1: r.line1 || void 0,
|
|
@@ -63,110 +63,110 @@ function _e(r) {
|
|
|
63
63
|
country: r.country_code || void 0
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
function
|
|
67
|
-
const
|
|
68
|
-
if (!
|
|
66
|
+
function Xe(r) {
|
|
67
|
+
const i = r?.trim().replace("_", "-");
|
|
68
|
+
if (!i)
|
|
69
69
|
return;
|
|
70
|
-
const l = [
|
|
70
|
+
const l = [i, i.toLowerCase(), i.split("-")[0].toLowerCase()];
|
|
71
71
|
for (const d of l)
|
|
72
|
-
if (
|
|
72
|
+
if ($e.has(d))
|
|
73
73
|
return d;
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
return
|
|
75
|
+
function He(r, i) {
|
|
76
|
+
return Qe(
|
|
77
77
|
r.name,
|
|
78
78
|
r.name_translations || null,
|
|
79
|
-
|
|
79
|
+
i
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
|
-
async function
|
|
82
|
+
async function Ge(r) {
|
|
83
83
|
if (!r.email)
|
|
84
84
|
return null;
|
|
85
|
-
const
|
|
85
|
+
const i = await _e(), l = pe(r.shippingAddress), d = r.shippingAddress?.recipient_name || r.billingAddress?.recipient_name || void 0, p = {
|
|
86
86
|
email: r.email,
|
|
87
87
|
name: r.billingAddress?.recipient_name || r.shippingAddress?.recipient_name || void 0,
|
|
88
88
|
phone: r.phone || void 0,
|
|
89
|
-
address:
|
|
89
|
+
address: pe(r.billingAddress),
|
|
90
90
|
metadata: r.userId ? { userId: r.userId } : void 0,
|
|
91
|
-
...
|
|
91
|
+
...l && d ? {
|
|
92
92
|
shipping: {
|
|
93
|
-
name:
|
|
93
|
+
name: d,
|
|
94
94
|
phone: r.phone || void 0,
|
|
95
|
-
address:
|
|
95
|
+
address: l
|
|
96
96
|
}
|
|
97
97
|
} : {}
|
|
98
98
|
};
|
|
99
99
|
try {
|
|
100
|
-
const
|
|
100
|
+
const _ = (await i.customers.list({
|
|
101
101
|
email: r.email,
|
|
102
102
|
limit: 1
|
|
103
103
|
})).data[0];
|
|
104
|
-
return
|
|
105
|
-
} catch (
|
|
106
|
-
return console.error("Failed to upsert Stripe customer for checkout prefill:",
|
|
104
|
+
return _ ? (await i.customers.update(_.id, p), _.id) : (await i.customers.create(p)).id;
|
|
105
|
+
} catch (u) {
|
|
106
|
+
return console.error("Failed to upsert Stripe customer for checkout prefill:", u), null;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
class
|
|
109
|
+
class ct {
|
|
110
110
|
getProviderName() {
|
|
111
111
|
return "Stripe";
|
|
112
112
|
}
|
|
113
113
|
async createCheckoutSession({
|
|
114
|
-
items:
|
|
114
|
+
items: i,
|
|
115
115
|
customerEmail: l,
|
|
116
116
|
customerPhone: d,
|
|
117
117
|
userId: p,
|
|
118
|
-
billingAddress:
|
|
119
|
-
shippingAddress:
|
|
120
|
-
shippingMethodId:
|
|
118
|
+
billingAddress: u,
|
|
119
|
+
shippingAddress: _,
|
|
120
|
+
shippingMethodId: D,
|
|
121
121
|
currencyCode: me,
|
|
122
|
-
locale:
|
|
123
|
-
couponCode:
|
|
122
|
+
locale: R,
|
|
123
|
+
couponCode: N,
|
|
124
124
|
couponContextItems: U
|
|
125
125
|
}) {
|
|
126
|
-
const
|
|
127
|
-
if (!
|
|
126
|
+
const he = await _e(), B = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL, O = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
|
127
|
+
if (!B || !O)
|
|
128
128
|
return console.error("Missing Supabase credentials for checkout (Service Key required)."), { error: "Internal Server Error", url: null };
|
|
129
|
-
const
|
|
130
|
-
if (!
|
|
129
|
+
const a = Pe(B, O), K = process.env.NEXT_PUBLIC_URL || "http://localhost:4200", Q = i.some((e) => !Ke(e));
|
|
130
|
+
if (!i.length)
|
|
131
131
|
return { error: "Cart is empty", url: null };
|
|
132
|
-
const { data:
|
|
132
|
+
const { data: fe, error: z } = await a.from("currencies").select(
|
|
133
133
|
"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"
|
|
134
|
-
).eq("is_active", !0).order("code", { ascending: !0 }), y =
|
|
135
|
-
if (
|
|
136
|
-
return console.error("Error fetching currencies for checkout:",
|
|
137
|
-
const
|
|
138
|
-
if (
|
|
139
|
-
return console.error("Error fetching products for validation:",
|
|
140
|
-
const { data:
|
|
141
|
-
if (
|
|
142
|
-
return console.error("Error fetching variants for validation:",
|
|
143
|
-
const
|
|
144
|
-
for (const e of
|
|
145
|
-
const t =
|
|
134
|
+
).eq("is_active", !0).order("code", { ascending: !0 }), y = fe ?? [];
|
|
135
|
+
if (z || y.length === 0)
|
|
136
|
+
return console.error("Error fetching currencies for checkout:", z), { error: "Failed to resolve store currencies", url: null };
|
|
137
|
+
const $ = Ne(y), m = y.find((e) => e.code === (me || "").toUpperCase()) ?? $, L = m.code.toLowerCase(), X = await Le(a), ve = i.map((e) => e.product_id), H = i.map((e) => e.variant_id).filter((e) => !!e), { data: G, error: V } = await a.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", ve);
|
|
138
|
+
if (V || !G)
|
|
139
|
+
return console.error("Error fetching products for validation:", V), { error: "Failed to validate product prices", url: null };
|
|
140
|
+
const { data: ye, error: W } = H.length ? await a.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", H) : { data: [], error: null };
|
|
141
|
+
if (W)
|
|
142
|
+
return console.error("Error fetching variants for validation:", W), { error: "Failed to validate product variants", url: null };
|
|
143
|
+
const Y = new Map(G.map((e) => [e.id, e])), j = new Map((ye || []).map((e) => [e.id, e])), M = /* @__PURE__ */ new Set(), w = /* @__PURE__ */ new Map();
|
|
144
|
+
for (const e of i) {
|
|
145
|
+
const t = Y.get(e.product_id);
|
|
146
146
|
if (!t)
|
|
147
147
|
continue;
|
|
148
|
-
const n = (e.variant_id ?
|
|
149
|
-
n && (M.add(n),
|
|
148
|
+
const n = (e.variant_id ? j.get(e.variant_id) : null)?.sku || t.sku;
|
|
149
|
+
n && (M.add(n), w.set(
|
|
150
150
|
n,
|
|
151
|
-
(
|
|
151
|
+
(w.get(n) ?? 0) + e.quantity
|
|
152
152
|
));
|
|
153
153
|
}
|
|
154
|
-
const { data:
|
|
155
|
-
if (
|
|
156
|
-
return console.error("Error fetching SKU inventory for validation:",
|
|
157
|
-
const
|
|
158
|
-
(
|
|
154
|
+
const { data: ge, error: J } = M.size ? await a.from("inventory_items").select("sku, quantity").in("sku", [...M]) : { data: [], error: null };
|
|
155
|
+
if (J)
|
|
156
|
+
return console.error("Error fetching SKU inventory for validation:", J), { error: "Failed to validate SKU inventory", url: null };
|
|
157
|
+
const b = new Map(
|
|
158
|
+
(ge || []).map((e) => [
|
|
159
159
|
e.sku,
|
|
160
160
|
Math.max(0, e.quantity ?? 0)
|
|
161
161
|
])
|
|
162
|
-
), g = [],
|
|
163
|
-
let
|
|
164
|
-
if (
|
|
162
|
+
), g = [], Z = [], ee = [];
|
|
163
|
+
let f = 0, S = 0, c = null;
|
|
164
|
+
if (N) {
|
|
165
165
|
const e = await be({
|
|
166
|
-
client:
|
|
167
|
-
code:
|
|
168
|
-
items: U && U.length > 0 ? U :
|
|
169
|
-
currencyCode:
|
|
166
|
+
client: a,
|
|
167
|
+
code: N,
|
|
168
|
+
items: U && U.length > 0 ? U : i,
|
|
169
|
+
currencyCode: m.code
|
|
170
170
|
});
|
|
171
171
|
if (!e.success)
|
|
172
172
|
return {
|
|
@@ -177,17 +177,17 @@ class nt {
|
|
|
177
177
|
};
|
|
178
178
|
c = e.quote;
|
|
179
179
|
}
|
|
180
|
-
const
|
|
181
|
-
const t = e.unitAmount * e.quantity,
|
|
182
|
-
if (
|
|
180
|
+
const Se = Te(c), Ce = (e) => {
|
|
181
|
+
const t = e.unitAmount * e.quantity, v = Math.max(0, t - e.lineDiscount);
|
|
182
|
+
if (v <= 0)
|
|
183
183
|
return;
|
|
184
|
-
const n = Math.floor(
|
|
184
|
+
const n = Math.floor(v / e.quantity), P = v - n * e.quantity, k = (q, E) => {
|
|
185
185
|
E <= 0 || q <= 0 || g.push({
|
|
186
186
|
price_data: {
|
|
187
187
|
currency: e.currency,
|
|
188
188
|
product_data: {
|
|
189
189
|
name: e.name,
|
|
190
|
-
tax_code:
|
|
190
|
+
tax_code: Re(e.isTaxable),
|
|
191
191
|
metadata: {
|
|
192
192
|
productId: e.productId,
|
|
193
193
|
variantId: e.variantId || ""
|
|
@@ -201,14 +201,14 @@ class nt {
|
|
|
201
201
|
};
|
|
202
202
|
k(n, e.quantity - P), k(n + 1, P);
|
|
203
203
|
};
|
|
204
|
-
for (const e of
|
|
205
|
-
const t =
|
|
204
|
+
for (const e of i) {
|
|
205
|
+
const t = Y.get(e.product_id);
|
|
206
206
|
if (!t)
|
|
207
207
|
return console.warn(`Product ${e.product_id} not found in DB.`), {
|
|
208
208
|
url: null,
|
|
209
|
-
...
|
|
209
|
+
...se(e.title)
|
|
210
210
|
};
|
|
211
|
-
const
|
|
211
|
+
const v = de({
|
|
212
212
|
prices: I(t.prices),
|
|
213
213
|
salePrices: t.sale_prices || {},
|
|
214
214
|
fallbackPrice: t.price,
|
|
@@ -218,24 +218,24 @@ class nt {
|
|
|
218
218
|
scheduledPrice: t.scheduled_price,
|
|
219
219
|
scheduledPrices: I(t.scheduled_prices),
|
|
220
220
|
scheduledPriceAt: t.scheduled_price_at,
|
|
221
|
-
currencyCode:
|
|
221
|
+
currencyCode: m.code,
|
|
222
222
|
currencies: y
|
|
223
223
|
});
|
|
224
|
-
let n =
|
|
224
|
+
let n = v.sale_price ?? v.price, P = t.title, k = null;
|
|
225
225
|
if (e.variant_id) {
|
|
226
|
-
const o =
|
|
226
|
+
const o = j.get(e.variant_id);
|
|
227
227
|
if (!o || o.product_id !== e.product_id)
|
|
228
228
|
return {
|
|
229
229
|
url: null,
|
|
230
|
-
...
|
|
230
|
+
...se(e.title)
|
|
231
231
|
};
|
|
232
|
-
const A =
|
|
233
|
-
if (
|
|
232
|
+
const A = w.get(o.sku) ?? e.quantity, ne = b.has(o.sku) ? b.get(o.sku) ?? 0 : Math.max(0, o.stock_quantity ?? 0);
|
|
233
|
+
if (X.trackQuantities && A > ne)
|
|
234
234
|
return {
|
|
235
235
|
url: null,
|
|
236
|
-
...
|
|
236
|
+
...ue(e.title, ne)
|
|
237
237
|
};
|
|
238
|
-
const
|
|
238
|
+
const ce = de({
|
|
239
239
|
prices: I(o.prices),
|
|
240
240
|
salePrices: o.sale_prices || {},
|
|
241
241
|
fallbackPrice: o.price,
|
|
@@ -245,16 +245,16 @@ class nt {
|
|
|
245
245
|
scheduledPrice: o.scheduled_price,
|
|
246
246
|
scheduledPrices: I(o.scheduled_prices),
|
|
247
247
|
scheduledPriceAt: o.scheduled_price_at,
|
|
248
|
-
currencyCode:
|
|
248
|
+
currencyCode: m.code,
|
|
249
249
|
currencies: y
|
|
250
250
|
});
|
|
251
|
-
n =
|
|
251
|
+
n = ce.sale_price ?? ce.price, k = o.id, P = e.variant_label ? `${t.title} - ${e.variant_label}` : `${t.title} - ${o.sku}`;
|
|
252
252
|
} else {
|
|
253
|
-
const o =
|
|
254
|
-
if (
|
|
253
|
+
const o = w.get(t.sku) ?? e.quantity, A = b.has(t.sku) ? b.get(t.sku) ?? 0 : Math.max(0, t.stock ?? 0);
|
|
254
|
+
if (X.trackQuantities && o > A)
|
|
255
255
|
return {
|
|
256
256
|
url: null,
|
|
257
|
-
...
|
|
257
|
+
...ue(e.title, A)
|
|
258
258
|
};
|
|
259
259
|
}
|
|
260
260
|
const q = t.is_taxable ?? !0;
|
|
@@ -262,9 +262,9 @@ class nt {
|
|
|
262
262
|
return { error: "A product variation produced an invalid price.", url: null };
|
|
263
263
|
const E = Math.min(
|
|
264
264
|
n * e.quantity,
|
|
265
|
-
|
|
265
|
+
Se.get(Ie(e)) ?? 0
|
|
266
266
|
);
|
|
267
|
-
|
|
267
|
+
Ce({
|
|
268
268
|
name: P,
|
|
269
269
|
currency: L,
|
|
270
270
|
productId: t.id,
|
|
@@ -273,12 +273,12 @@ class nt {
|
|
|
273
273
|
unitAmount: n,
|
|
274
274
|
quantity: e.quantity,
|
|
275
275
|
lineDiscount: E
|
|
276
|
-
}),
|
|
276
|
+
}), f += n * e.quantity, S += E, ee.push({
|
|
277
277
|
product_id: t.id,
|
|
278
278
|
quantity: e.quantity,
|
|
279
279
|
price_at_purchase: n,
|
|
280
280
|
variant_id: k
|
|
281
|
-
}),
|
|
281
|
+
}), Z.push({
|
|
282
282
|
product_id: t.id,
|
|
283
283
|
quantity: e.quantity,
|
|
284
284
|
unit_amount: n,
|
|
@@ -286,7 +286,7 @@ class nt {
|
|
|
286
286
|
is_taxable: q
|
|
287
287
|
});
|
|
288
288
|
}
|
|
289
|
-
if (g.length === 0 && S >=
|
|
289
|
+
if (g.length === 0 && S >= f)
|
|
290
290
|
return {
|
|
291
291
|
error: "This coupon would reduce the Stripe order to zero. Use a smaller discount for Stripe checkout.",
|
|
292
292
|
errorKey: "ecommerce.coupon_zero_total_not_supported",
|
|
@@ -295,77 +295,77 @@ class nt {
|
|
|
295
295
|
};
|
|
296
296
|
if (g.length === 0)
|
|
297
297
|
return { error: "No valid items in cart", url: null };
|
|
298
|
-
let
|
|
299
|
-
if (
|
|
300
|
-
const { data: e, error: t } = await
|
|
298
|
+
let h = 0, F = null;
|
|
299
|
+
if (D) {
|
|
300
|
+
const { data: e, error: t } = await a.from("shipping_zone_methods").select("id, name, name_translations, cost_amount, cost_currency").eq("id", D).single();
|
|
301
301
|
if (t)
|
|
302
302
|
return console.error("Failed to load shipping method:", t), { error: "Failed to load shipping method", url: null };
|
|
303
|
-
|
|
303
|
+
h = Be({
|
|
304
304
|
amount: e.cost_amount ?? 0,
|
|
305
|
-
fromCurrencyCode: e.cost_currency ||
|
|
306
|
-
toCurrencyCode:
|
|
305
|
+
fromCurrencyCode: e.cost_currency || $.code,
|
|
306
|
+
toCurrencyCode: m.code,
|
|
307
307
|
currencies: y
|
|
308
|
-
}), F =
|
|
308
|
+
}), F = He(e, R);
|
|
309
309
|
}
|
|
310
|
-
const
|
|
311
|
-
let
|
|
310
|
+
const te = Q ? _ ?? u : u;
|
|
311
|
+
let s;
|
|
312
312
|
try {
|
|
313
|
-
|
|
314
|
-
items:
|
|
313
|
+
s = await Me(a, {
|
|
314
|
+
items: Z,
|
|
315
315
|
destination: {
|
|
316
|
-
country_code:
|
|
317
|
-
state:
|
|
316
|
+
country_code: te?.country_code,
|
|
317
|
+
state: te?.state
|
|
318
318
|
}
|
|
319
319
|
});
|
|
320
320
|
} catch (e) {
|
|
321
321
|
return console.error("Failed to calculate checkout taxes:", e), { error: "Failed to calculate taxes", url: null };
|
|
322
322
|
}
|
|
323
|
-
|
|
323
|
+
h > 0 && F && g.push({
|
|
324
324
|
price_data: {
|
|
325
325
|
currency: L,
|
|
326
326
|
product_data: {
|
|
327
327
|
name: F,
|
|
328
|
-
tax_code:
|
|
328
|
+
tax_code: s.enabled && s.mode === "automatic" ? Fe : le
|
|
329
329
|
},
|
|
330
330
|
tax_behavior: "exclusive",
|
|
331
|
-
unit_amount:
|
|
331
|
+
unit_amount: h
|
|
332
332
|
},
|
|
333
333
|
quantity: 1
|
|
334
334
|
});
|
|
335
|
-
const C =
|
|
335
|
+
const C = s.enabled && s.mode === "manual" && !s.isPendingExternalCalculation ? s.amount : 0;
|
|
336
336
|
C > 0 && g.push({
|
|
337
337
|
price_data: {
|
|
338
338
|
currency: L,
|
|
339
339
|
product_data: {
|
|
340
340
|
name: "Tax",
|
|
341
|
-
tax_code:
|
|
341
|
+
tax_code: le
|
|
342
342
|
},
|
|
343
343
|
tax_behavior: "exclusive",
|
|
344
344
|
unit_amount: C
|
|
345
345
|
},
|
|
346
346
|
quantity: 1
|
|
347
347
|
});
|
|
348
|
-
const
|
|
348
|
+
const xe = we({
|
|
349
349
|
email: l,
|
|
350
350
|
phone: d,
|
|
351
|
-
name:
|
|
352
|
-
billing:
|
|
353
|
-
shipping:
|
|
354
|
-
}),
|
|
355
|
-
calculation:
|
|
356
|
-
subtotal:
|
|
357
|
-
shippingTotal:
|
|
358
|
-
total: Math.max(0,
|
|
359
|
-
currency:
|
|
360
|
-
}),
|
|
351
|
+
name: u?.recipient_name,
|
|
352
|
+
billing: u,
|
|
353
|
+
shipping: _
|
|
354
|
+
}), re = m.code, ke = Oe({
|
|
355
|
+
calculation: s,
|
|
356
|
+
subtotal: f,
|
|
357
|
+
shippingTotal: h,
|
|
358
|
+
total: Math.max(0, f - S) + h + C,
|
|
359
|
+
currency: re
|
|
360
|
+
}), Ee = Math.max(0, f - S) + h + C, { data: oe, error: ie } = await a.from("orders").insert({
|
|
361
361
|
status: "pending",
|
|
362
|
-
total:
|
|
363
|
-
currency:
|
|
364
|
-
exchange_rate_at_purchase:
|
|
365
|
-
subtotal:
|
|
366
|
-
shipping_total:
|
|
362
|
+
total: Ee,
|
|
363
|
+
currency: re,
|
|
364
|
+
exchange_rate_at_purchase: m.exchange_rate,
|
|
365
|
+
subtotal: f,
|
|
366
|
+
shipping_total: h,
|
|
367
367
|
tax_total: C,
|
|
368
|
-
tax_details:
|
|
368
|
+
tax_details: ke,
|
|
369
369
|
coupon_id: c?.couponId ?? null,
|
|
370
370
|
coupon_code: c?.code ?? null,
|
|
371
371
|
discount_total: S,
|
|
@@ -379,12 +379,12 @@ class nt {
|
|
|
379
379
|
} : null,
|
|
380
380
|
provider: "stripe",
|
|
381
381
|
user_id: p,
|
|
382
|
-
customer_details:
|
|
382
|
+
customer_details: xe
|
|
383
383
|
}).select("id").single();
|
|
384
|
-
if (ie || !
|
|
384
|
+
if (ie || !oe)
|
|
385
385
|
return console.error("Failed to create pending order:", ie), { error: "Failed to initiate order", url: null };
|
|
386
|
-
const x =
|
|
387
|
-
|
|
386
|
+
const x = oe.id, { error: ae } = await a.from("order_items").insert(
|
|
387
|
+
ee.map((e) => ({
|
|
388
388
|
order_id: x,
|
|
389
389
|
product_id: e.product_id,
|
|
390
390
|
variant_id: e.variant_id ?? null,
|
|
@@ -392,20 +392,20 @@ class nt {
|
|
|
392
392
|
price_at_purchase: e.price_at_purchase
|
|
393
393
|
}))
|
|
394
394
|
);
|
|
395
|
-
if (
|
|
396
|
-
return console.error("Failed to insert order items:",
|
|
395
|
+
if (ae)
|
|
396
|
+
return console.error("Failed to insert order items:", ae), await a.from("orders").update({ status: "failed" }).eq("id", x), { error: "Failed to record order items", url: null };
|
|
397
397
|
if (p)
|
|
398
398
|
try {
|
|
399
|
-
await
|
|
399
|
+
await De({
|
|
400
400
|
userId: p,
|
|
401
|
-
billingAddress:
|
|
402
|
-
shippingAddress:
|
|
403
|
-
client:
|
|
404
|
-
}), await
|
|
401
|
+
billingAddress: u,
|
|
402
|
+
shippingAddress: _,
|
|
403
|
+
client: a
|
|
404
|
+
}), await Ue({
|
|
405
405
|
userId: p,
|
|
406
|
-
fullName:
|
|
406
|
+
fullName: u?.recipient_name ?? _?.recipient_name ?? null,
|
|
407
407
|
phone: d,
|
|
408
|
-
client:
|
|
408
|
+
client: a
|
|
409
409
|
});
|
|
410
410
|
} catch (e) {
|
|
411
411
|
console.error(
|
|
@@ -413,8 +413,8 @@ class nt {
|
|
|
413
413
|
e
|
|
414
414
|
);
|
|
415
415
|
}
|
|
416
|
-
c && await
|
|
417
|
-
client:
|
|
416
|
+
c && await Ae({
|
|
417
|
+
client: a,
|
|
418
418
|
quote: c,
|
|
419
419
|
orderId: x,
|
|
420
420
|
provider: "stripe",
|
|
@@ -422,27 +422,27 @@ class nt {
|
|
|
422
422
|
userId: p,
|
|
423
423
|
customerEmail: l,
|
|
424
424
|
metadata: {
|
|
425
|
-
currency:
|
|
426
|
-
subtotal:
|
|
427
|
-
shipping_total:
|
|
425
|
+
currency: m.code,
|
|
426
|
+
subtotal: f,
|
|
427
|
+
shipping_total: h,
|
|
428
428
|
tax_total: C
|
|
429
429
|
}
|
|
430
430
|
});
|
|
431
|
-
const T = await
|
|
431
|
+
const T = await Ge({
|
|
432
432
|
email: l,
|
|
433
433
|
phone: d,
|
|
434
434
|
userId: p,
|
|
435
|
-
billingAddress:
|
|
436
|
-
shippingAddress:
|
|
435
|
+
billingAddress: u,
|
|
436
|
+
shippingAddress: _
|
|
437
437
|
});
|
|
438
438
|
try {
|
|
439
|
-
const e = await
|
|
439
|
+
const e = await he.checkout.sessions.create({
|
|
440
440
|
mode: "payment",
|
|
441
|
-
success_url: `${
|
|
442
|
-
cancel_url: `${
|
|
443
|
-
locale:
|
|
441
|
+
success_url: `${K}/checkout/success?session_id={CHECKOUT_SESSION_ID}`,
|
|
442
|
+
cancel_url: `${K}/checkout`,
|
|
443
|
+
locale: Xe(R),
|
|
444
444
|
line_items: g,
|
|
445
|
-
automatic_tax:
|
|
445
|
+
automatic_tax: s.enabled && s.mode === "automatic" ? { enabled: !0 } : void 0,
|
|
446
446
|
billing_address_collection: "auto",
|
|
447
447
|
customer: T || void 0,
|
|
448
448
|
customer_email: T ? void 0 : l || void 0,
|
|
@@ -452,22 +452,22 @@ class nt {
|
|
|
452
452
|
address: "auto",
|
|
453
453
|
shipping: "auto"
|
|
454
454
|
} : void 0,
|
|
455
|
-
shipping_address_collection:
|
|
456
|
-
allowed_countries:
|
|
455
|
+
shipping_address_collection: Q ? {
|
|
456
|
+
allowed_countries: ze
|
|
457
457
|
} : void 0,
|
|
458
458
|
metadata: {
|
|
459
459
|
orderId: x,
|
|
460
|
-
taxMode:
|
|
461
|
-
currencyCode:
|
|
460
|
+
taxMode: s.mode,
|
|
461
|
+
currencyCode: m.code,
|
|
462
462
|
couponCode: c?.code || ""
|
|
463
463
|
}
|
|
464
|
-
}), { error: t } = await
|
|
464
|
+
}), { error: t } = await a.from("orders").update({ stripe_session_id: e.id }).eq("id", x);
|
|
465
465
|
return t && console.error("Failed to save Stripe session ID on order:", t), { url: e.url };
|
|
466
466
|
} catch (e) {
|
|
467
|
-
return console.error("Stripe session creation failed:", e), await
|
|
467
|
+
return console.error("Stripe session creation failed:", e), await a.from("orders").update({ status: "failed" }).eq("id", x), { error: e.message, url: null };
|
|
468
468
|
}
|
|
469
469
|
}
|
|
470
470
|
}
|
|
471
471
|
export {
|
|
472
|
-
|
|
472
|
+
ct as StripeProvider
|
|
473
473
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("./client.cjs.js"),k=require("@supabase/supabase-js"),L=require("@nextblock-cms/db/server"),N=require("../shipping/resolver.cjs.js"),C=require("../currency.cjs.js"),T=async(n,d,P,A)=>{const m=process.env.NEXT_PUBLIC_SUPABASE_URL||process.env.SUPABASE_URL,h=process.env.SUPABASE_SERVICE_ROLE_KEY||process.env.SUPABASE_SECRET_KEY;if(!m||!h)return console.error("Missing Supabase credentials for checkout (Service Key required)."),{error:"Internal Server Error",url:null};const t=k.createClient(m,h),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("./client.cjs.js"),k=require("@supabase/supabase-js"),L=require("@nextblock-cms/db/server"),N=require("../shipping/resolver.cjs.js"),C=require("../currency.cjs.js"),T=async(n,d,P,A)=>{const m=process.env.NEXT_PUBLIC_SUPABASE_URL||process.env.SUPABASE_URL,h=process.env.SUPABASE_SERVICE_ROLE_KEY||process.env.SUPABASE_SECRET_KEY;if(!m||!h)return console.error("Missing Supabase credentials for checkout (Service Key required)."),{error:"Internal Server Error",url:null};const t=k.createClient(m,h),g=process.env.NEXT_PUBLIC_URL||"http://localhost:4200";if(!n.length)return{error:"Cart is empty",url:null};const{data:q}=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}),u=q??[],w=C.getDefaultCurrency(u),s=u.find(e=>e.code===(A||"").toUpperCase())??w;if(!await L.verifyPackageOnline("ecommerce"))return{error:"E-Commerce Package not active. Please purchase a license to accept payments.",url:null};const U=n.map(e=>e.product_id),{data:f,error:y}=await t.from("products").select("id, title, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at").in("id",U);if(y||!f)return console.error("Error fetching products for validation:",y),{error:"Failed to validate product prices",url:null};const I=new Map(f.map(e=>[e.id,e])),l=[];let c=0;const E=[];for(const e of n){const r=I.get(e.product_id);if(!r){console.warn(`Product ${e.product_id} not found in DB, skipping.`);continue}const v=C.resolveEffectivePriceForCurrency({prices:r.prices||{},salePrices:r.sale_prices||{},fallbackPrice:r.price,fallbackSalePrice:r.sale_price,saleStartAt:r.sale_start_at,saleEndAt:r.sale_end_at,scheduledPrice:r.scheduled_price,scheduledPrices:r.scheduled_prices||{},scheduledPriceAt:r.scheduled_price_at,currencyCode:s.code,currencies:u}),a=v.sale_price??v.price;a<=0&&console.warn(`[Checkout Session Warning] Product ${r.title} has zero or negative price!`),l.push({price_data:{currency:s.code.toLowerCase(),product_data:{name:r.title,images:[],metadata:{productId:r.id}},unit_amount:a},quantity:e.quantity}),c+=a*e.quantity,E.push({product_id:r.id,quantity:e.quantity,price_at_purchase:a})}if(l.length===0)return{error:"No valid items in cart",url:null};const{data:o,error:p}=await t.from("orders").insert({total:c,user_id:d,currency:s.code,exchange_rate_at_purchase:s.exchange_rate}).select("id").single();if(p||!o)return console.error("Failed to create pending order:",p),console.error("Order Data attempted:",{status:"pending",total:c}),{error:`Failed to initiate order: ${p?.message||"Unknown error"}`,url:null};const R=E.map(e=>({order_id:o.id,product_id:e.product_id,quantity:e.quantity,price_at_purchase:e.price_at_purchase})),{error:S}=await t.from("order_items").insert(R);S&&console.error("Failed to insert order items:",S);let _=[],i=P;if(!i&&d){const{data:e}=await t.from("user_addresses").select("country_code, state_code, postal_code").eq("user_id",d).eq("address_type","shipping").limit(1).single();e&&(i={country:e.country_code,state:e.state_code,postal_code:e.postal_code})}i&&(_=(await N.resolveShippingOptions(c,i,null,s.code)).map(r=>({shipping_rate_data:{type:"fixed_amount",fixed_amount:{amount:r.amount,currency:r.currency.toLowerCase()},display_name:r.name}})));try{const r=await(await b.getStripeClient()).checkout.sessions.create({mode:"payment",success_url:`${g}/checkout/success?session_id={CHECKOUT_SESSION_ID}`,cancel_url:`${g}/`,line_items:l,billing_address_collection:"required",shipping_address_collection:{allowed_countries:["US","CA","GB","AU","NZ","IE","FR","DE","IT","ES","MX","BR","AR","CL","CO","PE","ZA","NG","KE","IN","JP","KR","CN","SG","MY","PH","TH","VN","ID","AE","SA","EG","MA","DZ","TN","PT","NL","BE","CH","AT","SE","NO","DK","FI","PL","CZ","HU","RO","BG","GR","TR","IL","CY","MT"]},shipping_options:_.length>0?_:void 0,metadata:{orderId:o.id}});return await t.from("orders").update({stripe_session_id:r.id}).eq("id",o.id),{url:r.url}}catch(e){return console.error("Stripe session creation failed:",e),{error:e.message,url:null}}};exports.createCheckoutSession=T;
|