@easypayment/medusa-paypal 0.1.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 (272) hide show
  1. package/.medusa/server/src/admin/index.js +2127 -0
  2. package/.medusa/server/src/admin/index.mjs +2128 -0
  3. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts +3 -0
  4. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -0
  5. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js +25 -0
  6. package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js.map +1 -0
  7. package/.medusa/server/src/api/admin/paypal/audit-logs/route.d.ts +3 -0
  8. package/.medusa/server/src/api/admin/paypal/audit-logs/route.d.ts.map +1 -0
  9. package/.medusa/server/src/api/admin/paypal/audit-logs/route.js +12 -0
  10. package/.medusa/server/src/api/admin/paypal/audit-logs/route.js.map +1 -0
  11. package/.medusa/server/src/api/admin/paypal/disconnect/route.d.ts +3 -0
  12. package/.medusa/server/src/api/admin/paypal/disconnect/route.d.ts.map +1 -0
  13. package/.medusa/server/src/api/admin/paypal/disconnect/route.js +9 -0
  14. package/.medusa/server/src/api/admin/paypal/disconnect/route.js.map +1 -0
  15. package/.medusa/server/src/api/admin/paypal/disputes/[id]/route.d.ts +3 -0
  16. package/.medusa/server/src/api/admin/paypal/disputes/[id]/route.d.ts.map +1 -0
  17. package/.medusa/server/src/api/admin/paypal/disputes/[id]/route.js +17 -0
  18. package/.medusa/server/src/api/admin/paypal/disputes/[id]/route.js.map +1 -0
  19. package/.medusa/server/src/api/admin/paypal/disputes/route.d.ts +3 -0
  20. package/.medusa/server/src/api/admin/paypal/disputes/route.d.ts.map +1 -0
  21. package/.medusa/server/src/api/admin/paypal/disputes/route.js +27 -0
  22. package/.medusa/server/src/api/admin/paypal/disputes/route.js.map +1 -0
  23. package/.medusa/server/src/api/admin/paypal/disputes/summary/route.d.ts +3 -0
  24. package/.medusa/server/src/api/admin/paypal/disputes/summary/route.d.ts.map +1 -0
  25. package/.medusa/server/src/api/admin/paypal/disputes/summary/route.js +17 -0
  26. package/.medusa/server/src/api/admin/paypal/disputes/summary/route.js.map +1 -0
  27. package/.medusa/server/src/api/admin/paypal/environment/route.d.ts +4 -0
  28. package/.medusa/server/src/api/admin/paypal/environment/route.d.ts.map +1 -0
  29. package/.medusa/server/src/api/admin/paypal/environment/route.js +23 -0
  30. package/.medusa/server/src/api/admin/paypal/environment/route.js.map +1 -0
  31. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts +8 -0
  32. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts.map +1 -0
  33. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js +41 -0
  34. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js.map +1 -0
  35. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.d.ts +4 -0
  36. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.d.ts.map +1 -0
  37. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js +35 -0
  38. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js.map +1 -0
  39. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.d.ts +3 -0
  40. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.d.ts.map +1 -0
  41. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js +20 -0
  42. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js.map +1 -0
  43. package/.medusa/server/src/api/admin/paypal/reconciliation-status/route.d.ts +3 -0
  44. package/.medusa/server/src/api/admin/paypal/reconciliation-status/route.d.ts.map +1 -0
  45. package/.medusa/server/src/api/admin/paypal/reconciliation-status/route.js +8 -0
  46. package/.medusa/server/src/api/admin/paypal/reconciliation-status/route.js.map +1 -0
  47. package/.medusa/server/src/api/admin/paypal/rotate-credentials/route.d.ts +3 -0
  48. package/.medusa/server/src/api/admin/paypal/rotate-credentials/route.d.ts.map +1 -0
  49. package/.medusa/server/src/api/admin/paypal/rotate-credentials/route.js +9 -0
  50. package/.medusa/server/src/api/admin/paypal/rotate-credentials/route.js.map +1 -0
  51. package/.medusa/server/src/api/admin/paypal/save-credentials/route.d.ts +3 -0
  52. package/.medusa/server/src/api/admin/paypal/save-credentials/route.d.ts.map +1 -0
  53. package/.medusa/server/src/api/admin/paypal/save-credentials/route.js +13 -0
  54. package/.medusa/server/src/api/admin/paypal/save-credentials/route.js.map +1 -0
  55. package/.medusa/server/src/api/admin/paypal/settings/route.d.ts +4 -0
  56. package/.medusa/server/src/api/admin/paypal/settings/route.d.ts.map +1 -0
  57. package/.medusa/server/src/api/admin/paypal/settings/route.js +14 -0
  58. package/.medusa/server/src/api/admin/paypal/settings/route.js.map +1 -0
  59. package/.medusa/server/src/api/admin/paypal/status/route.d.ts +3 -0
  60. package/.medusa/server/src/api/admin/paypal/status/route.d.ts.map +1 -0
  61. package/.medusa/server/src/api/admin/paypal/status/route.js +11 -0
  62. package/.medusa/server/src/api/admin/paypal/status/route.js.map +1 -0
  63. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.d.ts +3 -0
  64. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -0
  65. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js +43 -0
  66. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js.map +1 -0
  67. package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts +3 -0
  68. package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts.map +1 -0
  69. package/.medusa/server/src/api/store/paypal/capture-order/route.js +215 -0
  70. package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -0
  71. package/.medusa/server/src/api/store/paypal/config/route.d.ts +3 -0
  72. package/.medusa/server/src/api/store/paypal/config/route.d.ts.map +1 -0
  73. package/.medusa/server/src/api/store/paypal/config/route.js +45 -0
  74. package/.medusa/server/src/api/store/paypal/config/route.js.map +1 -0
  75. package/.medusa/server/src/api/store/paypal/create-order/route.d.ts +3 -0
  76. package/.medusa/server/src/api/store/paypal/create-order/route.d.ts.map +1 -0
  77. package/.medusa/server/src/api/store/paypal/create-order/route.js +305 -0
  78. package/.medusa/server/src/api/store/paypal/create-order/route.js.map +1 -0
  79. package/.medusa/server/src/api/store/paypal/disputes/route.d.ts +3 -0
  80. package/.medusa/server/src/api/store/paypal/disputes/route.d.ts.map +1 -0
  81. package/.medusa/server/src/api/store/paypal/disputes/route.js +46 -0
  82. package/.medusa/server/src/api/store/paypal/disputes/route.js.map +1 -0
  83. package/.medusa/server/src/api/store/paypal/settings/route.d.ts +3 -0
  84. package/.medusa/server/src/api/store/paypal/settings/route.d.ts.map +1 -0
  85. package/.medusa/server/src/api/store/paypal/settings/route.js +14 -0
  86. package/.medusa/server/src/api/store/paypal/settings/route.js.map +1 -0
  87. package/.medusa/server/src/api/store/paypal/webhook/route.d.ts +3 -0
  88. package/.medusa/server/src/api/store/paypal/webhook/route.d.ts.map +1 -0
  89. package/.medusa/server/src/api/store/paypal/webhook/route.js +203 -0
  90. package/.medusa/server/src/api/store/paypal/webhook/route.js.map +1 -0
  91. package/.medusa/server/src/jobs/paypal-reconcile.d.ts +7 -0
  92. package/.medusa/server/src/jobs/paypal-reconcile.d.ts.map +1 -0
  93. package/.medusa/server/src/jobs/paypal-reconcile.js +131 -0
  94. package/.medusa/server/src/jobs/paypal-reconcile.js.map +1 -0
  95. package/.medusa/server/src/jobs/paypal-webhook-retry.d.ts +7 -0
  96. package/.medusa/server/src/jobs/paypal-webhook-retry.d.ts.map +1 -0
  97. package/.medusa/server/src/jobs/paypal-webhook-retry.js +78 -0
  98. package/.medusa/server/src/jobs/paypal-webhook-retry.js.map +1 -0
  99. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.d.ts +14 -0
  100. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.d.ts.map +1 -0
  101. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js +65 -0
  102. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js.map +1 -0
  103. package/.medusa/server/src/modules/paypal/index.d.ts +92 -0
  104. package/.medusa/server/src/modules/paypal/index.d.ts.map +1 -0
  105. package/.medusa/server/src/modules/paypal/index.js +13 -0
  106. package/.medusa/server/src/modules/paypal/index.js.map +1 -0
  107. package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.d.ts +6 -0
  108. package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.d.ts.map +1 -0
  109. package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.js +36 -0
  110. package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.js.map +1 -0
  111. package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.d.ts +6 -0
  112. package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.d.ts.map +1 -0
  113. package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.js +25 -0
  114. package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.js.map +1 -0
  115. package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.d.ts +6 -0
  116. package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.d.ts.map +1 -0
  117. package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.js +32 -0
  118. package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.js.map +1 -0
  119. package/.medusa/server/src/modules/paypal/migrations/20260301090000_create_paypal_audit_log.d.ts +6 -0
  120. package/.medusa/server/src/modules/paypal/migrations/20260301090000_create_paypal_audit_log.d.ts.map +1 -0
  121. package/.medusa/server/src/modules/paypal/migrations/20260301090000_create_paypal_audit_log.js +29 -0
  122. package/.medusa/server/src/modules/paypal/migrations/20260301090000_create_paypal_audit_log.js.map +1 -0
  123. package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.d.ts +6 -0
  124. package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.d.ts.map +1 -0
  125. package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.js +30 -0
  126. package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.js.map +1 -0
  127. package/.medusa/server/src/modules/paypal/migrations/20260501090000_create_paypal_dispute.d.ts +6 -0
  128. package/.medusa/server/src/modules/paypal/migrations/20260501090000_create_paypal_dispute.d.ts.map +1 -0
  129. package/.medusa/server/src/modules/paypal/migrations/20260501090000_create_paypal_dispute.js +43 -0
  130. package/.medusa/server/src/modules/paypal/migrations/20260501090000_create_paypal_dispute.js.map +1 -0
  131. package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.d.ts +6 -0
  132. package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.d.ts.map +1 -0
  133. package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.js +34 -0
  134. package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.js.map +1 -0
  135. package/.medusa/server/src/modules/paypal/models/paypal_audit_log.d.ts +7 -0
  136. package/.medusa/server/src/modules/paypal/models/paypal_audit_log.d.ts.map +1 -0
  137. package/.medusa/server/src/modules/paypal/models/paypal_audit_log.js +10 -0
  138. package/.medusa/server/src/modules/paypal/models/paypal_audit_log.js.map +1 -0
  139. package/.medusa/server/src/modules/paypal/models/paypal_connection.d.ts +14 -0
  140. package/.medusa/server/src/modules/paypal/models/paypal_connection.d.ts.map +1 -0
  141. package/.medusa/server/src/modules/paypal/models/paypal_connection.js +17 -0
  142. package/.medusa/server/src/modules/paypal/models/paypal_connection.js.map +1 -0
  143. package/.medusa/server/src/modules/paypal/models/paypal_dispute.d.ts +16 -0
  144. package/.medusa/server/src/modules/paypal/models/paypal_dispute.d.ts.map +1 -0
  145. package/.medusa/server/src/modules/paypal/models/paypal_dispute.js +19 -0
  146. package/.medusa/server/src/modules/paypal/models/paypal_dispute.js.map +1 -0
  147. package/.medusa/server/src/modules/paypal/models/paypal_metric.d.ts +7 -0
  148. package/.medusa/server/src/modules/paypal/models/paypal_metric.d.ts.map +1 -0
  149. package/.medusa/server/src/modules/paypal/models/paypal_metric.js +10 -0
  150. package/.medusa/server/src/modules/paypal/models/paypal_metric.js.map +1 -0
  151. package/.medusa/server/src/modules/paypal/models/paypal_settings.d.ts +6 -0
  152. package/.medusa/server/src/modules/paypal/models/paypal_settings.d.ts.map +1 -0
  153. package/.medusa/server/src/modules/paypal/models/paypal_settings.js +9 -0
  154. package/.medusa/server/src/modules/paypal/models/paypal_settings.js.map +1 -0
  155. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.d.ts +17 -0
  156. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.d.ts.map +1 -0
  157. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js +20 -0
  158. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js.map +1 -0
  159. package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts +35 -0
  160. package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts.map +1 -0
  161. package/.medusa/server/src/modules/paypal/payment-provider/card-service.js +569 -0
  162. package/.medusa/server/src/modules/paypal/payment-provider/card-service.js.map +1 -0
  163. package/.medusa/server/src/modules/paypal/payment-provider/index.d.ts +10 -0
  164. package/.medusa/server/src/modules/paypal/payment-provider/index.d.ts.map +1 -0
  165. package/.medusa/server/src/modules/paypal/payment-provider/index.js +22 -0
  166. package/.medusa/server/src/modules/paypal/payment-provider/index.js.map +1 -0
  167. package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts +44 -0
  168. package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts.map +1 -0
  169. package/.medusa/server/src/modules/paypal/payment-provider/service.js +825 -0
  170. package/.medusa/server/src/modules/paypal/payment-provider/service.js.map +1 -0
  171. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.d.ts +3 -0
  172. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.d.ts.map +1 -0
  173. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js +74 -0
  174. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js.map +1 -0
  175. package/.medusa/server/src/modules/paypal/service.d.ts +362 -0
  176. package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -0
  177. package/.medusa/server/src/modules/paypal/service.js +1180 -0
  178. package/.medusa/server/src/modules/paypal/service.js.map +1 -0
  179. package/.medusa/server/src/modules/paypal/types/config.d.ts +14 -0
  180. package/.medusa/server/src/modules/paypal/types/config.d.ts.map +1 -0
  181. package/.medusa/server/src/modules/paypal/types/config.js +33 -0
  182. package/.medusa/server/src/modules/paypal/types/config.js.map +1 -0
  183. package/.medusa/server/src/modules/paypal/utils/amounts.d.ts +3 -0
  184. package/.medusa/server/src/modules/paypal/utils/amounts.d.ts.map +1 -0
  185. package/.medusa/server/src/modules/paypal/utils/amounts.js +40 -0
  186. package/.medusa/server/src/modules/paypal/utils/amounts.js.map +1 -0
  187. package/.medusa/server/src/modules/paypal/utils/crypto.d.ts +4 -0
  188. package/.medusa/server/src/modules/paypal/utils/crypto.d.ts.map +1 -0
  189. package/.medusa/server/src/modules/paypal/utils/crypto.js +47 -0
  190. package/.medusa/server/src/modules/paypal/utils/crypto.js.map +1 -0
  191. package/.medusa/server/src/modules/paypal/utils/currencies.d.ts +19 -0
  192. package/.medusa/server/src/modules/paypal/utils/currencies.d.ts.map +1 -0
  193. package/.medusa/server/src/modules/paypal/utils/currencies.js +69 -0
  194. package/.medusa/server/src/modules/paypal/utils/currencies.js.map +1 -0
  195. package/.medusa/server/src/modules/paypal/utils/provider-ids.d.ts +9 -0
  196. package/.medusa/server/src/modules/paypal/utils/provider-ids.d.ts.map +1 -0
  197. package/.medusa/server/src/modules/paypal/utils/provider-ids.js +50 -0
  198. package/.medusa/server/src/modules/paypal/utils/provider-ids.js.map +1 -0
  199. package/.medusa/server/src/modules/paypal/webhook-processor.d.ts +38 -0
  200. package/.medusa/server/src/modules/paypal/webhook-processor.d.ts.map +1 -0
  201. package/.medusa/server/src/modules/paypal/webhook-processor.js +265 -0
  202. package/.medusa/server/src/modules/paypal/webhook-processor.js.map +1 -0
  203. package/LICENSE +21 -0
  204. package/README.md +67 -0
  205. package/package.json +61 -0
  206. package/postcss.config.cjs +3 -0
  207. package/src/admin/index.ts +7 -0
  208. package/src/admin/routes/settings/paypal/_components/Tabs.tsx +55 -0
  209. package/src/admin/routes/settings/paypal/_components/Toast.tsx +51 -0
  210. package/src/admin/routes/settings/paypal/additional-settings/page.tsx +346 -0
  211. package/src/admin/routes/settings/paypal/advanced-card-payments/page.tsx +381 -0
  212. package/src/admin/routes/settings/paypal/apple-pay/page.tsx +5 -0
  213. package/src/admin/routes/settings/paypal/audit-logs/page.tsx +131 -0
  214. package/src/admin/routes/settings/paypal/connection/page.tsx +750 -0
  215. package/src/admin/routes/settings/paypal/disputes/page.tsx +259 -0
  216. package/src/admin/routes/settings/paypal/google-pay/page.tsx +5 -0
  217. package/src/admin/routes/settings/paypal/page.tsx +16 -0
  218. package/src/admin/routes/settings/paypal/pay-later-messaging/page.tsx +5 -0
  219. package/src/admin/routes/settings/paypal/paypal-settings/page.tsx +557 -0
  220. package/src/admin/routes/settings/paypal/reconciliation-status/page.tsx +165 -0
  221. package/src/api/admin/payment-collections/[id]/payment-sessions/route.ts +32 -0
  222. package/src/api/admin/paypal/audit-logs/route.ts +13 -0
  223. package/src/api/admin/paypal/disconnect/route.ts +8 -0
  224. package/src/api/admin/paypal/disputes/[id]/route.ts +19 -0
  225. package/src/api/admin/paypal/disputes/route.ts +30 -0
  226. package/src/api/admin/paypal/disputes/summary/route.ts +18 -0
  227. package/src/api/admin/paypal/environment/route.ts +25 -0
  228. package/src/api/admin/paypal/onboard-complete/route.ts +44 -0
  229. package/src/api/admin/paypal/onboarding-link/route.ts +45 -0
  230. package/src/api/admin/paypal/onboarding-status/route.ts +18 -0
  231. package/src/api/admin/paypal/reconciliation-status/route.ts +7 -0
  232. package/src/api/admin/paypal/rotate-credentials/route.ts +8 -0
  233. package/src/api/admin/paypal/save-credentials/route.ts +14 -0
  234. package/src/api/admin/paypal/settings/route.ts +14 -0
  235. package/src/api/admin/paypal/status/route.ts +12 -0
  236. package/src/api/store/payment-collections/[id]/payment-sessions/route.ts +51 -0
  237. package/src/api/store/paypal/capture-order/route.ts +270 -0
  238. package/src/api/store/paypal/config/route.ts +59 -0
  239. package/src/api/store/paypal/create-order/route.ts +374 -0
  240. package/src/api/store/paypal/disputes/route.ts +67 -0
  241. package/src/api/store/paypal/settings/route.ts +12 -0
  242. package/src/api/store/paypal/webhook/route.ts +247 -0
  243. package/src/jobs/paypal-reconcile.ts +135 -0
  244. package/src/jobs/paypal-webhook-retry.ts +86 -0
  245. package/src/modules/paypal/clients/paypal-seller.client.ts +59 -0
  246. package/src/modules/paypal/index.ts +8 -0
  247. package/src/modules/paypal/migrations/20260115120000_create_paypal_connection.ts +33 -0
  248. package/src/modules/paypal/migrations/20260123090000_create_paypal_settings.ts +22 -0
  249. package/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.ts +29 -0
  250. package/src/modules/paypal/migrations/20260301090000_create_paypal_audit_log.ts +26 -0
  251. package/src/modules/paypal/migrations/20260401090000_create_paypal_metric.ts +27 -0
  252. package/src/modules/paypal/migrations/20260501090000_create_paypal_dispute.ts +40 -0
  253. package/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.ts +31 -0
  254. package/src/modules/paypal/models/paypal_audit_log.ts +9 -0
  255. package/src/modules/paypal/models/paypal_connection.ts +21 -0
  256. package/src/modules/paypal/models/paypal_dispute.ts +18 -0
  257. package/src/modules/paypal/models/paypal_metric.ts +9 -0
  258. package/src/modules/paypal/models/paypal_settings.ts +8 -0
  259. package/src/modules/paypal/models/paypal_webhook_event.ts +19 -0
  260. package/src/modules/paypal/payment-provider/README.md +22 -0
  261. package/src/modules/paypal/payment-provider/card-service.ts +710 -0
  262. package/src/modules/paypal/payment-provider/index.ts +19 -0
  263. package/src/modules/paypal/payment-provider/service.ts +1035 -0
  264. package/src/modules/paypal/payment-provider/webhook-utils.ts +88 -0
  265. package/src/modules/paypal/service.ts +1422 -0
  266. package/src/modules/paypal/types/config.ts +47 -0
  267. package/src/modules/paypal/utils/amounts.ts +41 -0
  268. package/src/modules/paypal/utils/crypto.ts +51 -0
  269. package/src/modules/paypal/utils/currencies.ts +84 -0
  270. package/src/modules/paypal/utils/provider-ids.ts +53 -0
  271. package/src/modules/paypal/webhook-processor.ts +313 -0
  272. package/tsconfig.json +31 -0
