@open-mercato/core 0.4.7-develop-0a657b411f → 0.4.7-develop-11728c8558

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 (275) hide show
  1. package/dist/generated/entities/carrier_shipment/index.js +37 -0
  2. package/dist/generated/entities/carrier_shipment/index.js.map +7 -0
  3. package/dist/generated/entities/gateway_transaction/index.js +47 -0
  4. package/dist/generated/entities/gateway_transaction/index.js.map +7 -0
  5. package/dist/generated/entities/webhook_processed_event/index.js +17 -0
  6. package/dist/generated/entities/webhook_processed_event/index.js.map +7 -0
  7. package/dist/generated/entities.ids.generated.js +10 -1
  8. package/dist/generated/entities.ids.generated.js.map +2 -2
  9. package/dist/generated/entity-fields-registry.js +6 -0
  10. package/dist/generated/entity-fields-registry.js.map +2 -2
  11. package/dist/modules/data_sync/api/runs/[id]/cancel.js +14 -5
  12. package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
  13. package/dist/modules/data_sync/backend/data-sync/page.meta.js +2 -2
  14. package/dist/modules/data_sync/backend/data-sync/page.meta.js.map +1 -1
  15. package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js +37 -12
  16. package/dist/modules/data_sync/backend/data-sync/runs/[id]/page.js.map +2 -2
  17. package/dist/modules/directory/api/get/tenants/lookup.js +1 -0
  18. package/dist/modules/directory/api/get/tenants/lookup.js.map +2 -2
  19. package/dist/modules/integrations/api/[id]/route.js +38 -11
  20. package/dist/modules/integrations/api/[id]/route.js.map +2 -2
  21. package/dist/modules/integrations/api/logs/route.js +52 -26
  22. package/dist/modules/integrations/api/logs/route.js.map +2 -2
  23. package/dist/modules/integrations/api/route.js +37 -7
  24. package/dist/modules/integrations/api/route.js.map +2 -2
  25. package/dist/modules/integrations/api/umes-read.js +121 -0
  26. package/dist/modules/integrations/api/umes-read.js.map +7 -0
  27. package/dist/modules/integrations/backend/integrations/[id]/page.js +715 -183
  28. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  29. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +30 -9
  30. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  31. package/dist/modules/integrations/backend/integrations/detail-page-widgets.js +46 -0
  32. package/dist/modules/integrations/backend/integrations/detail-page-widgets.js.map +7 -0
  33. package/dist/modules/integrations/backend/integrations/page.js +78 -62
  34. package/dist/modules/integrations/backend/integrations/page.js.map +2 -2
  35. package/dist/modules/integrations/backend/integrations/page.meta.js +2 -2
  36. package/dist/modules/integrations/backend/integrations/page.meta.js.map +1 -1
  37. package/dist/modules/integrations/setup.js +2 -2
  38. package/dist/modules/integrations/setup.js.map +2 -2
  39. package/dist/modules/payment_gateways/acl.js +12 -0
  40. package/dist/modules/payment_gateways/acl.js.map +7 -0
  41. package/dist/modules/payment_gateways/api/cancel/route.js +55 -0
  42. package/dist/modules/payment_gateways/api/cancel/route.js.map +7 -0
  43. package/dist/modules/payment_gateways/api/capture/route.js +55 -0
  44. package/dist/modules/payment_gateways/api/capture/route.js.map +7 -0
  45. package/dist/modules/payment_gateways/api/interceptors.js +24 -0
  46. package/dist/modules/payment_gateways/api/interceptors.js.map +7 -0
  47. package/dist/modules/payment_gateways/api/openapi.js +5 -0
  48. package/dist/modules/payment_gateways/api/openapi.js.map +7 -0
  49. package/dist/modules/payment_gateways/api/refund/route.js +56 -0
  50. package/dist/modules/payment_gateways/api/refund/route.js.map +7 -0
  51. package/dist/modules/payment_gateways/api/sessions/route.js +74 -0
  52. package/dist/modules/payment_gateways/api/sessions/route.js.map +7 -0
  53. package/dist/modules/payment_gateways/api/status/route.js +66 -0
  54. package/dist/modules/payment_gateways/api/status/route.js.map +7 -0
  55. package/dist/modules/payment_gateways/api/transactions/[id]/route.js +118 -0
  56. package/dist/modules/payment_gateways/api/transactions/[id]/route.js.map +7 -0
  57. package/dist/modules/payment_gateways/api/transactions/route.js +113 -0
  58. package/dist/modules/payment_gateways/api/transactions/route.js.map +7 -0
  59. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +136 -0
  60. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +7 -0
  61. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +496 -0
  62. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +7 -0
  63. package/dist/modules/payment_gateways/backend/payment-gateways/page.meta.js +23 -0
  64. package/dist/modules/payment_gateways/backend/payment-gateways/page.meta.js.map +7 -0
  65. package/dist/modules/payment_gateways/data/enrichers.js +5 -0
  66. package/dist/modules/payment_gateways/data/enrichers.js.map +7 -0
  67. package/dist/modules/payment_gateways/data/entities.js +131 -0
  68. package/dist/modules/payment_gateways/data/entities.js.map +7 -0
  69. package/dist/modules/payment_gateways/data/validators.js +57 -0
  70. package/dist/modules/payment_gateways/data/validators.js.map +7 -0
  71. package/dist/modules/payment_gateways/di.js +16 -0
  72. package/dist/modules/payment_gateways/di.js.map +7 -0
  73. package/dist/modules/payment_gateways/events.js +21 -0
  74. package/dist/modules/payment_gateways/events.js.map +7 -0
  75. package/dist/modules/payment_gateways/i18n/en.js +6 -0
  76. package/dist/modules/payment_gateways/i18n/en.js.map +7 -0
  77. package/dist/modules/payment_gateways/i18n/pl.js +6 -0
  78. package/dist/modules/payment_gateways/i18n/pl.js.map +7 -0
  79. package/dist/modules/payment_gateways/index.js +9 -0
  80. package/dist/modules/payment_gateways/index.js.map +7 -0
  81. package/dist/modules/payment_gateways/lib/gateway-service.js +378 -0
  82. package/dist/modules/payment_gateways/lib/gateway-service.js.map +7 -0
  83. package/dist/modules/payment_gateways/lib/queue.js +17 -0
  84. package/dist/modules/payment_gateways/lib/queue.js.map +7 -0
  85. package/dist/modules/payment_gateways/lib/status-machine.js +29 -0
  86. package/dist/modules/payment_gateways/lib/status-machine.js.map +7 -0
  87. package/dist/modules/payment_gateways/lib/webhook-processor.js +88 -0
  88. package/dist/modules/payment_gateways/lib/webhook-processor.js.map +7 -0
  89. package/dist/modules/payment_gateways/lib/webhook-utils.js +42 -0
  90. package/dist/modules/payment_gateways/lib/webhook-utils.js.map +7 -0
  91. package/dist/modules/payment_gateways/migrations/Migration20260305122155.js +19 -0
  92. package/dist/modules/payment_gateways/migrations/Migration20260305122155.js.map +7 -0
  93. package/dist/modules/payment_gateways/setup.js +13 -0
  94. package/dist/modules/payment_gateways/setup.js.map +7 -0
  95. package/dist/modules/payment_gateways/widgets/injection-table.js +7 -0
  96. package/dist/modules/payment_gateways/widgets/injection-table.js.map +7 -0
  97. package/dist/modules/payment_gateways/workers/status-poller.js +44 -0
  98. package/dist/modules/payment_gateways/workers/status-poller.js.map +7 -0
  99. package/dist/modules/payment_gateways/workers/webhook-processor.js +20 -0
  100. package/dist/modules/payment_gateways/workers/webhook-processor.js.map +7 -0
  101. package/dist/modules/sales/data/enrichers.js +80 -0
  102. package/dist/modules/sales/data/enrichers.js.map +7 -0
  103. package/dist/modules/sales/widgets/injection/payment-gateway-config-field/widget.js +29 -0
  104. package/dist/modules/sales/widgets/injection/payment-gateway-config-field/widget.js.map +7 -0
  105. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +23 -0
  106. package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +7 -0
  107. package/dist/modules/sales/widgets/injection-table.js +13 -1
  108. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  109. package/dist/modules/shipping_carriers/acl.js +10 -0
  110. package/dist/modules/shipping_carriers/acl.js.map +7 -0
  111. package/dist/modules/shipping_carriers/api/cancel/route.js +55 -0
  112. package/dist/modules/shipping_carriers/api/cancel/route.js.map +7 -0
  113. package/dist/modules/shipping_carriers/api/interceptors.js +21 -0
  114. package/dist/modules/shipping_carriers/api/interceptors.js.map +7 -0
  115. package/dist/modules/shipping_carriers/api/openapi.js +5 -0
  116. package/dist/modules/shipping_carriers/api/openapi.js.map +7 -0
  117. package/dist/modules/shipping_carriers/api/rates/route.js +55 -0
  118. package/dist/modules/shipping_carriers/api/rates/route.js.map +7 -0
  119. package/dist/modules/shipping_carriers/api/shipments/route.js +61 -0
  120. package/dist/modules/shipping_carriers/api/shipments/route.js.map +7 -0
  121. package/dist/modules/shipping_carriers/api/tracking/route.js +58 -0
  122. package/dist/modules/shipping_carriers/api/tracking/route.js.map +7 -0
  123. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js +119 -0
  124. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js.map +7 -0
  125. package/dist/modules/shipping_carriers/data/enrichers.js +82 -0
  126. package/dist/modules/shipping_carriers/data/enrichers.js.map +7 -0
  127. package/dist/modules/shipping_carriers/data/entities.js +80 -0
  128. package/dist/modules/shipping_carriers/data/entities.js.map +7 -0
  129. package/dist/modules/shipping_carriers/data/validators.js +49 -0
  130. package/dist/modules/shipping_carriers/data/validators.js.map +7 -0
  131. package/dist/modules/shipping_carriers/di.js +15 -0
  132. package/dist/modules/shipping_carriers/di.js.map +7 -0
  133. package/dist/modules/shipping_carriers/events.js +19 -0
  134. package/dist/modules/shipping_carriers/events.js.map +7 -0
  135. package/dist/modules/shipping_carriers/i18n/en.js +11 -0
  136. package/dist/modules/shipping_carriers/i18n/en.js.map +7 -0
  137. package/dist/modules/shipping_carriers/i18n/pl.js +11 -0
  138. package/dist/modules/shipping_carriers/i18n/pl.js.map +7 -0
  139. package/dist/modules/shipping_carriers/index.js +9 -0
  140. package/dist/modules/shipping_carriers/index.js.map +7 -0
  141. package/dist/modules/shipping_carriers/lib/adapter-registry.js +29 -0
  142. package/dist/modules/shipping_carriers/lib/adapter-registry.js.map +7 -0
  143. package/dist/modules/shipping_carriers/lib/adapter.js +1 -0
  144. package/dist/modules/shipping_carriers/lib/adapter.js.map +7 -0
  145. package/dist/modules/shipping_carriers/lib/queue.js +17 -0
  146. package/dist/modules/shipping_carriers/lib/queue.js.map +7 -0
  147. package/dist/modules/shipping_carriers/lib/shipping-service.js +155 -0
  148. package/dist/modules/shipping_carriers/lib/shipping-service.js.map +7 -0
  149. package/dist/modules/shipping_carriers/lib/status-sync.js +37 -0
  150. package/dist/modules/shipping_carriers/lib/status-sync.js.map +7 -0
  151. package/dist/modules/shipping_carriers/migrations/Migration20260305170000.js +16 -0
  152. package/dist/modules/shipping_carriers/migrations/Migration20260305170000.js.map +7 -0
  153. package/dist/modules/shipping_carriers/setup.js +13 -0
  154. package/dist/modules/shipping_carriers/setup.js.map +7 -0
  155. package/dist/modules/shipping_carriers/widgets/injection/create-shipment-button/widget.js +25 -0
  156. package/dist/modules/shipping_carriers/widgets/injection/create-shipment-button/widget.js.map +7 -0
  157. package/dist/modules/shipping_carriers/widgets/injection/tracking-column/widget.js +23 -0
  158. package/dist/modules/shipping_carriers/widgets/injection/tracking-column/widget.js.map +7 -0
  159. package/dist/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.js +40 -0
  160. package/dist/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.js.map +7 -0
  161. package/dist/modules/shipping_carriers/widgets/injection-table.js +24 -0
  162. package/dist/modules/shipping_carriers/widgets/injection-table.js.map +7 -0
  163. package/dist/modules/shipping_carriers/workers/status-poller.js +21 -0
  164. package/dist/modules/shipping_carriers/workers/status-poller.js.map +7 -0
  165. package/dist/modules/shipping_carriers/workers/webhook-processor.js +54 -0
  166. package/dist/modules/shipping_carriers/workers/webhook-processor.js.map +7 -0
  167. package/dist/modules/translations/api/get/locales.js +1 -0
  168. package/dist/modules/translations/api/get/locales.js.map +2 -2
  169. package/dist/modules/translations/api/put/locales.js +1 -0
  170. package/dist/modules/translations/api/put/locales.js.map +2 -2
  171. package/generated/entities/carrier_shipment/index.ts +17 -0
  172. package/generated/entities/gateway_transaction/index.ts +22 -0
  173. package/generated/entities/webhook_processed_event/index.ts +7 -0
  174. package/generated/entities.ids.generated.ts +10 -1
  175. package/generated/entity-fields-registry.ts +6 -0
  176. package/jest.config.cjs +1 -0
  177. package/package.json +5 -2
  178. package/src/modules/auth/i18n/de.json +1 -0
  179. package/src/modules/auth/i18n/en.json +1 -0
  180. package/src/modules/auth/i18n/es.json +1 -0
  181. package/src/modules/auth/i18n/pl.json +1 -0
  182. package/src/modules/data_sync/api/runs/[id]/cancel.ts +18 -5
  183. package/src/modules/data_sync/backend/data-sync/page.meta.ts +2 -2
  184. package/src/modules/data_sync/backend/data-sync/runs/[id]/page.tsx +50 -12
  185. package/src/modules/directory/api/get/tenants/lookup.ts +1 -0
  186. package/src/modules/integrations/AGENTS.md +31 -0
  187. package/src/modules/integrations/api/[id]/route.ts +38 -11
  188. package/src/modules/integrations/api/logs/route.ts +53 -27
  189. package/src/modules/integrations/api/route.ts +31 -1
  190. package/src/modules/integrations/api/umes-read.ts +177 -0
  191. package/src/modules/integrations/backend/integrations/[id]/page.tsx +902 -202
  192. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +43 -9
  193. package/src/modules/integrations/backend/integrations/detail-page-widgets.ts +74 -0
  194. package/src/modules/integrations/backend/integrations/page.meta.ts +2 -2
  195. package/src/modules/integrations/backend/integrations/page.tsx +65 -54
  196. package/src/modules/integrations/i18n/de.json +15 -0
  197. package/src/modules/integrations/i18n/en.json +15 -0
  198. package/src/modules/integrations/i18n/es.json +15 -0
  199. package/src/modules/integrations/i18n/pl.json +15 -0
  200. package/src/modules/integrations/setup.ts +2 -2
  201. package/src/modules/payment_gateways/acl.ts +8 -0
  202. package/src/modules/payment_gateways/api/cancel/route.ts +56 -0
  203. package/src/modules/payment_gateways/api/capture/route.ts +56 -0
  204. package/src/modules/payment_gateways/api/interceptors.ts +22 -0
  205. package/src/modules/payment_gateways/api/openapi.ts +1 -0
  206. package/src/modules/payment_gateways/api/refund/route.ts +57 -0
  207. package/src/modules/payment_gateways/api/sessions/route.ts +76 -0
  208. package/src/modules/payment_gateways/api/status/route.ts +69 -0
  209. package/src/modules/payment_gateways/api/transactions/[id]/route.ts +123 -0
  210. package/src/modules/payment_gateways/api/transactions/route.ts +120 -0
  211. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +161 -0
  212. package/src/modules/payment_gateways/backend/payment-gateways/page.meta.ts +19 -0
  213. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +660 -0
  214. package/src/modules/payment_gateways/data/enrichers.ts +8 -0
  215. package/src/modules/payment_gateways/data/entities.ts +106 -0
  216. package/src/modules/payment_gateways/data/validators.ts +67 -0
  217. package/src/modules/payment_gateways/di.ts +26 -0
  218. package/src/modules/payment_gateways/events.ts +17 -0
  219. package/src/modules/payment_gateways/i18n/de.json +77 -0
  220. package/src/modules/payment_gateways/i18n/en.json +77 -0
  221. package/src/modules/payment_gateways/i18n/en.ts +4 -0
  222. package/src/modules/payment_gateways/i18n/es.json +77 -0
  223. package/src/modules/payment_gateways/i18n/pl.json +77 -0
  224. package/src/modules/payment_gateways/i18n/pl.ts +4 -0
  225. package/src/modules/payment_gateways/index.ts +5 -0
  226. package/src/modules/payment_gateways/lib/gateway-service.ts +486 -0
  227. package/src/modules/payment_gateways/lib/queue.ts +19 -0
  228. package/src/modules/payment_gateways/lib/status-machine.ts +28 -0
  229. package/src/modules/payment_gateways/lib/webhook-processor.ts +133 -0
  230. package/src/modules/payment_gateways/lib/webhook-utils.ts +52 -0
  231. package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +373 -0
  232. package/src/modules/payment_gateways/migrations/Migration20260305122155.ts +20 -0
  233. package/src/modules/payment_gateways/setup.ts +11 -0
  234. package/src/modules/payment_gateways/widgets/injection-table.ts +9 -0
  235. package/src/modules/payment_gateways/workers/status-poller.ts +58 -0
  236. package/src/modules/payment_gateways/workers/webhook-processor.ts +30 -0
  237. package/src/modules/sales/data/enrichers.ts +94 -0
  238. package/src/modules/sales/widgets/injection/payment-gateway-config-field/widget.ts +28 -0
  239. package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +22 -0
  240. package/src/modules/sales/widgets/injection-table.ts +12 -0
  241. package/src/modules/shipping_carriers/acl.ts +6 -0
  242. package/src/modules/shipping_carriers/api/cancel/route.ts +53 -0
  243. package/src/modules/shipping_carriers/api/interceptors.ts +19 -0
  244. package/src/modules/shipping_carriers/api/openapi.ts +1 -0
  245. package/src/modules/shipping_carriers/api/rates/route.ts +53 -0
  246. package/src/modules/shipping_carriers/api/shipments/route.ts +59 -0
  247. package/src/modules/shipping_carriers/api/tracking/route.ts +56 -0
  248. package/src/modules/shipping_carriers/api/webhook/[provider]/route.ts +134 -0
  249. package/src/modules/shipping_carriers/data/enrichers.ts +89 -0
  250. package/src/modules/shipping_carriers/data/entities.ts +60 -0
  251. package/src/modules/shipping_carriers/data/validators.ts +48 -0
  252. package/src/modules/shipping_carriers/di.ts +20 -0
  253. package/src/modules/shipping_carriers/events.ts +16 -0
  254. package/src/modules/shipping_carriers/i18n/de.json +7 -0
  255. package/src/modules/shipping_carriers/i18n/en.json +7 -0
  256. package/src/modules/shipping_carriers/i18n/en.ts +7 -0
  257. package/src/modules/shipping_carriers/i18n/es.json +7 -0
  258. package/src/modules/shipping_carriers/i18n/pl.json +7 -0
  259. package/src/modules/shipping_carriers/i18n/pl.ts +7 -0
  260. package/src/modules/shipping_carriers/index.ts +5 -0
  261. package/src/modules/shipping_carriers/lib/adapter-registry.ts +33 -0
  262. package/src/modules/shipping_carriers/lib/adapter.ts +93 -0
  263. package/src/modules/shipping_carriers/lib/queue.ts +19 -0
  264. package/src/modules/shipping_carriers/lib/shipping-service.ts +204 -0
  265. package/src/modules/shipping_carriers/lib/status-sync.ts +38 -0
  266. package/src/modules/shipping_carriers/migrations/Migration20260305170000.ts +14 -0
  267. package/src/modules/shipping_carriers/setup.ts +11 -0
  268. package/src/modules/shipping_carriers/widgets/injection/create-shipment-button/widget.ts +24 -0
  269. package/src/modules/shipping_carriers/widgets/injection/tracking-column/widget.ts +22 -0
  270. package/src/modules/shipping_carriers/widgets/injection/tracking-status-badge/widget.tsx +44 -0
  271. package/src/modules/shipping_carriers/widgets/injection-table.ts +22 -0
  272. package/src/modules/shipping_carriers/workers/status-poller.ts +33 -0
  273. package/src/modules/shipping_carriers/workers/webhook-processor.ts +79 -0
  274. package/src/modules/translations/api/get/locales.ts +1 -0
  275. package/src/modules/translations/api/put/locales.ts +1 -0
