@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.
- package/.medusa/server/src/admin/index.js +1267 -0
- package/.medusa/server/src/admin/index.mjs +1268 -0
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts +3 -0
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -0
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js +18 -0
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js.map +1 -0
- package/.medusa/server/src/api/admin/paypal/disconnect/route.d.ts +3 -0
- package/.medusa/server/src/api/admin/paypal/disconnect/route.d.ts.map +1 -0
- package/.medusa/server/src/api/admin/paypal/disconnect/route.js +9 -0
- package/.medusa/server/src/api/admin/paypal/disconnect/route.js.map +1 -0
- package/.medusa/server/src/api/admin/paypal/environment/route.d.ts +4 -0
- package/.medusa/server/src/api/admin/paypal/environment/route.d.ts.map +1 -0
- package/.medusa/server/src/api/admin/paypal/environment/route.js +23 -0
- package/.medusa/server/src/api/admin/paypal/environment/route.js.map +1 -0
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts +4 -0
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts.map +1 -0
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js +31 -0
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js.map +1 -0
- package/.medusa/server/src/api/admin/paypal/onboarding-link/route.d.ts +4 -0
- package/.medusa/server/src/api/admin/paypal/onboarding-link/route.d.ts.map +1 -0
- package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js +35 -0
- package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js.map +1 -0
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.d.ts +3 -0
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.d.ts.map +1 -0
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js +19 -0
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js.map +1 -0
- package/.medusa/server/src/api/admin/paypal/save-credentials/route.d.ts +3 -0
- package/.medusa/server/src/api/admin/paypal/save-credentials/route.d.ts.map +1 -0
- package/.medusa/server/src/api/admin/paypal/save-credentials/route.js +17 -0
- package/.medusa/server/src/api/admin/paypal/save-credentials/route.js.map +1 -0
- package/.medusa/server/src/api/admin/paypal/settings/route.d.ts +4 -0
- package/.medusa/server/src/api/admin/paypal/settings/route.d.ts.map +1 -0
- package/.medusa/server/src/api/admin/paypal/settings/route.js +14 -0
- package/.medusa/server/src/api/admin/paypal/settings/route.js.map +1 -0
- package/.medusa/server/src/api/admin/paypal/status/route.d.ts +3 -0
- package/.medusa/server/src/api/admin/paypal/status/route.d.ts.map +1 -0
- package/.medusa/server/src/api/admin/paypal/status/route.js +11 -0
- package/.medusa/server/src/api/admin/paypal/status/route.js.map +1 -0
- package/.medusa/server/src/api/middlewares.d.ts +3 -0
- package/.medusa/server/src/api/middlewares.d.ts.map +1 -0
- package/.medusa/server/src/api/middlewares.js +16 -0
- package/.medusa/server/src/api/middlewares.js.map +1 -0
- package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.d.ts +3 -0
- package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -0
- package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js +43 -0
- package/.medusa/server/src/api/store/payment-collections/[id]/payment-sessions/route.js.map +1 -0
- package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts +3 -0
- package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts.map +1 -0
- package/.medusa/server/src/api/store/paypal/capture-order/route.js +204 -0
- package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -0
- package/.medusa/server/src/api/store/paypal/config/route.d.ts +3 -0
- package/.medusa/server/src/api/store/paypal/config/route.d.ts.map +1 -0
- package/.medusa/server/src/api/store/paypal/config/route.js +77 -0
- package/.medusa/server/src/api/store/paypal/config/route.js.map +1 -0
- package/.medusa/server/src/api/store/paypal/create-order/route.d.ts +3 -0
- package/.medusa/server/src/api/store/paypal/create-order/route.d.ts.map +1 -0
- package/.medusa/server/src/api/store/paypal/create-order/route.js +361 -0
- package/.medusa/server/src/api/store/paypal/create-order/route.js.map +1 -0
- package/.medusa/server/src/api/store/paypal/settings/route.d.ts +3 -0
- package/.medusa/server/src/api/store/paypal/settings/route.d.ts.map +1 -0
- package/.medusa/server/src/api/store/paypal/settings/route.js +20 -0
- package/.medusa/server/src/api/store/paypal/settings/route.js.map +1 -0
- package/.medusa/server/src/api/store/paypal/webhook/route.d.ts +3 -0
- package/.medusa/server/src/api/store/paypal/webhook/route.d.ts.map +1 -0
- package/.medusa/server/src/api/store/paypal/webhook/route.js +250 -0
- package/.medusa/server/src/api/store/paypal/webhook/route.js.map +1 -0
- package/.medusa/server/src/api/store/paypal-complete/route.d.ts +3 -0
- package/.medusa/server/src/api/store/paypal-complete/route.d.ts.map +1 -0
- package/.medusa/server/src/api/store/paypal-complete/route.js +76 -0
- package/.medusa/server/src/api/store/paypal-complete/route.js.map +1 -0
- package/.medusa/server/src/index.d.ts +2 -0
- package/.medusa/server/src/index.d.ts.map +1 -0
- package/.medusa/server/src/index.js +9 -0
- package/.medusa/server/src/index.js.map +1 -0
- package/.medusa/server/src/jobs/paypal-webhook-retry.d.ts +7 -0
- package/.medusa/server/src/jobs/paypal-webhook-retry.d.ts.map +1 -0
- package/.medusa/server/src/jobs/paypal-webhook-retry.js +132 -0
- package/.medusa/server/src/jobs/paypal-webhook-retry.js.map +1 -0
- package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.d.ts +15 -0
- package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js +67 -0
- package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js.map +1 -0
- package/.medusa/server/src/modules/paypal/index.d.ts +64 -0
- package/.medusa/server/src/modules/paypal/index.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/index.js +13 -0
- package/.medusa/server/src/modules/paypal/index.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.js +36 -0
- package/.medusa/server/src/modules/paypal/migrations/20260115120000_create_paypal_connection.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.js +25 -0
- package/.medusa/server/src/modules/paypal/migrations/20260123090000_create_paypal_settings.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.js +32 -0
- package/.medusa/server/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.js +30 -0
- package/.medusa/server/src/modules/paypal/migrations/20260401090000_create_paypal_metric.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.js +34 -0
- package/.medusa/server/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.js +28 -0
- package/.medusa/server/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.js +29 -0
- package/.medusa/server/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js +14 -0
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.js +14 -0
- package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.js +14 -0
- package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.js.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.js +20 -0
- package/.medusa/server/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.js.map +1 -0
- package/.medusa/server/src/modules/paypal/models/paypal_connection.d.ts +16 -0
- package/.medusa/server/src/modules/paypal/models/paypal_connection.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/models/paypal_connection.js +19 -0
- package/.medusa/server/src/modules/paypal/models/paypal_connection.js.map +1 -0
- package/.medusa/server/src/modules/paypal/models/paypal_metric.d.ts +7 -0
- package/.medusa/server/src/modules/paypal/models/paypal_metric.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/models/paypal_metric.js +10 -0
- package/.medusa/server/src/modules/paypal/models/paypal_metric.js.map +1 -0
- package/.medusa/server/src/modules/paypal/models/paypal_settings.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/models/paypal_settings.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/models/paypal_settings.js +9 -0
- package/.medusa/server/src/modules/paypal/models/paypal_settings.js.map +1 -0
- package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.d.ts +17 -0
- package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js +20 -0
- package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js.map +1 -0
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts +32 -0
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.js +625 -0
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.js.map +1 -0
- package/.medusa/server/src/modules/paypal/payment-provider/index.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/payment-provider/index.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/payment-provider/index.js +18 -0
- package/.medusa/server/src/modules/paypal/payment-provider/index.js.map +1 -0
- package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts +39 -0
- package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/payment-provider/service.js +869 -0
- package/.medusa/server/src/modules/paypal/payment-provider/service.js.map +1 -0
- package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.d.ts +3 -0
- package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js +74 -0
- package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js.map +1 -0
- package/.medusa/server/src/modules/paypal/service.d.ts +266 -0
- package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/service.js +1149 -0
- package/.medusa/server/src/modules/paypal/service.js.map +1 -0
- package/.medusa/server/src/modules/paypal/types/config.d.ts +12 -0
- package/.medusa/server/src/modules/paypal/types/config.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/types/config.js +24 -0
- package/.medusa/server/src/modules/paypal/types/config.js.map +1 -0
- package/.medusa/server/src/modules/paypal/utils/amounts.d.ts +3 -0
- package/.medusa/server/src/modules/paypal/utils/amounts.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/utils/amounts.js +40 -0
- package/.medusa/server/src/modules/paypal/utils/amounts.js.map +1 -0
- package/.medusa/server/src/modules/paypal/utils/currencies.d.ts +19 -0
- package/.medusa/server/src/modules/paypal/utils/currencies.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/utils/currencies.js +69 -0
- package/.medusa/server/src/modules/paypal/utils/currencies.js.map +1 -0
- package/.medusa/server/src/modules/paypal/utils/paypal-auth.d.ts +10 -0
- package/.medusa/server/src/modules/paypal/utils/paypal-auth.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/utils/paypal-auth.js +30 -0
- package/.medusa/server/src/modules/paypal/utils/paypal-auth.js.map +1 -0
- package/.medusa/server/src/modules/paypal/utils/provider-ids.d.ts +5 -0
- package/.medusa/server/src/modules/paypal/utils/provider-ids.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/utils/provider-ids.js +16 -0
- package/.medusa/server/src/modules/paypal/utils/provider-ids.js.map +1 -0
- package/.medusa/server/src/modules/paypal/webhook-processor.d.ts +29 -0
- package/.medusa/server/src/modules/paypal/webhook-processor.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/webhook-processor.js +267 -0
- package/.medusa/server/src/modules/paypal/webhook-processor.js.map +1 -0
- package/.medusa/server/src/providers/paypal/index.d.ts +5 -0
- package/.medusa/server/src/providers/paypal/index.d.ts.map +1 -0
- package/.medusa/server/src/providers/paypal/index.js +10 -0
- package/.medusa/server/src/providers/paypal/index.js.map +1 -0
- package/.medusa/server/src/providers/paypal_card/index.d.ts +5 -0
- package/.medusa/server/src/providers/paypal_card/index.d.ts.map +1 -0
- package/.medusa/server/src/providers/paypal_card/index.js +10 -0
- package/.medusa/server/src/providers/paypal_card/index.js.map +1 -0
- package/.medusa/server/src/subscribers/paypal-order-invoice.d.ts +6 -0
- package/.medusa/server/src/subscribers/paypal-order-invoice.d.ts.map +1 -0
- package/.medusa/server/src/subscribers/paypal-order-invoice.js +124 -0
- package/.medusa/server/src/subscribers/paypal-order-invoice.js.map +1 -0
- package/LICENSE +21 -0
- package/README.md +172 -0
- package/package.json +80 -0
- package/src/admin/index.ts +7 -0
- package/src/admin/routes/settings/paypal/_components/Tabs.tsx +48 -0
- package/src/admin/routes/settings/paypal/_components/Toast.tsx +51 -0
- package/src/admin/routes/settings/paypal/additional-settings/page.tsx +199 -0
- package/src/admin/routes/settings/paypal/advanced-card-payments/page.tsx +183 -0
- package/src/admin/routes/settings/paypal/apple-pay/page.tsx +5 -0
- package/src/admin/routes/settings/paypal/connection/page.tsx +699 -0
- package/src/admin/routes/settings/paypal/google-pay/page.tsx +5 -0
- package/src/admin/routes/settings/paypal/page.tsx +13 -0
- package/src/admin/routes/settings/paypal/pay-later-messaging/page.tsx +5 -0
- package/src/admin/routes/settings/paypal/paypal-settings/page.tsx +351 -0
- package/src/api/admin/payment-collections/[id]/payment-sessions/route.ts +24 -0
- package/src/api/admin/paypal/disconnect/route.ts +8 -0
- package/src/api/admin/paypal/environment/route.ts +25 -0
- package/src/api/admin/paypal/onboard-complete/route.ts +34 -0
- package/src/api/admin/paypal/onboarding-link/route.ts +45 -0
- package/src/api/admin/paypal/onboarding-status/route.ts +17 -0
- package/src/api/admin/paypal/save-credentials/route.ts +22 -0
- package/src/api/admin/paypal/settings/route.ts +14 -0
- package/src/api/admin/paypal/status/route.ts +12 -0
- package/src/api/middlewares.ts +14 -0
- package/src/api/store/payment-collections/[id]/payment-sessions/route.ts +56 -0
- package/src/api/store/paypal/capture-order/route.ts +265 -0
- package/src/api/store/paypal/config/route.ts +100 -0
- package/src/api/store/paypal/create-order/route.ts +449 -0
- package/src/api/store/paypal/settings/route.ts +19 -0
- package/src/api/store/paypal/webhook/route.ts +325 -0
- package/src/api/store/paypal-complete/route.ts +95 -0
- package/src/index.ts +1 -0
- package/src/jobs/paypal-webhook-retry.ts +149 -0
- package/src/modules/paypal/clients/paypal-seller.client.ts +62 -0
- package/src/modules/paypal/index.ts +8 -0
- package/src/modules/paypal/migrations/20260115120000_create_paypal_connection.ts +33 -0
- package/src/modules/paypal/migrations/20260123090000_create_paypal_settings.ts +22 -0
- package/src/modules/paypal/migrations/20260201090000_create_paypal_webhook_event.ts +29 -0
- package/src/modules/paypal/migrations/20260401090000_create_paypal_metric.ts +27 -0
- package/src/modules/paypal/migrations/20260701090000_add_paypal_webhook_event_processing.ts +31 -0
- package/src/modules/paypal/migrations/20261101090000_remove_paypal_reconciliation_status.ts +25 -0
- package/src/modules/paypal/migrations/20261201090000_remove_paypal_audit_log.ts +26 -0
- package/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.ts +11 -0
- package/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.ts +11 -0
- package/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.ts +11 -0
- package/src/modules/paypal/migrations/20270201000000_add_webhook_dead_letter.ts +17 -0
- package/src/modules/paypal/models/paypal_connection.ts +23 -0
- package/src/modules/paypal/models/paypal_metric.ts +9 -0
- package/src/modules/paypal/models/paypal_settings.ts +8 -0
- package/src/modules/paypal/models/paypal_webhook_event.ts +19 -0
- package/src/modules/paypal/payment-provider/README.md +22 -0
- package/src/modules/paypal/payment-provider/card-service.ts +767 -0
- package/src/modules/paypal/payment-provider/index.ts +15 -0
- package/src/modules/paypal/payment-provider/service.ts +1039 -0
- package/src/modules/paypal/payment-provider/webhook-utils.ts +88 -0
- package/src/modules/paypal/service.ts +1416 -0
- package/src/modules/paypal/types/config.ts +33 -0
- package/src/modules/paypal/utils/amounts.ts +41 -0
- package/src/modules/paypal/utils/currencies.ts +84 -0
- package/src/modules/paypal/utils/paypal-auth.ts +31 -0
- package/src/modules/paypal/utils/provider-ids.ts +15 -0
- package/src/modules/paypal/webhook-processor.ts +363 -0
- package/src/providers/paypal/index.ts +8 -0
- package/src/providers/paypal_card/index.ts +8 -0
- package/src/subscribers/paypal-order-invoice.ts +171 -0
- package/tsconfig.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# PayPal for Medusa
|
|
2
|
+
|
|
3
|
+
**Accept PayPal and advanced credit card payments in your Medusa v2 store — built by an official PayPal Partner.**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@easypayment/medusa-paypal)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://medusajs.com)
|
|
8
|
+
[](https://developer.paypal.com)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 📋 Table of Contents
|
|
13
|
+
|
|
14
|
+
- [📦 What's included](#-whats-included)
|
|
15
|
+
- [✅ Requirements](#-requirements)
|
|
16
|
+
- [🚀 Installation](#-installation)
|
|
17
|
+
- [⚙️ Setup](#%EF%B8%8F-setup)
|
|
18
|
+
- [Step 1 — Configure medusa-config.ts](#step-1--configure-medusa-configts)
|
|
19
|
+
- [Step 2 — Run database migrations](#step-2--run-database-migrations)
|
|
20
|
+
- [Step 3 — Connect your PayPal account](#step-3--connect-your-paypal-account)
|
|
21
|
+
- [Step 4 — Enable providers in your region](#step-4--enable-providers-in-your-region)
|
|
22
|
+
- [Step 5 — Configure settings](#step-5--configure-settings-optional)
|
|
23
|
+
- [Step 6 — Add PayPal to your storefront](#step-6--add-paypal-to-your-storefront)
|
|
24
|
+
- [📄 License](#-license)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 📦 What's included
|
|
29
|
+
|
|
30
|
+
| Feature | Details |
|
|
31
|
+
|---|---|
|
|
32
|
+
| 🔵 **PayPal Smart Buttons** | One-click wallet checkout via PayPal |
|
|
33
|
+
| 💳 **Advanced Card Fields** | Hosted, PCI-compliant advanced credit card inputs |
|
|
34
|
+
| 🛠 **Admin Dashboard** | Connect, configure, and switch environments from Medusa Admin |
|
|
35
|
+
| 🌍 **Sandbox & Live** | Toggle between test and production without restarting |
|
|
36
|
+
| ⚡ **Webhooks** | Automatically registered and verified with built-in retry support |
|
|
37
|
+
| 🔐 **3D Secure** | Configurable SCA/3DS per transaction |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## ✅ Requirements
|
|
42
|
+
|
|
43
|
+
- Medusa **v2**
|
|
44
|
+
- Node.js **18+**
|
|
45
|
+
- PostgreSQL
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 🚀 Installation
|
|
50
|
+
|
|
51
|
+
**In your Medusa backend directory**, run:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install @easypayment/medusa-paypal
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## ⚙️ Setup
|
|
60
|
+
|
|
61
|
+
### Step 1 — Configure `medusa-config.ts`
|
|
62
|
+
|
|
63
|
+
Add the plugin and both payment providers to your existing `medusa-config.ts`:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { loadEnv, defineConfig } from "@medusajs/framework/utils"
|
|
67
|
+
|
|
68
|
+
loadEnv(process.env.NODE_ENV || "development", process.cwd())
|
|
69
|
+
|
|
70
|
+
export default defineConfig({
|
|
71
|
+
projectConfig: {
|
|
72
|
+
databaseUrl: process.env.DATABASE_URL,
|
|
73
|
+
http: {
|
|
74
|
+
storeCors: process.env.STORE_CORS!,
|
|
75
|
+
adminCors: process.env.ADMIN_CORS!,
|
|
76
|
+
authCors: process.env.AUTH_CORS!,
|
|
77
|
+
jwtSecret: process.env.JWT_SECRET || "supersecret",
|
|
78
|
+
cookieSecret: process.env.COOKIE_SECRET || "supersecret",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
plugins: [
|
|
83
|
+
{
|
|
84
|
+
resolve: "@easypayment/medusa-paypal",
|
|
85
|
+
options: {},
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
|
|
89
|
+
modules: [
|
|
90
|
+
{
|
|
91
|
+
resolve: "@medusajs/medusa/payment",
|
|
92
|
+
options: {
|
|
93
|
+
providers: [
|
|
94
|
+
{
|
|
95
|
+
// PayPal Smart Buttons (wallet checkout)
|
|
96
|
+
resolve: "@easypayment/medusa-paypal/providers/paypal",
|
|
97
|
+
id: "paypal",
|
|
98
|
+
options: {},
|
|
99
|
+
dependencies: ["paypal_onboarding"],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
// Advanced Card Fields (hosted card inputs)
|
|
103
|
+
resolve: "@easypayment/medusa-paypal/providers/paypal_card",
|
|
104
|
+
id: "paypal_card",
|
|
105
|
+
options: {},
|
|
106
|
+
dependencies: ["paypal_onboarding"],
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
### Step 2 — Run database migrations
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npx medusa db:migrate
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### Step 3 — Connect your PayPal account
|
|
126
|
+
|
|
127
|
+
1. Start your Medusa server
|
|
128
|
+
2. Open **Medusa Admin → Settings → PayPal → PayPal Connection**
|
|
129
|
+
3. Choose **Sandbox** (testing) or **Live** (production)
|
|
130
|
+
4. Click **Connect to PayPal** and complete the onboarding flow
|
|
131
|
+
|
|
132
|
+
Credentials are saved automatically. Prefer manual setup? Click **Insert credentials manually** and paste your Client ID and Secret from [developer.paypal.com](https://developer.paypal.com/dashboard/).
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### Step 4 — Enable providers in your region
|
|
137
|
+
|
|
138
|
+
1. Go to **Medusa Admin → Settings → Regions → [your region]**
|
|
139
|
+
2. Under **Payment Providers**, enable:
|
|
140
|
+
|
|
141
|
+
| Provider ID | Description |
|
|
142
|
+
|---|---|
|
|
143
|
+
| `pp_paypal_paypal` | PayPal Smart Buttons (wallet) |
|
|
144
|
+
| `pp_paypal_card_paypal_card` | Advanced Card Fields (card) |
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### Step 5 — Configure settings *(optional)*
|
|
149
|
+
|
|
150
|
+
All settings live in **Medusa Admin → Settings → PayPal** and apply immediately — no server restart needed.
|
|
151
|
+
|
|
152
|
+
| Tab | What you can configure |
|
|
153
|
+
|---|---|
|
|
154
|
+
| **PayPal Settings** | Enable/disable, button color, shape, label |
|
|
155
|
+
| **Advanced Card Payments** | Enable/disable, 3D Secure mode |
|
|
156
|
+
| **Additional Settings** | Payment action (capture / authorize), brand name, invoice prefix |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### Step 6 — Add PayPal to your storefront
|
|
161
|
+
|
|
162
|
+
The checkout UI is shipped as a separate package — **install it inside your storefront project**, not in this backend.
|
|
163
|
+
|
|
164
|
+
📦 **[@easypayment/medusa-paypal-ui](https://www.npmjs.com/package/@easypayment/medusa-paypal-ui)** — React components, hooks, and a drop-in payment step adapter for Next.js App Router storefronts.
|
|
165
|
+
|
|
166
|
+
See the [storefront integration & testing guide →](https://www.npmjs.com/package/@easypayment/medusa-paypal-ui)
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 📄 License
|
|
171
|
+
|
|
172
|
+
MIT © [Easy Payment](https://www.npmjs.com/package/@easypayment/medusa-paypal)
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@easypayment/medusa-payment-paypal",
|
|
3
|
+
"version": "0.7.4",
|
|
4
|
+
"description": "PayPal integration for Medusa v2",
|
|
5
|
+
"author": "EasyPayment Plugins",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./.medusa/server/src/index.js",
|
|
8
|
+
"types": "./.medusa/server/src/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
".medusa/server",
|
|
11
|
+
"src",
|
|
12
|
+
"scripts",
|
|
13
|
+
"package.json",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
"tsconfig.json"
|
|
17
|
+
],
|
|
18
|
+
"exports": {
|
|
19
|
+
"./package.json": "./package.json",
|
|
20
|
+
"./admin": "./.medusa/server/src/admin/index.mjs",
|
|
21
|
+
"./workflows": "./.medusa/server/src/workflows/index.js",
|
|
22
|
+
"./providers/paypal": "./.medusa/server/src/providers/paypal/index.js",
|
|
23
|
+
"./providers/paypal_card": "./.medusa/server/src/providers/paypal_card/index.js",
|
|
24
|
+
"./modules/paypal": "./.medusa/server/src/modules/paypal/index.js",
|
|
25
|
+
".": "./.medusa/server/src/index.js",
|
|
26
|
+
"./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
27
|
+
"./.medusa/server/src/modules/paypal": "./.medusa/server/src/modules/paypal/index.js",
|
|
28
|
+
"./.medusa/server/src/providers/*": "./.medusa/server/src/providers/*/index.js",
|
|
29
|
+
"./.medusa/server/src/providers/paypal": "./.medusa/server/src/providers/paypal/index.js",
|
|
30
|
+
"./.medusa/server/src/providers/paypal_card": "./.medusa/server/src/providers/paypal_card/index.js",
|
|
31
|
+
"./.medusa/server/src/admin": "./.medusa/server/src/admin/index.mjs",
|
|
32
|
+
"./.medusa/server/src/workflows": "./.medusa/server/src/workflows/index.js",
|
|
33
|
+
"./.medusa/server/src/*": "./.medusa/server/src/*.js",
|
|
34
|
+
"./.medusa/*": "./.medusa/*"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "medusa plugin:build",
|
|
38
|
+
"develop": "medusa plugin:develop",
|
|
39
|
+
"prepare": "npm run build"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@medusajs/admin-sdk": "2.12.5",
|
|
43
|
+
"@medusajs/cli": "2.12.5",
|
|
44
|
+
"@medusajs/framework": "2.12.5",
|
|
45
|
+
"@medusajs/medusa": "2.12.5",
|
|
46
|
+
"@medusajs/test-utils": "2.12.5",
|
|
47
|
+
"@medusajs/ui": "^4.0.0",
|
|
48
|
+
"@medusajs/icons": "2.12.5",
|
|
49
|
+
"@swc/core": "^1.5.7",
|
|
50
|
+
"typescript": "^5.6.2"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@medusajs/admin-sdk": "^2.12.0",
|
|
54
|
+
"@medusajs/framework": "^2.12.0",
|
|
55
|
+
"@medusajs/medusa": "^2.12.0",
|
|
56
|
+
"@medusajs/ui": "^4.0.0",
|
|
57
|
+
"@medusajs/icons": "^2.12.0"
|
|
58
|
+
},
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=20"
|
|
64
|
+
},
|
|
65
|
+
"repository": {
|
|
66
|
+
"type": "git",
|
|
67
|
+
"url": "https://github.com/easypayment/medusa-paypal.git"
|
|
68
|
+
},
|
|
69
|
+
"keywords": [
|
|
70
|
+
"medusa",
|
|
71
|
+
"medusa-v2",
|
|
72
|
+
"medusa-plugin",
|
|
73
|
+
"medusa-plugin-integration",
|
|
74
|
+
"medusa-plugin-payment",
|
|
75
|
+
"medusa-paypal-payment",
|
|
76
|
+
"medusa-paypal-plugin",
|
|
77
|
+
"medusa-paypal-integration",
|
|
78
|
+
"medusa-paypal"
|
|
79
|
+
]
|
|
80
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { Link, useLocation } from "react-router-dom"
|
|
3
|
+
|
|
4
|
+
type Tab = {
|
|
5
|
+
label: string
|
|
6
|
+
to: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const BASE = "/settings/paypal"
|
|
10
|
+
|
|
11
|
+
const TABS: Tab[] = [
|
|
12
|
+
{ label: "PayPal Connection", to: `${BASE}/connection` },
|
|
13
|
+
{ label: "PayPal Settings", to: `${BASE}/paypal-settings` },
|
|
14
|
+
{ label: "Advanced Card Payments", to: `${BASE}/advanced-card-payments` },
|
|
15
|
+
{ label: "Additional Settings", to: `${BASE}/additional-settings` },
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
function isActive(pathname: string, to: string) {
|
|
19
|
+
return pathname === to || pathname.startsWith(to + "/")
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default function PayPalTabs() {
|
|
23
|
+
const { pathname } = useLocation()
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="border-b border-ui-border-base">
|
|
27
|
+
<div className="flex flex-wrap gap-6 text-sm">
|
|
28
|
+
{TABS.map((t) => {
|
|
29
|
+
const active = isActive(pathname, t.to)
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Link
|
|
33
|
+
key={t.to}
|
|
34
|
+
to={t.to}
|
|
35
|
+
className={
|
|
36
|
+
active
|
|
37
|
+
? "border-b-2 border-ui-fg-base pb-2 font-medium text-ui-fg-base"
|
|
38
|
+
: "pb-2 text-ui-fg-subtle hover:text-ui-fg-base"
|
|
39
|
+
}
|
|
40
|
+
>
|
|
41
|
+
{t.label}
|
|
42
|
+
</Link>
|
|
43
|
+
)
|
|
44
|
+
})}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { useEffect } from "react"
|
|
2
|
+
|
|
3
|
+
export type ToastKind = "success" | "error"
|
|
4
|
+
|
|
5
|
+
export type ToastState = {
|
|
6
|
+
kind: ToastKind
|
|
7
|
+
message: string
|
|
8
|
+
} | null
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
toast: ToastState
|
|
12
|
+
onClose: () => void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default function Toast({ toast, onClose }: Props) {
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!toast) return
|
|
18
|
+
const t = setTimeout(() => onClose(), 2500)
|
|
19
|
+
return () => clearTimeout(t)
|
|
20
|
+
}, [toast, onClose])
|
|
21
|
+
|
|
22
|
+
if (!toast) return null
|
|
23
|
+
|
|
24
|
+
const isSuccess = toast.kind === "success"
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div className="fixed right-6 top-6 z-[9999]">
|
|
28
|
+
<div
|
|
29
|
+
className={[
|
|
30
|
+
"min-w-[280px] max-w-[420px] rounded-lg border px-4 py-3 shadow-md",
|
|
31
|
+
isSuccess ? "border-emerald-500/30 bg-emerald-500/10" : "border-rose-500/30 bg-rose-500/10",
|
|
32
|
+
].join(" ")}
|
|
33
|
+
role="status"
|
|
34
|
+
aria-live="polite"
|
|
35
|
+
>
|
|
36
|
+
<div className="flex items-start gap-3">
|
|
37
|
+
<div className={["mt-0.5 h-2.5 w-2.5 rounded-full", isSuccess ? "bg-emerald-500" : "bg-rose-500"].join(" ")} />
|
|
38
|
+
<div className="flex-1 text-sm text-ui-fg-base">{toast.message}</div>
|
|
39
|
+
<button
|
|
40
|
+
type="button"
|
|
41
|
+
onClick={onClose}
|
|
42
|
+
className="text-ui-fg-subtle hover:text-ui-fg-base"
|
|
43
|
+
aria-label="Close"
|
|
44
|
+
>
|
|
45
|
+
×
|
|
46
|
+
</button>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from "react"
|
|
2
|
+
import PayPalTabs from "../_components/Tabs"
|
|
3
|
+
|
|
4
|
+
type AdminFetchOptions = {
|
|
5
|
+
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"
|
|
6
|
+
body?: Record<string, unknown>
|
|
7
|
+
query?: Record<string, string>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function adminFetch<T = unknown>(path: string, opts: AdminFetchOptions = {}): Promise<T> {
|
|
11
|
+
const { method = "GET", body, query } = opts
|
|
12
|
+
let url = path
|
|
13
|
+
if (query && Object.keys(query).length > 0) {
|
|
14
|
+
const params = new URLSearchParams(query)
|
|
15
|
+
url = `${path}?${params.toString()}`
|
|
16
|
+
}
|
|
17
|
+
const headers: Record<string, string> = { Accept: "application/json" }
|
|
18
|
+
if (body !== undefined) headers["Content-Type"] = "application/json"
|
|
19
|
+
if (typeof window !== "undefined") {
|
|
20
|
+
const token = (window as any).__medusa__?.token
|
|
21
|
+
if (token) headers["Authorization"] = `Bearer ${token}`
|
|
22
|
+
}
|
|
23
|
+
const res = await fetch(url, {
|
|
24
|
+
method, headers, credentials: "include",
|
|
25
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
26
|
+
})
|
|
27
|
+
const text = await res.text().catch(() => "")
|
|
28
|
+
if (!res.ok) {
|
|
29
|
+
if (res.status === 401) throw new Error("Unauthorized (401) - session may have expired. Please reload and log in again.")
|
|
30
|
+
if (res.status === 403) throw new Error("Forbidden (403) - you do not have permission to perform this action.")
|
|
31
|
+
throw new Error(text || `Request failed with status ${res.status}`)
|
|
32
|
+
}
|
|
33
|
+
if (!text) return {} as T
|
|
34
|
+
try { return JSON.parse(text) as T } catch { return {} as T }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type PaymentAction = "capture" | "authorize"
|
|
38
|
+
type LandingPage = "no_preference" | "login" | "billing"
|
|
39
|
+
|
|
40
|
+
type AdditionalSettingsForm = {
|
|
41
|
+
paymentAction: PaymentAction
|
|
42
|
+
brandName: string
|
|
43
|
+
landingPage: LandingPage
|
|
44
|
+
requireInstantPayment: boolean
|
|
45
|
+
sendItemDetails: boolean
|
|
46
|
+
invoicePrefix: string
|
|
47
|
+
creditCardStatementName: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const DEFAULT_FORM: AdditionalSettingsForm = {
|
|
51
|
+
paymentAction: "capture",
|
|
52
|
+
brandName: "PayPal",
|
|
53
|
+
landingPage: "no_preference",
|
|
54
|
+
requireInstantPayment: false,
|
|
55
|
+
sendItemDetails: true,
|
|
56
|
+
invoicePrefix: "WC-",
|
|
57
|
+
creditCardStatementName: "PayPal",
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function mergeWithDefaults(saved?: Partial<AdditionalSettingsForm> | null) {
|
|
61
|
+
if (!saved) return { ...DEFAULT_FORM }
|
|
62
|
+
const entries = Object.entries(saved).filter(([, value]) => value !== undefined)
|
|
63
|
+
return { ...DEFAULT_FORM, ...(Object.fromEntries(entries) as Partial<AdditionalSettingsForm>) }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function SectionCard({ title, description, right, children }: { title: string; description?: React.ReactNode; right?: React.ReactNode; children: React.ReactNode }) {
|
|
67
|
+
return (
|
|
68
|
+
<div className="rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm">
|
|
69
|
+
<div className="flex items-start justify-between gap-4 border-b border-ui-border-base p-4">
|
|
70
|
+
<div>
|
|
71
|
+
<div className="text-base font-semibold text-ui-fg-base">{title}</div>
|
|
72
|
+
{description ? <div className="mt-1 text-sm text-ui-fg-subtle">{description}</div> : null}
|
|
73
|
+
</div>
|
|
74
|
+
{right}
|
|
75
|
+
</div>
|
|
76
|
+
<div className="p-4">{children}</div>
|
|
77
|
+
</div>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function FieldRow({ label, hint, children }: { label: string; hint?: React.ReactNode; children: React.ReactNode }) {
|
|
82
|
+
return (
|
|
83
|
+
<div className="grid grid-cols-12 items-start gap-4 py-3">
|
|
84
|
+
<div className="col-span-12 md:col-span-4">
|
|
85
|
+
<div className="text-sm font-medium text-ui-fg-base">{label}</div>
|
|
86
|
+
{hint ? <div className="mt-1 text-xs text-ui-fg-subtle">{hint}</div> : null}
|
|
87
|
+
</div>
|
|
88
|
+
<div className="col-span-12 md:col-span-8">{children}</div>
|
|
89
|
+
</div>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export default function AdditionalSettingsTab() {
|
|
94
|
+
const [form, setForm] = useState<AdditionalSettingsForm>(() => ({ ...DEFAULT_FORM }))
|
|
95
|
+
const [loading, setLoading] = useState(false)
|
|
96
|
+
const [saving, setSaving] = useState(false)
|
|
97
|
+
const [toast, setToast] = useState<{ type: "success" | "error"; message: string } | null>(null)
|
|
98
|
+
const didInit = useRef(false)
|
|
99
|
+
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (didInit.current) return
|
|
102
|
+
didInit.current = true
|
|
103
|
+
;(async () => {
|
|
104
|
+
try {
|
|
105
|
+
setLoading(true)
|
|
106
|
+
const json = await adminFetch<any>("/admin/paypal/settings")
|
|
107
|
+
const payload = json?.data ?? json
|
|
108
|
+
const saved = payload?.additional_settings
|
|
109
|
+
if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved))
|
|
110
|
+
} catch {
|
|
111
|
+
} finally {
|
|
112
|
+
setLoading(false)
|
|
113
|
+
}
|
|
114
|
+
})()
|
|
115
|
+
}, [])
|
|
116
|
+
|
|
117
|
+
async function onSave() {
|
|
118
|
+
try {
|
|
119
|
+
setSaving(true)
|
|
120
|
+
setToast(null)
|
|
121
|
+
const json = await adminFetch<any>("/admin/paypal/settings", { method: "POST", body: { additional_settings: form as unknown as Record<string, unknown> } })
|
|
122
|
+
const payload = json?.data ?? json
|
|
123
|
+
const saved = payload?.additional_settings
|
|
124
|
+
if (saved && typeof saved === "object") setForm(mergeWithDefaults(saved))
|
|
125
|
+
setToast({ type: "success", message: "Settings saved" })
|
|
126
|
+
window.setTimeout(() => setToast(null), 2500)
|
|
127
|
+
} catch (e: unknown) {
|
|
128
|
+
setToast({ type: "error", message: e instanceof Error ? e.message : "Failed to save settings" })
|
|
129
|
+
window.setTimeout(() => setToast(null), 3500)
|
|
130
|
+
} finally {
|
|
131
|
+
setSaving(false)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<div className="p-6">
|
|
137
|
+
<div className="flex flex-col gap-6">
|
|
138
|
+
<div className="flex items-start justify-between gap-4">
|
|
139
|
+
<div><h1 className="text-xl font-semibold text-ui-fg-base">PayPal Gateway By Easy Payment</h1></div>
|
|
140
|
+
</div>
|
|
141
|
+
<PayPalTabs />
|
|
142
|
+
{toast ? (
|
|
143
|
+
<div 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" role="status" aria-live="polite">
|
|
144
|
+
<span className={toast.type === "success" ? "text-ui-fg-base" : "text-ui-fg-error"}>{toast.message}</span>
|
|
145
|
+
</div>
|
|
146
|
+
) : null}
|
|
147
|
+
<SectionCard
|
|
148
|
+
title="Additional Settings"
|
|
149
|
+
description="These settings control checkout behavior and PayPal experience."
|
|
150
|
+
right={(
|
|
151
|
+
<div className="flex items-center gap-3">
|
|
152
|
+
<button type="button" onClick={onSave} disabled={saving || loading} className="transition-fg relative inline-flex w-fit items-center justify-center overflow-hidden rounded-md outline-none shadow-buttons-neutral text-ui-fg-base bg-ui-button-neutral after:transition-fg after:absolute after:inset-0 after:content-[''] after:button-neutral-gradient hover:bg-ui-button-neutral-hover hover:after:button-neutral-hover-gradient active:bg-ui-button-neutral-pressed active:after:button-neutral-pressed-gradient focus-visible:shadow-buttons-neutral-focus disabled:bg-ui-bg-disabled disabled:border-ui-border-base disabled:text-ui-fg-disabled disabled:shadow-buttons-neutral disabled:after:hidden txt-compact-small-plus px-3 py-1.5">
|
|
153
|
+
{saving ? "Saving..." : "Save settings"}
|
|
154
|
+
</button>
|
|
155
|
+
{loading ? <span className="text-sm text-ui-fg-subtle">Loading...</span> : null}
|
|
156
|
+
</div>
|
|
157
|
+
)}
|
|
158
|
+
>
|
|
159
|
+
<div className="divide-y divide-ui-border-base">
|
|
160
|
+
<FieldRow label="Payment action">
|
|
161
|
+
<select value={form.paymentAction} onChange={(e) => setForm((p) => ({ ...p, paymentAction: e.target.value as PaymentAction }))} 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">
|
|
162
|
+
<option value="capture">Capture</option>
|
|
163
|
+
<option value="authorize">Authorize</option>
|
|
164
|
+
</select>
|
|
165
|
+
</FieldRow>
|
|
166
|
+
<FieldRow label="Brand Name">
|
|
167
|
+
<input value={form.brandName} onChange={(e) => setForm((p) => ({ ...p, brandName: e.target.value }))} 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" placeholder="PayPal" />
|
|
168
|
+
</FieldRow>
|
|
169
|
+
<FieldRow label="Landing Page">
|
|
170
|
+
<select value={form.landingPage} onChange={(e) => setForm((p) => ({ ...p, landingPage: e.target.value as LandingPage }))} 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">
|
|
171
|
+
<option value="no_preference">No Preference</option>
|
|
172
|
+
<option value="login">Login</option>
|
|
173
|
+
<option value="billing">Billing</option>
|
|
174
|
+
</select>
|
|
175
|
+
</FieldRow>
|
|
176
|
+
<FieldRow label="Instant Payments">
|
|
177
|
+
<label className="inline-flex items-center gap-2">
|
|
178
|
+
<input type="checkbox" checked={form.requireInstantPayment} onChange={(e) => setForm((p) => ({ ...p, requireInstantPayment: e.target.checked }))} className="h-4 w-4 rounded border-ui-border-base" />
|
|
179
|
+
<span className="text-sm text-ui-fg-base">Require Instant Payment</span>
|
|
180
|
+
</label>
|
|
181
|
+
</FieldRow>
|
|
182
|
+
<FieldRow label="Send Item Details" hint="Include all line item details in the payment request to PayPal so that they can be seen from the PayPal transaction details page.">
|
|
183
|
+
<label className="inline-flex items-center gap-2">
|
|
184
|
+
<input type="checkbox" checked={form.sendItemDetails} onChange={(e) => setForm((p) => ({ ...p, sendItemDetails: e.target.checked }))} className="h-4 w-4 rounded border-ui-border-base" />
|
|
185
|
+
<span className="text-sm text-ui-fg-base">Send line item details to PayPal</span>
|
|
186
|
+
</label>
|
|
187
|
+
</FieldRow>
|
|
188
|
+
<FieldRow label="Invoice prefix">
|
|
189
|
+
<input value={form.invoicePrefix} onChange={(e) => setForm((p) => ({ ...p, invoicePrefix: e.target.value }))} 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" placeholder="WC-" />
|
|
190
|
+
</FieldRow>
|
|
191
|
+
<FieldRow label="Credit Card Statement Name">
|
|
192
|
+
<input value={form.creditCardStatementName} onChange={(e) => setForm((p) => ({ ...p, creditCardStatementName: e.target.value }))} 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" placeholder="PayPal" />
|
|
193
|
+
</FieldRow>
|
|
194
|
+
</div>
|
|
195
|
+
</SectionCard>
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
)
|
|
199
|
+
}
|