@@ -0,0 +1,67 @@
1
+ import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
2
+ import type PayPalModuleService from "../../../../modules/paypal/service"
3
+
4
+ type DisputeRecord = {
5
+ id: string
6
+ dispute_id: string
7
+ status?: string | null
8
+ reason?: string | null
9
+ stage?: string | null
10
+ amount?: string | null
11
+ currency_code?: string | null
12
+ transaction_id?: string | null
13
+ seller_transaction_id?: string | null
14
+ order_id?: string | null
15
+ cart_id?: string | null
16
+ created_at?: string
17
+ updated_at?: string
18
+ }
19
+
20
+ function toPublicDispute(dispute: any): DisputeRecord {
21
+ return {
22
+ id: dispute.id,
23
+ dispute_id: dispute.dispute_id,
24
+ status: dispute.status ?? null,
25
+ reason: dispute.reason ?? null,
26
+ stage: dispute.stage ?? null,
27
+ amount: dispute.amount ?? null,
28
+ currency_code: dispute.currency_code ?? null,
29
+ transaction_id: dispute.transaction_id ?? null,
30
+ seller_transaction_id: dispute.seller_transaction_id ?? null,
31
+ order_id: dispute.order_id ?? null,
32
+ cart_id: dispute.cart_id ?? null,
33
+ created_at: dispute.created_at ?? null,
34
+ updated_at: dispute.updated_at ?? null,
35
+ }
36
+ }
37
+
38
+ export async function GET(req: MedusaRequest, res: MedusaResponse) {
39
+ const paypal = req.scope.resolve<PayPalModuleService>("paypal_onboarding")
40
+
41
+ const query = (req.query || {}) as Record<string, string | string[] | undefined>
42
+ const filters: Record<string, string> = {}
43
+
44
+ const addFilter = (key: string) => {
45
+ const value = query[key]
46
+ if (Array.isArray(value)) {
47
+ if (value[0]) {
48
+ filters[key] = value[0]
49
+ }
50
+ return
51
+ }
52
+ if (typeof value === "string" && value.trim()) {
53
+ filters[key] = value.trim()
54
+ }
55
+ }
56
+
57
+ addFilter("order_id")
58
+ addFilter("cart_id")
59
+ addFilter("dispute_id")
60
+
61
+ if (Object.keys(filters).length === 0) {
62
+ return res.status(400).json({ message: "order_id, cart_id, or dispute_id is required" })
63
+ }
64
+
65
+ const disputes = await paypal.listPayPalDisputes(filters)
66
+ return res.json({ disputes: (disputes || []).map(toPublicDispute) })
67
+ }
@@ -0,0 +1,12 @@
1
+ import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
2
+ import type PayPalModuleService from "../../../../modules/paypal/service"
3
+
4
+ export async function GET(req: MedusaRequest, res: MedusaResponse) {
5
+ const paypal = req.scope.resolve<PayPalModuleService>("paypal_onboarding")
6
+ try {
7
+ const settings = await paypal.getSettings()
8
+ return res.json(settings)
9
+ } catch (e: any) {
10
+ return res.status(500).json({ message: e?.message || "Failed to load PayPal settings" })
11
+ }
12
+ }
@@ -0,0 +1,247 @@
1
+ import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
2
+ import type PayPalModuleService from "../../../../modules/paypal/service"
3
+ import {
4
+ computeNextRetryAt,
5
+ isAllowedEventType,
6
+ normalizeEventVersion,
7
+ processPayPalWebhookEvent,
8
+ } from "../../../../modules/paypal/webhook-processor"
9
+
10
+ const REPLAY_WINDOW_MINUTES = (() => {
11
+ const configured = Number(process.env.PAYPAL_WEBHOOK_REPLAY_WINDOW_MINUTES)
12
+ return Number.isFinite(configured) ? configured : 60
13
+ })()
14
+
15
+ function getHeader(headers: Record<string, string | string[] | undefined>, name: string) {
16
+ const direct = headers[name]
17
+ if (Array.isArray(direct)) {
18
+ return direct[0]
19
+ }
20
+ if (typeof direct === "string") {
21
+ return direct
22
+ }
23
+
24
+ const needle = name.toLowerCase()
25
+ const key = Object.keys(headers).find((header) => header.toLowerCase() === needle)
26
+ const value = key ? headers[key] : undefined
27
+ if (Array.isArray(value)) {
28
+ return value[0]
29
+ }
30
+ return value
31
+ }
32
+
33
+ function isReplay(headers: Record<string, string | string[] | undefined>) {
34
+ const transmissionTime = getHeader(headers, "paypal-transmission-time")
35
+ if (!transmissionTime) {
36
+ throw new Error("Missing PayPal transmission time header")
37
+ }
38
+
39
+ const parsed = Date.parse(transmissionTime)
40
+ if (!Number.isFinite(parsed)) {
41
+ throw new Error("Invalid PayPal transmission time header")
42
+ }
43
+
44
+ const deltaMs = Math.abs(Date.now() - parsed)
45
+ return deltaMs > REPLAY_WINDOW_MINUTES * 60 * 1000
46
+ }
47
+
48
+ function resolveWebhookId(
49
+ environment: string,
50
+ settings?: Record<string, unknown>
51
+ ) {
52
+ const ids = (settings?.webhook_ids || {}) as Record<string, string | undefined>
53
+ const legacyLive = settings?.webhook_id_live as string | undefined
54
+ const legacySandbox = settings?.webhook_id_sandbox as string | undefined
55
+
56
+ if (environment === "live") {
57
+ return ids.live || legacyLive || process.env.PAYPAL_WEBHOOK_ID_LIVE
58
+ }
59
+ return ids.sandbox || legacySandbox || process.env.PAYPAL_WEBHOOK_ID_SANDBOX
60
+ }
61
+
62
+ async function verifyWebhookSignature(
63
+ paypal: PayPalModuleService,
64
+ environment: string,
65
+ body: Record<string, unknown>,
66
+ headers: Record<string, string | string[] | undefined>
67
+ ) {
68
+ if (isReplay(headers)) {
69
+ throw new Error("PayPal webhook replay protection triggered")
70
+ }
71
+
72
+ const settings = await paypal.getSettings().catch(() => ({ data: {} }))
73
+ const webhookId = resolveWebhookId(
74
+ environment,
75
+ (settings?.data as Record<string, unknown>) || {}
76
+ )
77
+ if (!webhookId) {
78
+ throw new Error(`Missing PayPal webhook ID for environment "${environment}"`)
79
+ }
80
+
81
+ const base =
82
+ environment === "live"
83
+ ? "https://api-m.paypal.com"
84
+ : "https://api-m.sandbox.paypal.com"
85
+ const accessToken = await paypal.getAppAccessToken()
86
+
87
+ const verifyPayload = {
88
+ auth_algo: getHeader(headers, "paypal-auth-algo"),
89
+ cert_url: getHeader(headers, "paypal-cert-url"),
90
+ transmission_id: getHeader(headers, "paypal-transmission-id"),
91
+ transmission_sig: getHeader(headers, "paypal-transmission-sig"),
92
+ transmission_time: getHeader(headers, "paypal-transmission-time"),
93
+ webhook_id: webhookId,
94
+ webhook_event: body,
95
+ }
96
+
97
+ const requiredHeaders = [
98
+ verifyPayload.auth_algo,
99
+ verifyPayload.cert_url,
100
+ verifyPayload.transmission_id,
101
+ verifyPayload.transmission_sig,
102
+ verifyPayload.transmission_time,
103
+ ]
104
+ if (requiredHeaders.some((value) => !value)) {
105
+ throw new Error("Missing required PayPal webhook signature headers")
106
+ }
107
+
108
+ const resp = await fetch(`${base}/v1/notifications/verify-webhook-signature`, {
109
+ method: "POST",
110
+ headers: {
111
+ Authorization: `Bearer ${accessToken}`,
112
+ "Content-Type": "application/json",
113
+ },
114
+ body: JSON.stringify(verifyPayload),
115
+ })
116
+
117
+ const json = await resp.json().catch(() => ({}))
118
+ if (!resp.ok || json?.verification_status !== "VERIFIED") {
119
+ const debugId = resp.headers.get("paypal-debug-id") || json?.debug_id
120
+ throw new Error(
121
+ `PayPal webhook verification failed (${resp.status}): ${JSON.stringify(json)}${
122
+ debugId ? ` debug_id=${debugId}` : ""
123
+ }`
124
+ )
125
+ }
126
+ }
127
+
128
+ export async function POST(req: MedusaRequest, res: MedusaResponse) {
129
+ const paypal = req.scope.resolve<PayPalModuleService>("paypal_onboarding")
130
+
131
+ try {
132
+ const payload = (req.body || {}) as Record<string, any>
133
+ const eventId = String(payload?.id || payload?.event_id || "")
134
+ const eventType = String(payload?.event_type || payload?.eventType || "")
135
+
136
+ if (!eventId || !eventType) {
137
+ return res.status(400).json({ message: "Missing PayPal event id or type" })
138
+ }
139
+
140
+ const creds = await paypal.getActiveCredentials()
141
+ await verifyWebhookSignature(paypal, creds.environment, payload, req.headers)
142
+ const transmissionId = getHeader(req.headers, "paypal-transmission-id") || null
143
+ const transmissionTimeHeader = getHeader(req.headers, "paypal-transmission-time")
144
+ const transmissionTime = transmissionTimeHeader ? new Date(transmissionTimeHeader) : null
145
+ const eventVersion = normalizeEventVersion(payload)
146
+
147
+ if (transmissionId) {
148
+ const existingByTransmission = await paypal.listPayPalWebhookEvents({
149
+ transmission_id: transmissionId,
150
+ })
151
+ if ((existingByTransmission || []).length > 0) {
152
+ return res.json({ ok: true, duplicate: true })
153
+ }
154
+ }
155
+
156
+ const recordResult = await paypal.createWebhookEventRecord({
157
+ event_id: eventId,
158
+ event_type: eventType,
159
+ payload,
160
+ event_version: eventVersion,
161
+ transmission_id: transmissionId,
162
+ transmission_time: transmissionTime,
163
+ status: "processing",
164
+ attempt_count: 1,
165
+ })
166
+ if (!recordResult.created) {
167
+ return res.json({ ok: true, duplicate: true })
168
+ }
169
+
170
+ if (!isAllowedEventType(eventType)) {
171
+ await paypal.recordAuditEvent("webhook_unsupported_event", {
172
+ event_id: eventId,
173
+ event_type: eventType,
174
+ })
175
+ if (recordResult.event?.id) {
176
+ await paypal.updateWebhookEventRecord({
177
+ id: recordResult.event.id,
178
+ status: "ignored",
179
+ processed_at: new Date(),
180
+ })
181
+ }
182
+ return res.json({ ok: true, ignored: true })
183
+ }
184
+
185
+ const processed = await processPayPalWebhookEvent(req.scope, {
186
+ eventType,
187
+ payload,
188
+ })
189
+
190
+ if (recordResult.event?.id) {
191
+ await paypal.updateWebhookEventRecord({
192
+ id: recordResult.event.id,
193
+ status: "processed",
194
+ processed_at: new Date(),
195
+ resource_id:
196
+ processed.disputeId || processed.refundId || processed.captureId || processed.orderId || null,
197
+ })
198
+ }
199
+
200
+ console.info("[PayPal] webhook", {
201
+ event_id: eventId,
202
+ event_type: eventType,
203
+ order_id: processed.orderId,
204
+ capture_id: processed.captureId,
205
+ refund_id: processed.refundId,
206
+ cart_id: processed.cartId,
207
+ })
208
+
209
+ try {
210
+ await paypal.recordMetric("webhook_success")
211
+ } catch {
212
+ // ignore metrics failures
213
+ }
214
+
215
+ return res.json({ ok: true })
216
+ } catch (e: any) {
217
+ try {
218
+ const payload = (req.body || {}) as Record<string, any>
219
+ const eventId = String(payload?.id || payload?.event_id || "")
220
+ const eventType = String(payload?.event_type || payload?.eventType || "")
221
+ if (eventId) {
222
+ const existing = await paypal.listPayPalWebhookEvents({ event_id: eventId })
223
+ const record = existing?.[0]
224
+ if (record?.id) {
225
+ const attemptCount = Number(record.attempt_count || 0) + 1
226
+ await paypal.updateWebhookEventRecord({
227
+ id: record.id,
228
+ status: "failed",
229
+ attempt_count: attemptCount,
230
+ next_retry_at: computeNextRetryAt(attemptCount),
231
+ last_error: e?.message || String(e),
232
+ })
233
+ }
234
+ }
235
+ await paypal.recordAuditEvent("webhook_failed", {
236
+ event_id: payload?.id || payload?.event_id,
237
+ event_type: payload?.event_type || payload?.eventType,
238
+ message: e?.message || String(e),
239
+ })
240
+ await paypal.recordMetric("webhook_failed")
241
+ } catch {
242
+ // ignore audit logging failures
243
+ }
244
+ console.error("[PayPal] webhook error", e?.message || e)
245
+ return res.status(500).json({ message: e?.message || "PayPal webhook error" })
246
+ }
247
+ }
@@ -0,0 +1,135 @@
1
+ import type { MedusaContainer } from "@medusajs/framework/types"
2
+ import type PayPalModuleService from "../modules/paypal/service"
3
+
4
+ const STATUS_MAP: Record<string, "pending" | "authorized" | "captured" | "canceled"> = {
5
+ CREATED: "pending",
6
+ APPROVED: "authorized",
7
+ COMPLETED: "captured",
8
+ VOIDED: "canceled",
9
+ CANCELLED: "canceled",
10
+ }
11
+
12
+ export default async function paypalReconcile(container: MedusaContainer) {
13
+ const paymentSessionService = container.resolve("payment_session") as any
14
+ const paypal = container.resolve<PayPalModuleService>("paypal_onboarding")
15
+
16
+ const sessions = await paymentSessionService.list({
17
+ provider_id: ["paypal", "paypal_card"],
18
+ status: ["pending", "authorized"],
19
+ })
20
+
21
+ let sessionsChecked = 0
22
+ let sessionsUpdated = 0
23
+ let driftCount = 0
24
+ let lastDriftAt: string | null = null
25
+ let lastDriftOrderId: string | null = null
26
+ let hadFailure = false
27
+ let lastErrorMessage: string | null = null
28
+
29
+ for (const session of sessions || []) {
30
+ const data = (session?.data || {}) as Record<string, any>
31
+ const paypalData = (data.paypal || {}) as Record<string, any>
32
+ const orderId = String(paypalData.order_id || data.order_id || "")
33
+ if (!orderId) {
34
+ continue
35
+ }
36
+
37
+ sessionsChecked += 1
38
+
39
+ try {
40
+ const order = await paypal.getOrderDetails(orderId)
41
+ const status = STATUS_MAP[String(order?.status || "").toUpperCase()]
42
+ if (!status) {
43
+ continue
44
+ }
45
+
46
+ const previousStatus = session?.status
47
+ if (previousStatus && previousStatus !== status) {
48
+ driftCount += 1
49
+ lastDriftAt = new Date().toISOString()
50
+ lastDriftOrderId = orderId
51
+ await paypal.recordPaymentLog("reconcile_drift", {
52
+ session_id: session.id,
53
+ order_id: orderId,
54
+ previous_status: previousStatus,
55
+ next_status: status,
56
+ })
57
+ await paypal.recordMetric("reconcile_drift")
58
+ await paypal.sendAlert({
59
+ type: "reconcile_drift",
60
+ message: `PayPal reconciliation drift detected for order ${orderId}.`,
61
+ metadata: {
62
+ session_id: session.id,
63
+ previous_status: previousStatus,
64
+ next_status: status,
65
+ },
66
+ })
67
+ }
68
+
69
+ await paymentSessionService.update(session.id, {
70
+ status,
71
+ data: {
72
+ ...(session.data || {}),
73
+ paypal: {
74
+ ...((session.data || {}).paypal || {}),
75
+ order,
76
+ reconciliation: {
77
+ last_reconciled_at: new Date().toISOString(),
78
+ last_status: status,
79
+ order_status: order?.status,
80
+ },
81
+ },
82
+ },
83
+ })
84
+ sessionsUpdated += 1
85
+ try {
86
+ await paypal.recordMetric("reconcile_success")
87
+ } catch {
88
+ // ignore metrics failures
89
+ }
90
+ } catch (error) {
91
+ hadFailure = true
92
+ lastErrorMessage = error instanceof Error ? error.message : String(error)
93
+ try {
94
+ await paypal.recordMetric("reconcile_failed")
95
+ } catch {
96
+ // ignore metrics failures
97
+ }
98
+ await paypal.sendAlert({
99
+ type: "reconcile_failed",
100
+ message: `PayPal reconciliation failed for order ${orderId}.`,
101
+ metadata: {
102
+ session_id: session.id,
103
+ },
104
+ })
105
+ console.error("[PayPal] reconcile error", error)
106
+ }
107
+ }
108
+
109
+ try {
110
+ await paypal.updateReconciliationStatus({
111
+ status: hadFailure ? "failed" : "success",
112
+ sessions_checked: sessionsChecked,
113
+ sessions_updated: sessionsUpdated,
114
+ drift_count: driftCount,
115
+ last_drift_at: lastDriftAt,
116
+ last_drift_order_id: lastDriftOrderId,
117
+ error_message: hadFailure ? lastErrorMessage : null,
118
+ })
119
+ } catch (error: any) {
120
+ await paypal.updateReconciliationStatus({
121
+ status: "failed",
122
+ sessions_checked: sessionsChecked,
123
+ sessions_updated: sessionsUpdated,
124
+ drift_count: driftCount,
125
+ last_drift_at: lastDriftAt,
126
+ last_drift_order_id: lastDriftOrderId,
127
+ error_message: error?.message,
128
+ })
129
+ }
130
+ }
131
+
132
+ export const config = {
133
+ name: "paypal-reconcile",
134
+ schedule: "*/15 * * * *",
135
+ }
@@ -0,0 +1,86 @@
1
+ import type { MedusaContainer } from "@medusajs/framework/types"
2
+ import type PayPalModuleService from "../modules/paypal/service"
3
+ import {
4
+ computeNextRetryAt,
5
+ isAllowedEventType,
6
+ processPayPalWebhookEvent,
7
+ } from "../modules/paypal/webhook-processor"
8
+
9
+ const MAX_WEBHOOK_ATTEMPTS = 5
10
+
11
+ export default async function paypalWebhookRetry(container: MedusaContainer) {
12
+ const paypal = container.resolve<PayPalModuleService>("paypal_onboarding")
13
+ const now = Date.now()
14
+ const candidates = await paypal.listPayPalWebhookEvents({ status: "failed" })
15
+
16
+ for (const event of candidates || []) {
17
+ const nextRetryAt = event?.next_retry_at ? new Date(event.next_retry_at).getTime() : null
18
+ if (!nextRetryAt || nextRetryAt > now) {
19
+ continue
20
+ }
21
+
22
+ const attemptCount = Number(event.attempt_count || 0) + 1
23
+ if (attemptCount > MAX_WEBHOOK_ATTEMPTS) {
24
+ continue
25
+ }
26
+
27
+ await paypal.updateWebhookEventRecord({
28
+ id: event.id,
29
+ status: "processing",
30
+ attempt_count: attemptCount,
31
+ next_retry_at: null,
32
+ last_error: null,
33
+ })
34
+
35
+ try {
36
+ const eventType = String(event.event_type || "")
37
+ if (!isAllowedEventType(eventType)) {
38
+ await paypal.updateWebhookEventRecord({
39
+ id: event.id,
40
+ status: "ignored",
41
+ processed_at: new Date(),
42
+ })
43
+ continue
44
+ }
45
+
46
+ const payload = (event.payload || {}) as Record<string, any>
47
+ const processed = await processPayPalWebhookEvent(container, {
48
+ eventType,
49
+ payload,
50
+ })
51
+
52
+ await paypal.updateWebhookEventRecord({
53
+ id: event.id,
54
+ status: "processed",
55
+ processed_at: new Date(),
56
+ resource_id:
57
+ processed.disputeId || processed.refundId || processed.captureId || processed.orderId || null,
58
+ })
59
+ try {
60
+ await paypal.recordMetric("webhook_retry_success")
61
+ } catch {
62
+ // ignore metrics failures
63
+ }
64
+ } catch (error: any) {
65
+ const nextRetry = attemptCount >= MAX_WEBHOOK_ATTEMPTS ? null : computeNextRetryAt(attemptCount)
66
+ await paypal.updateWebhookEventRecord({
67
+ id: event.id,
68
+ status: "failed",
69
+ attempt_count: attemptCount,
70
+ next_retry_at: nextRetry,
71
+ last_error: error?.message || String(error),
72
+ })
73
+ try {
74
+ await paypal.recordMetric("webhook_retry_failed")
75
+ } catch {
76
+ // ignore metrics failures
77
+ }
78
+ console.error("[PayPal] webhook retry error", error)
79
+ }
80
+ }
81
+ }
82
+
83
+ export const config = {
84
+ name: "paypal-webhook-retry",
85
+ schedule: "*/10 * * * *",
86
+ }
@@ -0,0 +1,59 @@
1
+ export class PayPalSellerClient {
2
+ constructor(private opts: { environment: "sandbox" | "live"; accessToken: string }) {}
3
+
4
+ private baseUrl() {
5
+ return this.opts.environment === "live"
6
+ ? "https://api-m.paypal.com"
7
+ : "https://api-m.sandbox.paypal.com"
8
+ }
9
+
10
+ private headers(extra?: Record<string, string>) {
11
+ return {
12
+ "Content-Type": "application/json",
13
+ Authorization: `Bearer ${this.opts.accessToken}`,
14
+ ...(extra ?? {}),
15
+ }
16
+ }
17
+
18
+ async createOrder(body: any) {
19
+ const res = await fetch(`${this.baseUrl()}/v2/checkout/orders`, {
20
+ method: "POST",
21
+ headers: this.headers(),
22
+ body: JSON.stringify(body),
23
+ })
24
+ const json = await res.json().catch(() => ({}))
25
+ if (!res.ok) throw new Error(`PayPal createOrder failed (${res.status}): ${JSON.stringify(json)}`)
26
+ return json
27
+ }
28
+
29
+ async getOrder(orderId: string) {
30
+ const res = await fetch(`${this.baseUrl()}/v2/checkout/orders/${orderId}`, {
31
+ method: "GET",
32
+ headers: this.headers(),
33
+ })
34
+ const json = await res.json().catch(() => ({}))
35
+ if (!res.ok) throw new Error(`PayPal getOrder failed (${res.status}): ${JSON.stringify(json)}`)
36
+ return json
37
+ }
38
+
39
+ async captureOrder(orderId: string) {
40
+ const res = await fetch(`${this.baseUrl()}/v2/checkout/orders/${orderId}/capture`, {
41
+ method: "POST",
42
+ headers: this.headers(),
43
+ })
44
+ const json = await res.json().catch(() => ({}))
45
+ if (!res.ok) throw new Error(`PayPal captureOrder failed (${res.status}): ${JSON.stringify(json)}`)
46
+ return json
47
+ }
48
+
49
+ async refundCapture(captureId: string, body?: any) {
50
+ const res = await fetch(`${this.baseUrl()}/v2/payments/captures/${captureId}/refund`, {
51
+ method: "POST",
52
+ headers: this.headers(),
53
+ body: body ? JSON.stringify(body) : "{}",
54
+ })
55
+ const json = await res.json().catch(() => ({}))
56
+ if (!res.ok) throw new Error(`PayPal refund failed (${res.status}): ${JSON.stringify(json)}`)
57
+ return json
58
+ }
59
+ }
@@ -0,0 +1,8 @@
1
+ import { Module } from "@medusajs/framework/utils"
2
+ import PayPalModuleService from "./service"
3
+
4
+ export const PAYPAL_MODULE = "paypal_onboarding"
5
+
6
+ export default Module(PAYPAL_MODULE, {
7
+ service: PayPalModuleService,
8
+ })
@@ -0,0 +1,33 @@
1
+ import { Migration } from "@medusajs/framework/mikro-orm/migrations"
2
+
3
+ export class Migration20260115120000 extends Migration {
4
+ async up(): Promise<void> {
5
+ this.addSql(`
6
+ CREATE TABLE IF NOT EXISTS "paypal_connection" (
7
+ "id" text NOT NULL,
8
+ "environment" text NOT NULL DEFAULT 'sandbox',
9
+ "status" text NOT NULL DEFAULT 'disconnected',
10
+ "shared_id" text NULL,
11
+ "auth_code" text NULL,
12
+ "seller_client_id" text NULL,
13
+ "seller_client_secret" text NULL,
14
+ "app_access_token" text NULL,
15
+ "app_access_token_expires_at" timestamptz NULL,
16
+ "metadata" jsonb NOT NULL DEFAULT '{}'::jsonb,
17
+ "created_at" timestamptz NOT NULL DEFAULT now(),
18
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
19
+ "deleted_at" timestamptz NULL,
20
+ CONSTRAINT "paypal_connection_pkey" PRIMARY KEY ("id")
21
+ );
22
+
23
+ CREATE INDEX IF NOT EXISTS "idx_paypal_connection_deleted_at"
24
+ ON "paypal_connection" ("deleted_at");
25
+ `)
26
+ }
27
+
28
+ async down(): Promise<void> {
29
+ this.addSql(`
30
+ DROP TABLE IF EXISTS "paypal_connection" CASCADE;
31
+ `)
32
+ }
33
+ }
@@ -0,0 +1,22 @@
1
+ import { Migration } from "@medusajs/framework/mikro-orm/migrations"
2
+
3
+ export class Migration20260123090000 extends Migration {
4
+ async up(): Promise<void> {
5
+ this.addSql(`
6
+ CREATE TABLE IF NOT EXISTS "paypal_settings" (
7
+ "id" text NOT NULL,
8
+ "data" jsonb NULL,
9
+ "created_at" timestamptz NOT NULL DEFAULT now(),
10
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
11
+ "deleted_at" timestamptz NULL,
12
+ CONSTRAINT "paypal_settings_pkey" PRIMARY KEY ("id")
13
+ );
14
+ CREATE INDEX IF NOT EXISTS "idx_paypal_settings_deleted_at"
15
+ ON "paypal_settings" ("deleted_at");
16
+ `)
17
+ }
18
+
19
+ async down(): Promise<void> {
20
+ this.addSql(`DROP TABLE IF EXISTS "paypal_settings" CASCADE;`)
21
+ }
22
+ }