@monkeyplus/payscope 1.0.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.
Files changed (82) hide show
  1. package/dist/THIRD-PARTY-LICENSES.md +41 -0
  2. package/dist/_chunks/auth.d.mts +707 -0
  3. package/dist/_chunks/database.mjs +831 -0
  4. package/dist/_chunks/db.d.mts +7100 -0
  5. package/dist/_chunks/index.d.mts +178 -0
  6. package/dist/_chunks/lib.mjs +3073 -0
  7. package/dist/_chunks/libs/better-call.d.mts +478 -0
  8. package/dist/_chunks/libs/postgres.d.mts +1 -0
  9. package/dist/_chunks/rolldown-runtime.mjs +11 -0
  10. package/dist/server/db.d.mts +2 -0
  11. package/dist/server/db.mjs +108 -0
  12. package/dist/server/env.d.mts +21 -0
  13. package/dist/server/env.mjs +22 -0
  14. package/dist/server/lib.d.mts +362 -0
  15. package/dist/server/lib.mjs +2 -0
  16. package/dist/server/router.d.mts +1218 -0
  17. package/dist/server/router.mjs +1157 -0
  18. package/dist/server/schemas/auth.d.mts +2 -0
  19. package/dist/server/schemas/auth.mjs +62 -0
  20. package/package.json +58 -0
  21. package/storefront/Readme.md +0 -0
  22. package/storefront/auth.ts +29 -0
  23. package/storefront/cart/ResumeCart.vue +217 -0
  24. package/storefront/cart/ResumeCartSelect.vue +32 -0
  25. package/storefront/cart/ShoppinCart.vue +100 -0
  26. package/storefront/cart/ShoppinCartItem.vue +99 -0
  27. package/storefront/checkout/App.vue +36 -0
  28. package/storefront/checkout/AppCart.vue +72 -0
  29. package/storefront/checkout/AppCartDiscount.vue +74 -0
  30. package/storefront/checkout/AppCartTotals.vue +72 -0
  31. package/storefront/checkout/AppLoading.vue +55 -0
  32. package/storefront/checkout/composables.ts +28 -0
  33. package/storefront/checkout/constants.ts +0 -0
  34. package/storefront/checkout/main.ts +11 -0
  35. package/storefront/checkout/pages/Address/Address.vue +95 -0
  36. package/storefront/checkout/pages/Info/Info.vue +94 -0
  37. package/storefront/checkout/pages/Info/InfoUser.vue +38 -0
  38. package/storefront/checkout/pages/Pay/Pay.vue +115 -0
  39. package/storefront/checkout/pages/Pay/Providers/BancoEconomico/BancoEconomico.vue +9 -0
  40. package/storefront/checkout/pages/Pay/Providers/Cybersource/Cybersource.vue +9 -0
  41. package/storefront/checkout/pages/Pay/Providers/Datafast/Datafast.vue +9 -0
  42. package/storefront/checkout/pages/Pay/Providers/Multipago/Multipago.vue +9 -0
  43. package/storefront/checkout/pages/Pay/Providers/Pagomedios/Pagomedios.vue +93 -0
  44. package/storefront/checkout/pages/Pay/Providers/Pagomedios/composable.ts +23 -0
  45. package/storefront/checkout/pages/Pay/Providers/Paypal/Paypal.vue +168 -0
  46. package/storefront/checkout/pages/Pay/Providers/Paypal/composable.ts +33 -0
  47. package/storefront/checkout/pages/Pay/Providers/Placetopay/Placetopay.vue +9 -0
  48. package/storefront/checkout/pages/Pay/Providers/Wabi/Wabi.vue +9 -0
  49. package/storefront/checkout/pages/Pay/Providers/composable.ts +30 -0
  50. package/storefront/checkout/pages/Payment/Payment.vue +19 -0
  51. package/storefront/checkout/pages/Payment/PaymentStatus.vue +187 -0
  52. package/storefront/checkout/pages/Payment/PaymentStatusDetail.vue +77 -0
  53. package/storefront/checkout/pages/Payment/composable.ts +81 -0
  54. package/storefront/checkout/pages/Shipping/Shipping.vue +67 -0
  55. package/storefront/checkout/pages/StepInfo.vue +37 -0
  56. package/storefront/checkout/router.ts +59 -0
  57. package/storefront/index.ts +3 -0
  58. package/storefront/login/App.vue +9 -0
  59. package/storefront/login/main.ts +10 -0
  60. package/storefront/login/pages/SignIn/Login.vue +82 -0
  61. package/storefront/login/pages/SignUp/SignUp.vue +99 -0
  62. package/storefront/login/router.ts +15 -0
  63. package/storefront/product/AddProduct.vue +303 -0
  64. package/storefront/product/AddProductNumber.vue +62 -0
  65. package/storefront/product/AddProductVariant.vue +66 -0
  66. package/storefront/profile/App.vue +88 -0
  67. package/storefront/profile/main.ts +10 -0
  68. package/storefront/profile/pages/Addresses/Addresses.vue +79 -0
  69. package/storefront/profile/pages/Addresses/AddressesForm.vue +95 -0
  70. package/storefront/profile/pages/Addresses/AddressesModal.vue +24 -0
  71. package/storefront/profile/pages/Buys/Buys.vue +8 -0
  72. package/storefront/profile/pages/Me/Me.vue +15 -0
  73. package/storefront/profile/pages/Me/MeBilling.vue +79 -0
  74. package/storefront/profile/pages/Me/MeBillingForm.vue +66 -0
  75. package/storefront/profile/pages/Me/MeBillingModal.vue +24 -0
  76. package/storefront/profile/pages/Me/MeInfo.vue +75 -0
  77. package/storefront/profile/pages/Me/MePassword.vue +53 -0
  78. package/storefront/profile/pages/Me/MeSubscriptions.vue +15 -0
  79. package/storefront/profile/pages/Returns/Returns.vue +8 -0
  80. package/storefront/profile/pages/Whislist/Whislist.vue +8 -0
  81. package/storefront/profile/router.ts +32 -0
  82. package/storefront/stores.ts +320 -0
