@pradip1995/commerce-core 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/README.md +15 -0
  2. package/package.json +70 -0
  3. package/src/analytics/ga4-ecommerce.ts +96 -0
  4. package/src/config.ts +36 -0
  5. package/src/constants.tsx +84 -0
  6. package/src/context/modal-context.tsx +40 -0
  7. package/src/context/wishlist-context.tsx +96 -0
  8. package/src/data/cart/abandoned.ts +111 -0
  9. package/src/data/cart/buyNow.ts +184 -0
  10. package/src/data/cart/checkout.ts +487 -0
  11. package/src/data/cart/index.ts +7 -0
  12. package/src/data/cart/mutations.ts +189 -0
  13. package/src/data/cart/promotions.ts +121 -0
  14. package/src/data/cart/region.ts +66 -0
  15. package/src/data/cart/retrieve.ts +162 -0
  16. package/src/data/categories.ts +90 -0
  17. package/src/data/collections.ts +109 -0
  18. package/src/data/contact.ts +143 -0
  19. package/src/data/cookies.ts +170 -0
  20. package/src/data/customer-registration.ts +365 -0
  21. package/src/data/customer.ts +638 -0
  22. package/src/data/dynamic-config.ts +420 -0
  23. package/src/data/fulfillment.ts +95 -0
  24. package/src/data/guest.ts +357 -0
  25. package/src/data/locale-actions.ts +74 -0
  26. package/src/data/locales.ts +28 -0
  27. package/src/data/newsletter.ts +41 -0
  28. package/src/data/notifications.ts +22 -0
  29. package/src/data/onboarding.ts +9 -0
  30. package/src/data/orders.ts +500 -0
  31. package/src/data/payment-details.ts +68 -0
  32. package/src/data/payment.ts +32 -0
  33. package/src/data/products.ts +424 -0
  34. package/src/data/regions.ts +64 -0
  35. package/src/data/returns.ts +305 -0
  36. package/src/data/reviews.ts +279 -0
  37. package/src/data/swaps.ts +154 -0
  38. package/src/data/variants.ts +38 -0
  39. package/src/data/wishlist.ts +292 -0
  40. package/src/domain/cart/abandoned-carts.ts +49 -0
  41. package/src/domain/cart/buy-now.ts +15 -0
  42. package/src/domain/cart/checkout.ts +25 -0
  43. package/src/domain/cart/index.ts +8 -0
  44. package/src/domain/cart/metadata.ts +21 -0
  45. package/src/domain/cart/payment.ts +21 -0
  46. package/src/domain/cart/phone.ts +17 -0
  47. package/src/domain/cart/reorder.ts +19 -0
  48. package/src/domain/cart/validation.ts +43 -0
  49. package/src/domain/product/pricing.ts +49 -0
  50. package/src/domain/product/variant-selection.ts +193 -0
  51. package/src/firebase.ts +48 -0
  52. package/src/hooks/index.ts +8 -0
  53. package/src/hooks/use-add-to-cart.ts +63 -0
  54. package/src/hooks/use-cart.ts +132 -0
  55. package/src/hooks/use-checkout.ts +62 -0
  56. package/src/hooks/use-in-view.tsx +29 -0
  57. package/src/hooks/use-product-actions.ts +190 -0
  58. package/src/hooks/use-product-reviews.ts +18 -0
  59. package/src/hooks/use-product-variant.ts +142 -0
  60. package/src/hooks/use-server-action.ts +30 -0
  61. package/src/hooks/use-toggle-state.tsx +46 -0
  62. package/src/hooks/use-wishlist.ts +3 -0
  63. package/src/theme/inline-vars.ts +12 -0
  64. package/src/types/account.ts +21 -0
  65. package/src/types/cart.ts +13 -0
  66. package/src/types/home.ts +52 -0
  67. package/src/types/layout.ts +29 -0
  68. package/src/types/product-card.ts +17 -0
  69. package/src/util/compare-addresses.ts +28 -0
  70. package/src/util/env.ts +3 -0
  71. package/src/util/get-locale-header.ts +8 -0
  72. package/src/util/get-percentage-diff.ts +6 -0
  73. package/src/util/get-product-price.ts +78 -0
  74. package/src/util/google-oauth.ts +28 -0
  75. package/src/util/isEmpty.ts +11 -0
  76. package/src/util/medusa-error.ts +18 -0
  77. package/src/util/money.ts +26 -0
  78. package/src/util/order-status.tsx +179 -0
  79. package/src/util/product.ts +431 -0
  80. package/src/util/repeat.ts +5 -0
  81. package/src/util/returns.ts +71 -0
  82. package/src/util/sort-products.ts +48 -0
