@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,381 @@
1
+ import React, {useEffect, useMemo, useRef, useState} from "react"
2
+ import PayPalTabs from "../_components/Tabs"
3
+
4
+ type DisabledCardBrand =
5
+ | "visa"
6
+ | "mastercard"
7
+ | "amex"
8
+ | "discover"
9
+ | "diners"
10
+ | "jcb"
11
+ | "unionpay"
12
+
13
+ type ThreeDSContingency = "sli" | "when_required" | "always"
14
+
15
+ type AdvancedCardPaymentsForm = {
16
+ enabled: boolean
17
+ title: string
18
+ disabledCards: DisabledCardBrand[]
19
+ threeDS: ThreeDSContingency
20
+ cardSaveEnabled: boolean
21
+ }
22
+
23
+ const DEFAULT_FORM: AdvancedCardPaymentsForm = {
24
+ enabled: true,
25
+ title: "Credit or Debit Card",
26
+ disabledCards: [],
27
+ threeDS: "when_required",
28
+ cardSaveEnabled: false,
29
+ }
30
+
31
+ function mergeWithDefaults(saved?: Partial<AdvancedCardPaymentsForm> | null) {
32
+ if (!saved) return { ...DEFAULT_FORM }
33
+ const entries = Object.entries(saved).filter(([, value]) => value !== undefined)
34
+ return {
35
+ ...DEFAULT_FORM,
36
+ ...(Object.fromEntries(entries) as Partial<AdvancedCardPaymentsForm>),
37
+ }
38
+ }
39
+
40
+ const CARD_BRANDS: { value: DisabledCardBrand; label: string }[] = [
41
+ { value: "visa", label: "Visa" },
42
+ { value: "mastercard", label: "Mastercard" },
43
+ { value: "amex", label: "American Express" },
44
+ { value: "discover", label: "Discover" },
45
+ { value: "diners", label: "Diners Club" },
46
+ { value: "jcb", label: "JCB" },
47
+ { value: "unionpay", label: "UnionPay" },
48
+ ]
49
+
50
+ const THREE_DS_OPTIONS: { value: ThreeDSContingency; label: string; hint?: string }[] = [
51
+ {
52
+ value: "when_required",
53
+ label: "3D Secure when required",
54
+ hint: "Triggers 3DS only when the card / issuer requires it.",
55
+ },
56
+ {
57
+ value: "sli",
58
+ label: "3D Secure (SCA) / liability shift (recommended)",
59
+ hint: "Attempts to optimize for liability shift while remaining compliant.",
60
+ },
61
+ {
62
+ value: "always",
63
+ label: "Always request 3D Secure",
64
+ hint: "Forces 3DS challenge whenever possible (may reduce conversion).",
65
+ },
66
+ ]
67
+
68
+ function cx(...parts: Array<string | false | undefined | null>) {
69
+ return parts.filter(Boolean).join(" ")
70
+ }
71
+
72
+ function Pill({
73
+ children,
74
+ onRemove,
75
+ }: {
76
+ children: React.ReactNode
77
+ onRemove?: () => void
78
+ }) {
79
+ return (
80
+ <span className="inline-flex items-center gap-1 rounded-md border border-ui-border-base bg-ui-bg-base px-2 py-1 text-sm text-ui-fg-base">
81
+ {children}
82
+ {onRemove ? (
83
+ <button
84
+ type="button"
85
+ onClick={onRemove}
86
+ className="ml-1 rounded px-1 text-ui-fg-subtle hover:text-ui-fg-base"
87
+ aria-label="Remove"
88
+ >
89
+ ×
90
+ </button>
91
+ ) : null}
92
+ </span>
93
+ )
94
+ }
95
+
96
+ function SectionCard({
97
+ title,
98
+ description,
99
+ right,
100
+ children,
101
+ }: {
102
+ title: string
103
+ description?: string
104
+ right?: React.ReactNode
105
+ children: React.ReactNode
106
+ }) {
107
+ return (
108
+ <div className="rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm">
109
+ <div className="flex items-start justify-between gap-4 border-b border-ui-border-base p-4">
110
+ <div>
111
+ <div className="text-base font-semibold text-ui-fg-base">{title}</div>
112
+ {description ? <div className="mt-1 text-sm text-ui-fg-subtle">{description}</div> : null}
113
+ </div>
114
+ {right}
115
+ </div>
116
+ <div className="p-4">{children}</div>
117
+ </div>
118
+ )
119
+ }
120
+
121
+ function FieldRow({
122
+ label,
123
+ hint,
124
+ children,
125
+ }: {
126
+ label: string
127
+ hint?: React.ReactNode
128
+ children: React.ReactNode
129
+ }) {
130
+ return (
131
+ <div className="grid grid-cols-12 items-start gap-4 py-3">
132
+ <div className="col-span-12 md:col-span-4">
133
+ <div className="text-sm font-medium text-ui-fg-base">{label}</div>
134
+ {hint ? <div className="mt-1 text-xs text-ui-fg-subtle">{hint}</div> : null}
135
+ </div>
136
+ <div className="col-span-12 md:col-span-8">{children}</div>
137
+ </div>
138
+ )
139
+ }
140
+
141
+ export default function AdvancedCardPaymentsTab() {
142
+ const [form, setForm] = useState<AdvancedCardPaymentsForm>(() => ({ ...DEFAULT_FORM }))
143
+ const [loading, setLoading] = useState(false)
144
+ const [saving, setSaving] = useState(false)
145
+
146
+ const [toast, setToast] = useState<{ type: "success" | "error"; message: string } | null>(null)
147
+ const didInit = useRef(false)
148
+
149
+ useEffect(() => {
150
+ if (didInit.current) return
151
+ didInit.current = true
152
+
153
+ ;(async () => {
154
+ try {
155
+ setLoading(true)
156
+ const r = await fetch("/admin/paypal/settings", {
157
+ credentials: "include",
158
+ headers: { "Accept": "application/json" },
159
+ })
160
+ if (!r.ok) return
161
+ const json = await r.json()
162
+ const payload = (json?.data ?? json) as any
163
+ const saved = payload?.advanced_card_payments
164
+ if (saved && typeof saved === "object") {
165
+ setForm(mergeWithDefaults(saved))
166
+ }
167
+ } finally {
168
+ setLoading(false)
169
+ }
170
+ })()
171
+ }, [])
172
+
173
+ async function onSave() {
174
+ try {
175
+ setSaving(true)
176
+ const r = await fetch("/admin/paypal/settings", {
177
+ method: "POST",
178
+ credentials: "include",
179
+ headers: {
180
+ "Content-Type": "application/json",
181
+ "Accept": "application/json",
182
+ },
183
+ body: JSON.stringify({ advanced_card_payments: form }),
184
+ })
185
+ if (!r.ok) {
186
+ const t = await r.text()
187
+ setToast({ type: "error", message: "Failed to save settings. " + t })
188
+ window.setTimeout(() => setToast(null), 3500)
189
+ return
190
+ }
191
+ const json = await r.json().catch(() => null)
192
+ const payload = (json?.data ?? json) as any
193
+ const saved = payload?.advanced_card_payments
194
+ if (saved && typeof saved === "object") {
195
+ setForm(mergeWithDefaults(saved))
196
+ }
197
+ setToast({ type: "success", message: "Settings saved" })
198
+ window.setTimeout(() => setToast(null), 2500)
199
+ } finally {
200
+ setSaving(false)
201
+ }
202
+ }
203
+
204
+
205
+ const disabledSet = useMemo(() => new Set(form.disabledCards), [form.disabledCards])
206
+
207
+ function toggleDisabledCard(value: DisabledCardBrand) {
208
+ setForm((prev) => {
209
+ const exists = prev.disabledCards.includes(value)
210
+ return {
211
+ ...prev,
212
+ disabledCards: exists
213
+ ? prev.disabledCards.filter((v) => v !== value)
214
+ : [...prev.disabledCards, value],
215
+ }
216
+ })
217
+ }
218
+
219
+ function removeDisabledCard(value: DisabledCardBrand) {
220
+ setForm((prev) => ({
221
+ ...prev,
222
+ disabledCards: prev.disabledCards.filter((v) => v !== value),
223
+ }))
224
+ }
225
+
226
+ return (
227
+ <div className="p-6">
228
+ <div className="flex flex-col gap-6">
229
+ <div className="flex items-start justify-between gap-4">
230
+ <div>
231
+ <h1 className="text-xl font-semibold text-ui-fg-base">PayPal Gateway By Easy Payment</h1>
232
+
233
+ </div>
234
+
235
+
236
+ </div>
237
+
238
+ <PayPalTabs />
239
+
240
+
241
+ {toast ? (
242
+ <div
243
+ className="fixed right-6 top-6 z-50 rounded-md border border-ui-border-base bg-ui-bg-base px-4 py-3 text-sm shadow-lg"
244
+ role="status"
245
+ aria-live="polite"
246
+ >
247
+ <span className={toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error"}>
248
+ {toast.message}
249
+ </span>
250
+ </div>
251
+ ) : null}
252
+ <SectionCard
253
+ title="Advanced Card Payments"
254
+ description="Control card checkout settings, 3D Secure behavior, and card saving."
255
+
256
+
257
+ right={(
258
+ <div className="flex items-center gap-3">
259
+ <button
260
+ type="button"
261
+ onClick={onSave}
262
+ disabled={saving || loading}
263
+ className="rounded-md bg-ui-button-neutral px-4 py-2 text-sm font-medium text-ui-fg-on-color shadow-sm hover:opacity-90 disabled:opacity-60"
264
+ >
265
+ {saving ? "Saving..." : "Save settings"}
266
+ </button>
267
+ {loading ? <span className="text-sm text-ui-fg-subtle">Loading…</span> : null}
268
+ </div>
269
+ )}
270
+ >
271
+ <div className="divide-y divide-ui-border-base">
272
+ <FieldRow label="Enable/Disable">
273
+ <label className="inline-flex items-center gap-2">
274
+ <input
275
+ type="checkbox"
276
+ checked={form.enabled}
277
+ onChange={(e) => setForm((p) => ({ ...p, enabled: e.target.checked }))}
278
+ className="h-4 w-4 rounded border-ui-border-base"
279
+ />
280
+ <span className="text-sm text-ui-fg-base">Enable Advanced Credit/Debit Card</span>
281
+ </label>
282
+ </FieldRow>
283
+
284
+ <FieldRow label="Title">
285
+ <input
286
+ value={form.title}
287
+ onChange={(e) => setForm((p) => ({ ...p, title: e.target.value }))}
288
+ className="w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive"
289
+ placeholder="Credit or Debit Card"
290
+ />
291
+ </FieldRow>
292
+
293
+ <FieldRow
294
+ label="Disable specific credit cards"
295
+ hint="Select card brands to hide from the card form."
296
+ >
297
+ <div className="flex flex-col gap-2">
298
+ <div className="flex flex-wrap gap-2">
299
+ {form.disabledCards.length ? (
300
+ form.disabledCards.map((v) => {
301
+ const label = CARD_BRANDS.find((b) => b.value === v)?.label ?? v
302
+ return (
303
+ <Pill key={v} onRemove={() => removeDisabledCard(v)}>
304
+ {label}
305
+ </Pill>
306
+ )
307
+ })
308
+ ) : (
309
+ <span className="text-sm text-ui-fg-subtle">No card brands disabled.</span>
310
+ )}
311
+ </div>
312
+
313
+ <div className="rounded-md border border-ui-border-base p-3">
314
+ <div className="grid gap-2 md:grid-cols-2">
315
+ {CARD_BRANDS.map((b) => {
316
+ const checked = disabledSet.has(b.value)
317
+ return (
318
+ <label
319
+ key={b.value}
320
+ className={cx(
321
+ "flex items-center gap-2 rounded-md p-2",
322
+ "hover:bg-ui-bg-subtle"
323
+ )}
324
+ >
325
+ <input
326
+ type="checkbox"
327
+ checked={checked}
328
+ onChange={() => toggleDisabledCard(b.value)}
329
+ className="h-4 w-4 rounded border-ui-border-base"
330
+ />
331
+ <span className="text-sm text-ui-fg-base">{b.label}</span>
332
+ </label>
333
+ )
334
+ })}
335
+ </div>
336
+ </div>
337
+ </div>
338
+ </FieldRow>
339
+
340
+ <FieldRow
341
+ label="Contingency for 3D Secure"
342
+ hint="Choose when 3D Secure should be triggered during card payments."
343
+ >
344
+ <div className="flex flex-col gap-2">
345
+ <select
346
+ value={form.threeDS}
347
+ onChange={(e) => setForm((p) => ({ ...p, threeDS: e.target.value as ThreeDSContingency }))}
348
+ className="w-full rounded-md border border-ui-border-base bg-ui-bg-base px-3 py-2 text-sm text-ui-fg-base outline-none focus:ring-2 focus:ring-ui-border-interactive"
349
+ >
350
+ {THREE_DS_OPTIONS.map((o) => (
351
+ <option key={o.value} value={o.value}>
352
+ {o.label}
353
+ </option>
354
+ ))}
355
+ </select>
356
+
357
+ {THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)?.hint ? (
358
+ <div className="text-xs text-ui-fg-subtle">
359
+ {THREE_DS_OPTIONS.find((o) => o.value === form.threeDS)?.hint}
360
+ </div>
361
+ ) : null}
362
+ </div>
363
+ </FieldRow>
364
+
365
+ <FieldRow label="Card Save Enabled" hint="Allow customers to save a card at checkout for future use.">
366
+ <label className="inline-flex items-center gap-2">
367
+ <input
368
+ type="checkbox"
369
+ checked={form.cardSaveEnabled}
370
+ onChange={(e) => setForm((p) => ({ ...p, cardSaveEnabled: e.target.checked }))}
371
+ className="h-4 w-4 rounded border-ui-border-base"
372
+ />
373
+ <span className="text-sm text-ui-fg-base">Enable card saving at checkout</span>
374
+ </label>
375
+ </FieldRow>
376
+ </div>
377
+ </SectionCard>
378
+ </div>
379
+ </div>
380
+ )
381
+ }
@@ -0,0 +1,5 @@
1
+ import { Navigate } from "react-router-dom"
2
+
3
+ export default function PayPalApplePayPage() {
4
+ return <Navigate to="/settings/paypal/connection" replace />
5
+ }
@@ -0,0 +1,131 @@
1
+ import React, { useCallback, useEffect, useState } from "react"
2
+ import PayPalTabs from "../_components/Tabs"
3
+
4
+ type AuditLog = {
5
+ id: string
6
+ event_type: string
7
+ metadata?: Record<string, unknown>
8
+ created_at?: string | null
9
+ }
10
+
11
+ function formatDate(value?: string | null) {
12
+ if (!value) {
13
+ return ""
14
+ }
15
+ const parsed = new Date(value)
16
+ if (Number.isNaN(parsed.getTime())) {
17
+ return value
18
+ }
19
+ return parsed.toLocaleString()
20
+ }
21
+
22
+ export default function PayPalAuditLogsPage() {
23
+ const [logs, setLogs] = useState<AuditLog[]>([])
24
+ const [loading, setLoading] = useState(false)
25
+ const [error, setError] = useState<string | null>(null)
26
+
27
+ const fetchLogs = useCallback(async () => {
28
+ try {
29
+ setLoading(true)
30
+ setError(null)
31
+ const response = await fetch("/admin/paypal/audit-logs?limit=50", {
32
+ credentials: "include",
33
+ headers: {
34
+ Accept: "application/json",
35
+ },
36
+ })
37
+
38
+ if (!response.ok) {
39
+ const message = await response.text().catch(() => "")
40
+ throw new Error(message || "Failed to load audit logs.")
41
+ }
42
+
43
+ const data = await response.json().catch(() => ({}))
44
+ setLogs((data?.logs as AuditLog[]) || [])
45
+ } catch (fetchError: any) {
46
+ setError(fetchError?.message || "Failed to load audit logs.")
47
+ setLogs([])
48
+ } finally {
49
+ setLoading(false)
50
+ }
51
+ }, [])
52
+
53
+ useEffect(() => {
54
+ fetchLogs()
55
+ }, [fetchLogs])
56
+
57
+ return (
58
+ <div className="p-6">
59
+ <div className="flex flex-col gap-6">
60
+ <div>
61
+ <h1 className="text-xl font-semibold text-ui-fg-base">PayPal Audit Logs</h1>
62
+ <p className="mt-1 text-sm text-ui-fg-subtle">
63
+ Track administrative changes and credential events for PayPal configuration.
64
+ </p>
65
+ </div>
66
+
67
+ <PayPalTabs />
68
+
69
+ <div className="rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm">
70
+ <div className="border-b border-ui-border-base p-4">
71
+ <div className="flex items-center justify-between gap-4">
72
+ <div className="text-base font-semibold text-ui-fg-base">Latest events</div>
73
+ <button
74
+ type="button"
75
+ onClick={fetchLogs}
76
+ className="rounded-md border border-ui-border-base px-3 py-2 text-sm text-ui-fg-base"
77
+ disabled={loading}
78
+ >
79
+ {loading ? "Refreshing..." : "Refresh"}
80
+ </button>
81
+ </div>
82
+ </div>
83
+ <div className="p-4">
84
+ {error ? (
85
+ <div className="rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-600">
86
+ {error}
87
+ </div>
88
+ ) : null}
89
+
90
+ {!error && logs.length === 0 ? (
91
+ <div className="text-sm text-ui-fg-subtle">
92
+ {loading ? "Loading audit logs..." : "No audit log entries found yet."}
93
+ </div>
94
+ ) : null}
95
+
96
+ {logs.length > 0 ? (
97
+ <div className="overflow-x-auto">
98
+ <table className="min-w-full text-left text-sm">
99
+ <thead className="text-ui-fg-muted">
100
+ <tr>
101
+ <th className="pb-2 pr-4 font-medium">Timestamp</th>
102
+ <th className="pb-2 pr-4 font-medium">Event</th>
103
+ <th className="pb-2 font-medium">Details</th>
104
+ </tr>
105
+ </thead>
106
+ <tbody>
107
+ {logs.map((entry) => (
108
+ <tr key={entry.id} className="border-t border-ui-border-base">
109
+ <td className="py-3 pr-4 text-ui-fg-base">
110
+ {formatDate(entry.created_at) || "—"}
111
+ </td>
112
+ <td className="py-3 pr-4 text-ui-fg-base">
113
+ {entry.event_type || "—"}
114
+ </td>
115
+ <td className="py-3 text-ui-fg-subtle">
116
+ <pre className="whitespace-pre-wrap rounded-md bg-ui-bg-subtle p-2 text-xs text-ui-fg-subtle">
117
+ {JSON.stringify(entry.metadata || {}, null, 2)}
118
+ </pre>
119
+ </td>
120
+ </tr>
121
+ ))}
122
+ </tbody>
123
+ </table>
124
+ </div>
125
+ ) : null}
126
+ </div>
127
+ </div>
128
+ </div>
129
+ </div>
130
+ )
131
+ }