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