@@ -0,0 +1,500 @@
1
+ "use server"
2
+
3
+ import { cookies } from "next/headers"
4
+ import { sdk } from "@core/config"
5
+ import medusaError from "@core/util/medusa-error"
6
+ import {
7
+ getAuthHeaders,
8
+ getCacheOptions,
9
+ getCacheTag,
10
+ setCartId,
11
+ setBuyNowCartId,
12
+ removeBuyNowCartId,
13
+ } from "./cookies"
14
+ import { listReturnReasons } from "./returns"
15
+ import { HttpTypes } from "@medusajs/types"
16
+ import { revalidateTag } from "next/cache"
17
+
18
+ export const retrieveOrder = async (id: string) => {
19
+ const cookieStore = await cookies()
20
+ const token = cookieStore.get("_medusa_jwt")?.value
21
+ // Check for guest token if regular token is missing
22
+ const guestToken = !token
23
+ ? cookieStore.get("_medusa_guest_jwt")?.value ||
24
+ cookieStore.get("_medusa_guest_token")?.value
25
+ : null
26
+
27
+ // Log token details for debugging (only first 20 chars for security)
28
+
29
+ const next = {
30
+ ...(await getCacheOptions("orders")),
31
+ }
32
+
33
+ // If guest user, use the main orders endpoint with guest token to get full details
34
+ if (guestToken && !token) {
35
+ const publishableKey = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY
36
+
37
+ const requestHeaders: Record<string, string> = {
38
+ Authorization: `Bearer ${guestToken}`,
39
+ }
40
+ if (publishableKey) requestHeaders["x-publishable-api-key"] = publishableKey
41
+
42
+ const response = await sdk.client.fetch<any>(`/store/orders/${id}`, {
43
+ method: "GET",
44
+ headers: requestHeaders,
45
+ query: {
46
+ fields:
47
+ "id,display_id,customer_id,email,created_at,status,fulfillment_status,payment_status,currency_code,subtotal,shipping_total,tax_total,discount_total,metadata,total,*payment_collections.payments,*items,*items.metadata,*items.variant,*items.variant.images,*items.variant.product,*items.variant.product.thumbnail,*items.variant.product.images,*items.variant.product.variants,*items.product,*items.product.thumbnail,*items.product.images,*items.product.variants,*fulfillments,*fulfillments.items,*fulfillments.location_id,*returns,*returns.items,*cart,*shipping_address,*billing_address,*region,*shipping_methods",
48
+ },
49
+ cache: "no-store",
50
+ })
51
+
52
+ if (!response || !response.order) {
53
+ throw new Error("Order not found or access denied")
54
+ }
55
+
56
+ return response.order
57
+ }
58
+
59
+ // Regular logged-in user flow
60
+ const headers = {
61
+ ...(await getAuthHeaders()),
62
+ }
63
+
64
+ return sdk.client
65
+ .fetch<HttpTypes.StoreOrderResponse>(`/store/orders/${id}`, {
66
+ method: "GET",
67
+ query: {
68
+ fields:
69
+ "id,display_id,customer_id,email,created_at,status,fulfillment_status,payment_status,currency_code,subtotal,shipping_total,tax_total,discount_total,metadata,total,*payment_collections.payments,*items,*items.metadata,*items.variant,*items.variant.images,*items.variant.product,*items.variant.product.variants,*items.product,*items.product.variants,*returns,*shipping_address,*billing_address,*region,*shipping_methods",
70
+ },
71
+ headers,
72
+ next,
73
+ cache: "no-store", // Changed from "force-cache" to "no-store" to always fetch fresh data
74
+ })
75
+ .then(({ order }) => {
76
+ return order
77
+ })
78
+ .catch((err) => {
79
+ return medusaError(err)
80
+ })
81
+ }
82
+
83
+ export const listOrders = async (
84
+ limit: number = 10,
85
+ offset: number = 0,
86
+ filters?: Record<string, any>
87
+ ) => {
88
+ const headers = {
89
+ ...(await getAuthHeaders()),
90
+ }
91
+
92
+ const next = {
93
+ ...(await getCacheOptions("orders")),
94
+ }
95
+
96
+ return sdk.client
97
+ .fetch<HttpTypes.StoreOrderListResponse>(`/store/orders`, {
98
+ method: "GET",
99
+ query: {
100
+ limit,
101
+ offset,
102
+ order: "-created_at",
103
+ fields:
104
+ "id,display_id,created_at,total,currency_code,status,fulfillment_status,payment_status,*items,+items.metadata,*items.variant,*items.variant.images,*items.product,*returns",
105
+ ...filters,
106
+ },
107
+ headers,
108
+ next,
109
+ cache: "no-store",
110
+ })
111
+ .then(({ orders }) => orders)
112
+ .catch((err) => medusaError(err))
113
+ }
114
+
115
+ export const createTransferRequest = async (
116
+ state: {
117
+ success: boolean
118
+ error: string | null
119
+ order: HttpTypes.StoreOrder | null
120
+ },
121
+ formData: FormData
122
+ ): Promise<{
123
+ success: boolean
124
+ error: string | null
125
+ order: HttpTypes.StoreOrder | null
126
+ }> => {
127
+ const id = formData.get("order_id") as string
128
+
129
+ if (!id) {
130
+ return { success: false, error: "Order ID is required", order: null }
131
+ }
132
+
133
+ const headers = await getAuthHeaders()
134
+
135
+ return await sdk.store.order
136
+ .requestTransfer(
137
+ id,
138
+ {},
139
+ {
140
+ fields: "id, email",
141
+ },
142
+ headers
143
+ )
144
+ .then(({ order }) => ({ success: true, error: null, order }))
145
+ .catch((err) => ({ success: false, error: err.message, order: null }))
146
+ }
147
+
148
+ export const acceptTransferRequest = async (id: string, token: string) => {
149
+ const headers = await getAuthHeaders()
150
+
151
+ return await sdk.store.order
152
+ .acceptTransfer(id, { token }, {}, headers)
153
+ .then(({ order }) => ({ success: true, error: null, order }))
154
+ .catch((err) => ({ success: false, error: err.message, order: null }))
155
+ }
156
+
157
+ export const declineTransferRequest = async (id: string, token: string) => {
158
+ const headers = await getAuthHeaders()
159
+
160
+ return await sdk.store.order
161
+ .declineTransfer(id, { token }, {}, headers)
162
+ .then(({ order }) => ({ success: true, error: null, order }))
163
+ .catch((err) => ({ success: false, error: err.message, order: null }))
164
+ }
165
+
166
+ export const downloadInvoice = async (orderId: string) => {
167
+ try {
168
+ const cookieStore = await cookies()
169
+ const token = cookieStore.get("_medusa_jwt")?.value
170
+ // Check for guest token if regular token is missing
171
+ const guestToken = !token
172
+ ? cookieStore.get("_medusa_guest_jwt")?.value ||
173
+ cookieStore.get("_medusa_guest_token")?.value
174
+ : null
175
+
176
+ const headers: HeadersInit = {
177
+ "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY!,
178
+ }
179
+
180
+ let url = `/store/invoice/download/${orderId}`
181
+
182
+ if (token) {
183
+ headers["Cookie"] = `_medusa_jwt=${token}`
184
+ headers["Authorization"] = `Bearer ${token}`
185
+ } else if (guestToken) {
186
+ // Use guest endpoint and token
187
+ url = `/store/guest/invoice/download/${orderId}`
188
+ headers["Cookie"] = `_medusa_guest_jwt=${guestToken}`
189
+ headers["Authorization"] = `Bearer ${guestToken}`
190
+ }
191
+
192
+ const backendUrl =
193
+ process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL || "http://localhost:9000"
194
+ const response = await fetch(`${backendUrl}${url}`, {
195
+ method: "GET",
196
+ headers,
197
+ cache: "no-store",
198
+ })
199
+
200
+ if (!response.ok) {
201
+ throw new Error(
202
+ `Failed to download invoice: ${response.status} ${response.statusText}`
203
+ )
204
+ }
205
+
206
+ const contentType = response.headers.get("content-type")
207
+ if (!contentType || !contentType.includes("application/pdf")) {
208
+ throw new Error("Server returned non-PDF content")
209
+ }
210
+
211
+ const arrayBuffer = await response.arrayBuffer()
212
+
213
+ if (arrayBuffer.byteLength === 0) {
214
+ throw new Error("Generated PDF is empty")
215
+ }
216
+
217
+ const base64 = Buffer.from(arrayBuffer).toString("base64")
218
+
219
+ return { success: true, data: base64 }
220
+ } catch (error: any) {
221
+ return { success: false, error: error.message }
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Cancel an order
227
+ */
228
+ export const cancelOrder = async (orderId: string, reasonId?: string) => {
229
+ try {
230
+ const authHeaders = await getAuthHeaders()
231
+ const cookiesStore = await cookies()
232
+ const guestToken =
233
+ cookiesStore.get("_medusa_guest_jwt")?.value ||
234
+ cookiesStore.get("_medusa_guest_token")?.value
235
+ const publishableKey = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY
236
+ const backendUrl =
237
+ process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL || "http://localhost:9000"
238
+
239
+ // 1. Regular logged-in user flow ALWAYS takes priority
240
+ const token = cookiesStore.get("_medusa_jwt")?.value
241
+
242
+ if (token) {
243
+ let finalReasonId = reasonId
244
+ if (!finalReasonId) {
245
+ const reasons = await listReturnReasons()
246
+ finalReasonId =
247
+ reasons.find((r) => r.value === "other")?.id || reasons[0]?.id || "other"
248
+ }
249
+
250
+ const headers: Record<string, string> = {
251
+ "Content-Type": "application/json",
252
+ "x-publishable-api-key": publishableKey!,
253
+ Authorization: `Bearer ${token}`,
254
+ }
255
+
256
+ // Try the primary endpoint
257
+ let response = await fetch(`${backendUrl}/store/orders/cancel/${orderId}`, {
258
+ method: "POST",
259
+ headers,
260
+ body: JSON.stringify({ reason_id: finalReasonId }),
261
+ cache: "no-store",
262
+ })
263
+
264
+ // If the first endpoint fails with 404 or a resolution error, try the alternative format
265
+ if (!response.ok) {
266
+ const errorData = await response.json().catch(() => ({}))
267
+
268
+ if (
269
+ response.status === 404 ||
270
+ (errorData.message && errorData.message.includes("resolve"))
271
+ ) {
272
+ const altResponse = await fetch(
273
+ `${backendUrl}/store/orders/${orderId}/cancel`,
274
+ {
275
+ method: "POST",
276
+ headers,
277
+ body: JSON.stringify({ reason_id: finalReasonId }),
278
+ cache: "no-store",
279
+ }
280
+ )
281
+
282
+ if (altResponse.ok) return { success: true }
283
+
284
+ // If both fail, return the error from the second attempt
285
+ const altError = await altResponse
286
+ .json()
287
+ .catch(() => ({ message: "Failed to cancel order" }))
288
+ return { success: false, error: altError.message || "Failed to cancel order" }
289
+ }
290
+
291
+ return { success: false, error: errorData.message || "Failed to cancel order" }
292
+ }
293
+
294
+ return { success: true }
295
+ }
296
+
297
+ // 2. Only if NOT logged in, check for guest user token
298
+ if (guestToken) {
299
+ let finalReasonId = reasonId
300
+ if (!finalReasonId) {
301
+ const reasons = await listReturnReasons()
302
+ finalReasonId =
303
+ reasons.find((r) => r.value === "other")?.id || reasons[0]?.id || "other"
304
+ }
305
+
306
+ // Try guest endpoint
307
+ const response = await fetch(
308
+ `${backendUrl}/store/guest-orders/${orderId}/cancel`,
309
+ {
310
+ method: "POST",
311
+ headers: {
312
+ "Content-Type": "application/json",
313
+ "x-publishable-api-key": publishableKey!,
314
+ Authorization: `Bearer ${guestToken}`,
315
+ },
316
+ body: JSON.stringify({ reason_id: finalReasonId }),
317
+ cache: "no-store",
318
+ }
319
+ )
320
+
321
+ if (!response.ok) {
322
+ // Fallback for guest as well
323
+ const altResponse = await fetch(
324
+ `${backendUrl}/store/guest/orders/${orderId}/cancel`,
325
+ {
326
+ method: "POST",
327
+ headers: {
328
+ "Content-Type": "application/json",
329
+ "x-publishable-api-key": publishableKey!,
330
+ Authorization: `Bearer ${guestToken}`,
331
+ },
332
+ body: JSON.stringify({ reason_id: finalReasonId }),
333
+ cache: "no-store",
334
+ }
335
+ )
336
+
337
+ if (altResponse.ok) return { success: true }
338
+ return { success: false, error: "Failed to cancel order" }
339
+ }
340
+ return { success: true }
341
+ }
342
+
343
+ // 3. Neither token found
344
+ return { success: false, error: "Unauthorized: No valid session found" }
345
+ } catch (error: any) {
346
+ return { success: false, error: error.message }
347
+ }
348
+ }
349
+
350
+ /**
351
+ * Reorder an order (supports both logged-in and guest users)
352
+ */
353
+ export const reorderOrder = async (
354
+ orderId: string,
355
+ skipVariantIds?: string[],
356
+ forceReorder: boolean = false
357
+ ) => {
358
+ try {
359
+ const cookieStore = await cookies()
360
+ const token = cookieStore.get("_medusa_jwt")?.value
361
+ // Check for guest token if regular token is missing
362
+ const guestToken = !token
363
+ ? cookieStore.get("_medusa_guest_jwt")?.value ||
364
+ cookieStore.get("_medusa_guest_token")?.value
365
+ : null
366
+
367
+ const publishableKey = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY
368
+ const backendUrl =
369
+ process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL || "http://localhost:9000"
370
+
371
+ const headers: HeadersInit = {
372
+ "Content-Type": "application/json",
373
+ "x-publishable-api-key": publishableKey!,
374
+ }
375
+
376
+ // Determine the correct endpoint based on user type
377
+ let url = `${backendUrl}/store/orders/reorder/${orderId}`
378
+
379
+ if (token) {
380
+ // IMPORTANT: The Order Management plugin requires an explicit Bearer token
381
+ // in the Authorization header to identify actor_id. Using getAuthHeaders()
382
+ // alone (which is cookie-based) is not enough for this custom endpoint.
383
+ headers["Authorization"] = `Bearer ${token}`
384
+ } else if (guestToken) {
385
+ // Use guest reorder endpoint
386
+ url = `${backendUrl}/store/guest-orders/${orderId}/reorder`
387
+ headers["Authorization"] = `Bearer ${guestToken}`
388
+ } else {
389
+ return { success: false, error: "Unauthorized: Please log in to reorder." }
390
+ }
391
+
392
+ // Add force_reorder query param if requested
393
+ if (forceReorder) {
394
+ url += `?force_reorder=true`
395
+ }
396
+
397
+ // Call the plugin's reorder endpoint (adds all items)
398
+ const response = await fetch(url, {
399
+ method: "POST",
400
+ headers,
401
+ cache: "no-store",
402
+ })
403
+
404
+ if (!response.ok) {
405
+ const errorBody = await response.json().catch(() => null)
406
+
407
+ // Handle 409 Conflict - Inventory Issues
408
+ if (response.status === 409 && errorBody?.inventory_issues) {
409
+ return {
410
+ success: false,
411
+ error: "Inventory issues found",
412
+ inventory_issues: errorBody.inventory_issues,
413
+ }
414
+ }
415
+
416
+ const errorMsg = errorBody?.message || "Failed to reorder"
417
+ return { success: false, error: errorMsg }
418
+ }
419
+
420
+ const data = await response.json()
421
+
422
+ // Support multiple response formats: data.cart.id, data.id, or data.cart_id
423
+ const newCartId = data.cart?.id || data.id || data.cart_id || data.reorder?.cart_id
424
+
425
+ // Set the cart ID in cookies and revalidate
426
+ if (newCartId) {
427
+ // 1. Tag the cart as Buy Now to prevent merging and allow auto-restore,
428
+ // and add is_reorder flag to distinguish it
429
+ try {
430
+ await sdk.store.cart.update(
431
+ newCartId,
432
+ {
433
+ metadata: {
434
+ is_reorder: true,
435
+ },
436
+ },
437
+ {},
438
+ {
439
+ ...headers,
440
+ cache: "no-store",
441
+ } as any
442
+ )
443
+
444
+ // 2. Ensure this new cart is not merged with existing ones (CRITICAL for Buy Now flow)
445
+ await sdk.client.fetch(`/store/carts/merge/skip`, {
446
+ method: "POST",
447
+ body: { cart_id: newCartId },
448
+ headers: headers as Record<string, string>,
449
+ })
450
+ } catch (updateErr) {
451
+ console.error(
452
+ "[Reorder] Error updating cart metadata or skipping merge:",
453
+ updateErr
454
+ )
455
+ }
456
+
457
+ // FALLBACK: If skipVariantIds were provided but the plugin added everything,
458
+ // we manually remove the unwanted items from the new cart.
459
+ if (skipVariantIds && skipVariantIds.length > 0) {
460
+ try {
461
+ // Fetch the new cart to find line item IDs
462
+ const { cart } = await sdk.store.cart.retrieve(newCartId, {}, {
463
+ ...headers,
464
+ } as any)
465
+
466
+ if (cart && cart.items) {
467
+ const itemsToRemove = cart.items.filter(
468
+ (item) => item.variant_id && skipVariantIds.includes(item.variant_id)
469
+ )
470
+
471
+ // Delete unwanted items one by one
472
+ for (const item of itemsToRemove) {
473
+ await sdk.store.cart.deleteLineItem(newCartId, item.id, {}, {
474
+ ...headers,
475
+ } as any)
476
+ }
477
+ }
478
+ } catch (removeErr) {
479
+ console.error("[Reorder] Error removing skipped items:", removeErr)
480
+ // We continue anyway since the cart is created
481
+ }
482
+ }
483
+
484
+ // Use buy_now_cart_id instead of overwriting main cart
485
+ await removeBuyNowCartId()
486
+ await setBuyNowCartId(newCartId)
487
+
488
+ // Revalidate standard carts tag
489
+ revalidateTag("carts")
490
+
491
+ // Also revalidate specific cache tag if available
492
+ const cartCacheTag = await getCacheTag("carts")
493
+ if (cartCacheTag) revalidateTag(cartCacheTag)
494
+ }
495
+
496
+ return { success: true, data }
497
+ } catch (error: any) {
498
+ return { success: false, error: error.message }
499
+ }
500
+ }
@@ -0,0 +1,68 @@
1
+ "use server"
2
+
3
+ import { sdk } from "@core/config"
4
+ import { getAuthHeaders, getCacheOptions } from "./cookies"
5
+
6
+ export const listPaymentDetails = async () => {
7
+ const authHeaders = await getAuthHeaders()
8
+
9
+ // If no auth headers (guest user), don't even try to fetch
10
+ if (!authHeaders || Object.keys(authHeaders).length === 0) {
11
+ return []
12
+ }
13
+
14
+ const headers = {
15
+ ...authHeaders,
16
+ }
17
+
18
+ const next = {
19
+ ...(await getCacheOptions("payment_details")),
20
+ }
21
+
22
+ return sdk.client
23
+ .fetch<any>(`/store/payment-details`, {
24
+ method: "GET",
25
+ headers,
26
+ next,
27
+ cache: "no-store",
28
+ })
29
+ .then((res: any) => res.payment_details || [])
30
+ .catch(() => [])
31
+ }
32
+
33
+ export const createPaymentDetail = async (
34
+ type: "upi" | "bank" | "card",
35
+ detail_json: Record<string, string>
36
+ ) => {
37
+ const headers = {
38
+ ...(await getAuthHeaders()),
39
+ }
40
+
41
+ return sdk.client.fetch<any>(`/store/payment-details`, {
42
+ method: "POST",
43
+ headers,
44
+ body: { type, detail_json },
45
+ })
46
+ }
47
+
48
+ export const makeDefaultPaymentDetail = async (id: string) => {
49
+ const headers = {
50
+ ...(await getAuthHeaders()),
51
+ }
52
+
53
+ return sdk.client.fetch<any>(`/store/payment-details/${id}/make-default`, {
54
+ method: "POST",
55
+ headers,
56
+ })
57
+ }
58
+
59
+ export const deletePaymentDetail = async (id: string) => {
60
+ const headers = {
61
+ ...(await getAuthHeaders()),
62
+ }
63
+
64
+ return sdk.client.fetch<any>(`/store/payment-details/${id}`, {
65
+ method: "DELETE",
66
+ headers,
67
+ })
68
+ }
@@ -0,0 +1,32 @@
1
+ "use server"
2
+
3
+ import { sdk } from "@core/config"
4
+ import { getAuthHeaders, getCacheOptions } from "./cookies"
5
+ import { HttpTypes } from "@medusajs/types"
6
+
7
+ export const listCartPaymentMethods = async (regionId: string) => {
8
+ const headers = {
9
+ ...(await getAuthHeaders()),
10
+ }
11
+
12
+ const next = {
13
+ ...(await getCacheOptions("payment_providers")),
14
+ }
15
+
16
+ return sdk.client
17
+ .fetch<HttpTypes.StorePaymentProviderListResponse>(`/store/payment-providers`, {
18
+ method: "GET",
19
+ query: { region_id: regionId },
20
+ headers,
21
+ next,
22
+ cache: "no-store",
23
+ })
24
+ .then(({ payment_providers }) =>
25
+ payment_providers.sort((a, b) => {
26
+ return a.id > b.id ? 1 : -1
27
+ })
28
+ )
29
+ .catch(() => {
30
+ return null
31
+ })
32
+ }