@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,33 @@
1
+ export type PayPalModuleConfig = {
2
+ partnerServiceUrl: string
3
+ partnerJsUrl: string
4
+ backendUrl: string
5
+ sellerNonce: string
6
+ bnCode?: string
7
+ partnerMerchantIdSandbox: string
8
+ partnerMerchantIdLive: string
9
+ alertWebhookUrls?: string[]
10
+ }
11
+
12
+ const STATIC_CFG: PayPalModuleConfig = {
13
+ partnerServiceUrl: "https://mbjtechnolabs.com/ppcp-seller-onboarding/seller-onboarding.php?from=medusa",
14
+ partnerJsUrl: "https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js",
15
+ backendUrl: "http://localhost:9000",
16
+ sellerNonce: "a1233wtergfsdt4365tzrshgfbaewa36AGa1233wtergfsdt4365tzrshgfbaewa36AG",
17
+ bnCode: "MBJTechnolabs_SI_SPB",
18
+ partnerMerchantIdSandbox: "K6QLN2LPGQRHL",
19
+ partnerMerchantIdLive: "GT5R877JNBPLL",
20
+ alertWebhookUrls: [],
21
+ }
22
+
23
+ export function getPayPalConfig(): PayPalModuleConfig {
24
+ return {
25
+ ...STATIC_CFG,
26
+ backendUrl: process.env.MEDUSA_BACKEND_URL || STATIC_CFG.backendUrl,
27
+ alertWebhookUrls:
28
+ (process.env.PAYPAL_ALERT_WEBHOOK_URLS || "")
29
+ .split(",")
30
+ .map((url) => url.trim())
31
+ .filter(Boolean) || STATIC_CFG.alertWebhookUrls,
32
+ }
33
+ }
@@ -0,0 +1,41 @@
1
+ const ZERO_DECIMAL_CURRENCIES = new Set([
2
+ "BIF",
3
+ "CLP",
4
+ "DJF",
5
+ "GNF",
6
+ "JPY",
7
+ "KMF",
8
+ "KRW",
9
+ "MGA",
10
+ "PYG",
11
+ "RWF",
12
+ "UGX",
13
+ "VND",
14
+ "VUV",
15
+ "XAF",
16
+ "XOF",
17
+ "XPF",
18
+ ])
19
+
20
+ const THREE_DECIMAL_CURRENCIES = new Set(["BHD", "JOD", "KWD", "OMR", "TND"])
21
+
22
+ export function getCurrencyExponent(currencyCode: string) {
23
+ const code = currencyCode.toUpperCase()
24
+ if (ZERO_DECIMAL_CURRENCIES.has(code)) {
25
+ return 0
26
+ }
27
+ if (THREE_DECIMAL_CURRENCIES.has(code)) {
28
+ return 3
29
+ }
30
+ return 2
31
+ }
32
+
33
+ export function formatAmountForPayPal(
34
+ minorAmount: number,
35
+ currencyCode: string
36
+ ) {
37
+ const exponent = getCurrencyExponent(currencyCode)
38
+ const factor = 10 ** exponent
39
+ const majorAmount = Number(minorAmount || 0) / factor
40
+ return majorAmount.toFixed(exponent)
41
+ }
@@ -0,0 +1,84 @@
1
+ const PAYPAL_SUPPORTED_CURRENCIES = new Set([
2
+ "AUD",
3
+ "BRL",
4
+ "CAD",
5
+ "CHF",
6
+ "CZK",
7
+ "DKK",
8
+ "EUR",
9
+ "GBP",
10
+ "HKD",
11
+ "HUF",
12
+ "ILS",
13
+ "JPY",
14
+ "MXN",
15
+ "MYR",
16
+ "NOK",
17
+ "NZD",
18
+ "PHP",
19
+ "PLN",
20
+ "SEK",
21
+ "SGD",
22
+ "THB",
23
+ "TWD",
24
+ "USD",
25
+ ])
26
+
27
+ type CurrencyCheck = {
28
+ currency: string
29
+ overrideCurrency?: string
30
+ supported: boolean
31
+ errors: string[]
32
+ }
33
+
34
+ export function normalizeCurrencyCode(code?: string, fallback = "EUR") {
35
+ const trimmed = String(code || "").trim()
36
+ return (trimmed || fallback).toUpperCase()
37
+ }
38
+
39
+ export function isPayPalCurrencySupported(currencyCode: string) {
40
+ return PAYPAL_SUPPORTED_CURRENCIES.has(normalizeCurrencyCode(currencyCode))
41
+ }
42
+
43
+ export function getPayPalCurrencyCompatibility(input: {
44
+ currencyCode?: string
45
+ paypalCurrencyOverride?: string
46
+ }): CurrencyCheck {
47
+ const currency = normalizeCurrencyCode(input.currencyCode)
48
+ const overrideCurrency = input.paypalCurrencyOverride
49
+ ? normalizeCurrencyCode(input.paypalCurrencyOverride)
50
+ : undefined
51
+ const errors: string[] = []
52
+
53
+ if (!isPayPalCurrencySupported(currency)) {
54
+ errors.push(`PayPal does not support currency "${currency}".`)
55
+ }
56
+
57
+ if (overrideCurrency && overrideCurrency !== currency) {
58
+ errors.push(
59
+ `PayPal is configured for "${overrideCurrency}", but the store cart uses "${currency}".`
60
+ )
61
+ }
62
+
63
+ return {
64
+ currency,
65
+ overrideCurrency,
66
+ supported: errors.length === 0,
67
+ errors,
68
+ }
69
+ }
70
+
71
+ export function assertPayPalCurrencySupported(input: {
72
+ currencyCode?: string
73
+ paypalCurrencyOverride?: string
74
+ }) {
75
+ const result = getPayPalCurrencyCompatibility(input)
76
+ if (!result.supported) {
77
+ throw new Error(result.errors.join(" "))
78
+ }
79
+ return result
80
+ }
81
+
82
+ export function getPayPalSupportedCurrencies() {
83
+ return Array.from(PAYPAL_SUPPORTED_CURRENCIES.values())
84
+ }
@@ -0,0 +1,31 @@
1
+ export function getPayPalApiBase(environment: string): string {
2
+ return environment === "live"
3
+ ? "https://api-m.paypal.com"
4
+ : "https://api-m.sandbox.paypal.com"
5
+ }
6
+
7
+ const BN_CODE = "MBJTechnolabs_SI_SPB"
8
+
9
+ export async function getPayPalAccessToken(opts: {
10
+ environment: string
11
+ client_id: string
12
+ client_secret: string
13
+ }): Promise<{ accessToken: string; base: string }> {
14
+ const base = getPayPalApiBase(opts.environment)
15
+ const auth = Buffer.from(`${opts.client_id}:${opts.client_secret}`).toString("base64")
16
+ const resp = await fetch(`${base}/v1/oauth2/token`, {
17
+ method: "POST",
18
+ headers: {
19
+ Authorization: `Basic ${auth}`,
20
+ "Content-Type": "application/x-www-form-urlencoded",
21
+ "PayPal-Partner-Attribution-Id": BN_CODE,
22
+ },
23
+ body: "grant_type=client_credentials",
24
+ })
25
+ const text = await resp.text()
26
+ if (!resp.ok) {
27
+ throw new Error(`PayPal token error (${resp.status}): ${text}`)
28
+ }
29
+ const json = JSON.parse(text)
30
+ return { accessToken: String(json.access_token), base }
31
+ }
@@ -0,0 +1,15 @@
1
+ export const PAYPAL_WALLET_PROVIDER_ID = "pp_paypal_paypal" as const
2
+ export const PAYPAL_CARD_PROVIDER_ID = "pp_paypal_card_paypal_card" as const
3
+
4
+ export const PAYPAL_PROVIDER_IDS = [
5
+ PAYPAL_WALLET_PROVIDER_ID,
6
+ PAYPAL_CARD_PROVIDER_ID,
7
+ ] as const
8
+
9
+ export const isPayPalProviderId = (providerId?: string | null) => {
10
+ if (!providerId) return false
11
+
12
+ return PAYPAL_PROVIDER_IDS.includes(
13
+ providerId as (typeof PAYPAL_PROVIDER_IDS)[number]
14
+ )
15
+ }
@@ -0,0 +1,363 @@
1
+ import type { MedusaContainer } from "@medusajs/framework/types"
2
+ import { Modules } from "@medusajs/framework/utils"
3
+ import { isPayPalProviderId } from "./utils/provider-ids"
4
+
5
+
6
+ export const EVENT_STATUS_MAP: Record<
7
+ string,
8
+ "authorized" | "captured" | "canceled" | "error"
9
+ > = {
10
+ "CHECKOUT.ORDER.APPROVED": "authorized",
11
+ "CHECKOUT.ORDER.CANCELLED": "canceled",
12
+ "PAYMENT.CAPTURE.COMPLETED": "captured",
13
+ "PAYMENT.CAPTURE.DENIED": "error",
14
+ "PAYMENT.CAPTURE.PENDING": "authorized",
15
+ "PAYMENT.CAPTURE.REFUNDED": "canceled",
16
+ "PAYMENT.CAPTURE.REVERSED": "canceled",
17
+ "PAYMENT.AUTHORIZATION.CREATED": "authorized",
18
+ "PAYMENT.AUTHORIZATION.VOIDED": "canceled",
19
+ "PAYMENT.AUTHORIZATION.DENIED": "error",
20
+ "PAYMENT.AUTHORIZATION.EXPIRED": "canceled",
21
+ "PAYMENT.REFUND.COMPLETED": "canceled",
22
+ "PAYMENT.REFUND.DENIED": "error",
23
+ }
24
+
25
+
26
+ const ALLOWED_TRANSITIONS: Record<string, Set<string>> = {
27
+ pending: new Set(["authorized", "captured", "canceled", "error"]),
28
+ authorized: new Set(["captured", "canceled", "error"]),
29
+ captured: new Set(["canceled"]),
30
+ canceled: new Set([]),
31
+ error: new Set(["authorized", "captured", "canceled"]),
32
+ }
33
+
34
+ export function isTransitionAllowed(from: string, to: string): boolean {
35
+ return ALLOWED_TRANSITIONS[from]?.has(to) ?? false
36
+ }
37
+
38
+
39
+ export const SUPPORTED_EVENT_PREFIXES = [
40
+ "PAYMENT.CAPTURE.",
41
+ "CHECKOUT.ORDER.",
42
+ "PAYMENT.AUTHORIZATION.",
43
+ "PAYMENT.REFUND.",
44
+ ]
45
+
46
+ export function isAllowedEventType(eventType: string): boolean {
47
+ return SUPPORTED_EVENT_PREFIXES.some((prefix) => eventType.startsWith(prefix))
48
+ }
49
+
50
+
51
+ const NON_RETRYABLE_PATTERNS = [
52
+ "payment collection not found",
53
+ "no paypal session",
54
+ "session not found",
55
+ "cart not found",
56
+ "no payment collection",
57
+ ]
58
+
59
+ export function isRetryableError(error: unknown): boolean {
60
+ const message = String(
61
+ error instanceof Error ? error.message : error ?? ""
62
+ ).toLowerCase()
63
+ return !NON_RETRYABLE_PATTERNS.some((p) => message.includes(p))
64
+ }
65
+
66
+
67
+ const RETRY_SCHEDULE_MINUTES = [2, 10, 30, 60, 120]
68
+ export const MAX_WEBHOOK_ATTEMPTS = RETRY_SCHEDULE_MINUTES.length + 1
69
+
70
+ export function computeNextRetryAt(attemptCount: number): Date | null {
71
+ const idx = attemptCount - 1
72
+ const delayMinutes = RETRY_SCHEDULE_MINUTES[idx]
73
+ if (delayMinutes === undefined || attemptCount <= 0) return null
74
+ return new Date(Date.now() + delayMinutes * 60 * 1000)
75
+ }
76
+
77
+
78
+ export function normalizeResource(payload: Record<string, any>): Record<string, any> {
79
+ const resource = payload?.resource
80
+ if (!resource) return {}
81
+ if (typeof resource === "string") {
82
+ try {
83
+ return JSON.parse(resource)
84
+ } catch {
85
+ return {}
86
+ }
87
+ }
88
+ return resource as Record<string, any>
89
+ }
90
+
91
+ export function normalizeEventVersion(payload: Record<string, any>): string | null {
92
+ const raw =
93
+ payload?.event_version ??
94
+ payload?.resource_version ??
95
+ payload?.resource?.resource_version ??
96
+ payload?.resource?.version ??
97
+ null
98
+ if (!raw) return null
99
+ return String(raw).trim().replace(/^v/i, "")
100
+ }
101
+
102
+
103
+ export interface ExtractedIdentifiers {
104
+ orderId: string | null
105
+ captureId: string | null
106
+ refundId: string | null
107
+ cartId: string | null
108
+ }
109
+
110
+ export function extractIdentifiers(
111
+ resource: Record<string, any>,
112
+ eventType: string
113
+ ): ExtractedIdentifiers {
114
+ const related = resource?.supplementary_data?.related_ids || {}
115
+ const isOrder = eventType.startsWith("CHECKOUT.ORDER.")
116
+ const isCapture = eventType.startsWith("PAYMENT.CAPTURE.")
117
+ const isAuthorization = eventType.startsWith("PAYMENT.AUTHORIZATION.")
118
+ const isRefund = eventType.startsWith("PAYMENT.REFUND.")
119
+
120
+ let orderId: string | null = null
121
+ let captureId: string | null = null
122
+ let refundId: string | null = null
123
+ let cartId: string | null = null
124
+
125
+ if (isOrder) {
126
+ orderId = String(resource?.id || "").trim() || null
127
+ cartId =
128
+ String(
129
+ resource?.purchase_units?.[0]?.custom_id || resource?.custom_id || ""
130
+ ).trim() || null
131
+ captureId =
132
+ String(
133
+ resource?.purchase_units?.[0]?.payments?.captures?.[0]?.id || ""
134
+ ).trim() || null
135
+ } else if (isCapture) {
136
+ captureId = String(resource?.id || "").trim() || null
137
+ orderId = String(related?.order_id || "").trim() || null
138
+ cartId = String(resource?.custom_id || "").trim() || null
139
+ } else if (isAuthorization) {
140
+ orderId = String(related?.order_id || "").trim() || null
141
+ cartId = String(resource?.custom_id || "").trim() || null
142
+ } else if (isRefund) {
143
+ refundId = String(resource?.id || "").trim() || null
144
+ orderId = String(related?.order_id || "").trim() || null
145
+ captureId = String(related?.capture_id || "").trim() || null
146
+ cartId = null
147
+ }
148
+
149
+ return { orderId, captureId, refundId, cartId }
150
+ }
151
+
152
+
153
+ interface ResolvedSession {
154
+ sessionId: string
155
+ sessionData: Record<string, any>
156
+ sessionStatus: string
157
+ collectionId: string
158
+ }
159
+
160
+ async function findPayPalSession(
161
+ container: MedusaContainer,
162
+ cartId: string
163
+ ): Promise<ResolvedSession | null> {
164
+ const paymentModule = container.resolve(Modules.PAYMENT) as any
165
+
166
+ let collections: any[]
167
+ try {
168
+ collections = await paymentModule.listPaymentCollections(
169
+ { cart_id: [cartId] },
170
+ { take: 1 }
171
+ )
172
+ } catch (e: any) {
173
+ throw new Error(`payment collection not found for cart ${cartId}: ${e?.message}`)
174
+ }
175
+
176
+ const collection = collections?.[0]
177
+ if (!collection?.id) {
178
+ throw new Error(`payment collection not found for cart ${cartId}`)
179
+ }
180
+
181
+ const sessions = await paymentModule.listPaymentSessions({
182
+ payment_collection_id: collection.id,
183
+ })
184
+
185
+ const paypalSession = (sessions || [])
186
+ .filter((s: any) => isPayPalProviderId(s.provider_id))
187
+ .sort(
188
+ (a: any, b: any) =>
189
+ new Date(b.created_at || 0).getTime() -
190
+ new Date(a.created_at || 0).getTime()
191
+ )[0]
192
+
193
+ if (!paypalSession) {
194
+ throw new Error(
195
+ `no paypal session found in collection ${collection.id} for cart ${cartId}`
196
+ )
197
+ }
198
+
199
+ return {
200
+ sessionId: paypalSession.id,
201
+ sessionData: (paypalSession.data || {}) as Record<string, any>,
202
+ sessionStatus: String(paypalSession.status || "pending"),
203
+ collectionId: collection.id,
204
+ }
205
+ }
206
+
207
+
208
+ function mergeRefunds(existing: any[], incoming: any[]): any[] {
209
+ const seen = new Set<string>()
210
+ const merged: any[] = []
211
+ for (const refund of [...existing, ...incoming]) {
212
+ const id = String(refund?.id || "")
213
+ if (id && seen.has(id)) continue
214
+ if (id) seen.add(id)
215
+ merged.push(refund)
216
+ }
217
+ return merged
218
+ }
219
+
220
+ async function applyStatusToSession(
221
+ container: MedusaContainer,
222
+ resolved: ResolvedSession,
223
+ status: string,
224
+ patch: Record<string, unknown>
225
+ ): Promise<void> {
226
+ const paymentModule = container.resolve(Modules.PAYMENT) as any
227
+
228
+ if (!isTransitionAllowed(resolved.sessionStatus, status)) {
229
+ console.info(
230
+ `[PayPal] webhook: skipping disallowed transition ${resolved.sessionStatus} → ${status} for session ${resolved.sessionId}`
231
+ )
232
+ return
233
+ }
234
+
235
+ const existingPaypal = (resolved.sessionData.paypal || {}) as Record<string, any>
236
+ const existingRefunds = Array.isArray(existingPaypal.refunds)
237
+ ? existingPaypal.refunds
238
+ : []
239
+ const incomingRefunds = Array.isArray(patch.refunds)
240
+ ? (patch.refunds as any[])
241
+ : null
242
+ const nextRefunds = incomingRefunds
243
+ ? mergeRefunds(existingRefunds, incomingRefunds)
244
+ : existingRefunds
245
+
246
+ await paymentModule.updatePaymentSession({
247
+ id: resolved.sessionId,
248
+ status,
249
+ data: {
250
+ ...resolved.sessionData,
251
+ paypal: {
252
+ ...existingPaypal,
253
+ ...patch,
254
+ refunds: nextRefunds,
255
+ },
256
+ },
257
+ })
258
+ }
259
+
260
+
261
+ export interface ProcessResult {
262
+ orderId: string | null
263
+ captureId: string | null
264
+ refundId: string | null
265
+ cartId: string | null
266
+ sessionUpdated: boolean
267
+ }
268
+
269
+ export async function processPayPalWebhookEvent(
270
+ container: MedusaContainer,
271
+ input: {
272
+ eventType: string
273
+ payload: Record<string, any>
274
+ }
275
+ ): Promise<ProcessResult> {
276
+ const resource = normalizeResource(input.payload)
277
+ const { orderId, captureId, refundId, cartId: rawCartId } = extractIdentifiers(
278
+ resource,
279
+ input.eventType
280
+ )
281
+
282
+ const refundReason =
283
+ String(
284
+ resource?.note_to_payer || resource?.reason || resource?.seller_note || ""
285
+ ).trim() || undefined
286
+ const refundReasonCode =
287
+ String(resource?.reason_code || resource?.reasonCode || "").trim() ||
288
+ undefined
289
+
290
+ const targetStatus = EVENT_STATUS_MAP[input.eventType]
291
+ if (!targetStatus) {
292
+ return { orderId, captureId, refundId, cartId: rawCartId, sessionUpdated: false }
293
+ }
294
+
295
+ let cartId = rawCartId
296
+
297
+ if (!cartId) {
298
+ try {
299
+ const paymentModule = container.resolve(Modules.PAYMENT) as any
300
+ const allSessions = await paymentModule.listPaymentSessions({
301
+ provider_id: ["pp_paypal_paypal", "pp_paypal_card_paypal_card"],
302
+ })
303
+ const matchedSession = (allSessions || []).find((s: any) => {
304
+ const pp = ((s.data || {}) as Record<string, any>).paypal || {}
305
+ if (orderId && pp.order_id === orderId) return true
306
+ if (captureId && pp.capture_id === captureId) return true
307
+ return false
308
+ })
309
+ if (matchedSession?.payment_collection_id) {
310
+ const colls = await paymentModule.listPaymentCollections(
311
+ { id: [matchedSession.payment_collection_id] },
312
+ { take: 1 }
313
+ )
314
+ cartId = String(colls?.[0]?.cart_id || "").trim() || null
315
+ }
316
+ } catch (e: any) {
317
+ console.warn(
318
+ `[PayPal] webhook: cartId fallback lookup failed for ${input.eventType}:`,
319
+ e?.message
320
+ )
321
+ }
322
+ }
323
+
324
+ let sessionUpdated = false
325
+
326
+ if (cartId) {
327
+ const resolved = await findPayPalSession(container, cartId)
328
+ if (resolved) {
329
+ const refundEntry = refundId
330
+ ? [
331
+ {
332
+ id: refundId,
333
+ status: resource?.status,
334
+ reason: refundReason,
335
+ reason_code: refundReasonCode,
336
+ amount: resource?.amount,
337
+ raw: resource,
338
+ },
339
+ ]
340
+ : null
341
+
342
+ await applyStatusToSession(container, resolved, targetStatus, {
343
+ order_id: orderId,
344
+ capture_id: captureId ?? resolved.sessionData.paypal?.capture_id ?? undefined,
345
+ refund_id: refundId,
346
+ refund_status: refundId ? resource?.status : undefined,
347
+ refund_reason: refundReason,
348
+ refund_reason_code: refundReasonCode,
349
+ ...(refundEntry ? { refunds: refundEntry } : {}),
350
+ webhook_event_type: input.eventType,
351
+ last_webhook_at: new Date().toISOString(),
352
+ })
353
+ sessionUpdated = true
354
+ }
355
+ } else {
356
+ console.warn(
357
+ `[PayPal] webhook: could not resolve cartId for event ${input.eventType}`,
358
+ { orderId, captureId, refundId }
359
+ )
360
+ }
361
+
362
+ return { orderId, captureId, refundId, cartId, sessionUpdated }
363
+ }
@@ -0,0 +1,8 @@
1
+ import { ModuleProvider, Modules } from "@medusajs/framework/utils"
2
+ import { PayPalPaymentProvider } from "../../modules/paypal/payment-provider/service"
3
+
4
+ export default ModuleProvider(Modules.PAYMENT, {
5
+ services: [PayPalPaymentProvider],
6
+ })
7
+
8
+ export { PayPalPaymentProvider }
@@ -0,0 +1,8 @@
1
+ import { ModuleProvider, Modules } from "@medusajs/framework/utils"
2
+ import { PayPalAdvancedCardProvider } from "../../modules/paypal/payment-provider/card-service"
3
+
4
+ export default ModuleProvider(Modules.PAYMENT, {
5
+ services: [PayPalAdvancedCardProvider],
6
+ })
7
+
8
+ export { PayPalAdvancedCardProvider }