@easypayment/medusa-payment-paypal 0.7.4

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 (268) hide show
  1. package/.medusa/server/src/admin/index.js +1267 -0
  2. package/.medusa/server/src/admin/index.mjs +1268 -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 +18 -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/disconnect/route.d.ts +3 -0
  8. package/.medusa/server/src/api/admin/paypal/disconnect/route.d.ts.map +1 -0
  9. package/.medusa/server/src/api/admin/paypal/disconnect/route.js +9 -0
  10. package/.medusa/server/src/api/admin/paypal/disconnect/route.js.map +1 -0
  11. package/.medusa/server/src/api/admin/paypal/environment/route.d.ts +4 -0
  12. package/.medusa/server/src/api/admin/paypal/environment/route.d.ts.map +1 -0
  13. package/.medusa/server/src/api/admin/paypal/environment/route.js +23 -0
  14. package/.medusa/server/src/api/admin/paypal/environment/route.js.map +1 -0
  15. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts +4 -0
  16. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts.map +1 -0
  17. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js +31 -0
  18. package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js.map +1 -0
  19. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.d.ts +4 -0
  20. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.d.ts.map +1 -0
  21. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js +35 -0
  22. package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js.map +1 -0
  23. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.d.ts +3 -0
  24. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.d.ts.map +1 -0
  25. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js +19 -0
  26. package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js.map +1 -0
  27. package/.medusa/server/src/api/admin/paypal/save-credentials/route.d.ts +3 -0
  28. package/.medusa/server/src/api/admin/paypal/save-credentials/route.d.ts.map +1 -0
  29. package/.medusa/server/src/api/admin/paypal/save-credentials/route.js +17 -0
  30. package/.medusa/server/src/api/admin/paypal/save-credentials/route.js.map +1 -0
  31. package/.medusa/server/src/api/admin/paypal/settings/route.d.ts +4 -0
  32. package/.medusa/server/src/api/admin/paypal/settings/route.d.ts.map +1 -0
  33. package/.medusa/server/src/api/admin/paypal/settings/route.js +14 -0
  34. package/.medusa/server/src/api/admin/paypal/settings/route.js.map +1 -0
  35. package/.medusa/server/src/api/admin/paypal/status/route.d.ts +3 -0
  36. package/.medusa/server/src/api/admin/paypal/status/route.d.ts.map +1 -0
  37. package/.medusa/server/src/api/admin/paypal/status/route.js +11 -0
  38. package/.medusa/server/src/api/admin/paypal/status/route.js.map +1 -0
  39. package/.medusa/server/src/api/middlewares.d.ts +3 -0
  40. package/.medusa/server/src/api/middlewares.d.ts.map +1 -0
  41. package/.medusa/server/src/api/middlewares.js +16 -0
  42. package/.medusa/server/src/api/middlewares.js.map +1 -0
  43. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.d.ts +3 -0
  44. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -0
  45. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js +43 -0
  46. package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js.map +1 -0
  47. package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts +3 -0
  48. package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts.map +1 -0
  49. package/.medusa/server/src/api/store/paypal/capture-order/route.js +204 -0
  50. package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -0
  51. package/.medusa/server/src/api/store/paypal/config/route.d.ts +3 -0
  52. package/.medusa/server/src/api/store/paypal/config/route.d.ts.map +1 -0
  53. package/.medusa/server/src/api/store/paypal/config/route.js +77 -0
  54. package/.medusa/server/src/api/store/paypal/config/route.js.map +1 -0
  55. package/.medusa/server/src/api/store/paypal/create-order/route.d.ts +3 -0
  56. package/.medusa/server/src/api/store/paypal/create-order/route.d.ts.map +1 -0
  57. package/.medusa/server/src/api/store/paypal/create-order/route.js +361 -0
  58. package/.medusa/server/src/api/store/paypal/create-order/route.js.map +1 -0
  59. package/.medusa/server/src/api/store/paypal/settings/route.d.ts +3 -0
  60. package/.medusa/server/src/api/store/paypal/settings/route.d.ts.map +1 -0
  61. package/.medusa/server/src/api/store/paypal/settings/route.js +20 -0
  62. package/.medusa/server/src/api/store/paypal/settings/route.js.map +1 -0
  63. package/.medusa/server/src/api/store/paypal/webhook/route.d.ts +3 -0
  64. package/.medusa/server/src/api/store/paypal/webhook/route.d.ts.map +1 -0
  65. package/.medusa/server/src/api/store/paypal/webhook/route.js +250 -0
  66. package/.medusa/server/src/api/store/paypal/webhook/route.js.map +1 -0
  67. package/.medusa/server/src/api/store/paypal-complete/route.d.ts +3 -0
  68. package/.medusa/server/src/api/store/paypal-complete/route.d.ts.map +1 -0
  69. package/.medusa/server/src/api/store/paypal-complete/route.js +76 -0
  70. package/.medusa/server/src/api/store/paypal-complete/route.js.map +1 -0
  71. package/.medusa/server/src/index.d.ts +2 -0
  72. package/.medusa/server/src/index.d.ts.map +1 -0
  73. package/.medusa/server/src/index.js +9 -0
  74. package/.medusa/server/src/index.js.map +1 -0
  75. package/.medusa/server/src/jobs/paypal-webhook-retry.d.ts +7 -0
  76. package/.medusa/server/src/jobs/paypal-webhook-retry.d.ts.map +1 -0
  77. package/.medusa/server/src/jobs/paypal-webhook-retry.js +132 -0
  78. package/.medusa/server/src/jobs/paypal-webhook-retry.js.map +1 -0
  79. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.d.ts +15 -0
  80. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.d.ts.map +1 -0
  81. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js +67 -0
  82. package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js.map +1 -0
  83. package/.medusa/server/src/modules/paypal/index.d.ts +64 -0
  84. package/.medusa/server/src/modules/paypal/index.d.ts.map +1 -0
  85. package/.medusa/server/src/modules/paypal/index.js +13 -0
  86. package/.medusa/server/src/modules/paypal/index.js.map +1 -0
  87. package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.d.ts +6 -0
  88. package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.d.ts.map +1 -0
  89. package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.js +36 -0
  90. package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.js.map +1 -0
  91. package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.d.ts +6 -0
  92. package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.d.ts.map +1 -0
  93. package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.js +25 -0
  94. package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.js.map +1 -0
  95. package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.d.ts +6 -0
  96. package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.d.ts.map +1 -0
  97. package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.js +32 -0
  98. package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.js.map +1 -0
  99. package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.d.ts +6 -0
  100. package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.d.ts.map +1 -0
  101. package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.js +30 -0
  102. package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.js.map +1 -0
  103. package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.d.ts +6 -0
  104. package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.d.ts.map +1 -0
  105. package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.js +34 -0
  106. package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.js.map +1 -0
  107. package/.medusa/server/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.d.ts +6 -0
  108. package/.medusa/server/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.d.ts.map +1 -0
  109. package/.medusa/server/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.js +28 -0
  110. package/.medusa/server/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.js.map +1 -0
  111. package/.medusa/server/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.d.ts +6 -0
  112. package/.medusa/server/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.d.ts.map +1 -0
  113. package/.medusa/server/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.js +29 -0
  114. package/.medusa/server/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.js.map +1 -0
  115. package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts +6 -0
  116. package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts.map +1 -0
  117. package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js +14 -0
  118. package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js.map +1 -0
  119. package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.d.ts +6 -0
  120. package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.d.ts.map +1 -0
  121. package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.js +14 -0
  122. package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.js.map +1 -0
  123. package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.d.ts +6 -0
  124. package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.d.ts.map +1 -0
  125. package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.js +14 -0
  126. package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.js.map +1 -0
  127. package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.d.ts +6 -0
  128. package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.d.ts.map +1 -0
  129. package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.js +20 -0
  130. package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.js.map +1 -0
  131. package/.medusa/server/src/modules/paypal/models/paypal_connection.d.ts +16 -0
  132. package/.medusa/server/src/modules/paypal/models/paypal_connection.d.ts.map +1 -0
  133. package/.medusa/server/src/modules/paypal/models/paypal_connection.js +19 -0
  134. package/.medusa/server/src/modules/paypal/models/paypal_connection.js.map +1 -0
  135. package/.medusa/server/src/modules/paypal/models/paypal_metric.d.ts +7 -0
  136. package/.medusa/server/src/modules/paypal/models/paypal_metric.d.ts.map +1 -0
  137. package/.medusa/server/src/modules/paypal/models/paypal_metric.js +10 -0
  138. package/.medusa/server/src/modules/paypal/models/paypal_metric.js.map +1 -0
  139. package/.medusa/server/src/modules/paypal/models/paypal_settings.d.ts +6 -0
  140. package/.medusa/server/src/modules/paypal/models/paypal_settings.d.ts.map +1 -0
  141. package/.medusa/server/src/modules/paypal/models/paypal_settings.js +9 -0
  142. package/.medusa/server/src/modules/paypal/models/paypal_settings.js.map +1 -0
  143. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.d.ts +17 -0
  144. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.d.ts.map +1 -0
  145. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js +20 -0
  146. package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js.map +1 -0
  147. package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts +32 -0
  148. package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts.map +1 -0
  149. package/.medusa/server/src/modules/paypal/payment-provider/card-service.js +625 -0
  150. package/.medusa/server/src/modules/paypal/payment-provider/card-service.js.map +1 -0
  151. package/.medusa/server/src/modules/paypal/payment-provider/index.d.ts +6 -0
  152. package/.medusa/server/src/modules/paypal/payment-provider/index.d.ts.map +1 -0
  153. package/.medusa/server/src/modules/paypal/payment-provider/index.js +18 -0
  154. package/.medusa/server/src/modules/paypal/payment-provider/index.js.map +1 -0
  155. package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts +39 -0
  156. package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts.map +1 -0
  157. package/.medusa/server/src/modules/paypal/payment-provider/service.js +869 -0
  158. package/.medusa/server/src/modules/paypal/payment-provider/service.js.map +1 -0
  159. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.d.ts +3 -0
  160. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.d.ts.map +1 -0
  161. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js +74 -0
  162. package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js.map +1 -0
  163. package/.medusa/server/src/modules/paypal/service.d.ts +266 -0
  164. package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -0
  165. package/.medusa/server/src/modules/paypal/service.js +1149 -0
  166. package/.medusa/server/src/modules/paypal/service.js.map +1 -0
  167. package/.medusa/server/src/modules/paypal/types/config.d.ts +12 -0
  168. package/.medusa/server/src/modules/paypal/types/config.d.ts.map +1 -0
  169. package/.medusa/server/src/modules/paypal/types/config.js +24 -0
  170. package/.medusa/server/src/modules/paypal/types/config.js.map +1 -0
  171. package/.medusa/server/src/modules/paypal/utils/amounts.d.ts +3 -0
  172. package/.medusa/server/src/modules/paypal/utils/amounts.d.ts.map +1 -0
  173. package/.medusa/server/src/modules/paypal/utils/amounts.js +40 -0
  174. package/.medusa/server/src/modules/paypal/utils/amounts.js.map +1 -0
  175. package/.medusa/server/src/modules/paypal/utils/currencies.d.ts +19 -0
  176. package/.medusa/server/src/modules/paypal/utils/currencies.d.ts.map +1 -0
  177. package/.medusa/server/src/modules/paypal/utils/currencies.js +69 -0
  178. package/.medusa/server/src/modules/paypal/utils/currencies.js.map +1 -0
  179. package/.medusa/server/src/modules/paypal/utils/paypal-auth.d.ts +10 -0
  180. package/.medusa/server/src/modules/paypal/utils/paypal-auth.d.ts.map +1 -0
  181. package/.medusa/server/src/modules/paypal/utils/paypal-auth.js +30 -0
  182. package/.medusa/server/src/modules/paypal/utils/paypal-auth.js.map +1 -0
  183. package/.medusa/server/src/modules/paypal/utils/provider-ids.d.ts +5 -0
  184. package/.medusa/server/src/modules/paypal/utils/provider-ids.d.ts.map +1 -0
  185. package/.medusa/server/src/modules/paypal/utils/provider-ids.js +16 -0
  186. package/.medusa/server/src/modules/paypal/utils/provider-ids.js.map +1 -0
  187. package/.medusa/server/src/modules/paypal/webhook-processor.d.ts +29 -0
  188. package/.medusa/server/src/modules/paypal/webhook-processor.d.ts.map +1 -0
  189. package/.medusa/server/src/modules/paypal/webhook-processor.js +267 -0
  190. package/.medusa/server/src/modules/paypal/webhook-processor.js.map +1 -0
  191. package/.medusa/server/src/providers/paypal/index.d.ts +5 -0
  192. package/.medusa/server/src/providers/paypal/index.d.ts.map +1 -0
  193. package/.medusa/server/src/providers/paypal/index.js +10 -0
  194. package/.medusa/server/src/providers/paypal/index.js.map +1 -0
  195. package/.medusa/server/src/providers/paypal_card/index.d.ts +5 -0
  196. package/.medusa/server/src/providers/paypal_card/index.d.ts.map +1 -0
  197. package/.medusa/server/src/providers/paypal_card/index.js +10 -0
  198. package/.medusa/server/src/providers/paypal_card/index.js.map +1 -0
  199. package/.medusa/server/src/subscribers/paypal-order-invoice.d.ts +6 -0
  200. package/.medusa/server/src/subscribers/paypal-order-invoice.d.ts.map +1 -0
  201. package/.medusa/server/src/subscribers/paypal-order-invoice.js +124 -0
  202. package/.medusa/server/src/subscribers/paypal-order-invoice.js.map +1 -0
  203. package/LICENSE +21 -0
  204. package/README.md +172 -0
  205. package/package.json +80 -0
  206. package/src/admin/index.ts +7 -0
  207. package/src/admin/routes/settings/paypal/_components/Tabs.tsx +48 -0
  208. package/src/admin/routes/settings/paypal/_components/Toast.tsx +51 -0
  209. package/src/admin/routes/settings/paypal/additional-settings/page.tsx +199 -0
  210. package/src/admin/routes/settings/paypal/advanced-card-payments/page.tsx +183 -0
  211. package/src/admin/routes/settings/paypal/apple-pay/page.tsx +5 -0
  212. package/src/admin/routes/settings/paypal/connection/page.tsx +699 -0
  213. package/src/admin/routes/settings/paypal/google-pay/page.tsx +5 -0
  214. package/src/admin/routes/settings/paypal/page.tsx +13 -0
  215. package/src/admin/routes/settings/paypal/pay-later-messaging/page.tsx +5 -0
  216. package/src/admin/routes/settings/paypal/paypal-settings/page.tsx +351 -0
  217. package/src/api/admin/payment-collections/[id]/payment-sessions/route.ts +24 -0
  218. package/src/api/admin/paypal/disconnect/route.ts +8 -0
  219. package/src/api/admin/paypal/environment/route.ts +25 -0
  220. package/src/api/admin/paypal/onboard-complete/route.ts +34 -0
  221. package/src/api/admin/paypal/onboarding-link/route.ts +45 -0
  222. package/src/api/admin/paypal/onboarding-status/route.ts +17 -0
  223. package/src/api/admin/paypal/save-credentials/route.ts +22 -0
  224. package/src/api/admin/paypal/settings/route.ts +14 -0
  225. package/src/api/admin/paypal/status/route.ts +12 -0
  226. package/src/api/middlewares.ts +14 -0
  227. package/src/api/store/payment-collections/[id]/payment-sessions/route.ts +56 -0
  228. package/src/api/store/paypal/capture-order/route.ts +265 -0
  229. package/src/api/store/paypal/config/route.ts +100 -0
  230. package/src/api/store/paypal/create-order/route.ts +449 -0
  231. package/src/api/store/paypal/settings/route.ts +19 -0
  232. package/src/api/store/paypal/webhook/route.ts +325 -0
  233. package/src/api/store/paypal-complete/route.ts +95 -0
  234. package/src/index.ts +1 -0
  235. package/src/jobs/paypal-webhook-retry.ts +149 -0
  236. package/src/modules/paypal/clients/paypal-seller.client.ts +62 -0
  237. package/src/modules/paypal/index.ts +8 -0
  238. package/src/modules/paypal/migrations/20260115120000_create_paypal_connection.ts +33 -0
  239. package/src/modules/paypal/migrations/20260123090000_create_paypal_settings.ts +22 -0
  240. package/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.ts +29 -0
  241. package/src/modules/paypal/migrations/20260401090000_create_paypal_metric.ts +27 -0
  242. package/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.ts +31 -0
  243. package/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.ts +25 -0
  244. package/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.ts +26 -0
  245. package/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.ts +11 -0
  246. package/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.ts +11 -0
  247. package/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.ts +11 -0
  248. package/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.ts +17 -0
  249. package/src/modules/paypal/models/paypal_connection.ts +23 -0
  250. package/src/modules/paypal/models/paypal_metric.ts +9 -0
  251. package/src/modules/paypal/models/paypal_settings.ts +8 -0
  252. package/src/modules/paypal/models/paypal_webhook_event.ts +19 -0
  253. package/src/modules/paypal/payment-provider/README.md +22 -0
  254. package/src/modules/paypal/payment-provider/card-service.ts +767 -0
  255. package/src/modules/paypal/payment-provider/index.ts +15 -0
  256. package/src/modules/paypal/payment-provider/service.ts +1039 -0
  257. package/src/modules/paypal/payment-provider/webhook-utils.ts +88 -0
  258. package/src/modules/paypal/service.ts +1416 -0
  259. package/src/modules/paypal/types/config.ts +33 -0
  260. package/src/modules/paypal/utils/amounts.ts +41 -0
  261. package/src/modules/paypal/utils/currencies.ts +84 -0
  262. package/src/modules/paypal/utils/paypal-auth.ts +31 -0
  263. package/src/modules/paypal/utils/provider-ids.ts +15 -0
  264. package/src/modules/paypal/webhook-processor.ts +363 -0
  265. package/src/providers/paypal/index.ts +8 -0
  266. package/src/providers/paypal_card/index.ts +8 -0
  267. package/src/subscribers/paypal-order-invoice.ts +171 -0
  268. package/tsconfig.json +31 -0