@@ -0,0 +1,1157 @@
1
+ import { checkouts, customerAddresses, customerBillings, customerWhislists } from "../_chunks/database.mjs";
2
+ import { GRAPHQL_TOKEN, TASKS_ENDPOINT, URL } from "./env.mjs";
3
+ import { createGraphql, createPayment } from "../_chunks/lib.mjs";
4
+ import { eq } from "drizzle-orm";
5
+ import dayjs from "dayjs";
6
+ import { HTTPError, createError, eventHandler, getCookie, getQuery, getRequestIP, getRouterParam, readBody, redirect, setCookie } from "h3";
7
+ import { joinURL } from "ufo";
8
+ import { defu } from "defu";
9
+ function useUser(event) {
10
+ return event.context.user;
11
+ }
12
+ function registerAccount(app, db, { path, storeId }) {
13
+ app.post(path("/account/billings"), eventHandler(async (event) => {
14
+ const { id: customerId } = useUser(event);
15
+ const data = await readBody(event);
16
+ return await db.insert(customerBillings).values({
17
+ storeId,
18
+ customerId,
19
+ data
20
+ });
21
+ }));
22
+ app.get(path("/account/billings"), eventHandler(async (event) => {
23
+ const { id: customerId } = useUser(event);
24
+ const items = await db.query.customerBillings.findMany({ where: {
25
+ storeId,
26
+ customerId
27
+ } });
28
+ const formatted = (data) => {
29
+ return { formatted: [
30
+ data.identification,
31
+ data.fullname,
32
+ data.email
33
+ ].filter((v) => !!v).join("/ ") };
34
+ };
35
+ return items.map((item) => ({
36
+ ...item,
37
+ ...item.data,
38
+ ...formatted(item.data),
39
+ data: void 0
40
+ }));
41
+ }));
42
+ app.patch(path("/account/billings/:id"), eventHandler(async (event) => {
43
+ const id = getRouterParam(event, "id");
44
+ const data = await readBody(event);
45
+ return await db.update(customerBillings).set({ data }).where(eq(customerBillings.id, Number(id))).returning();
46
+ }));
47
+ app.delete(path("/account/billings/:id"), eventHandler(async (event) => {
48
+ const id = getRouterParam(event, "id");
49
+ return await db.delete(customerBillings).where(eq(customerBillings.id, Number(id)));
50
+ }));
51
+ app.post(path("/account/addresses"), eventHandler(async (event) => {
52
+ const { id: customerId } = useUser(event);
53
+ const data = await readBody(event);
54
+ return await db.insert(customerAddresses).values({
55
+ storeId,
56
+ customerId,
57
+ data
58
+ });
59
+ }));
60
+ app.get(path("/account/addresses"), eventHandler(async (event) => {
61
+ const { id: customerId } = useUser(event);
62
+ const items = await db.query.customerAddresses.findMany({ where: {
63
+ storeId,
64
+ customerId
65
+ } });
66
+ const formatted = (data) => {
67
+ return {
68
+ name: [data.firstName, data.lastName].filter((v) => !!v).join(" "),
69
+ formatted: [
70
+ data.address1,
71
+ data.address2,
72
+ data.zip,
73
+ data.city,
74
+ data.country
75
+ ].filter((v) => !!v).join(", ")
76
+ };
77
+ };
78
+ return items.map((item) => ({
79
+ ...item,
80
+ ...item.data,
81
+ ...formatted(item.data),
82
+ data: void 0
83
+ }));
84
+ }));
85
+ app.patch(path("/account/addresses/:id"), eventHandler(async (event) => {
86
+ const id = getRouterParam(event, "id");
87
+ const data = await readBody(event);
88
+ return await db.update(customerAddresses).set({ data }).where(eq(customerAddresses.id, Number(id))).returning();
89
+ }));
90
+ app.delete(path("/account/addresses/:id"), eventHandler(async (event) => {
91
+ const id = getRouterParam(event, "id");
92
+ return await db.delete(customerAddresses).where(eq(customerAddresses.id, Number(id)));
93
+ }));
94
+ app.post(path("/account/wishlist"), eventHandler(async (event) => {
95
+ const { id: customerId } = useUser(event);
96
+ const data = await readBody(event);
97
+ return await db.insert(customerWhislists).values({
98
+ storeId,
99
+ customerId,
100
+ productId: data?.productId,
101
+ data: data?.data
102
+ });
103
+ }));
104
+ app.get(path("/account/wishlist"), eventHandler(async (event) => {
105
+ const { id: customerId } = useUser(event);
106
+ return await db.query.customerWhislists.findMany({ where: {
107
+ storeId,
108
+ customerId
109
+ } });
110
+ }));
111
+ app.patch(path("/account/wishlist/:id"), eventHandler(async (event) => {
112
+ const id = getRouterParam(event, "id");
113
+ const data = await readBody(event);
114
+ return await db.update(customerWhislists).set({ data }).where(eq(customerWhislists.id, Number(id))).returning();
115
+ }));
116
+ app.delete(path("/account/wishlist/:id"), eventHandler(async (event) => {
117
+ const id = getRouterParam(event, "id");
118
+ return await db.delete(customerWhislists).where(eq(customerWhislists.id, Number(id)));
119
+ }));
120
+ app.get(path("/account/returns"), eventHandler(async (event) => {
121
+ const { id: customerId } = useUser(event);
122
+ return await db.query.customerReturns.findMany({ where: {
123
+ storeId,
124
+ customerId
125
+ } });
126
+ }));
127
+ app.get(path("/account/orders"), eventHandler(async (event) => {
128
+ const { id: customerId } = useUser(event);
129
+ return await db.query.orders.findMany({ where: {
130
+ storeId,
131
+ customerId
132
+ } });
133
+ }));
134
+ }
135
+ function useGuardSession(auth, options) {
136
+ return eventHandler(async (event) => {
137
+ console.log(`${event.method}::${event.path}`);
138
+ if (options.pathsToExclude.some((p) => event.path.startsWith(p))) return;
139
+ const session = await auth.api.getSession({ headers: event.req.headers });
140
+ if (!session?.user) return createError({
141
+ statusCode: 401,
142
+ statusMessage: "Unauthorized"
143
+ });
144
+ event.context.user = session.user;
145
+ event.context.session = session.session;
146
+ });
147
+ }
148
+ function registerAuthMiddleware(app, options) {
149
+ app.use(options.guard?.path || "/**", useGuardSession(options.auth, { pathsToExclude: [
150
+ "/api/auth/",
151
+ "/api/session",
152
+ ...options.guard?.excludePaths || []
153
+ ] }));
154
+ }
155
+ function registerAuth(app, auth) {
156
+ app.use("/api/auth/**", eventHandler(async (event) => {
157
+ const r = await auth.handler(event.req);
158
+ if (r.status === 302) return redirect(r.headers.get("location"));
159
+ r.headers.forEach((value, key) => {
160
+ event.res.errHeaders.set(key, value);
161
+ });
162
+ return r;
163
+ }));
164
+ app.get("/api/session/me", eventHandler(async (event) => {
165
+ return await auth.api.getSession({ headers: event.headers });
166
+ }));
167
+ }
168
+ function getTax(store) {
169
+ const tax = store?.storeTaxes?.default;
170
+ const taxes = store.country.taxesList;
171
+ const def = taxes.find((e) => String(e.id) === tax);
172
+ const def0 = taxes.find((e) => +e.value === 0);
173
+ return def || def0;
174
+ }
175
+ function normalizeProduct(opts) {
176
+ const calcPrice = (price, discount) => {
177
+ const p = +price;
178
+ return (p - p * +discount / 100).toFixed(2);
179
+ };
180
+ const theTax = getTax(opts.store);
181
+ const taxIncluded = opts.store?.storeTaxes?.included;
182
+ const getTaxPercentage = () => {
183
+ return Number(theTax?.value || 0);
184
+ };
185
+ const priceWithTaxt = (price = 0) => {
186
+ price = +price;
187
+ const tax = getTaxPercentage();
188
+ if (taxIncluded) return price.toFixed(2);
189
+ return (price + price * tax / 100).toFixed(2);
190
+ };
191
+ return (product) => {
192
+ const image = product?.images?.[0];
193
+ const discount = product?.discount || 0;
194
+ const options = product?.variants?.options?.map((option) => {
195
+ return {
196
+ id: option?.option?.name?.toLowerCase(),
197
+ name: option?.option?.name?.toLowerCase(),
198
+ values: option.values,
199
+ type: option?.option?.select
200
+ };
201
+ });
202
+ const variants = product.variants?.variants?.map((variant) => {
203
+ const imageVariant = variant?.images?.[0];
204
+ let price = variant.price || product.price;
205
+ if (discount) price = calcPrice(price, discount);
206
+ return {
207
+ id: variant.id,
208
+ productId: product.id,
209
+ sku: variant?.sku || product?.sku || "",
210
+ image: imageVariant || image,
211
+ price,
212
+ showPrice: priceWithTaxt(price),
213
+ priceWithTax: priceWithTaxt(price),
214
+ comparedPrice: product.comparedPrice,
215
+ title: product.title,
216
+ available: true,
217
+ selectedOptions: Object.entries(variant?.options || {}).map(([key, value]) => {
218
+ return {
219
+ name: key,
220
+ value
221
+ };
222
+ })
223
+ };
224
+ });
225
+ let price = product.price;
226
+ if (discount) price = calcPrice(price, discount);
227
+ const taxes = product.taxes?.length ? product.taxes.map((tax) => {
228
+ return {
229
+ ...tax.tax,
230
+ included: tax.included
231
+ };
232
+ }) : theTax ? [{
233
+ ...theTax,
234
+ included: taxIncluded
235
+ }] : [];
236
+ return {
237
+ ...product,
238
+ price,
239
+ showPrice: priceWithTaxt(price),
240
+ priceWithTax: priceWithTaxt(price),
241
+ comparedPrice: product.comparedPrice || priceWithTaxt(+(product.price || 0)),
242
+ image,
243
+ taxes,
244
+ variants: variants || [{
245
+ id: product.sku || product.id,
246
+ productId: product.id,
247
+ comparedPrice: product.comparedPrice,
248
+ priceWithTax: priceWithTaxt(price),
249
+ image,
250
+ price: product.price,
251
+ selectedOptions: [{
252
+ name: product.sku ? "sku" : "item",
253
+ value: product.sku ? String(product.sku) : String(product.id)
254
+ }],
255
+ title: product.title,
256
+ available: true
257
+ }],
258
+ noVariants: !variants?.length,
259
+ options: options || [{
260
+ id: "1",
261
+ name: product.sku ? "sku" : "item",
262
+ values: [product.sku ? String(product.sku) : String(product.id)]
263
+ }]
264
+ };
265
+ };
266
+ }
267
+ const cache = /* @__PURE__ */ new Map();
268
+ function useProducts(db) {
269
+ const getStore = async (storeId) => {
270
+ const _cache = cache.get(`store:${storeId}`);
271
+ if (_cache && _cache.expires > Date.now()) return _cache.data;
272
+ const store = await db.query.stores.findFirst({
273
+ where: { id: storeId },
274
+ with: { country: { with: { taxesList: { with: { type: true } } } } }
275
+ });
276
+ cache.set(`store:${storeId}`, {
277
+ expires: Date.now() + 3600 * 1e3,
278
+ data: store
279
+ });
280
+ return store;
281
+ };
282
+ const getProducts = async (storeId) => {
283
+ const _cache = cache.get(`products:${storeId}`);
284
+ if (_cache && _cache.expires > Date.now()) return _cache.data;
285
+ const items = await db.query.products.findMany({
286
+ limit: 1e3,
287
+ columns: {
288
+ id: true,
289
+ title: true,
290
+ variants: true,
291
+ extras: true,
292
+ discount: true
293
+ },
294
+ with: { taxes: {
295
+ columns: {
296
+ id: true,
297
+ included: true
298
+ },
299
+ with: { tax: {
300
+ columns: {
301
+ id: true,
302
+ code: true,
303
+ value: true
304
+ },
305
+ with: { type: { columns: {
306
+ code: true,
307
+ name: true
308
+ } } }
309
+ } }
310
+ } }
311
+ });
312
+ cache.set(`products:${storeId}`, {
313
+ expires: Date.now() + 3600 * 1e3,
314
+ data: items
315
+ });
316
+ return items;
317
+ };
318
+ return {
319
+ getProducts: async (storeId) => {
320
+ const store = await getStore(storeId);
321
+ return (await getProducts(storeId)).map((p) => normalizeProduct({ store })(p));
322
+ },
323
+ getStore
324
+ };
325
+ }
326
+ function registerCache(app, db, { path, storeId }) {
327
+ const { getProducts } = useProducts(db);
328
+ app.get(path("/cache/products"), eventHandler(async () => {
329
+ return await getProducts(storeId);
330
+ }));
331
+ app.get(path("/cache/products/:id/stock"), eventHandler(async (event) => {
332
+ const productId = getRouterParam(event, "id");
333
+ const items = await db.query.productStocks.findMany({ where: {
334
+ productId: +productId,
335
+ variant: { ne: "" }
336
+ } });
337
+ const query = getQuery(event);
338
+ if (typeof query.selectedOptions === "string") query.selectedOptions = JSON.parse(query.selectedOptions || "[]");
339
+ const variantId = {
340
+ selectedOptions: [],
341
+ ...query
342
+ }.selectedOptions.map((e) => e.value).join("/");
343
+ const quantityAvailable = items.find((e) => e.variant === variantId)?.quantity || 0;
344
+ const firstOption = items.reduce((acc, stock) => {
345
+ if (!stock?.variant) return { ...acc };
346
+ const [option] = stock?.variant?.split("/");
347
+ const v = (stock.quantity || 0) + (acc[option] || 0);
348
+ return {
349
+ ...acc,
350
+ [option]: v
351
+ };
352
+ }, {});
353
+ const total = Object.values(firstOption).reduce((acc, e) => acc + e, 0);
354
+ return {
355
+ variant: {
356
+ availableForSale: !!quantityAvailable,
357
+ quantityAvailable
358
+ },
359
+ stocks: items,
360
+ firstOption,
361
+ total
362
+ };
363
+ }));
364
+ app.get(path("/cache/products/:id/verify"), eventHandler(async (event) => {
365
+ const productId = getRouterParam(event, "id");
366
+ const items = await db.query.productStocks.findMany({ where: {
367
+ productId: +productId,
368
+ variant: { ne: "" }
369
+ } });
370
+ const query = getQuery(event);
371
+ if (typeof query.selectedOptions === "string") query.selectedOptions = JSON.parse(query.selectedOptions || "[]");
372
+ const variantId = {
373
+ selectedOptions: [],
374
+ ...query
375
+ }.selectedOptions.map((e) => e.value).join("/");
376
+ return { ok: !!(items.find((e) => e.variant === variantId)?.quantity || 0) };
377
+ }));
378
+ }
379
+ async function getLineItems(cart, getProducts) {
380
+ const products = await getProducts();
381
+ const keys = Object.keys(cart);
382
+ const allVariants = products.filter((product) => product.variants.some((variant) => {
383
+ return keys.includes(`${product.id}:${variant.id}`);
384
+ })).map((product) => {
385
+ return product.variants.map((variant) => {
386
+ return {
387
+ id: `${product.id}:${variant.id}`,
388
+ title: product.title,
389
+ quantity: cart[`${product.id}:${variant.id}`],
390
+ variant,
391
+ taxes: product.taxes,
392
+ category: product.extras?.category || "none",
393
+ originalPrice: variant?.originalPrice || product?.originalPrice || 0,
394
+ originalDiscount: product?.discount || 0
395
+ };
396
+ });
397
+ });
398
+ return [].concat(...allVariants).filter((line) => keys.includes(`${line.id}`));
399
+ }
400
+ async function returnCart(event, cart, getProducts) {
401
+ const expires = new Date(dayjs().add(20, "minutes").format());
402
+ const start = Date.now();
403
+ const lineItems = await getLineItems(cart, getProducts);
404
+ console.log("getLineItems", `${Date.now() - start}ms`);
405
+ setCookie(event, "eCart", JSON.stringify(cart), { expires });
406
+ return { lineItems };
407
+ }
408
+ function registerCart(app, { getProducts, path }) {
409
+ const useCart = (event) => {
410
+ const rawCart = getCookie(event, "eCart");
411
+ if (!rawCart) return {};
412
+ return JSON.parse(rawCart);
413
+ };
414
+ app.get(path("/cart"), eventHandler(async (event) => {
415
+ const cart = useCart(event);
416
+ if (!Object.keys(cart).length) return { lineItems: [] };
417
+ return await returnCart(event, cart, getProducts);
418
+ }));
419
+ const getCartItem = async (event) => {
420
+ const body = await readBody(event);
421
+ return {
422
+ id: getQuery(event).id || body?.id,
423
+ quantity: body?.quantity
424
+ };
425
+ };
426
+ app.post(path("/cart"), eventHandler(async (event) => {
427
+ let cart = useCart(event);
428
+ const payload = await getCartItem(event);
429
+ cart = {
430
+ ...cart,
431
+ [payload.id]: payload.quantity
432
+ };
433
+ return await returnCart(event, cart, getProducts);
434
+ }));
435
+ app.delete(path("/cart"), eventHandler((event) => {
436
+ setCookie(event, "eCart", "{}");
437
+ return { lineItems: [] };
438
+ }));
439
+ app.delete(path("/cart/**:id"), eventHandler(async (event) => {
440
+ const cart = useCart(event);
441
+ let id = getRouterParam(event, "id");
442
+ id = decodeURIComponent(id);
443
+ delete cart[id];
444
+ return await returnCart(event, cart, getProducts);
445
+ }));
446
+ }
447
+ function roundNum(v, r = 2) {
448
+ return Number(Number(v).toFixed(r));
449
+ }
450
+ function calcPercentaje(value, percentaje, hasInclude) {
451
+ const val = +value;
452
+ const per = +percentaje;
453
+ if (hasInclude) return roundNum(val * per / (100 + per));
454
+ else return roundNum(val / 100 * per);
455
+ }
456
+ function calcDiscount(amount, discount) {
457
+ if ("percent" in discount) return {
458
+ amount: calcPercentaje(amount, discount.percent),
459
+ percent: +discount.percent
460
+ };
461
+ else return { amount: +discount.amount };
462
+ }
463
+ const sum = (arr) => arr.reduce((a, b) => a + b, 0);
464
+ const flatten = (arr) => arr.reduce((a, b) => a.concat(b), []);
465
+ function groupBy(fn, arr) {
466
+ return arr.reduce((acc, value) => {
467
+ const key = fn(value);
468
+ if (!acc[key]) acc[key] = [];
469
+ acc[key].push(value);
470
+ return acc;
471
+ }, {});
472
+ }
473
+ function calcAmount(_itemDiscount, _parentDiscount, taxIncluded) {
474
+ return (price) => {
475
+ if (!taxIncluded) {
476
+ const itemDiscount = calcDiscount(price, _itemDiscount);
477
+ const parentDiscount = calcDiscount(price - itemDiscount.amount, _parentDiscount);
478
+ const unitBase = price - (itemDiscount.amount + parentDiscount.amount);
479
+ return {
480
+ price,
481
+ discounts: {
482
+ itemDiscount,
483
+ parentDiscount
484
+ },
485
+ unitAmount: unitBase,
486
+ unitBase
487
+ };
488
+ } else {
489
+ const parentDiscount = calcDiscount(price, _parentDiscount);
490
+ const itemDiscount = calcDiscount(price - parentDiscount.amount, _itemDiscount);
491
+ return {
492
+ price,
493
+ discounts: {
494
+ itemDiscount,
495
+ parentDiscount
496
+ },
497
+ unitAmount: price - (itemDiscount.amount + parentDiscount.amount),
498
+ unitBase: 0
499
+ };
500
+ }
501
+ };
502
+ }
503
+ function calcSingleItem(parentDiscount = { amount: 0 }) {
504
+ return (item) => {
505
+ const quantity = +item.quantity;
506
+ const taxes = item.taxes || [];
507
+ const calcRawTax = (base, rate) => base * rate / 100;
508
+ const calculateTaxesForward = (originalBase, finalBase, raw = false) => {
509
+ const firstTaxes = [];
510
+ const latestTaxes = [];
511
+ let totalFirstTaxesAmount = 0;
512
+ let totalLatestTaxesAmount = 0;
513
+ for (const t of taxes) if (t.beforeTaxes) {
514
+ const baseToUse = t.excludeDiscount ? originalBase : finalBase;
515
+ const amount = raw ? calcRawTax(baseToUse, +t.value) : calcPercentaje(baseToUse, t.value, false);
516
+ firstTaxes.push({
517
+ ...t,
518
+ base: baseToUse,
519
+ amount,
520
+ totalBase: baseToUse * quantity,
521
+ totalAmount: amount * quantity
522
+ });
523
+ totalFirstTaxesAmount += amount;
524
+ }
525
+ for (const t of taxes) if (!t.beforeTaxes) {
526
+ const baseToUse = (t.excludeDiscount ? originalBase : finalBase) + totalFirstTaxesAmount;
527
+ const amount = raw ? calcRawTax(baseToUse, +t.value) : calcPercentaje(baseToUse, t.value, false);
528
+ latestTaxes.push({
529
+ ...t,
530
+ base: baseToUse,
531
+ amount,
532
+ totalBase: baseToUse * quantity,
533
+ totalAmount: amount * quantity
534
+ });
535
+ totalLatestTaxesAmount += amount;
536
+ }
537
+ return {
538
+ firstTaxes,
539
+ latestTaxes,
540
+ totalTaxes: totalFirstTaxesAmount + totalLatestTaxesAmount,
541
+ totalPrice: finalBase + totalFirstTaxesAmount + totalLatestTaxesAmount
542
+ };
543
+ };
544
+ if (!item.taxIncluded) {
545
+ const amounts = calcAmount(item.discount, parentDiscount, false)(+item.price);
546
+ const originalBase = amounts.price;
547
+ const finalBase = amounts.unitBase;
548
+ const result = calculateTaxesForward(originalBase, finalBase, false);
549
+ amounts.total = amounts.unitBase * quantity + result.totalTaxes * quantity;
550
+ return {
551
+ id: item.id,
552
+ title: item.title,
553
+ taxIncluded: item.taxIncluded,
554
+ item: amounts,
555
+ taxes: [...result.firstTaxes, ...result.latestTaxes],
556
+ quantity,
557
+ product: item.product,
558
+ variant: item.variant,
559
+ discountAllocations: item.discountAllocations
560
+ };
561
+ } else {
562
+ const amounts = calcAmount(item.discount, parentDiscount, true)(+item.price);
563
+ const originalPriceWithTaxes = amounts.price;
564
+ const finalPriceWithTaxes = amounts.unitAmount;
565
+ const T1_1 = calculateTaxesForward(1, 1, true).totalPrice;
566
+ const originalBaseRaw = originalPriceWithTaxes / (T1_1 === 0 ? 1 : T1_1);
567
+ const T0 = calculateTaxesForward(originalBaseRaw, 0, true).totalPrice;
568
+ const M = calculateTaxesForward(originalBaseRaw, 1, true).totalPrice - T0;
569
+ const result = calculateTaxesForward(originalBaseRaw, M === 0 ? finalPriceWithTaxes - T0 : (finalPriceWithTaxes - T0) / M, false);
570
+ const adjustedFinalBase = finalPriceWithTaxes - result.totalTaxes;
571
+ amounts.unitBase = adjustedFinalBase;
572
+ amounts.total = finalPriceWithTaxes * quantity;
573
+ for (const t of result.firstTaxes) if (!t.excludeDiscount) {
574
+ t.base = adjustedFinalBase;
575
+ t.totalBase = adjustedFinalBase * quantity;
576
+ }
577
+ const firstTotal = sum(result.firstTaxes.map((t) => t.amount));
578
+ for (const t of result.latestTaxes) if (!t.excludeDiscount) {
579
+ t.base = adjustedFinalBase + firstTotal;
580
+ t.totalBase = t.base * quantity;
581
+ }
582
+ return {
583
+ id: item.id,
584
+ title: item.title,
585
+ taxIncluded: item.taxIncluded,
586
+ item: amounts,
587
+ taxes: [...result.firstTaxes, ...result.latestTaxes],
588
+ quantity,
589
+ product: item.product,
590
+ variant: item.variant,
591
+ discountAllocations: item.discountAllocations
592
+ };
593
+ }
594
+ };
595
+ }
596
+ function calcItems(items, parentDiscount = { amount: 0 }) {
597
+ return items.map(calcSingleItem(parentDiscount));
598
+ }
599
+ function buildInvoice(items) {
600
+ const base = sum(items.map((item) => item.item.unitBase * item.quantity));
601
+ const lineItemsSubtotalPrice = sum(items.filter((item) => !["_envio"].includes(item.id)).map((item) => item.item.price * item.quantity));
602
+ const shipping = sum(items.filter((item) => ["_envio"].includes(item.id)).map((item) => item.item.price * item.quantity));
603
+ const totalDiscount = sum(items.map((item) => {
604
+ const discounts = item.item.discounts;
605
+ if (!discounts) return 0;
606
+ return ((discounts.itemDiscount?.amount || 0) + (discounts.parentDiscount?.amount || 0)) * item.quantity;
607
+ }));
608
+ const imp = groupBy((tax) => {
609
+ return `${tax.type.code}_${tax.code}`;
610
+ }, flatten(items.map((item) => item.taxes)));
611
+ const _taxes = Object.values(imp).map((taxes) => {
612
+ let taxBase = 0;
613
+ let value = 0;
614
+ const type = taxes[0].type.code;
615
+ const title = taxes[0].type.name;
616
+ const code = taxes[0].code;
617
+ const rate = +taxes[0].value;
618
+ for (const iterator of taxes) {
619
+ taxBase += +iterator.totalBase;
620
+ value += +iterator.totalAmount;
621
+ }
622
+ return {
623
+ type,
624
+ code,
625
+ base: taxBase,
626
+ value,
627
+ rate,
628
+ title
629
+ };
630
+ });
631
+ return {
632
+ total: base + sum(_taxes.map((tax) => tax.value)),
633
+ totalTax: sum(_taxes.map((t) => t.value)),
634
+ totalDiscount,
635
+ base,
636
+ items,
637
+ taxes: _taxes,
638
+ lineItemsSubtotalPrice,
639
+ shipping
640
+ };
641
+ }
642
+ function calculateFormula(expression, variables) {
643
+ if (!/^[\w+\-*/().\s<>=?:&|"']+$/.test(expression)) throw new TypeError("Formula contains invalid characters");
644
+ const context = { ...variables };
645
+ try {
646
+ let processedExpression = expression;
647
+ for (const [key, value] of Object.entries(context)) {
648
+ const regex = new RegExp(`\\b${key}\\b`, "g");
649
+ const safeValue = typeof value === "string" ? `"${value}"` : String(value);
650
+ processedExpression = processedExpression.replace(regex, safeValue);
651
+ }
652
+ const result = new Function(`return ${processedExpression}`)();
653
+ if (typeof result !== "number" || Number.isNaN(result)) throw new TypeError("Formula result is not a valid number");
654
+ return result;
655
+ } catch (error) {
656
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
657
+ throw new Error(`Error evaluating formula "${expression}": ${errorMessage}`);
658
+ }
659
+ }
660
+ function getCheckoutId(event) {
661
+ const cookie = getCookie(event, "eCheckout");
662
+ if (!cookie) throw new HTTPError({
663
+ statusCode: 404,
664
+ status: 404,
665
+ message: "Checkout not found"
666
+ });
667
+ return +cookie;
668
+ }
669
+ function registerCheckout(app, db, { path, storeId }) {
670
+ const { getStore } = useProducts(db);
671
+ app.post(path("/checkout"), eventHandler(async (event) => {
672
+ const payload = await readBody(event);
673
+ if (!payload.items) return new HTTPError({
674
+ status: 400,
675
+ statusCode: 400,
676
+ message: "Items not found"
677
+ });
678
+ const checkout = await db.insert(checkouts).values({
679
+ taxes: [],
680
+ billingInfo: {},
681
+ shippingInfo: {},
682
+ ...payload
683
+ }).returning();
684
+ setCookie(event, "eCheckout", `${checkout[0].id}`);
685
+ return { id: checkout[0].id };
686
+ }));
687
+ app.get(path("/checkout"), eventHandler(async (event) => {
688
+ const id = getCheckoutId(event);
689
+ const checkout = await db.query.checkouts.findFirst({ where: { id } });
690
+ if (!checkout) return;
691
+ const store = await getStore(storeId);
692
+ if (!store) return;
693
+ const theDiscount = (checkout.discount || [])[0]?.options || {};
694
+ const theTax = getTax(store);
695
+ const TAX_INCLUDED = store.storeTaxes?.included ?? true;
696
+ console.log(theTax, TAX_INCLUDED);
697
+ const items = checkout.items.filter((el) => !el?.id.startsWith("_")).map((el) => {
698
+ const discount = theDiscount?.type === "percentage" ? { percent: theDiscount?.value } : theDiscount?.type === "amount" ? { amount: theDiscount?.value } : { amount: 0 };
699
+ console.log("el.taxes", el.taxes);
700
+ const taxIncluded = el.taxes?.some((tax) => tax.included) ?? TAX_INCLUDED;
701
+ const taxes = el.taxes && el.taxes.length ? el.taxes : theTax ? [{
702
+ ...theTax,
703
+ included: taxIncluded
704
+ }] : [];
705
+ console.log("taxes", taxes);
706
+ return {
707
+ productId: el.variant?.productId,
708
+ discount,
709
+ id: el.variant.id,
710
+ price: el.variant.price,
711
+ quantity: el.quantity,
712
+ product: el.product,
713
+ variant: el.variant,
714
+ discountAllocations: el.discountAllocations || [],
715
+ taxes,
716
+ taxIncluded,
717
+ title: `${el.variant?.title} - ${el.variant?.id}`,
718
+ category: el.category || "none",
719
+ originalPrice: el.originalPrice || 0,
720
+ originalDiscount: el.originalDiscount || 0
721
+ };
722
+ });
723
+ if (checkout.shippingType && checkout.shippingType?.id) {
724
+ const taxShipping = checkout.shippingType.addTax ? {
725
+ code: "4",
726
+ description: "Envio",
727
+ included: false,
728
+ value: 15,
729
+ type: {
730
+ code: "2",
731
+ name: "IVA"
732
+ }
733
+ } : {
734
+ code: "0",
735
+ description: "Envio",
736
+ included: true,
737
+ value: 0,
738
+ type: {
739
+ code: "2",
740
+ name: "IVA"
741
+ }
742
+ };
743
+ const taxIncluded = !checkout.shippingType.addTax;
744
+ items.push({
745
+ discount: { amount: 0 },
746
+ price: +(checkout.shippingType.priceV2?.amount || checkout.shippingType.price),
747
+ id: "_envio",
748
+ quantity: 1,
749
+ taxIncluded,
750
+ title: "envio",
751
+ taxes: [taxShipping]
752
+ });
753
+ }
754
+ const itemsInvoice = calcItems(items);
755
+ const invoice = buildInvoice(itemsInvoice);
756
+ await db.update(checkouts).set({
757
+ items: items.map((el) => {
758
+ const item = itemsInvoice.find((e) => e.id === el.id);
759
+ return {
760
+ ...el,
761
+ item: item?.item,
762
+ lineItem: item
763
+ };
764
+ }),
765
+ total: invoice.total,
766
+ base: invoice.base,
767
+ taxes: invoice.taxes,
768
+ shippingType: checkout.shippingType || {}
769
+ }).where(eq(checkouts.id, id));
770
+ return {
771
+ invoice: {
772
+ ...invoice,
773
+ discounts: checkout.discount || []
774
+ },
775
+ lineItems: checkout.items.filter((el) => !el?.id.startsWith("_")),
776
+ address: checkout.shippingInfo,
777
+ billing: checkout.billingInfo,
778
+ shipping: checkout.shippingType
779
+ };
780
+ }));
781
+ app.post(path("/checkout/address"), eventHandler(async (event) => {
782
+ const id = getCheckoutId(event);
783
+ const payload = await readBody(event);
784
+ await db.update(checkouts).set({ shippingInfo: { ...payload } }).where(eq(checkouts.id, id));
785
+ return { ok: true };
786
+ }));
787
+ app.post(path("/checkout/billing"), eventHandler(async (event) => {
788
+ const id = getCheckoutId(event);
789
+ const payload = await readBody(event);
790
+ await db.update(checkouts).set({ billingInfo: { ...payload } }).where(eq(checkouts.id, id));
791
+ return { ok: true };
792
+ }));
793
+ app.get(path("/checkout/shippings"), eventHandler(async (event) => {
794
+ const store = await getStore(storeId);
795
+ const id = getCheckoutId(event);
796
+ const shippings = store.storeShippings || store?.storeSettings?.shippingType || [];
797
+ const type = store?.storeShippingsOptions?.type || "simple";
798
+ const checkout = await db.query.checkouts.findFirst({ where: { id } });
799
+ if (!checkout) return new HTTPError({
800
+ statusCode: 404,
801
+ statusMessage: "Checkout not found"
802
+ });
803
+ if (type === "complex") {
804
+ const allFormulates = store.storeShippingsOptions?.formulate || [];
805
+ const normalizeText = (text) => {
806
+ return text.toLowerCase().replace(/ /g, "-").replace(/[^a-z0-9-]/g, "");
807
+ };
808
+ const state = normalizeText(checkout.shippingInfo?.state || "TUNGURAHUA");
809
+ const city = normalizeText(checkout.shippingInfo?.city || "");
810
+ const item = shippings.find((e) => {
811
+ const _city = normalizeText(e.regionCity || "");
812
+ const _state = normalizeText(e.regionState || "");
813
+ return _city === city && _state === state;
814
+ });
815
+ console.log("item", item);
816
+ const pickup = {
817
+ _raw: [{
818
+ name: "Pickup - Retiro en tienda(Quito o Guayaquil)",
819
+ value: "0.00"
820
+ }],
821
+ items: [{
822
+ title: "Pickup - Retiro en tienda",
823
+ handle: "shopify-Pickup-0.00",
824
+ priceV2: {
825
+ amount: "0.00",
826
+ currencyCode: "USD"
827
+ },
828
+ price: "USD 0.00",
829
+ id: "shopify-Pickup-0.00",
830
+ name: "Pickup - Retiro en tienda (Sucursal Quito o Guayaquil)"
831
+ }]
832
+ };
833
+ if (item) {
834
+ let stocks = await ofetch(`${store.endpoint}/storefront/cache/the-stocks/${checkout.items.map((e) => e.productId || e.id).join("-")}`, { params: { ids: checkout.items.map((e) => e.productId || e.id).join(",") } }).catch(() => []);
835
+ stocks = stocks.map((v) => {
836
+ return {
837
+ ...v,
838
+ category: checkout.items.find((e) => {
839
+ return String(e.id) === String(v.sku) || String(e.productId) === String(v.sku);
840
+ })?.category || "none",
841
+ quantity: checkout.items.find((e) => {
842
+ return String(e.id) === String(v.sku) || String(e.productId) === String(v.sku);
843
+ })?.quantity || 1
844
+ };
845
+ });
846
+ console.log("stocks", stocks);
847
+ const variables = store.storeShippingsOptions.variables.reduce((acc, curr) => {
848
+ return {
849
+ ...acc,
850
+ [curr.name]: curr.default
851
+ };
852
+ }, {});
853
+ let sumTax = false;
854
+ const prices = stocks.filter(({ id }) => !id.startsWith("_")).map((curr) => {
855
+ console.log("curr", curr);
856
+ let quantity = curr.quantity || 1;
857
+ const _formulate = allFormulates.find((f) => f.key === curr.category) || allFormulates.find((f) => f.key === "default") || item.formulate[0];
858
+ if (_formulate.noQuantity) quantity = 1;
859
+ const weight = Number(curr.weight || 0) * Number(quantity || 1);
860
+ const vars = {
861
+ ...variables,
862
+ ...item,
863
+ weight,
864
+ sku: curr.sku,
865
+ quantity
866
+ };
867
+ const formulate = _formulate.value;
868
+ if (_formulate.key !== "default") sumTax = _formulate.tax || false;
869
+ console.log("formulate", curr, formulate, vars);
870
+ return calculateFormula(formulate, vars);
871
+ });
872
+ console.log("prices", prices);
873
+ if (prices.some((p) => p < 0)) return {
874
+ _raw: [],
875
+ items: [],
876
+ message: "Elemento sin covertura"
877
+ };
878
+ const title = `${item?.regionState || ""} - ${item?.regionCity || ""}`;
879
+ const total = prices.reduce((acc, curr) => acc + curr, 0).toFixed(2);
880
+ return {
881
+ _raw: [{
882
+ name: title,
883
+ value: total
884
+ }, ...pickup._raw],
885
+ items: [{
886
+ title,
887
+ handle: title,
888
+ priceV2: {
889
+ amount: total,
890
+ currencyCode: "USD"
891
+ },
892
+ notify: item.correos || "",
893
+ notify2: item.facturacion || "",
894
+ addTax: sumTax,
895
+ item,
896
+ price: `USD ${total}`,
897
+ id: title,
898
+ name: title
899
+ }, ...pickup.items]
900
+ };
901
+ } else return {
902
+ ...pickup,
903
+ code: "no-shipping"
904
+ };
905
+ }
906
+ if (!shippings.length) return {
907
+ _raw: [{
908
+ name: "Standard",
909
+ value: "0.00"
910
+ }],
911
+ items: [{
912
+ title: "Standard",
913
+ handle: "shopify-Standard-0.00",
914
+ priceV2: {
915
+ amount: "0.0",
916
+ currencyCode: "USD"
917
+ },
918
+ price: "USD 0.0",
919
+ id: "shopify-Standard-0.00",
920
+ name: "Standard"
921
+ }]
922
+ };
923
+ return {
924
+ _raw: shippings,
925
+ items: shippings.map((item) => {
926
+ const id = `${item.name}-${item.value}`;
927
+ return {
928
+ _raw: item,
929
+ title: item.name,
930
+ handle: id,
931
+ priceV2: {
932
+ amount: item.value,
933
+ currencyCode: "USD"
934
+ },
935
+ price: (+item.value).toFixed(2),
936
+ id,
937
+ name: item.name
938
+ };
939
+ })
940
+ };
941
+ }));
942
+ app.post(path("/checkout/shippings"), eventHandler(async (event) => {
943
+ const id = getCheckoutId(event);
944
+ const payload = await readBody(event);
945
+ await db.update(checkouts).set({ shippingType: { ...payload } }).where(eq(checkouts.id, id));
946
+ return { ok: true };
947
+ }));
948
+ app.post(path("/checkout/discount"), eventHandler(async (event) => {
949
+ const id = getCheckoutId(event);
950
+ const store = await getStore(storeId);
951
+ const { coupon } = await readBody(event);
952
+ const coupons = store?.storeDiscounts || [];
953
+ const user = useUser(event);
954
+ const item = coupons.filter((e) => e.select.toLowerCase() === "codigo").find((c) => c.value === coupon);
955
+ if (!item) return {
956
+ message: "Cupón no válido",
957
+ code: 0
958
+ };
959
+ const condition = {
960
+ storeId,
961
+ customerId: user.id,
962
+ code: coupon
963
+ };
964
+ if (await db.query.discountCoupons.findFirst({ where: condition }) && item.options.apply === "once") return {
965
+ message: "Cupón ya utilizado",
966
+ code: 0
967
+ };
968
+ if (item) await db.update(checkouts).set({ discount: [{
969
+ ...item,
970
+ coupon,
971
+ customerId: user.id
972
+ }] }).where(eq(checkouts.id, id));
973
+ return {
974
+ message: "Cupón aplicado",
975
+ code: 1
976
+ };
977
+ }));
978
+ app.delete(path("/checkout/discount"), eventHandler(async (event) => {
979
+ const id = getCheckoutId(event);
980
+ await db.update(checkouts).set({ discount: [] }).where(eq(checkouts.id, id));
981
+ return { ok: true };
982
+ }));
983
+ }
984
+ const safeParams = (v) => v.split("?")[0];
985
+ const TASKS = {
986
+ notify: {
987
+ type: "external",
988
+ endpoint: `${URL}/storefront/webhooks/notify/success`
989
+ },
990
+ stock: {
991
+ type: "internal",
992
+ task: "updateStocks",
993
+ payload: { omit: "tranference" }
994
+ }
995
+ };
996
+ const presets = { ecommerce: { prepare: { preHandle: async (event, payment) => {
997
+ const checkoutId = getCheckoutId(event);
998
+ const _body = await readBody(event);
999
+ const user = useUser(event);
1000
+ const { customer, shippingIdentification, extras } = _body;
1001
+ const { card, ...body } = _body;
1002
+ const session = {
1003
+ email: user.email,
1004
+ identification: customer?.billingInfo?.identification || shippingIdentification || "0000000000",
1005
+ customer: {
1006
+ givenName: customer?.billingInfo?.fullname || "",
1007
+ surname: "",
1008
+ billingInfo: customer?.billingInfo,
1009
+ ...user
1010
+ }
1011
+ };
1012
+ const theSession = await payment.session.create(session);
1013
+ const store = await payment.getStore();
1014
+ const successTasks = [];
1015
+ if (store.storeTasks?.success?.notify) successTasks.push(TASKS.notify);
1016
+ if (store.storeTasks?.success?.stock) successTasks.push(TASKS.stock);
1017
+ store.storeTasks?.successTasks?.forEach((el) => {
1018
+ const endpoint = el.url.startsWith("/") ? `${URL}${el.url}` : el.url;
1019
+ successTasks.push({
1020
+ type: "external",
1021
+ task: String(el.id),
1022
+ endpoint
1023
+ });
1024
+ });
1025
+ const success = successTasks.map((el) => ({
1026
+ ...el,
1027
+ payload: {
1028
+ ...body,
1029
+ ...el.payload
1030
+ }
1031
+ }));
1032
+ const failed = (store.storeSettings?.flow?.failed || [{
1033
+ type: "external",
1034
+ endpoint: `${URL}/storefront/webhooks/notify/failed`
1035
+ }]).map((el) => ({
1036
+ ...el,
1037
+ payload: body
1038
+ }));
1039
+ await payment.checkout.associate(checkoutId, theSession.id);
1040
+ const provider = getRouterParam(event, "provider");
1041
+ console.log("Preparing payment for provider:", provider);
1042
+ event.context.body = {
1043
+ sessionId: theSession.id,
1044
+ checkoutId,
1045
+ description: "Compra",
1046
+ ip: getRequestIP(event),
1047
+ endpoints: { verify: { endpoint: `${URL}/payment/verify/${provider}` } },
1048
+ tasks: {
1049
+ success,
1050
+ failed
1051
+ },
1052
+ extras
1053
+ };
1054
+ event.context.card = card;
1055
+ } } } };
1056
+ function registerPayment(app, db, { path, storeId, providers, preset, providerOptions, redirect: globalRedirect }) {
1057
+ const instance = createPayment({
1058
+ graphql: createGraphql(db),
1059
+ storeId,
1060
+ providers,
1061
+ secret: "secret",
1062
+ tasks: {
1063
+ url: TASKS_ENDPOINT,
1064
+ headers: { Authorization: `Bearer ${GRAPHQL_TOKEN}` }
1065
+ }
1066
+ });
1067
+ const extend = typeof preset === "string" ? presets[preset] || {} : preset;
1068
+ const payHandle = eventHandler(async (event) => {
1069
+ const { payment } = instance;
1070
+ console.log(event, event.headers);
1071
+ const query = getQuery(event);
1072
+ const { uid } = query;
1073
+ const redirect$1 = query.redirect || globalRedirect;
1074
+ const provider = safeParams(event.context.params?.provider || "");
1075
+ let body = {};
1076
+ if (event.req.method === "POST") body = await readBody(event);
1077
+ const r = await payment.pay(provider, {
1078
+ ...query,
1079
+ uid,
1080
+ body
1081
+ });
1082
+ const { provider: _1, uid: _2, id: _3, ...rest } = query;
1083
+ const params = Object.entries(rest).map(([key, value]) => `${key}=${value}`).join("&");
1084
+ const pathRedirect = joinURL(URL, `${redirect$1}?provider=${provider}&id=${r.id}&uid=${uid}&${params}`);
1085
+ console.log("pathredirect", pathRedirect);
1086
+ if (redirect$1 !== "0" || redirect$1.startsWith("/")) return redirect(pathRedirect, 301);
1087
+ return {
1088
+ redirect: pathRedirect,
1089
+ payload: r
1090
+ };
1091
+ });
1092
+ app.post(path("/pay/:provider"), payHandle);
1093
+ app.get(path("/pay/:provider"), payHandle);
1094
+ app.post(path("/post-prepare/:provider"), eventHandler(async (event) => {
1095
+ const { payment } = instance;
1096
+ const hooks = extend?.postPrepare;
1097
+ if (hooks?.preHandle) await hooks.preHandle(event, instance);
1098
+ let body = event.context.body;
1099
+ if (!body) body = await readBody(event);
1100
+ const { options } = body;
1101
+ const provider = safeParams(getRouterParam(event, "provider") || "");
1102
+ const defaultProviderOptions = defu(providerOptions?.[provider] || {}, options || {});
1103
+ const { options: _opt, ...theBody } = body;
1104
+ try {
1105
+ const r = await payment.postPrepare(provider, theBody, {
1106
+ ...defaultProviderOptions,
1107
+ card: event.context.card || void 0,
1108
+ returnUrl: event.context.returnUrl || void 0,
1109
+ transactionMode: event.context.transactionMode || void 0,
1110
+ deviceInformation: event.context.deviceInformation || void 0
1111
+ });
1112
+ if (hooks?.postHandle) await hooks.postHandle(event, r);
1113
+ return r;
1114
+ } catch (error) {
1115
+ console.log(error?.response?.body || error);
1116
+ throw createError({ statusCode: 500 });
1117
+ }
1118
+ }));
1119
+ app.post(path("/prepare/:provider"), eventHandler(async (event) => {
1120
+ const _payment = instance;
1121
+ const { payment } = _payment;
1122
+ const hooks = extend?.prepare;
1123
+ if (hooks?.preHandle) await hooks.preHandle(event, _payment);
1124
+ let body = event.context.body;
1125
+ if (!body) body = await readBody(event);
1126
+ const { options } = body;
1127
+ const provider = safeParams(getRouterParam(event, "provider") || "");
1128
+ const defaultProviderOptions = defu(providerOptions?.[provider] || {}, options || {});
1129
+ const { options: _opt, ...theBody } = body;
1130
+ try {
1131
+ const r = await payment.prepare(provider, theBody, {
1132
+ ...defaultProviderOptions,
1133
+ card: event.context.card || void 0
1134
+ });
1135
+ if (hooks?.postHandle) await hooks.postHandle(event, r);
1136
+ return r;
1137
+ } catch (error) {
1138
+ console.log(error?.response?.body || error);
1139
+ throw createError({ statusCode: 500 });
1140
+ }
1141
+ }));
1142
+ app.post(path("/verify/:provider"), eventHandler(async (event) => {
1143
+ const { payment } = instance;
1144
+ const { uid } = await readBody(event);
1145
+ const provider = safeParams(event.context.params?.provider || "");
1146
+ const query = getQuery(event);
1147
+ return await payment.verify(provider, uid, !!query.override);
1148
+ }));
1149
+ app.post(path("/webhook/:provider"), eventHandler(async (event) => {
1150
+ const { payment } = instance;
1151
+ const body = await readBody(event);
1152
+ const { reference: uid } = body;
1153
+ const provider = safeParams(event.context.params?.provider || "");
1154
+ return await payment?.webhook?.(provider, uid, body);
1155
+ }));
1156
+ }
1157
+ export { getCheckoutId, getTax, registerAccount, registerAuth, registerAuthMiddleware, registerCache, registerCart, registerCheckout, registerPayment, safeParams, useProducts, useUser };