@@ -0,0 +1,56 @@
1
+ import { NextResponse } from "next/server";
2
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
3
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
+ import { readJsonSafe } from "@open-mercato/shared/lib/http/readJsonSafe";
5
+ import { refundSchema } from "../../data/validators.js";
6
+ import { paymentGatewaysTag } from "../openapi.js";
7
+ const metadata = {
8
+ path: "/payment_gateways/refund",
9
+ POST: { requireAuth: true, requireFeatures: ["payment_gateways.refund"] }
10
+ };
11
+ async function POST(req) {
12
+ const auth = await getAuthFromRequest(req);
13
+ if (!auth?.tenantId || !auth.orgId) {
14
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
15
+ }
16
+ const payload = await readJsonSafe(req);
17
+ const parsed = refundSchema.safeParse(payload);
18
+ if (!parsed.success) {
19
+ return NextResponse.json({ error: "Invalid payload", details: parsed.error.flatten() }, { status: 422 });
20
+ }
21
+ const container = await createRequestContainer();
22
+ const service = container.resolve("paymentGatewayService");
23
+ try {
24
+ const result = await service.refundPayment(
25
+ parsed.data.transactionId,
26
+ parsed.data.amount,
27
+ parsed.data.reason,
28
+ { organizationId: auth.orgId, tenantId: auth.tenantId }
29
+ );
30
+ return NextResponse.json(result);
31
+ } catch (err) {
32
+ const message = err instanceof Error ? err.message : "Refund failed";
33
+ return NextResponse.json({ error: message }, { status: 502 });
34
+ }
35
+ }
36
+ const openApi = {
37
+ tags: [paymentGatewaysTag],
38
+ summary: "Refund a captured payment",
39
+ methods: {
40
+ POST: {
41
+ summary: "Refund payment",
42
+ tags: [paymentGatewaysTag],
43
+ responses: [
44
+ { status: 200, description: "Payment refunded" },
45
+ { status: 422, description: "Invalid payload" },
46
+ { status: 502, description: "Gateway provider error" }
47
+ ]
48
+ }
49
+ }
50
+ };
51
+ export {
52
+ POST,
53
+ metadata,
54
+ openApi
55
+ };
56
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/payment_gateways/api/refund/route.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { refundSchema } from '../../data/validators'\nimport type { PaymentGatewayService } from '../../lib/gateway-service'\nimport { paymentGatewaysTag } from '../openapi'\n\nexport const metadata = {\n path: '/payment_gateways/refund',\n POST: { requireAuth: true, requireFeatures: ['payment_gateways.refund'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const payload = await readJsonSafe<unknown>(req)\n const parsed = refundSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n\n const container = await createRequestContainer()\n const service = container.resolve('paymentGatewayService') as PaymentGatewayService\n\n try {\n const result = await service.refundPayment(\n parsed.data.transactionId,\n parsed.data.amount,\n parsed.data.reason,\n { organizationId: auth.orgId as string, tenantId: auth.tenantId },\n )\n return NextResponse.json(result)\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : 'Refund failed'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Refund a captured payment',\n methods: {\n POST: {\n summary: 'Refund payment',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Payment refunded' },\n { status: 422, description: 'Invalid payload' },\n { status: 502, description: 'Gateway provider error' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAE7B,SAAS,0BAA0B;AAE5B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,yBAAyB,EAAE;AAC1E;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AAEA,QAAM,UAAU,MAAM,aAAsB,GAAG;AAC/C,QAAM,SAAS,aAAa,UAAU,OAAO;AAC7C,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,mBAAmB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,uBAAuB;AAEzD,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,EAAE,gBAAgB,KAAK,OAAiB,UAAU,KAAK,SAAS;AAAA,IAClE;AACA,WAAO,aAAa,KAAK,MAAM;AAAA,EACjC,SAAS,KAAc;AACrB,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,WAAO,aAAa,KAAK,EAAE,OAAO,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,kBAAkB;AAAA,EACzB,SAAS;AAAA,EACT,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM,CAAC,kBAAkB;AAAA,MACzB,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,mBAAmB;AAAA,QAC/C,EAAE,QAAQ,KAAK,aAAa,kBAAkB;AAAA,QAC9C,EAAE,QAAQ,KAAK,aAAa,yBAAyB;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,74 @@
1
+ import { NextResponse } from "next/server";
2
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
3
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
+ import { readJsonSafe } from "@open-mercato/shared/lib/http/readJsonSafe";
5
+ import { createSessionSchema } from "../../data/validators.js";
6
+ import { paymentGatewaysTag } from "../openapi.js";
7
+ const metadata = {
8
+ path: "/payment_gateways/sessions",
9
+ POST: { requireAuth: true, requireFeatures: ["payment_gateways.manage"] }
10
+ };
11
+ async function POST(req) {
12
+ const auth = await getAuthFromRequest(req);
13
+ if (!auth?.tenantId || !auth.orgId) {
14
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
15
+ }
16
+ const payload = await readJsonSafe(req);
17
+ const parsed = createSessionSchema.safeParse(payload);
18
+ if (!parsed.success) {
19
+ return NextResponse.json({ error: "Invalid payload", details: parsed.error.flatten() }, { status: 422 });
20
+ }
21
+ const container = await createRequestContainer();
22
+ const service = container.resolve("paymentGatewayService");
23
+ try {
24
+ const { transaction, session } = await service.createPaymentSession({
25
+ providerKey: parsed.data.providerKey,
26
+ paymentId: crypto.randomUUID(),
27
+ orderId: parsed.data.orderId,
28
+ amount: parsed.data.amount,
29
+ currencyCode: parsed.data.currencyCode,
30
+ captureMethod: parsed.data.captureMethod,
31
+ description: parsed.data.description,
32
+ successUrl: parsed.data.successUrl,
33
+ cancelUrl: parsed.data.cancelUrl,
34
+ metadata: parsed.data.metadata,
35
+ organizationId: auth.orgId,
36
+ tenantId: auth.tenantId
37
+ });
38
+ return NextResponse.json({
39
+ transactionId: transaction.id,
40
+ sessionId: session.sessionId,
41
+ providerKey: transaction.providerKey,
42
+ clientSecret: session.clientSecret,
43
+ redirectUrl: session.redirectUrl,
44
+ providerData: session.providerData ?? null,
45
+ status: session.status,
46
+ paymentId: transaction.paymentId
47
+ }, { status: 201 });
48
+ } catch (err) {
49
+ const message = err instanceof Error ? err.message : "Failed to create payment session";
50
+ const status = message.includes("No gateway adapter") ? 422 : 502;
51
+ return NextResponse.json({ error: message }, { status });
52
+ }
53
+ }
54
+ const openApi = {
55
+ tags: [paymentGatewaysTag],
56
+ summary: "Create a payment session via a gateway provider",
57
+ methods: {
58
+ POST: {
59
+ summary: "Create payment session",
60
+ tags: [paymentGatewaysTag],
61
+ responses: [
62
+ { status: 201, description: "Payment session created" },
63
+ { status: 422, description: "Invalid payload or unknown provider" },
64
+ { status: 502, description: "Gateway provider error" }
65
+ ]
66
+ }
67
+ }
68
+ };
69
+ export {
70
+ POST,
71
+ metadata,
72
+ openApi
73
+ };
74
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/payment_gateways/api/sessions/route.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport { createSessionSchema } from '../../data/validators'\nimport type { PaymentGatewayService } from '../../lib/gateway-service'\nimport { paymentGatewaysTag } from '../openapi'\n\nexport const metadata = {\n path: '/payment_gateways/sessions',\n POST: { requireAuth: true, requireFeatures: ['payment_gateways.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const payload = await readJsonSafe<unknown>(req)\n const parsed = createSessionSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n\n const container = await createRequestContainer()\n const service = container.resolve('paymentGatewayService') as PaymentGatewayService\n\n try {\n const { transaction, session } = await service.createPaymentSession({\n providerKey: parsed.data.providerKey,\n paymentId: crypto.randomUUID(),\n orderId: parsed.data.orderId,\n amount: parsed.data.amount,\n currencyCode: parsed.data.currencyCode,\n captureMethod: parsed.data.captureMethod,\n description: parsed.data.description,\n successUrl: parsed.data.successUrl,\n cancelUrl: parsed.data.cancelUrl,\n metadata: parsed.data.metadata,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n\n return NextResponse.json({\n transactionId: transaction.id,\n sessionId: session.sessionId,\n providerKey: transaction.providerKey,\n clientSecret: session.clientSecret,\n redirectUrl: session.redirectUrl,\n providerData: session.providerData ?? null,\n status: session.status,\n paymentId: transaction.paymentId,\n }, { status: 201 })\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : 'Failed to create payment session'\n const status = message.includes('No gateway adapter') ? 422 : 502\n return NextResponse.json({ error: message }, { status })\n }\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Create a payment session via a gateway provider',\n methods: {\n POST: {\n summary: 'Create payment session',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 201, description: 'Payment session created' },\n { status: 422, description: 'Invalid payload or unknown provider' },\n { status: 502, description: 'Gateway provider error' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAC7B,SAAS,2BAA2B;AAEpC,SAAS,0BAA0B;AAE5B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,yBAAyB,EAAE;AAC1E;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AAEA,QAAM,UAAU,MAAM,aAAsB,GAAG;AAC/C,QAAM,SAAS,oBAAoB,UAAU,OAAO;AACpD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,mBAAmB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,uBAAuB;AAEzD,MAAI;AACF,UAAM,EAAE,aAAa,QAAQ,IAAI,MAAM,QAAQ,qBAAqB;AAAA,MAClE,aAAa,OAAO,KAAK;AAAA,MACzB,WAAW,OAAO,WAAW;AAAA,MAC7B,SAAS,OAAO,KAAK;AAAA,MACrB,QAAQ,OAAO,KAAK;AAAA,MACpB,cAAc,OAAO,KAAK;AAAA,MAC1B,eAAe,OAAO,KAAK;AAAA,MAC3B,aAAa,OAAO,KAAK;AAAA,MACzB,YAAY,OAAO,KAAK;AAAA,MACxB,WAAW,OAAO,KAAK;AAAA,MACvB,UAAU,OAAO,KAAK;AAAA,MACtB,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,IACjB,CAAC;AAED,WAAO,aAAa,KAAK;AAAA,MACvB,eAAe,YAAY;AAAA,MAC3B,WAAW,QAAQ;AAAA,MACnB,aAAa,YAAY;AAAA,MACzB,cAAc,QAAQ;AAAA,MACtB,aAAa,QAAQ;AAAA,MACrB,cAAc,QAAQ,gBAAgB;AAAA,MACtC,QAAQ,QAAQ;AAAA,MAChB,WAAW,YAAY;AAAA,IACzB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACpB,SAAS,KAAc;AACrB,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,UAAM,SAAS,QAAQ,SAAS,oBAAoB,IAAI,MAAM;AAC9D,WAAO,aAAa,KAAK,EAAE,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC;AAAA,EACzD;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,kBAAkB;AAAA,EACzB,SAAS;AAAA,EACT,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM,CAAC,kBAAkB;AAAA,MACzB,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,0BAA0B;AAAA,QACtD,EAAE,QAAQ,KAAK,aAAa,sCAAsC;AAAA,QAClE,EAAE,QAAQ,KAAK,aAAa,yBAAyB;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,66 @@
1
+ import { NextResponse } from "next/server";
2
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
3
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
+ import { paymentGatewaysTag } from "../openapi.js";
5
+ const metadata = {
6
+ path: "/payment_gateways/status",
7
+ GET: { requireAuth: true, requireFeatures: ["payment_gateways.view"] }
8
+ };
9
+ async function GET(req) {
10
+ const auth = await getAuthFromRequest(req);
11
+ if (!auth?.tenantId || !auth.orgId) {
12
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
13
+ }
14
+ const url = new URL(req.url);
15
+ const transactionId = url.searchParams.get("transactionId");
16
+ if (!transactionId) {
17
+ return NextResponse.json({ error: "transactionId is required" }, { status: 400 });
18
+ }
19
+ const container = await createRequestContainer();
20
+ const service = container.resolve("paymentGatewayService");
21
+ try {
22
+ const scope = { organizationId: auth.orgId, tenantId: auth.tenantId };
23
+ const transaction = await service.findTransaction(transactionId, scope);
24
+ if (!transaction) {
25
+ return NextResponse.json({ error: "Transaction not found" }, { status: 404 });
26
+ }
27
+ const status = await service.getPaymentStatus(transactionId, scope);
28
+ return NextResponse.json({
29
+ transactionId: transaction.id,
30
+ paymentId: transaction.paymentId,
31
+ providerKey: transaction.providerKey,
32
+ sessionId: transaction.providerSessionId,
33
+ status: status.status,
34
+ gatewayStatus: transaction.gatewayStatus,
35
+ amount: status.amount,
36
+ amountReceived: status.amountReceived,
37
+ currencyCode: status.currencyCode,
38
+ redirectUrl: transaction.redirectUrl,
39
+ createdAt: transaction.createdAt.toISOString(),
40
+ updatedAt: transaction.updatedAt.toISOString()
41
+ });
42
+ } catch (err) {
43
+ const message = err instanceof Error ? err.message : "Failed to get status";
44
+ return NextResponse.json({ error: message }, { status: 500 });
45
+ }
46
+ }
47
+ const openApi = {
48
+ tags: [paymentGatewaysTag],
49
+ summary: "Get payment transaction status",
50
+ methods: {
51
+ GET: {
52
+ summary: "Get transaction status",
53
+ tags: [paymentGatewaysTag],
54
+ responses: [
55
+ { status: 200, description: "Transaction status" },
56
+ { status: 404, description: "Transaction not found" }
57
+ ]
58
+ }
59
+ }
60
+ };
61
+ export {
62
+ GET,
63
+ metadata,
64
+ openApi
65
+ };
66
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/payment_gateways/api/status/route.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { PaymentGatewayService } from '../../lib/gateway-service'\nimport { paymentGatewaysTag } from '../openapi'\n\nexport const metadata = {\n path: '/payment_gateways/status',\n GET: { requireAuth: true, requireFeatures: ['payment_gateways.view'] },\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const url = new URL(req.url)\n const transactionId = url.searchParams.get('transactionId')\n if (!transactionId) {\n return NextResponse.json({ error: 'transactionId is required' }, { status: 400 })\n }\n\n const container = await createRequestContainer()\n const service = container.resolve('paymentGatewayService') as PaymentGatewayService\n\n try {\n const scope = { organizationId: auth.orgId as string, tenantId: auth.tenantId }\n const transaction = await service.findTransaction(transactionId, scope)\n if (!transaction) {\n return NextResponse.json({ error: 'Transaction not found' }, { status: 404 })\n }\n\n const status = await service.getPaymentStatus(transactionId, scope)\n\n return NextResponse.json({\n transactionId: transaction.id,\n paymentId: transaction.paymentId,\n providerKey: transaction.providerKey,\n sessionId: transaction.providerSessionId,\n status: status.status,\n gatewayStatus: transaction.gatewayStatus,\n amount: status.amount,\n amountReceived: status.amountReceived,\n currencyCode: status.currencyCode,\n redirectUrl: transaction.redirectUrl,\n createdAt: transaction.createdAt.toISOString(),\n updatedAt: transaction.updatedAt.toISOString(),\n })\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : 'Failed to get status'\n return NextResponse.json({ error: message }, { status: 500 })\n }\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Get payment transaction status',\n methods: {\n GET: {\n summary: 'Get transaction status',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Transaction status' },\n { status: 404, description: 'Transaction not found' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AAEvC,SAAS,0BAA0B;AAE5B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,uBAAuB,EAAE;AACvE;AAEA,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AAEA,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,QAAM,gBAAgB,IAAI,aAAa,IAAI,eAAe;AAC1D,MAAI,CAAC,eAAe;AAClB,WAAO,aAAa,KAAK,EAAE,OAAO,4BAA4B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAClF;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,uBAAuB;AAEzD,MAAI;AACF,UAAM,QAAQ,EAAE,gBAAgB,KAAK,OAAiB,UAAU,KAAK,SAAS;AAC9E,UAAM,cAAc,MAAM,QAAQ,gBAAgB,eAAe,KAAK;AACtE,QAAI,CAAC,aAAa;AAChB,aAAO,aAAa,KAAK,EAAE,OAAO,wBAAwB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC9E;AAEA,UAAM,SAAS,MAAM,QAAQ,iBAAiB,eAAe,KAAK;AAElE,WAAO,aAAa,KAAK;AAAA,MACvB,eAAe,YAAY;AAAA,MAC3B,WAAW,YAAY;AAAA,MACvB,aAAa,YAAY;AAAA,MACzB,WAAW,YAAY;AAAA,MACvB,QAAQ,OAAO;AAAA,MACf,eAAe,YAAY;AAAA,MAC3B,QAAQ,OAAO;AAAA,MACf,gBAAgB,OAAO;AAAA,MACvB,cAAc,OAAO;AAAA,MACrB,aAAa,YAAY;AAAA,MACzB,WAAW,YAAY,UAAU,YAAY;AAAA,MAC7C,WAAW,YAAY,UAAU,YAAY;AAAA,IAC/C,CAAC;AAAA,EACH,SAAS,KAAc;AACrB,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,WAAO,aAAa,KAAK,EAAE,OAAO,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,kBAAkB;AAAA,EACzB,SAAS;AAAA,EACT,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,MAAM,CAAC,kBAAkB;AAAA,MACzB,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,qBAAqB;AAAA,QACjD,EAAE,QAAQ,KAAK,aAAa,wBAAwB;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,118 @@
1
+ import { NextResponse } from "next/server";
2
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
3
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
+ import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
5
+ import { GatewayTransaction } from "../../../data/entities.js";
6
+ import { paymentGatewaysTag } from "../../openapi.js";
7
+ const metadata = {
8
+ path: "/payment_gateways/transactions/[id]",
9
+ GET: { requireAuth: true, requireFeatures: ["payment_gateways.view"] }
10
+ };
11
+ function toIsoString(value) {
12
+ if (!value) return null;
13
+ if (value instanceof Date) return value.toISOString();
14
+ if (typeof value === "string") {
15
+ const parsed2 = new Date(value);
16
+ if (!Number.isNaN(parsed2.getTime())) return parsed2.toISOString();
17
+ return value;
18
+ }
19
+ const parsed = new Date(value);
20
+ return Number.isNaN(parsed.getTime()) ? null : parsed.toISOString();
21
+ }
22
+ async function GET(req, { params }) {
23
+ const auth = await getAuthFromRequest(req);
24
+ if (!auth?.tenantId || !auth.orgId) {
25
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
26
+ }
27
+ const resolvedParams = await params;
28
+ const transactionId = resolvedParams?.id;
29
+ if (!transactionId) {
30
+ return NextResponse.json({ error: "Transaction id is required" }, { status: 400 });
31
+ }
32
+ const { resolve } = await createRequestContainer();
33
+ const scope = { organizationId: auth.orgId, tenantId: auth.tenantId };
34
+ const em = resolve("em");
35
+ const integrationLogService = resolve("integrationLogService");
36
+ const transaction = await findOneWithDecryption(
37
+ em,
38
+ GatewayTransaction,
39
+ {
40
+ id: transactionId,
41
+ organizationId: scope.organizationId,
42
+ tenantId: scope.tenantId,
43
+ deletedAt: null
44
+ },
45
+ void 0,
46
+ scope
47
+ );
48
+ if (!transaction) {
49
+ return NextResponse.json({ error: "Transaction not found" }, { status: 404 });
50
+ }
51
+ const integrationId = `gateway_${transaction.providerKey}`;
52
+ const { items: logRows } = await integrationLogService.query(
53
+ {
54
+ integrationId,
55
+ entityType: "payment_transaction",
56
+ entityId: transactionId,
57
+ page: 1,
58
+ pageSize: 100
59
+ },
60
+ scope
61
+ );
62
+ return NextResponse.json({
63
+ transaction: {
64
+ id: transaction.id,
65
+ paymentId: transaction.paymentId,
66
+ providerKey: transaction.providerKey,
67
+ providerSessionId: transaction.providerSessionId ?? null,
68
+ gatewayPaymentId: transaction.gatewayPaymentId ?? null,
69
+ gatewayRefundId: transaction.gatewayRefundId ?? null,
70
+ unifiedStatus: transaction.unifiedStatus,
71
+ gatewayStatus: transaction.gatewayStatus ?? null,
72
+ redirectUrl: transaction.redirectUrl ?? null,
73
+ amount: transaction.amount,
74
+ currencyCode: transaction.currencyCode,
75
+ gatewayMetadata: transaction.gatewayMetadata ?? null,
76
+ webhookLog: Array.isArray(transaction.webhookLog) ? transaction.webhookLog : [],
77
+ lastWebhookAt: toIsoString(transaction.lastWebhookAt),
78
+ lastPolledAt: toIsoString(transaction.lastPolledAt),
79
+ expiresAt: toIsoString(transaction.expiresAt),
80
+ createdAt: toIsoString(transaction.createdAt),
81
+ updatedAt: toIsoString(transaction.updatedAt)
82
+ },
83
+ logs: logRows.map((row) => ({
84
+ id: row.id,
85
+ integrationId: row.integrationId,
86
+ runId: row.runId ?? null,
87
+ scopeEntityType: row.scopeEntityType ?? null,
88
+ scopeEntityId: row.scopeEntityId ?? null,
89
+ level: row.level,
90
+ message: row.message,
91
+ code: row.code ?? null,
92
+ payload: row.payload ?? null,
93
+ createdAt: toIsoString(row.createdAt)
94
+ }))
95
+ });
96
+ }
97
+ const openApi = {
98
+ tags: [paymentGatewaysTag],
99
+ summary: "Get payment transaction details",
100
+ methods: {
101
+ GET: {
102
+ summary: "Get payment transaction details",
103
+ tags: [paymentGatewaysTag],
104
+ responses: [
105
+ { status: 200, description: "Payment transaction details" },
106
+ { status: 404, description: "Transaction not found" }
107
+ ]
108
+ }
109
+ }
110
+ };
111
+ var route_default = GET;
112
+ export {
113
+ GET,
114
+ route_default as default,
115
+ metadata,
116
+ openApi
117
+ };
118
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/modules/payment_gateways/api/transactions/%5Bid%5D/route.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { IntegrationLogService } from '../../../../integrations/lib/log-service'\nimport { GatewayTransaction } from '../../../data/entities'\nimport { paymentGatewaysTag } from '../../openapi'\n\nexport const metadata = {\n path: '/payment_gateways/transactions/[id]',\n GET: { requireAuth: true, requireFeatures: ['payment_gateways.view'] },\n}\n\nfunction toIsoString(value: unknown): string | null {\n if (!value) return null\n if (value instanceof Date) return value.toISOString()\n if (typeof value === 'string') {\n const parsed = new Date(value)\n if (!Number.isNaN(parsed.getTime())) return parsed.toISOString()\n return value\n }\n const parsed = new Date(value as string | number)\n return Number.isNaN(parsed.getTime()) ? null : parsed.toISOString()\n}\n\nexport async function GET(req: Request, { params }: { params: Promise<{ id: string }> | { id: string } }) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const resolvedParams = await params\n const transactionId = resolvedParams?.id\n if (!transactionId) {\n return NextResponse.json({ error: 'Transaction id is required' }, { status: 400 })\n }\n\n const { resolve } = await createRequestContainer()\n const scope = { organizationId: auth.orgId as string, tenantId: auth.tenantId }\n const em = resolve('em') as EntityManager\n const integrationLogService = resolve('integrationLogService') as IntegrationLogService\n const transaction = await findOneWithDecryption(\n em,\n GatewayTransaction,\n {\n id: transactionId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n\n if (!transaction) {\n return NextResponse.json({ error: 'Transaction not found' }, { status: 404 })\n }\n\n const integrationId = `gateway_${transaction.providerKey}`\n const { items: logRows } = await integrationLogService.query(\n {\n integrationId,\n entityType: 'payment_transaction',\n entityId: transactionId,\n page: 1,\n pageSize: 100,\n },\n scope,\n )\n\n return NextResponse.json({\n transaction: {\n id: transaction.id,\n paymentId: transaction.paymentId,\n providerKey: transaction.providerKey,\n providerSessionId: transaction.providerSessionId ?? null,\n gatewayPaymentId: transaction.gatewayPaymentId ?? null,\n gatewayRefundId: transaction.gatewayRefundId ?? null,\n unifiedStatus: transaction.unifiedStatus,\n gatewayStatus: transaction.gatewayStatus ?? null,\n redirectUrl: transaction.redirectUrl ?? null,\n amount: transaction.amount,\n currencyCode: transaction.currencyCode,\n gatewayMetadata: transaction.gatewayMetadata ?? null,\n webhookLog: Array.isArray(transaction.webhookLog) ? transaction.webhookLog : [],\n lastWebhookAt: toIsoString(transaction.lastWebhookAt),\n lastPolledAt: toIsoString(transaction.lastPolledAt),\n expiresAt: toIsoString(transaction.expiresAt),\n createdAt: toIsoString(transaction.createdAt),\n updatedAt: toIsoString(transaction.updatedAt),\n },\n logs: logRows.map((row) => ({\n id: row.id,\n integrationId: row.integrationId,\n runId: row.runId ?? null,\n scopeEntityType: row.scopeEntityType ?? null,\n scopeEntityId: row.scopeEntityId ?? null,\n level: row.level,\n message: row.message,\n code: row.code ?? null,\n payload: row.payload ?? null,\n createdAt: toIsoString(row.createdAt),\n })),\n })\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'Get payment transaction details',\n methods: {\n GET: {\n summary: 'Get payment transaction details',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Payment transaction details' },\n { status: 404, description: 'Transaction not found' },\n ],\n },\n },\n}\n\nexport default GET\n"],
5
+ "mappings": "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",
6
+ "names": ["parsed"]
7
+ }
@@ -0,0 +1,113 @@
1
+ import { NextResponse } from "next/server";
2
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
3
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
+ import { GatewayTransaction } from "../../data/entities.js";
5
+ import { listTransactionsQuerySchema } from "../../data/validators.js";
6
+ import { paymentGatewaysTag } from "../openapi.js";
7
+ const metadata = {
8
+ path: "/payment_gateways/transactions",
9
+ GET: { requireAuth: true, requireFeatures: ["payment_gateways.view"] }
10
+ };
11
+ function escapeLikePattern(value) {
12
+ return value.replace(/[\\%_]/g, "\\$&");
13
+ }
14
+ function formatDateValue(value) {
15
+ if (!value) return null;
16
+ if (value instanceof Date) return value.toISOString();
17
+ if (typeof value === "string") {
18
+ const parsed = new Date(value);
19
+ if (!Number.isNaN(parsed.getTime())) return parsed.toISOString();
20
+ return value;
21
+ }
22
+ const fallback = new Date(value);
23
+ return Number.isNaN(fallback.getTime()) ? null : fallback.toISOString();
24
+ }
25
+ async function GET(req) {
26
+ const auth = await getAuthFromRequest(req);
27
+ if (!auth?.tenantId || !auth.orgId) {
28
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
29
+ }
30
+ const url = new URL(req.url);
31
+ const parsed = listTransactionsQuerySchema.safeParse(Object.fromEntries(url.searchParams.entries()));
32
+ if (!parsed.success) {
33
+ return NextResponse.json({ error: "Invalid query", details: parsed.error.flatten() }, { status: 400 });
34
+ }
35
+ const { page, pageSize, search, providerKey, status } = parsed.data;
36
+ const offset = (page - 1) * pageSize;
37
+ const { resolve } = await createRequestContainer();
38
+ const em = resolve("em");
39
+ const qb = em.createQueryBuilder(GatewayTransaction, "gt");
40
+ qb.where({
41
+ organizationId: auth.orgId,
42
+ tenantId: auth.tenantId,
43
+ deletedAt: null
44
+ });
45
+ if (providerKey) {
46
+ qb.andWhere({ providerKey });
47
+ }
48
+ if (status) {
49
+ qb.andWhere({ unifiedStatus: status });
50
+ }
51
+ if (search) {
52
+ const pattern = `%${escapeLikePattern(search)}%`;
53
+ qb.andWhere(`(
54
+ cast(gt.id as text) ilike ?
55
+ or cast(gt.payment_id as text) ilike ?
56
+ or coalesce(gt.provider_key, '') ilike ?
57
+ or coalesce(gt.provider_session_id, '') ilike ?
58
+ or coalesce(gt.gateway_payment_id, '') ilike ?
59
+ or coalesce(gt.gateway_refund_id, '') ilike ?
60
+ ) escape '\\'`, [pattern, pattern, pattern, pattern, pattern, pattern]);
61
+ }
62
+ const countQb = qb.clone();
63
+ qb.orderBy({ createdAt: "desc" });
64
+ qb.limit(pageSize).offset(offset);
65
+ const [items, total] = await Promise.all([
66
+ qb.getResultList(),
67
+ countQb.count("gt.id", true)
68
+ ]);
69
+ return NextResponse.json({
70
+ items: items.map((item) => ({
71
+ id: item.id,
72
+ paymentId: item.paymentId,
73
+ providerKey: item.providerKey,
74
+ providerSessionId: item.providerSessionId ?? null,
75
+ gatewayPaymentId: item.gatewayPaymentId ?? null,
76
+ gatewayRefundId: item.gatewayRefundId ?? null,
77
+ unifiedStatus: item.unifiedStatus,
78
+ gatewayStatus: item.gatewayStatus ?? null,
79
+ amount: item.amount,
80
+ currencyCode: item.currencyCode,
81
+ redirectUrl: item.redirectUrl ?? null,
82
+ lastWebhookAt: formatDateValue(item.lastWebhookAt),
83
+ lastPolledAt: formatDateValue(item.lastPolledAt),
84
+ createdAt: formatDateValue(item.createdAt),
85
+ updatedAt: formatDateValue(item.updatedAt)
86
+ })),
87
+ total,
88
+ page,
89
+ pageSize,
90
+ totalPages: Math.max(1, Math.ceil(total / pageSize))
91
+ });
92
+ }
93
+ const openApi = {
94
+ tags: [paymentGatewaysTag],
95
+ summary: "List payment transactions",
96
+ methods: {
97
+ GET: {
98
+ summary: "List payment transactions",
99
+ tags: [paymentGatewaysTag],
100
+ responses: [
101
+ { status: 200, description: "Payment transaction list" }
102
+ ]
103
+ }
104
+ }
105
+ };
106
+ var route_default = GET;
107
+ export {
108
+ GET,
109
+ route_default as default,
110
+ metadata,
111
+ openApi
112
+ };
113
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/payment_gateways/api/transactions/route.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { GatewayTransaction } from '../../data/entities'\nimport { listTransactionsQuerySchema } from '../../data/validators'\nimport { paymentGatewaysTag } from '../openapi'\n\nexport const metadata = {\n path: '/payment_gateways/transactions',\n GET: { requireAuth: true, requireFeatures: ['payment_gateways.view'] },\n}\n\nfunction escapeLikePattern(value: string): string {\n return value.replace(/[\\\\%_]/g, '\\\\$&')\n}\n\nfunction formatDateValue(value: unknown): string | null {\n if (!value) return null\n if (value instanceof Date) return value.toISOString()\n if (typeof value === 'string') {\n const parsed = new Date(value)\n if (!Number.isNaN(parsed.getTime())) return parsed.toISOString()\n return value\n }\n const fallback = new Date(value as string | number)\n return Number.isNaN(fallback.getTime()) ? null : fallback.toISOString()\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const url = new URL(req.url)\n const parsed = listTransactionsQuerySchema.safeParse(Object.fromEntries(url.searchParams.entries()))\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid query', details: parsed.error.flatten() }, { status: 400 })\n }\n\n const { page, pageSize, search, providerKey, status } = parsed.data\n const offset = (page - 1) * pageSize\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as EntityManager\n const qb = em.createQueryBuilder(GatewayTransaction, 'gt')\n\n qb.where({\n organizationId: auth.orgId,\n tenantId: auth.tenantId,\n deletedAt: null,\n })\n\n if (providerKey) {\n qb.andWhere({ providerKey })\n }\n if (status) {\n qb.andWhere({ unifiedStatus: status })\n }\n if (search) {\n const pattern = `%${escapeLikePattern(search)}%`\n qb.andWhere(`(\n cast(gt.id as text) ilike ?\n or cast(gt.payment_id as text) ilike ?\n or coalesce(gt.provider_key, '') ilike ?\n or coalesce(gt.provider_session_id, '') ilike ?\n or coalesce(gt.gateway_payment_id, '') ilike ?\n or coalesce(gt.gateway_refund_id, '') ilike ?\n ) escape '\\\\'`, [pattern, pattern, pattern, pattern, pattern, pattern])\n }\n\n const countQb = qb.clone()\n qb.orderBy({ createdAt: 'desc' })\n qb.limit(pageSize).offset(offset)\n\n const [items, total] = await Promise.all([\n qb.getResultList(),\n countQb.count('gt.id', true),\n ])\n\n return NextResponse.json({\n items: items.map((item) => ({\n id: item.id,\n paymentId: item.paymentId,\n providerKey: item.providerKey,\n providerSessionId: item.providerSessionId ?? null,\n gatewayPaymentId: item.gatewayPaymentId ?? null,\n gatewayRefundId: item.gatewayRefundId ?? null,\n unifiedStatus: item.unifiedStatus,\n gatewayStatus: item.gatewayStatus ?? null,\n amount: item.amount,\n currencyCode: item.currencyCode,\n redirectUrl: item.redirectUrl ?? null,\n lastWebhookAt: formatDateValue(item.lastWebhookAt),\n lastPolledAt: formatDateValue(item.lastPolledAt),\n createdAt: formatDateValue(item.createdAt),\n updatedAt: formatDateValue(item.updatedAt),\n })),\n total,\n page,\n pageSize,\n totalPages: Math.max(1, Math.ceil(total / pageSize)),\n })\n}\n\nexport const openApi = {\n tags: [paymentGatewaysTag],\n summary: 'List payment transactions',\n methods: {\n GET: {\n summary: 'List payment transactions',\n tags: [paymentGatewaysTag],\n responses: [\n { status: 200, description: 'Payment transaction list' },\n ],\n },\n },\n}\n\nexport default GET\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,136 @@
1
+ import { NextResponse } from "next/server";
2
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
3
+ import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
4
+ import { readJsonSafe } from "@open-mercato/shared/lib/http/readJsonSafe";
5
+ import { getWebhookHandler } from "@open-mercato/shared/modules/payment_gateways/types";
6
+ import { GatewayTransaction } from "../../../data/entities.js";
7
+ import { getPaymentGatewayQueue } from "../../../lib/queue.js";
8
+ import { processPaymentGatewayWebhookJob } from "../../../lib/webhook-processor.js";
9
+ import { paymentGatewaysTag } from "../../openapi.js";
10
+ const metadata = {
11
+ path: "/payment_gateways/webhook/[provider]",
12
+ POST: { requireAuth: false }
13
+ };
14
+ function readScopeFromEventData(data) {
15
+ const metadata2 = data.metadata;
16
+ if (!metadata2 || typeof metadata2 !== "object") return null;
17
+ const metadataRecord = metadata2;
18
+ const organizationId = typeof metadataRecord.organizationId === "string" ? metadataRecord.organizationId.trim() : "";
19
+ const tenantId = typeof metadataRecord.tenantId === "string" ? metadataRecord.tenantId.trim() : "";
20
+ if (!organizationId || !tenantId) return null;
21
+ return { organizationId, tenantId };
22
+ }
23
+ async function POST(req, { params }) {
24
+ const resolvedParams = await params;
25
+ const providerKey = resolvedParams.provider;
26
+ const container = await createRequestContainer();
27
+ const registration = getWebhookHandler(providerKey);
28
+ if (!registration) {
29
+ return NextResponse.json({ error: `No webhook handler for provider: ${providerKey}` }, { status: 404 });
30
+ }
31
+ const rawBody = await req.text();
32
+ const headers = {};
33
+ req.headers.forEach((value, key) => {
34
+ headers[key] = value;
35
+ });
36
+ const service = container.resolve("paymentGatewayService");
37
+ const em = container.resolve("em");
38
+ const integrationCredentialsService = container.resolve("integrationCredentialsService");
39
+ const queue = getPaymentGatewayQueue(registration.queue ?? "payment-gateways-webhook");
40
+ const payload = await readJsonSafe(rawBody);
41
+ const sessionIdHint = registration.readSessionIdHint?.(payload) ?? null;
42
+ try {
43
+ const candidates = sessionIdHint ? await findWithDecryption(
44
+ em,
45
+ GatewayTransaction,
46
+ {
47
+ providerKey,
48
+ providerSessionId: sessionIdHint,
49
+ deletedAt: null
50
+ },
51
+ { limit: 10, orderBy: { createdAt: "desc" } }
52
+ ) : [];
53
+ let transaction = null;
54
+ let matchedScope = null;
55
+ let event = null;
56
+ let lastVerificationError = null;
57
+ for (const candidate of candidates) {
58
+ const candidateScope = { organizationId: candidate.organizationId, tenantId: candidate.tenantId };
59
+ const credentials = await integrationCredentialsService.resolve(`gateway_${providerKey}`, candidateScope) ?? {};
60
+ try {
61
+ event = await registration.handler({ rawBody, headers, credentials });
62
+ transaction = candidate;
63
+ matchedScope = candidateScope;
64
+ break;
65
+ } catch (error) {
66
+ lastVerificationError = error;
67
+ }
68
+ }
69
+ if (!event) {
70
+ try {
71
+ event = await registration.handler({ rawBody, headers, credentials: {} });
72
+ } catch (error) {
73
+ throw lastVerificationError ?? error;
74
+ }
75
+ }
76
+ if (!event) {
77
+ throw new Error("Webhook verification failed");
78
+ }
79
+ if (!transaction && sessionIdHint) {
80
+ const derivedScope = readScopeFromEventData(event.data);
81
+ if (derivedScope) {
82
+ transaction = await service.findTransactionBySessionId(sessionIdHint, derivedScope, providerKey);
83
+ matchedScope = transaction ? { organizationId: transaction.organizationId, tenantId: transaction.tenantId } : derivedScope;
84
+ }
85
+ }
86
+ const scope = transaction ? { organizationId: transaction.organizationId, tenantId: transaction.tenantId } : matchedScope ?? readScopeFromEventData(event.data);
87
+ const jobPayload = {
88
+ providerKey,
89
+ event,
90
+ transactionId: transaction?.id ?? null,
91
+ scope
92
+ };
93
+ if (process.env.QUEUE_STRATEGY === "async") {
94
+ await queue.enqueue({
95
+ name: "payment-gateway-webhook",
96
+ payload: jobPayload
97
+ });
98
+ } else {
99
+ await processPaymentGatewayWebhookJob(
100
+ {
101
+ em: container.resolve("em"),
102
+ paymentGatewayService: service,
103
+ integrationLogService: container.resolve("integrationLogService")
104
+ },
105
+ jobPayload
106
+ );
107
+ }
108
+ return NextResponse.json({ received: true, queued: true }, { status: 202 });
109
+ } catch (err) {
110
+ const message = err instanceof Error ? err.message : "Webhook verification failed";
111
+ return NextResponse.json({ error: message }, { status: 401 });
112
+ }
113
+ }
114
+ const openApi = {
115
+ tags: [paymentGatewaysTag],
116
+ summary: "Receive payment gateway webhook",
117
+ methods: {
118
+ POST: {
119
+ summary: "Process inbound webhook from payment provider",
120
+ tags: [paymentGatewaysTag],
121
+ responses: [
122
+ { status: 202, description: "Webhook accepted for async processing" },
123
+ { status: 401, description: "Signature verification failed" },
124
+ { status: 404, description: "Unknown provider" }
125
+ ]
126
+ }
127
+ }
128
+ };
129
+ var route_default = POST;
130
+ export {
131
+ POST,
132
+ route_default as default,
133
+ metadata,
134
+ openApi
135
+ };
136
+ //# sourceMappingURL=route.js.map