@@ -0,0 +1,449 @@
1
+ import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
2
+ import { randomUUID } from "crypto"
3
+ import { getCurrencyExponent } from "../../../../modules/paypal/utils/amounts"
4
+ import {
5
+ assertPayPalCurrencySupported,
6
+ normalizeCurrencyCode,
7
+ } from "../../../../modules/paypal/utils/currencies"
8
+ import { getPayPalAccessToken } from "../../../../modules/paypal/utils/paypal-auth"
9
+ import type PayPalModuleService from "../../../../modules/paypal/service"
10
+ import { isPayPalProviderId } from "../../../../modules/paypal/utils/provider-ids"
11
+
12
+ const BN_CODE = "MBJTechnolabs_SI_SPB"
13
+
14
+ type Body = {
15
+ cart_id: string
16
+ is_card_payment?: boolean
17
+ }
18
+
19
+ function resolveIdempotencyKey(req: MedusaRequest, suffix: string, fallback: string) {
20
+ const header =
21
+ req.headers["idempotency-key"] ||
22
+ req.headers["Idempotency-Key"] ||
23
+ req.headers["x-idempotency-key"] ||
24
+ req.headers["X-Idempotency-Key"]
25
+ const key = Array.isArray(header) ? header[0] : header
26
+ if (key && String(key).trim()) {
27
+ return `${String(key).trim()}-${suffix}`
28
+ }
29
+ return fallback || `pp-${suffix}-${randomUUID()}`
30
+ }
31
+
32
+ async function attachPayPalOrderToSession(
33
+ req: MedusaRequest,
34
+ cartId: string,
35
+ orderId: string
36
+ ) {
37
+ try {
38
+ const paymentCollectionService = req.scope.resolve("payment_collection") as any
39
+ const paymentSessionService = req.scope.resolve("payment_session") as any
40
+
41
+ const pc = await paymentCollectionService.retrieveByCartId(cartId).catch(() => null)
42
+ if (!pc?.id) {
43
+ return
44
+ }
45
+
46
+ const sessions = await paymentSessionService.list({ payment_collection_id: pc.id })
47
+ const paypalSession = sessions?.find((s: any) => isPayPalProviderId(s.provider_id))
48
+ if (!paypalSession) {
49
+ return
50
+ }
51
+
52
+ await paymentSessionService.update(paypalSession.id, {
53
+ amount: paypalSession.amount,
54
+ data: {
55
+ ...(paypalSession.data || {}),
56
+ paypal: {
57
+ ...((paypalSession.data || {}).paypal || {}),
58
+ order_id: orderId,
59
+ },
60
+ },
61
+ })
62
+ } catch {
63
+ }
64
+ }
65
+
66
+ async function getExistingPayPalOrderId(req: MedusaRequest, cartId: string) {
67
+ try {
68
+ const paymentCollectionService = req.scope.resolve("payment_collection") as any
69
+ const paymentSessionService = req.scope.resolve("payment_session") as any
70
+
71
+ const pc = await paymentCollectionService.retrieveByCartId(cartId).catch(() => null)
72
+ if (!pc?.id) {
73
+ return null
74
+ }
75
+
76
+ const sessions = await paymentSessionService.list({ payment_collection_id: pc.id })
77
+ const paypalSession = sessions?.find((s: any) => isPayPalProviderId(s.provider_id))
78
+ if (!paypalSession) {
79
+ return null
80
+ }
81
+
82
+ const paypalData = (paypalSession.data || {}).paypal || {}
83
+ return paypalData.order_id ? String(paypalData.order_id) : null
84
+ } catch {
85
+ return null
86
+ }
87
+ }
88
+
89
+ function resolveReturnUrl(req: MedusaRequest) {
90
+ const configured = process.env.STOREFRONT_URL || process.env.STORE_URL
91
+ if (!configured) {
92
+ return undefined
93
+ }
94
+ return `${configured.replace(/\/$/, "")}/checkout`
95
+ }
96
+
97
+ function resolveCancelUrl(req: MedusaRequest) {
98
+ const configured = process.env.STOREFRONT_URL || process.env.STORE_URL
99
+ if (!configured) {
100
+ return undefined
101
+ }
102
+ return `${configured.replace(/\/$/, "")}/cart`
103
+ }
104
+
105
+ export async function POST(req: MedusaRequest, res: MedusaResponse) {
106
+ const paypal = req.scope.resolve<PayPalModuleService>("paypal_onboarding")
107
+ let debugId: string | null = null
108
+
109
+ try {
110
+ const body = (req.body || {}) as Body
111
+ const cartId = body.cart_id
112
+ const isCardPayment = !!(body as any).is_card_payment
113
+
114
+ if (!cartId) {
115
+ return res.status(400).json({ message: "cart_id is required" })
116
+ }
117
+
118
+ const existingOrderId = await getExistingPayPalOrderId(req, cartId)
119
+ if (existingOrderId) {
120
+ return res.json({ id: existingOrderId })
121
+ }
122
+
123
+ const query = req.scope.resolve("query")
124
+
125
+ const { data } = await query.graph({
126
+ entity: "cart",
127
+ fields: [
128
+ "id",
129
+ "total",
130
+ "subtotal",
131
+ "shipping_total",
132
+ "tax_total",
133
+ "discount_total",
134
+ "gift_card_total",
135
+ "currency_code",
136
+ "region.currency_code",
137
+ "items.title",
138
+ "items.quantity",
139
+ "items.unit_price",
140
+ "items.subtotal",
141
+ "items.tax_total",
142
+ "items.total",
143
+ ],
144
+ filters: { id: cartId },
145
+ })
146
+
147
+ const cart = (data?.[0] as any) || null
148
+
149
+ if (!cart) {
150
+ return res.status(404).json({ message: "Cart not found" })
151
+ }
152
+
153
+ const creds = await paypal.getActiveCredentials()
154
+
155
+ type PayPalSettingsResponse = {
156
+ data?: {
157
+ additional_settings?: Record<string, unknown>
158
+ api_details?: Record<string, unknown>
159
+ advanced_card_payments?: Record<string, unknown>
160
+ }
161
+ }
162
+ const settings = await paypal
163
+ .getSettings()
164
+ .catch((): PayPalSettingsResponse => ({}))
165
+ const settingsData = (settings.data || {}) as Record<string, any>
166
+ const additionalSettings = settingsData.additional_settings || {}
167
+ const apiDetails = settingsData.api_details || {}
168
+ const advancedCardSettings = (settingsData.advanced_card_payments || {}) as Record<string, any>
169
+
170
+ const threeDsRaw =
171
+ typeof advancedCardSettings.threeDS === "string"
172
+ ? advancedCardSettings.threeDS
173
+ : "when_required"
174
+
175
+ const threeDsMethod: string | null = isCardPayment
176
+ ? (threeDsRaw === "always"
177
+ ? "SCA_ALWAYS"
178
+ : "SCA_WHEN_REQUIRED")
179
+ : null
180
+ const configuredCurrency =
181
+ typeof apiDetails.currency_code === "string"
182
+ ? normalizeCurrencyCode(apiDetails.currency_code)
183
+ : normalizeCurrencyCode(process.env.PAYPAL_CURRENCY || "EUR")
184
+
185
+ const currency = normalizeCurrencyCode(
186
+ cart.region?.currency_code || cart.currency_code || configuredCurrency
187
+ )
188
+ assertPayPalCurrencySupported({
189
+ currencyCode: currency,
190
+ paypalCurrencyOverride: configuredCurrency,
191
+ })
192
+
193
+ const exponent = getCurrencyExponent(currency)
194
+ const totalMajor = Number(cart.total || 0)
195
+ const value = totalMajor.toFixed(exponent)
196
+
197
+ const paymentActionRaw =
198
+ typeof additionalSettings.paymentAction === "string"
199
+ ? additionalSettings.paymentAction
200
+ : "capture"
201
+ const paymentAction = paymentActionRaw === "authorize" ? "AUTHORIZE" : "CAPTURE"
202
+ const brandName =
203
+ typeof additionalSettings.brandName === "string"
204
+ ? additionalSettings.brandName
205
+ : undefined
206
+ const landingPageRaw =
207
+ typeof additionalSettings.landingPage === "string"
208
+ ? additionalSettings.landingPage
209
+ : undefined
210
+ const landingPage =
211
+ landingPageRaw === "login"
212
+ ? "LOGIN"
213
+ : landingPageRaw === "billing"
214
+ ? "BILLING"
215
+ : landingPageRaw === "no_preference"
216
+ ? "NO_PREFERENCE"
217
+ : undefined
218
+ const requireInstantPayment =
219
+ typeof additionalSettings.requireInstantPayment === "boolean"
220
+ ? additionalSettings.requireInstantPayment
221
+ : undefined
222
+ const sendItemDetails = additionalSettings.sendItemDetails !== false
223
+ const statementName =
224
+ typeof additionalSettings.creditCardStatementName === "string"
225
+ ? additionalSettings.creditCardStatementName.trim()
226
+ : ""
227
+ const invoicePrefix =
228
+ typeof additionalSettings.invoicePrefix === "string"
229
+ ? additionalSettings.invoicePrefix
230
+ : ""
231
+ const cartIdSuffix = cart.id.slice(-12).toUpperCase()
232
+ const invoiceId = `${invoicePrefix}${cartIdSuffix}`.trim() || cart.id
233
+ const returnUrl =
234
+ (typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
235
+ ? `${apiDetails.storefront_url.replace(/\/$/, "")}/checkout`
236
+ : resolveReturnUrl(req))
237
+ const cancelUrl =
238
+ (typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
239
+ ? `${apiDetails.storefront_url.replace(/\/$/, "")}/cart`
240
+ : resolveCancelUrl(req))
241
+
242
+ const applicationContext: Record<string, any> = {
243
+ ...(brandName ? { brand_name: brandName } : {}),
244
+ ...(landingPage ? { landing_page: landingPage } : {}),
245
+ ...(requireInstantPayment ? { payment_method_preference: "IMMEDIATE_PAYMENT_REQUIRED" } : {}),
246
+ ...(returnUrl ? { return_url: returnUrl } : {}),
247
+ ...(cancelUrl ? { cancel_url: cancelUrl } : {}),
248
+ }
249
+
250
+ const subtotalMajor = Number(cart.subtotal || 0)
251
+ const shippingMajor = Number(cart.shipping_total || 0)
252
+ const taxMajor = Number(cart.tax_total || 0)
253
+ const discountMajor = Number(cart.discount_total || 0)
254
+ const giftCardMajor = Number(cart.gift_card_total || 0)
255
+ const lineItems = Array.isArray((cart as any).items) ? (cart as any).items : []
256
+
257
+ const purchaseItemsRaw = sendItemDetails
258
+ ? lineItems
259
+ .map((item: any) => {
260
+ const quantity = Number(item?.quantity || 0)
261
+ const lineSubtotalMajor = Number(
262
+ item?.subtotal ?? (Number(item?.unit_price || 0) * quantity)
263
+ )
264
+ const unitAmount =
265
+ quantity > 0 ? parseFloat((lineSubtotalMajor / quantity).toFixed(exponent)) : 0
266
+
267
+ if (!quantity || Number.isNaN(quantity) || Number.isNaN(unitAmount)) {
268
+ return null
269
+ }
270
+
271
+ return {
272
+ quantity,
273
+ unitAmount,
274
+ paypalItem: {
275
+ name: String(item?.title || "Item").slice(0, 127),
276
+ quantity: String(Math.max(1, quantity)),
277
+ unit_amount: {
278
+ currency_code: currency,
279
+ value: unitAmount.toFixed(exponent),
280
+ },
281
+ },
282
+ }
283
+ })
284
+ .filter(Boolean)
285
+ : []
286
+
287
+ const roundedItemSum = purchaseItemsRaw.reduce(
288
+ (sum: number, item: any) => sum + item.unitAmount * item.quantity,
289
+ 0
290
+ )
291
+ const roundedItemSumFixed = parseFloat(roundedItemSum.toFixed(exponent))
292
+
293
+ const adjustedItemTotal = roundedItemSumFixed
294
+
295
+ const diff = parseFloat((adjustedItemTotal - roundedItemSumFixed).toFixed(exponent))
296
+
297
+ const finalPurchaseItems = purchaseItemsRaw.map((item: any) => item.paypalItem)
298
+
299
+ if (Math.abs(diff) > 0.000001 && sendItemDetails && finalPurchaseItems.length > 0) {
300
+ finalPurchaseItems.push({
301
+ name: "Line Item Amount Offset",
302
+ quantity: "1",
303
+ unit_amount: {
304
+ currency_code: currency,
305
+ value: diff.toFixed(exponent),
306
+ },
307
+ })
308
+ }
309
+
310
+ const breakdown: Record<string, any> = {}
311
+ if (adjustedItemTotal > 0) {
312
+ breakdown.item_total = {
313
+ currency_code: currency,
314
+ value: adjustedItemTotal.toFixed(exponent),
315
+ }
316
+ }
317
+ if (shippingMajor > 0) {
318
+ breakdown.shipping = {
319
+ currency_code: currency,
320
+ value: shippingMajor.toFixed(exponent),
321
+ }
322
+ }
323
+ if (taxMajor > 0) {
324
+ breakdown.tax_total = {
325
+ currency_code: currency,
326
+ value: taxMajor.toFixed(exponent),
327
+ }
328
+ }
329
+
330
+ const discountValue = discountMajor + giftCardMajor
331
+ if (discountValue > 0 && finalPurchaseItems.length > 0) {
332
+ breakdown.discount = {
333
+ currency_code: currency,
334
+ value: discountValue.toFixed(exponent),
335
+ }
336
+ }
337
+
338
+ const breakdownSum = parseFloat(
339
+ (adjustedItemTotal + shippingMajor + taxMajor - discountValue).toFixed(exponent)
340
+ )
341
+
342
+ if (Math.abs(breakdownSum - totalMajor) > 0.000001) {
343
+ const gap = parseFloat((totalMajor - breakdownSum).toFixed(exponent))
344
+
345
+ if (gap > 0) {
346
+ breakdown.tax_total = {
347
+ currency_code: currency,
348
+ value: parseFloat(
349
+ ((Number(breakdown.tax_total?.value || 0) + gap).toFixed(exponent))
350
+ ).toFixed(exponent),
351
+ }
352
+ } else {
353
+ breakdown.shipping_discount = {
354
+ currency_code: currency,
355
+ value: Math.abs(gap).toFixed(exponent),
356
+ }
357
+ }
358
+ }
359
+
360
+ const { accessToken, base } = await getPayPalAccessToken({
361
+ environment: creds.environment,
362
+ client_id: creds.client_id,
363
+ client_secret: creds.client_secret,
364
+ })
365
+
366
+ const requestId = resolveIdempotencyKey(req, "create-order", `pp-create-${cart.id}`)
367
+
368
+ const ppResp = await fetch(`${base}/v2/checkout/orders`, {
369
+ method: "POST",
370
+ headers: {
371
+ Authorization: `Bearer ${accessToken}`,
372
+ "Content-Type": "application/json",
373
+ "PayPal-Request-Id": requestId,
374
+ "PayPal-Partner-Attribution-Id": BN_CODE,
375
+ },
376
+ body: JSON.stringify({
377
+ intent: paymentAction,
378
+ purchase_units: [
379
+ {
380
+ reference_id: "default",
381
+ invoice_id: invoiceId,
382
+ ...(statementName ? { soft_descriptor: statementName.slice(0, 22) } : {}),
383
+ amount: {
384
+ currency_code: currency,
385
+ value,
386
+ ...(Object.keys(breakdown).length > 0 ? { breakdown } : {}),
387
+ },
388
+ ...(finalPurchaseItems.length > 0 ? { items: finalPurchaseItems } : {}),
389
+ },
390
+ ],
391
+ ...(threeDsMethod
392
+ ? {
393
+ payment_source: {
394
+ card: {
395
+ attributes: {
396
+ verification: {
397
+ method: threeDsMethod,
398
+ },
399
+ },
400
+ },
401
+ },
402
+ }
403
+ : {}),
404
+ custom_id: cart.id,
405
+ ...(Object.keys(applicationContext).length > 0
406
+ ? { application_context: applicationContext }
407
+ : {}),
408
+ }),
409
+ })
410
+
411
+ const ppText = await ppResp.text()
412
+ debugId = ppResp.headers.get("paypal-debug-id")
413
+ if (!ppResp.ok) {
414
+ throw new Error(
415
+ `PayPal create order error (${ppResp.status}): ${ppText}${
416
+ debugId ? ` debug_id=${debugId}` : ""
417
+ }`
418
+ )
419
+ }
420
+
421
+ const order = JSON.parse(ppText)
422
+
423
+ await attachPayPalOrderToSession(req, cart.id, order.id)
424
+
425
+ try {
426
+ await paypal.recordMetric("create_order_success")
427
+ } catch {
428
+ }
429
+ return res.json({ id: order.id })
430
+ } catch (e: any) {
431
+ try {
432
+ const body = (req.body || {}) as Body
433
+ await paypal.recordAuditEvent("create_order_failed", {
434
+ cart_id: body.cart_id,
435
+ debug_id: debugId,
436
+ message: e?.message || String(e),
437
+ })
438
+ await paypal.recordMetric("create_order_failed")
439
+ } catch {
440
+ }
441
+ const message = e?.message || "Failed to create PayPal order"
442
+ const status = message.includes("PayPal does not support currency")
443
+ ? 400
444
+ : message.includes("PayPal is configured for")
445
+ ? 400
446
+ : 500
447
+ return res.status(status).json({ message })
448
+ }
449
+ }
@@ -0,0 +1,19 @@
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
+ const data = (settings?.data || {}) as Record<string, any>
9
+ const additionalSettings = (data.additional_settings || {}) as Record<string, any>
10
+ const advancedCard = (data.advanced_card_payments || {}) as Record<string, any>
11
+
12
+ return res.json({
13
+ paymentAction: additionalSettings.paymentAction === "authorize" ? "authorize" : "capture",
14
+ advancedCardEnabled: advancedCard.enabled === true,
15
+ })
16
+ } catch (e: any) {
17
+ return res.status(500).json({ message: e?.message || "Failed to load PayPal settings" })
18
+ }
19
+ }