@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,825 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PayPalPaymentProvider = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const crypto_1 = require("crypto");
6
+ const amounts_1 = require("../utils/amounts");
7
+ const currencies_1 = require("../utils/currencies");
8
+ const webhook_utils_1 = require("./webhook-utils");
9
+ const LEGACY_PROVIDER_ID_MAP = {
10
+ pp_paypal_paypal: "paypal",
11
+ pp_paypal_card_paypal: "paypal_card",
12
+ pp: "paypal",
13
+ card: "paypal_card",
14
+ };
15
+ function normalizeProviderId(providerId) {
16
+ if (!providerId) {
17
+ return providerId;
18
+ }
19
+ return LEGACY_PROVIDER_ID_MAP[providerId] ?? providerId;
20
+ }
21
+ function generateSessionId() {
22
+ try {
23
+ return (0, crypto_1.randomUUID)();
24
+ }
25
+ catch {
26
+ // Fallback for environments where randomUUID isn't available
27
+ return `pp_${Date.now()}_${Math.random().toString(16).slice(2)}`;
28
+ }
29
+ }
30
+ class PayPalPaymentProvider extends utils_1.AbstractPaymentProvider {
31
+ static identifier = "paypal";
32
+ options_;
33
+ constructor(cradle, options) {
34
+ super(cradle, options);
35
+ this.options_ = options;
36
+ }
37
+ resolvePayPalService() {
38
+ const container = this.container;
39
+ return container.resolve("paypal_onboarding");
40
+ }
41
+ async resolveSettings() {
42
+ const paypal = this.resolvePayPalService();
43
+ const settings = await paypal.getSettings().catch(() => ({}));
44
+ const data = settings && typeof settings === "object" && "data" in settings
45
+ ? (settings.data ?? {})
46
+ : {};
47
+ return {
48
+ additionalSettings: (data.additional_settings || {}),
49
+ apiDetails: (data.api_details || {}),
50
+ };
51
+ }
52
+ async resolveCurrencyOverride() {
53
+ const { apiDetails } = await this.resolveSettings();
54
+ if (typeof apiDetails.currency_code === "string" && apiDetails.currency_code.trim()) {
55
+ return (0, currencies_1.normalizeCurrencyCode)(apiDetails.currency_code);
56
+ }
57
+ return (0, currencies_1.normalizeCurrencyCode)(process.env.PAYPAL_CURRENCY || "USD");
58
+ }
59
+ async getPayPalAccessToken() {
60
+ const paypal = this.resolvePayPalService();
61
+ const creds = await paypal.getActiveCredentials();
62
+ const base = creds.environment === "live"
63
+ ? "https://api-m.paypal.com"
64
+ : "https://api-m.sandbox.paypal.com";
65
+ const auth = Buffer.from(`${creds.client_id}:${creds.client_secret}`).toString("base64");
66
+ const resp = await fetch(`${base}/v1/oauth2/token`, {
67
+ method: "POST",
68
+ headers: {
69
+ Authorization: `Basic ${auth}`,
70
+ "Content-Type": "application/x-www-form-urlencoded",
71
+ },
72
+ body: "grant_type=client_credentials",
73
+ });
74
+ const text = await resp.text();
75
+ if (!resp.ok) {
76
+ throw new Error(`PayPal token error (${resp.status}): ${text}`);
77
+ }
78
+ const json = JSON.parse(text);
79
+ return { accessToken: String(json.access_token), base };
80
+ }
81
+ async getOrderDetails(orderId) {
82
+ const { accessToken, base } = await this.getPayPalAccessToken();
83
+ const resp = await fetch(`${base}/v2/checkout/orders/${orderId}`, {
84
+ method: "GET",
85
+ headers: {
86
+ Authorization: `Bearer ${accessToken}`,
87
+ "Content-Type": "application/json",
88
+ },
89
+ });
90
+ const text = await resp.text();
91
+ if (!resp.ok) {
92
+ throw new Error(`PayPal get order error (${resp.status}): ${text}`);
93
+ }
94
+ return JSON.parse(text);
95
+ }
96
+ getIdempotencyKey(input, suffix) {
97
+ const key = input?.context?.idempotency_key?.trim();
98
+ if (key) {
99
+ return `${key}-${suffix}`;
100
+ }
101
+ return `pp-${suffix}-${generateSessionId()}`;
102
+ }
103
+ async normalizePaymentData(input) {
104
+ const data = (input.data || {});
105
+ const amount = Number(data.amount ?? 0);
106
+ const currencyOverride = await this.resolveCurrencyOverride();
107
+ const currencyCode = (0, currencies_1.normalizeCurrencyCode)(data.currency_code || currencyOverride || "USD");
108
+ (0, currencies_1.assertPayPalCurrencySupported)({
109
+ currencyCode,
110
+ paypalCurrencyOverride: currencyOverride,
111
+ });
112
+ return { data, amount, currencyCode };
113
+ }
114
+ mapCaptureStatus(status) {
115
+ const normalized = String(status || "").toUpperCase();
116
+ if (!normalized) {
117
+ return null;
118
+ }
119
+ if (normalized === "COMPLETED") {
120
+ return "captured";
121
+ }
122
+ if (normalized === "PENDING") {
123
+ return "pending";
124
+ }
125
+ if (["DENIED", "DECLINED", "FAILED"].includes(normalized)) {
126
+ return "error";
127
+ }
128
+ if (["REFUNDED", "PARTIALLY_REFUNDED", "REVERSED"].includes(normalized)) {
129
+ return "canceled";
130
+ }
131
+ return null;
132
+ }
133
+ mapAuthorizationStatus(status) {
134
+ const normalized = String(status || "").toUpperCase();
135
+ if (!normalized) {
136
+ return null;
137
+ }
138
+ if (["CREATED", "APPROVED", "PENDING"].includes(normalized)) {
139
+ return "authorized";
140
+ }
141
+ if (["VOIDED", "EXPIRED"].includes(normalized)) {
142
+ return "canceled";
143
+ }
144
+ if (["DENIED", "DECLINED", "FAILED"].includes(normalized)) {
145
+ return "error";
146
+ }
147
+ return null;
148
+ }
149
+ serializeError(error) {
150
+ if (error instanceof Error) {
151
+ const errorWithCause = error;
152
+ const cause = errorWithCause.cause;
153
+ return {
154
+ name: error.name,
155
+ message: error.message,
156
+ stack: error.stack,
157
+ cause: cause instanceof Error
158
+ ? {
159
+ name: cause.name,
160
+ message: cause.message,
161
+ stack: cause.stack,
162
+ }
163
+ : cause,
164
+ };
165
+ }
166
+ return {
167
+ message: String(error),
168
+ };
169
+ }
170
+ mapOrderStatus(status) {
171
+ const normalized = String(status || "").toUpperCase();
172
+ if (!normalized) {
173
+ return "pending";
174
+ }
175
+ if (normalized === "COMPLETED") {
176
+ return "captured";
177
+ }
178
+ if (normalized === "APPROVED") {
179
+ return "authorized";
180
+ }
181
+ if (["VOIDED", "CANCELLED"].includes(normalized)) {
182
+ return "canceled";
183
+ }
184
+ if (["CREATED", "SAVED", "PAYER_ACTION_REQUIRED"].includes(normalized)) {
185
+ return "pending";
186
+ }
187
+ if (["FAILED", "EXPIRED"].includes(normalized)) {
188
+ return "error";
189
+ }
190
+ return "pending";
191
+ }
192
+ async recordFailure(eventType, metadata) {
193
+ try {
194
+ const paypal = this.resolvePayPalService();
195
+ await paypal.recordPaymentLog(eventType, metadata);
196
+ await paypal.recordAuditEvent(eventType, metadata);
197
+ await paypal.recordMetric(eventType);
198
+ }
199
+ catch {
200
+ // ignore audit logging failures
201
+ }
202
+ }
203
+ async recordSuccess(metricName) {
204
+ try {
205
+ const paypal = this.resolvePayPalService();
206
+ await paypal.recordMetric(metricName);
207
+ }
208
+ catch {
209
+ // ignore metrics failures
210
+ }
211
+ }
212
+ async recordPaymentEvent(eventType, metadata) {
213
+ try {
214
+ const paypal = this.resolvePayPalService();
215
+ await paypal.recordPaymentLog(eventType, metadata);
216
+ }
217
+ catch {
218
+ // ignore payment logging failures
219
+ }
220
+ }
221
+ async createAccountHolder(input) {
222
+ const customerId = input.context?.customer?.id;
223
+ const externalId = customerId ? `paypal_${customerId}` : `paypal_${generateSessionId()}`;
224
+ return {
225
+ id: externalId,
226
+ data: {
227
+ email: input.context?.customer?.email || null,
228
+ customer_id: customerId || null,
229
+ },
230
+ };
231
+ }
232
+ /**
233
+ * Create a payment session when the customer selects PayPal.
234
+ * Must return an object containing an `id` and `data`.
235
+ */
236
+ async initiatePayment(input) {
237
+ try {
238
+ const currencyOverride = await this.resolveCurrencyOverride();
239
+ const currencyCode = (0, currencies_1.normalizeCurrencyCode)(input.currency_code || currencyOverride || "USD");
240
+ (0, currencies_1.assertPayPalCurrencySupported)({
241
+ currencyCode,
242
+ paypalCurrencyOverride: currencyOverride,
243
+ });
244
+ const providerId = normalizeProviderId(input.data?.provider_id);
245
+ return {
246
+ id: generateSessionId(),
247
+ data: {
248
+ ...(input.data || {}),
249
+ ...(providerId ? { provider_id: providerId } : {}),
250
+ amount: input.amount,
251
+ currency_code: currencyCode,
252
+ },
253
+ };
254
+ }
255
+ catch (error) {
256
+ await this.recordFailure("initiate_failed", {
257
+ error: this.serializeError(error),
258
+ currency_code: input.currency_code,
259
+ amount: input.amount,
260
+ provider_id: input.data?.provider_id,
261
+ data: input.data ?? null,
262
+ });
263
+ throw error;
264
+ }
265
+ }
266
+ async updatePayment(input) {
267
+ const currencyOverride = await this.resolveCurrencyOverride();
268
+ const currencyCode = (0, currencies_1.normalizeCurrencyCode)(input.currency_code || currencyOverride || "USD");
269
+ (0, currencies_1.assertPayPalCurrencySupported)({
270
+ currencyCode,
271
+ paypalCurrencyOverride: currencyOverride,
272
+ });
273
+ const providerId = normalizeProviderId(input.data?.provider_id);
274
+ return {
275
+ data: {
276
+ ...(input.data || {}),
277
+ ...(providerId ? { provider_id: providerId } : {}),
278
+ amount: input.amount,
279
+ currency_code: currencyCode,
280
+ },
281
+ };
282
+ }
283
+ async authorizePayment(input) {
284
+ const { data, amount, currencyCode } = await this.normalizePaymentData(input);
285
+ const requestId = this.getIdempotencyKey(input, "authorize");
286
+ let debugId = null;
287
+ const { additionalSettings } = await this.resolveSettings();
288
+ const paymentActionRaw = typeof additionalSettings.paymentAction === "string"
289
+ ? additionalSettings.paymentAction
290
+ : "capture";
291
+ const orderIntent = paymentActionRaw === "authorize" ? "AUTHORIZE" : "CAPTURE";
292
+ try {
293
+ const { accessToken, base } = await this.getPayPalAccessToken();
294
+ const existingPayPal = (data.paypal || {});
295
+ let orderId = String(existingPayPal.order_id || data.order_id || "");
296
+ let order = null;
297
+ let authorization = null;
298
+ if (!orderId) {
299
+ const value = (0, amounts_1.formatAmountForPayPal)(amount, currencyCode || "USD");
300
+ const orderPayload = {
301
+ intent: orderIntent,
302
+ purchase_units: [
303
+ {
304
+ reference_id: data.cart_id || data.payment_collection_id || undefined,
305
+ custom_id: data.session_id || data.cart_id || data.payment_collection_id || undefined,
306
+ amount: {
307
+ currency_code: currencyCode || "USD",
308
+ value,
309
+ },
310
+ },
311
+ ],
312
+ custom_id: data.session_id || data.cart_id || data.payment_collection_id || undefined,
313
+ };
314
+ const ppResp = await fetch(`${base}/v2/checkout/orders`, {
315
+ method: "POST",
316
+ headers: {
317
+ Authorization: `Bearer ${accessToken}`,
318
+ "Content-Type": "application/json",
319
+ "PayPal-Request-Id": requestId,
320
+ },
321
+ body: JSON.stringify(orderPayload),
322
+ });
323
+ const ppText = await ppResp.text();
324
+ debugId = ppResp.headers.get("paypal-debug-id");
325
+ if (!ppResp.ok) {
326
+ throw new Error(`PayPal create order error (${ppResp.status}): ${ppText}${debugId ? ` debug_id=${debugId}` : ""}`);
327
+ }
328
+ order = JSON.parse(ppText);
329
+ orderId = String(order.id || "");
330
+ }
331
+ else {
332
+ order = (await this.getOrderDetails(orderId));
333
+ }
334
+ if (!order || !orderId) {
335
+ throw new Error("Unable to resolve PayPal order details for authorization.");
336
+ }
337
+ const existingAuthorization = order?.purchase_units?.[0]?.payments?.authorizations?.[0] || null;
338
+ if (existingAuthorization) {
339
+ authorization = order;
340
+ }
341
+ else {
342
+ const authorizeResp = await fetch(`${base}/v2/checkout/orders/${orderId}/authorize`, {
343
+ method: "POST",
344
+ headers: {
345
+ Authorization: `Bearer ${accessToken}`,
346
+ "Content-Type": "application/json",
347
+ "PayPal-Request-Id": `${requestId}-auth`,
348
+ },
349
+ });
350
+ const authorizeText = await authorizeResp.text();
351
+ const authorizeDebugId = authorizeResp.headers.get("paypal-debug-id");
352
+ if (!authorizeResp.ok) {
353
+ throw new Error(`PayPal authorize order error (${authorizeResp.status}): ${authorizeText}${authorizeDebugId ? ` debug_id=${authorizeDebugId}` : ""}`);
354
+ }
355
+ authorization = JSON.parse(authorizeText);
356
+ }
357
+ const authorizationId = authorization?.purchase_units?.[0]?.payments?.authorizations?.[0]?.id ||
358
+ existingAuthorization?.id;
359
+ console.info("[PayPal] provider authorize", {
360
+ order_id: orderId,
361
+ authorization_id: authorizationId,
362
+ request_id: requestId,
363
+ debug_id: debugId,
364
+ });
365
+ await this.recordSuccess("authorize_success");
366
+ await this.recordPaymentEvent("authorize", {
367
+ order_id: orderId,
368
+ authorization_id: authorizationId,
369
+ amount,
370
+ currency_code: currencyCode,
371
+ request_id: requestId,
372
+ });
373
+ return {
374
+ status: "authorized",
375
+ data: {
376
+ ...(input.data || {}),
377
+ paypal: {
378
+ ...(input.data || {}).paypal,
379
+ order_id: orderId,
380
+ order: order || authorization,
381
+ authorization_id: authorizationId,
382
+ authorizations: authorization?.purchase_units?.[0]?.payments?.authorizations || [],
383
+ },
384
+ authorized_at: new Date().toISOString(),
385
+ },
386
+ };
387
+ }
388
+ catch (error) {
389
+ await this.recordFailure("authorize_failed", {
390
+ request_id: requestId,
391
+ cart_id: data.cart_id,
392
+ payment_collection_id: data.payment_collection_id,
393
+ debug_id: debugId,
394
+ message: error?.message,
395
+ });
396
+ throw error;
397
+ }
398
+ }
399
+ async retrievePayment(input) {
400
+ const data = (input.data || {});
401
+ const paypalData = (data.paypal || {});
402
+ const orderId = String(paypalData.order_id || data.order_id || "");
403
+ if (!orderId) {
404
+ return { data: { ...(input.data || {}) } };
405
+ }
406
+ const order = await this.getOrderDetails(orderId);
407
+ const capture = order?.purchase_units?.[0]?.payments?.captures?.[0];
408
+ const authorization = order?.purchase_units?.[0]?.payments?.authorizations?.[0];
409
+ return {
410
+ data: {
411
+ ...(input.data || {}),
412
+ paypal: {
413
+ ...(input.data || {}).paypal,
414
+ order,
415
+ authorization_id: authorization?.id || paypalData.authorization_id,
416
+ capture_id: capture?.id || paypalData.capture_id,
417
+ },
418
+ },
419
+ };
420
+ }
421
+ async getPaymentStatus(input) {
422
+ const data = (input.data || {});
423
+ const paypalData = (data.paypal || {});
424
+ const orderId = String(paypalData.order_id || data.order_id || "");
425
+ if (!orderId) {
426
+ return { status: "pending", data: { ...(input.data || {}) } };
427
+ }
428
+ try {
429
+ const order = await this.getOrderDetails(orderId);
430
+ const capture = order?.purchase_units?.[0]?.payments?.captures?.[0];
431
+ const authorization = order?.purchase_units?.[0]?.payments?.authorizations?.[0];
432
+ const mappedStatus = this.mapCaptureStatus(capture?.status) ||
433
+ this.mapAuthorizationStatus(authorization?.status) ||
434
+ this.mapOrderStatus(order?.status) ||
435
+ "pending";
436
+ await this.recordSuccess("status_success");
437
+ return {
438
+ status: mappedStatus,
439
+ data: {
440
+ ...(input.data || {}),
441
+ paypal: {
442
+ ...(input.data || {}).paypal,
443
+ order,
444
+ authorization_id: authorization?.id || paypalData.authorization_id,
445
+ capture_id: capture?.id || paypalData.capture_id,
446
+ },
447
+ },
448
+ };
449
+ }
450
+ catch (error) {
451
+ await this.recordFailure("status_failed", {
452
+ order_id: orderId,
453
+ message: error?.message,
454
+ });
455
+ throw error;
456
+ }
457
+ }
458
+ async capturePayment(input) {
459
+ const data = (input.data || {});
460
+ const paypalData = (data.paypal || {});
461
+ const orderId = String(paypalData.order_id || data.order_id || "");
462
+ let authorizationId = String(paypalData.authorization_id || data.authorization_id || "");
463
+ if (!orderId) {
464
+ throw new Error("PayPal order_id is required to capture payment");
465
+ }
466
+ if (paypalData.capture_id || paypalData.capture) {
467
+ return {
468
+ data: {
469
+ ...(input.data || {}),
470
+ paypal: {
471
+ ...(input.data || {}).paypal,
472
+ capture_id: paypalData.capture_id,
473
+ capture: paypalData.capture,
474
+ },
475
+ captured_at: new Date().toISOString(),
476
+ },
477
+ };
478
+ }
479
+ const requestId = this.getIdempotencyKey(input, `capture-${orderId}`);
480
+ const { amount, currencyCode } = await this.normalizePaymentData(input);
481
+ let debugId = null;
482
+ try {
483
+ const { accessToken, base } = await this.getPayPalAccessToken();
484
+ const order = await this.getOrderDetails(orderId).catch(() => null);
485
+ const existingCapture = order?.purchase_units?.[0]?.payments?.captures?.[0];
486
+ if (existingCapture?.id) {
487
+ return {
488
+ data: {
489
+ ...(input.data || {}),
490
+ paypal: {
491
+ ...(input.data || {}).paypal,
492
+ capture_id: existingCapture.id,
493
+ capture: existingCapture,
494
+ },
495
+ captured_at: new Date().toISOString(),
496
+ },
497
+ };
498
+ }
499
+ const resolvedIntent = String(order?.intent || paypalData.order?.intent || data.intent || "").toUpperCase();
500
+ if (!authorizationId && resolvedIntent === "AUTHORIZE") {
501
+ const authorizeResp = await fetch(`${base}/v2/checkout/orders/${orderId}/authorize`, {
502
+ method: "POST",
503
+ headers: {
504
+ Authorization: `Bearer ${accessToken}`,
505
+ "Content-Type": "application/json",
506
+ "PayPal-Request-Id": `${requestId}-auth`,
507
+ },
508
+ });
509
+ const authorizeText = await authorizeResp.text();
510
+ debugId = authorizeResp.headers.get("paypal-debug-id");
511
+ if (!authorizeResp.ok) {
512
+ throw new Error(`PayPal authorize order error (${authorizeResp.status}): ${authorizeText}${debugId ? ` debug_id=${debugId}` : ""}`);
513
+ }
514
+ const authorization = JSON.parse(authorizeText);
515
+ authorizationId =
516
+ authorization?.purchase_units?.[0]?.payments?.authorizations?.[0]?.id;
517
+ }
518
+ const isFinalCapture = paypalData.is_final_capture ??
519
+ data.is_final_capture ??
520
+ data.final_capture ??
521
+ undefined;
522
+ const capturePayload = amount > 0
523
+ ? {
524
+ amount: {
525
+ currency_code: currencyCode || "USD",
526
+ value: (0, amounts_1.formatAmountForPayPal)(amount, currencyCode || "USD"),
527
+ },
528
+ ...(typeof isFinalCapture === "boolean"
529
+ ? { is_final_capture: isFinalCapture }
530
+ : {}),
531
+ }
532
+ : {
533
+ ...(typeof isFinalCapture === "boolean"
534
+ ? { is_final_capture: isFinalCapture }
535
+ : {}),
536
+ };
537
+ const captureUrl = authorizationId
538
+ ? `${base}/v2/payments/authorizations/${authorizationId}/capture`
539
+ : `${base}/v2/checkout/orders/${orderId}/capture`;
540
+ const ppResp = await fetch(captureUrl, {
541
+ method: "POST",
542
+ headers: {
543
+ Authorization: `Bearer ${accessToken}`,
544
+ "Content-Type": "application/json",
545
+ "PayPal-Request-Id": requestId,
546
+ },
547
+ body: JSON.stringify(capturePayload),
548
+ });
549
+ const ppText = await ppResp.text();
550
+ debugId = ppResp.headers.get("paypal-debug-id");
551
+ if (!ppResp.ok) {
552
+ throw new Error(`PayPal capture error (${ppResp.status}): ${ppText}${debugId ? ` debug_id=${debugId}` : ""}`);
553
+ }
554
+ const capture = JSON.parse(ppText);
555
+ const captureId = capture?.id || capture?.purchase_units?.[0]?.payments?.captures?.[0]?.id;
556
+ const existingCaptures = Array.isArray(paypalData.captures)
557
+ ? paypalData.captures
558
+ : [];
559
+ const captureEntry = {
560
+ id: captureId,
561
+ status: capture?.status,
562
+ amount: capture?.amount,
563
+ raw: capture,
564
+ };
565
+ console.info("[PayPal] provider capture", {
566
+ order_id: orderId,
567
+ capture_id: captureId,
568
+ authorization_id: authorizationId || undefined,
569
+ request_id: requestId,
570
+ debug_id: ppResp.headers.get("paypal-debug-id"),
571
+ });
572
+ await this.recordSuccess("capture_success");
573
+ await this.recordPaymentEvent("capture", {
574
+ order_id: orderId,
575
+ capture_id: captureId,
576
+ authorization_id: authorizationId || undefined,
577
+ amount,
578
+ currency_code: currencyCode,
579
+ request_id: requestId,
580
+ });
581
+ return {
582
+ data: {
583
+ ...(input.data || {}),
584
+ paypal: {
585
+ ...(input.data || {}).paypal,
586
+ order_id: orderId,
587
+ capture_id: captureId,
588
+ capture,
589
+ authorization_id: authorizationId || paypalData.authorization_id,
590
+ captures: [...existingCaptures, captureEntry],
591
+ },
592
+ captured_at: new Date().toISOString(),
593
+ },
594
+ };
595
+ }
596
+ catch (error) {
597
+ await this.recordFailure("capture_failed", {
598
+ order_id: orderId,
599
+ request_id: requestId,
600
+ debug_id: debugId,
601
+ message: error?.message,
602
+ });
603
+ throw error;
604
+ }
605
+ }
606
+ async refundPayment(input) {
607
+ const data = (input.data || {});
608
+ const paypalData = (data.paypal || {});
609
+ const captureId = String(paypalData.capture_id || data.capture_id || "");
610
+ const refundReason = String(paypalData.refund_reason || data.refund_reason || data.reason || "").trim();
611
+ const refundReasonCode = String(paypalData.refund_reason_code || data.refund_reason_code || data.reason_code || "").trim();
612
+ if (!captureId) {
613
+ return {
614
+ data: {
615
+ ...(input.data || {}),
616
+ refunded_at: new Date().toISOString(),
617
+ },
618
+ };
619
+ }
620
+ const requestId = this.getIdempotencyKey(input, `refund-${captureId}`);
621
+ const { amount, currencyCode } = await this.normalizePaymentData(input);
622
+ let debugId = null;
623
+ try {
624
+ const { accessToken, base } = await this.getPayPalAccessToken();
625
+ const refundPayload = amount > 0
626
+ ? {
627
+ amount: {
628
+ currency_code: currencyCode || "USD",
629
+ value: (0, amounts_1.formatAmountForPayPal)(amount, currencyCode || "USD"),
630
+ },
631
+ }
632
+ : {};
633
+ if (refundReason) {
634
+ refundPayload.note_to_payer = refundReason;
635
+ }
636
+ const ppResp = await fetch(`${base}/v2/payments/captures/${captureId}/refund`, {
637
+ method: "POST",
638
+ headers: {
639
+ Authorization: `Bearer ${accessToken}`,
640
+ "Content-Type": "application/json",
641
+ "PayPal-Request-Id": requestId,
642
+ },
643
+ body: JSON.stringify(refundPayload),
644
+ });
645
+ const ppText = await ppResp.text();
646
+ debugId = ppResp.headers.get("paypal-debug-id");
647
+ if (!ppResp.ok) {
648
+ throw new Error(`PayPal refund error (${ppResp.status}): ${ppText}${debugId ? ` debug_id=${debugId}` : ""}`);
649
+ }
650
+ const refund = JSON.parse(ppText);
651
+ const existingRefunds = Array.isArray(paypalData.refunds) ? paypalData.refunds : [];
652
+ const refundEntry = {
653
+ id: refund?.id,
654
+ status: refund?.status,
655
+ amount: refund?.amount,
656
+ reason: refundReason || refund?.note_to_payer,
657
+ reason_code: refundReasonCode || refund?.reason_code,
658
+ raw: refund,
659
+ };
660
+ console.info("[PayPal] provider refund", {
661
+ capture_id: captureId,
662
+ refund_id: refund?.id,
663
+ request_id: requestId,
664
+ debug_id: ppResp.headers.get("paypal-debug-id"),
665
+ });
666
+ await this.recordSuccess("refund_success");
667
+ await this.recordPaymentEvent("refund", {
668
+ capture_id: captureId,
669
+ refund_id: refund?.id,
670
+ amount,
671
+ currency_code: currencyCode,
672
+ request_id: requestId,
673
+ reason: refundReason,
674
+ reason_code: refundReasonCode,
675
+ });
676
+ return {
677
+ data: {
678
+ ...(input.data || {}),
679
+ paypal: {
680
+ ...(input.data || {}).paypal,
681
+ refund_id: refund?.id,
682
+ refund_status: refund?.status,
683
+ refund_reason: refundReason || refund?.note_to_payer,
684
+ refund_reason_code: refundReasonCode || refund?.reason_code,
685
+ refunds: [...existingRefunds, refundEntry],
686
+ refund,
687
+ },
688
+ refunded_at: new Date().toISOString(),
689
+ },
690
+ };
691
+ }
692
+ catch (error) {
693
+ await this.recordFailure("refund_failed", {
694
+ capture_id: captureId,
695
+ request_id: requestId,
696
+ debug_id: debugId,
697
+ message: error?.message,
698
+ });
699
+ throw error;
700
+ }
701
+ }
702
+ async cancelPayment(input) {
703
+ const data = (input.data || {});
704
+ const paypalData = (data.paypal || {});
705
+ const orderId = String(paypalData.order_id || data.order_id || "");
706
+ const captureId = String(paypalData.capture_id || data.capture_id || "");
707
+ const storedAuthorizationId = String(paypalData.authorization_id || data.authorization_id || "");
708
+ let debugId = null;
709
+ try {
710
+ const order = orderId ? await this.getOrderDetails(orderId) : null;
711
+ const intent = String(order?.intent || "").toUpperCase();
712
+ const authorizationId = order?.purchase_units?.[0]?.payments?.authorizations?.[0]?.id ||
713
+ storedAuthorizationId;
714
+ if (intent === "AUTHORIZE" && authorizationId) {
715
+ const { accessToken, base } = await this.getPayPalAccessToken();
716
+ const requestId = this.getIdempotencyKey(input, `void-${authorizationId}`);
717
+ const resp = await fetch(`${base}/v2/payments/authorizations/${authorizationId}/void`, {
718
+ method: "POST",
719
+ headers: {
720
+ Authorization: `Bearer ${accessToken}`,
721
+ "Content-Type": "application/json",
722
+ "PayPal-Request-Id": requestId,
723
+ },
724
+ });
725
+ if (!resp.ok) {
726
+ const text = await resp.text();
727
+ debugId = resp.headers.get("paypal-debug-id");
728
+ throw new Error(`PayPal void error (${resp.status}): ${text}${debugId ? ` debug_id=${debugId}` : ""}`);
729
+ }
730
+ console.info("[PayPal] provider void", {
731
+ order_id: orderId,
732
+ authorization_id: authorizationId,
733
+ request_id: requestId,
734
+ debug_id: resp.headers.get("paypal-debug-id"),
735
+ });
736
+ await this.recordSuccess("void_success");
737
+ await this.recordPaymentEvent("void", {
738
+ order_id: orderId,
739
+ authorization_id: authorizationId,
740
+ request_id: requestId,
741
+ });
742
+ }
743
+ else if (captureId) {
744
+ const { accessToken, base } = await this.getPayPalAccessToken();
745
+ const requestId = this.getIdempotencyKey(input, `refund-${captureId}`);
746
+ const resp = await fetch(`${base}/v2/payments/captures/${captureId}/refund`, {
747
+ method: "POST",
748
+ headers: {
749
+ Authorization: `Bearer ${accessToken}`,
750
+ "Content-Type": "application/json",
751
+ "PayPal-Request-Id": requestId,
752
+ },
753
+ body: JSON.stringify({}),
754
+ });
755
+ if (!resp.ok) {
756
+ const text = await resp.text();
757
+ debugId = resp.headers.get("paypal-debug-id");
758
+ throw new Error(`PayPal refund error (${resp.status}): ${text}${debugId ? ` debug_id=${debugId}` : ""}`);
759
+ }
760
+ const refund = await resp.json().catch(() => ({}));
761
+ const existingRefunds = Array.isArray(paypalData.refunds) ? paypalData.refunds : [];
762
+ const refundEntry = {
763
+ id: refund?.id,
764
+ status: refund?.status,
765
+ amount: refund?.amount,
766
+ raw: refund,
767
+ };
768
+ paypalData.refund_id = refund?.id;
769
+ paypalData.refund_status = refund?.status;
770
+ paypalData.refunds = [...existingRefunds, refundEntry];
771
+ console.info("[PayPal] provider refund", {
772
+ order_id: orderId,
773
+ capture_id: captureId,
774
+ refund_id: refund?.id,
775
+ request_id: requestId,
776
+ debug_id: resp.headers.get("paypal-debug-id"),
777
+ });
778
+ await this.recordSuccess("cancel_refund_success");
779
+ await this.recordPaymentEvent("cancel_refund", {
780
+ order_id: orderId,
781
+ capture_id: captureId,
782
+ refund_id: refund?.id,
783
+ request_id: requestId,
784
+ });
785
+ }
786
+ return {
787
+ data: {
788
+ ...(input.data || {}),
789
+ paypal: {
790
+ ...(input.data || {}).paypal,
791
+ order: order || undefined,
792
+ authorization_id: authorizationId || storedAuthorizationId,
793
+ capture_id: captureId || paypalData.capture_id,
794
+ refund_id: paypalData.refund_id,
795
+ refund_status: paypalData.refund_status,
796
+ refunds: paypalData.refunds,
797
+ },
798
+ canceled_at: new Date().toISOString(),
799
+ },
800
+ };
801
+ }
802
+ catch (error) {
803
+ await this.recordFailure("cancel_failed", {
804
+ order_id: orderId,
805
+ capture_id: captureId,
806
+ debug_id: debugId,
807
+ message: error?.message,
808
+ });
809
+ throw error;
810
+ }
811
+ }
812
+ async deletePayment(_input) {
813
+ return { data: {} };
814
+ }
815
+ /**
816
+ * Required by AbstractPaymentProvider in Medusa v2.
817
+ * This is used by /hooks/payment/{identifier}_{providerId}
818
+ */
819
+ async getWebhookActionAndData(payload) {
820
+ return (0, webhook_utils_1.getPayPalWebhookActionAndData)(payload);
821
+ }
822
+ }
823
+ exports.PayPalPaymentProvider = PayPalPaymentProvider;
824
+ exports.default = PayPalPaymentProvider;
825
+ //# sourceMappingURL=service.js.map