@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
|
@@ -0,0 +1,699 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useLayoutEffect,
|
|
5
|
+
useMemo,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
} from "react"
|
|
9
|
+
import { defineRouteConfig } from "@medusajs/admin-sdk"
|
|
10
|
+
import PayPalTabs from "../_components/Tabs"
|
|
11
|
+
|
|
12
|
+
export const config = defineRouteConfig({
|
|
13
|
+
label: "PayPal Connection",
|
|
14
|
+
hide: true,
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
if (typeof window !== "undefined") {
|
|
19
|
+
const preloadHref =
|
|
20
|
+
"https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js"
|
|
21
|
+
|
|
22
|
+
const existingPreload = document.head.querySelector(
|
|
23
|
+
`link[rel="preload"][href="${preloadHref}"]`
|
|
24
|
+
)
|
|
25
|
+
if (!existingPreload) {
|
|
26
|
+
const preloadLink = document.createElement("link")
|
|
27
|
+
preloadLink.rel = "preload"
|
|
28
|
+
preloadLink.href = preloadHref
|
|
29
|
+
preloadLink.as = "script"
|
|
30
|
+
document.head.appendChild(preloadLink)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const existingScript = document.getElementById(
|
|
34
|
+
"paypal-partner-js"
|
|
35
|
+
) as HTMLScriptElement | null
|
|
36
|
+
if (!existingScript) {
|
|
37
|
+
const ppScript = document.createElement("script")
|
|
38
|
+
ppScript.id = "paypal-partner-js"
|
|
39
|
+
ppScript.src = preloadHref
|
|
40
|
+
ppScript.async = true
|
|
41
|
+
document.head.appendChild(ppScript)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
declare global {
|
|
46
|
+
interface Window {
|
|
47
|
+
PAYPAL?: {
|
|
48
|
+
apps?: {
|
|
49
|
+
Signup?: {
|
|
50
|
+
miniBrowser?: { init: () => void }
|
|
51
|
+
MiniBrowser?: { closeFlow?: () => void }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
onboardingCallback?: (authCode: string, sharedId: string) => void
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
const SERVICE_URL = "/admin/paypal/onboarding-link"
|
|
61
|
+
const CACHE_KEY = "pp_onboard_cache"
|
|
62
|
+
const RELOAD_KEY = "pp_onboard_reloaded_once"
|
|
63
|
+
const CACHE_EXPIRY = 10 * 60 * 1000
|
|
64
|
+
|
|
65
|
+
const ONBOARDING_COMPLETE_ENDPOINT = "/admin/paypal/onboard-complete"
|
|
66
|
+
const STATUS_ENDPOINT = "/admin/paypal/status"
|
|
67
|
+
const SAVE_CREDENTIALS_ENDPOINT = "/admin/paypal/save-credentials"
|
|
68
|
+
const DISCONNECT_ENDPOINT = "/admin/paypal/disconnect"
|
|
69
|
+
|
|
70
|
+
let cachedUrl: string | null = null
|
|
71
|
+
if (typeof window !== "undefined") {
|
|
72
|
+
try {
|
|
73
|
+
const cached = localStorage.getItem(CACHE_KEY)
|
|
74
|
+
if (cached) {
|
|
75
|
+
const data = JSON.parse(cached)
|
|
76
|
+
if (new Date().getTime() - data.ts < CACHE_EXPIRY) {
|
|
77
|
+
cachedUrl = data.url
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
console.error("Cache read error:", e)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
export default function PayPalConnectionPage() {
|
|
87
|
+
const [env, setEnv] = useState<"sandbox" | "live">("live")
|
|
88
|
+
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
fetch("/admin/paypal/environment", { method: "GET" })
|
|
91
|
+
.then((r) => r.json())
|
|
92
|
+
.then((d) => {
|
|
93
|
+
const v = d?.environment === "sandbox" ? "sandbox" : "live"
|
|
94
|
+
setEnv(v)
|
|
95
|
+
})
|
|
96
|
+
.catch(() => {})
|
|
97
|
+
}, [])
|
|
98
|
+
const [connState, setConnState] = useState<
|
|
99
|
+
"loading" | "ready" | "connected" | "error"
|
|
100
|
+
>("loading")
|
|
101
|
+
const [error, setError] = useState<string | null>(null)
|
|
102
|
+
const [finalUrl, setFinalUrl] = useState<string>("")
|
|
103
|
+
const [showManual, setShowManual] = useState(false)
|
|
104
|
+
const [clientId, setClientId] = useState("")
|
|
105
|
+
const [secret, setSecret] = useState("")
|
|
106
|
+
const [statusInfo, setStatusInfo] = useState<{
|
|
107
|
+
seller_client_id_masked?: string | null
|
|
108
|
+
seller_client_secret_masked?: string | null
|
|
109
|
+
seller_email?: string | null
|
|
110
|
+
} | null>(null)
|
|
111
|
+
|
|
112
|
+
const [onboardingInProgress, setOnboardingInProgress] = useState(false)
|
|
113
|
+
|
|
114
|
+
const initLoaderRef = useRef<HTMLDivElement>(null)
|
|
115
|
+
const paypalButtonRef = useRef<HTMLAnchorElement>(null)
|
|
116
|
+
const errorLogRef = useRef<HTMLDivElement>(null)
|
|
117
|
+
const runIdRef = useRef(0)
|
|
118
|
+
const currentRunId = useRef(0)
|
|
119
|
+
|
|
120
|
+
const ppBtnMeasureRef = useRef<HTMLAnchorElement | null>(null)
|
|
121
|
+
const [ppBtnWidth, setPpBtnWidth] = useState<number | null>(null)
|
|
122
|
+
|
|
123
|
+
const canSaveManual = useMemo(() => {
|
|
124
|
+
return clientId.trim().length > 0 && secret.trim().length > 0
|
|
125
|
+
}, [clientId, secret])
|
|
126
|
+
|
|
127
|
+
const fetchFreshLink = useCallback(
|
|
128
|
+
(runId: number) => {
|
|
129
|
+
if (initLoaderRef.current) {
|
|
130
|
+
const loaderText = initLoaderRef.current.querySelector("#loader-text")
|
|
131
|
+
if (loaderText)
|
|
132
|
+
loaderText.textContent = "Generating onboarding session..."
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
fetch(SERVICE_URL, {
|
|
136
|
+
method: "POST",
|
|
137
|
+
headers: { "content-type": "application/json" },
|
|
138
|
+
body: JSON.stringify({
|
|
139
|
+
products: ["PPCP"],
|
|
140
|
+
}),
|
|
141
|
+
})
|
|
142
|
+
.then((r) => r.json())
|
|
143
|
+
.then((data) => {
|
|
144
|
+
if (runId !== currentRunId.current) return
|
|
145
|
+
|
|
146
|
+
const href = data?.onboarding_url
|
|
147
|
+
if (!href) {
|
|
148
|
+
showError("Onboarding URL not returned.")
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const finalUrl =
|
|
153
|
+
href + (href.includes("?") ? "&" : "?") + "displayMode=minibrowser"
|
|
154
|
+
|
|
155
|
+
localStorage.setItem(
|
|
156
|
+
CACHE_KEY,
|
|
157
|
+
JSON.stringify({
|
|
158
|
+
url: finalUrl,
|
|
159
|
+
ts: Date.now(),
|
|
160
|
+
})
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
if (!localStorage.getItem(RELOAD_KEY)) {
|
|
164
|
+
localStorage.setItem(RELOAD_KEY, "1")
|
|
165
|
+
window.location.reload()
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
activatePayPal(finalUrl, runId)
|
|
170
|
+
})
|
|
171
|
+
.catch(() => {
|
|
172
|
+
if (runId !== currentRunId.current) return
|
|
173
|
+
showError("Unable to connect to service.")
|
|
174
|
+
})
|
|
175
|
+
},
|
|
176
|
+
[env]
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
const showUI = useCallback(() => {
|
|
180
|
+
const btn = document.querySelector('[data-paypal-button="true"]')
|
|
181
|
+
if (btn && window.PAYPAL?.apps?.Signup?.miniBrowser?.init) {
|
|
182
|
+
window.PAYPAL.apps.Signup.miniBrowser.init()
|
|
183
|
+
}
|
|
184
|
+
setConnState("ready")
|
|
185
|
+
}, [])
|
|
186
|
+
|
|
187
|
+
const showError = useCallback((msg: string) => {
|
|
188
|
+
setConnState("error")
|
|
189
|
+
setError(msg)
|
|
190
|
+
}, [])
|
|
191
|
+
|
|
192
|
+
const activatePayPal = useCallback(
|
|
193
|
+
(url: string, runId: number) => {
|
|
194
|
+
if (paypalButtonRef.current) {
|
|
195
|
+
paypalButtonRef.current.href = url
|
|
196
|
+
}
|
|
197
|
+
setFinalUrl(url)
|
|
198
|
+
|
|
199
|
+
const tryInit = () => {
|
|
200
|
+
if (runId !== currentRunId.current) return
|
|
201
|
+
if (window.PAYPAL?.apps?.Signup) {
|
|
202
|
+
showUI()
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
setTimeout(tryInit, 50)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
tryInit()
|
|
209
|
+
},
|
|
210
|
+
[showUI]
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
useEffect(() => {
|
|
214
|
+
currentRunId.current = ++runIdRef.current
|
|
215
|
+
const runId = currentRunId.current
|
|
216
|
+
|
|
217
|
+
let cancelled = false
|
|
218
|
+
|
|
219
|
+
const run = async () => {
|
|
220
|
+
setConnState("loading")
|
|
221
|
+
setError(null)
|
|
222
|
+
setFinalUrl("")
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
const r = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
226
|
+
method: "GET",
|
|
227
|
+
})
|
|
228
|
+
const st = await r.json().catch(() => ({}))
|
|
229
|
+
|
|
230
|
+
if (cancelled || runId !== currentRunId.current) return
|
|
231
|
+
|
|
232
|
+
setStatusInfo(st)
|
|
233
|
+
|
|
234
|
+
const isConnected =
|
|
235
|
+
st?.status === "connected" && st?.seller_client_id_present === true
|
|
236
|
+
|
|
237
|
+
if (isConnected) {
|
|
238
|
+
setConnState("connected")
|
|
239
|
+
setShowManual(false)
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
} catch (e) {
|
|
243
|
+
console.error(e)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (cachedUrl) {
|
|
247
|
+
activatePayPal(cachedUrl, runId)
|
|
248
|
+
} else {
|
|
249
|
+
fetchFreshLink(runId)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
run()
|
|
254
|
+
|
|
255
|
+
return () => {
|
|
256
|
+
cancelled = true
|
|
257
|
+
currentRunId.current = 0
|
|
258
|
+
}
|
|
259
|
+
}, [env, fetchFreshLink, activatePayPal])
|
|
260
|
+
|
|
261
|
+
useLayoutEffect(() => {
|
|
262
|
+
window.onboardingCallback = async function (authCode: string, sharedId: string) {
|
|
263
|
+
try {
|
|
264
|
+
;(window as any).onbeforeunload = ""
|
|
265
|
+
} catch {}
|
|
266
|
+
|
|
267
|
+
setOnboardingInProgress(true)
|
|
268
|
+
setConnState("loading")
|
|
269
|
+
setError(null)
|
|
270
|
+
|
|
271
|
+
const payload = {
|
|
272
|
+
authCode,
|
|
273
|
+
sharedId,
|
|
274
|
+
env: env === "sandbox" ? "sandbox" : "live",
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
const res = await fetch(ONBOARDING_COMPLETE_ENDPOINT, {
|
|
279
|
+
method: "POST",
|
|
280
|
+
headers: { "content-type": "application/json" },
|
|
281
|
+
body: JSON.stringify(payload),
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
if (!res.ok) {
|
|
285
|
+
const txt = await res.text().catch(() => "")
|
|
286
|
+
throw new Error(txt || `Onboarding exchange failed (${res.status})`)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
try {
|
|
290
|
+
const close1 = window.PAYPAL?.apps?.Signup?.MiniBrowser?.closeFlow
|
|
291
|
+
if (typeof close1 === "function") close1()
|
|
292
|
+
} catch {}
|
|
293
|
+
try {
|
|
294
|
+
const close2 =
|
|
295
|
+
window.PAYPAL?.apps?.Signup?.miniBrowser &&
|
|
296
|
+
(window.PAYPAL.apps.Signup.miniBrowser as any).closeFlow
|
|
297
|
+
if (typeof close2 === "function") close2()
|
|
298
|
+
} catch {}
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
localStorage.removeItem(CACHE_KEY)
|
|
302
|
+
localStorage.removeItem(RELOAD_KEY)
|
|
303
|
+
} catch {}
|
|
304
|
+
|
|
305
|
+
window.location.href = window.location.href
|
|
306
|
+
} catch (e: any) {
|
|
307
|
+
console.error(e)
|
|
308
|
+
setConnState("error")
|
|
309
|
+
setError(e?.message || "Exchange failed while saving credentials.")
|
|
310
|
+
setOnboardingInProgress(false)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return () => {
|
|
315
|
+
window.onboardingCallback = undefined
|
|
316
|
+
}
|
|
317
|
+
}, [env])
|
|
318
|
+
|
|
319
|
+
useLayoutEffect(() => {
|
|
320
|
+
const el = ppBtnMeasureRef.current
|
|
321
|
+
if (!el) return
|
|
322
|
+
|
|
323
|
+
const update = () => {
|
|
324
|
+
const w = Math.round(el.getBoundingClientRect().width || 0)
|
|
325
|
+
if (w > 0) setPpBtnWidth(w)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
update()
|
|
329
|
+
|
|
330
|
+
let ro: ResizeObserver | null = null
|
|
331
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
332
|
+
ro = new ResizeObserver(() => update())
|
|
333
|
+
ro.observe(el)
|
|
334
|
+
} else {
|
|
335
|
+
window.addEventListener("resize", update)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return () => {
|
|
339
|
+
if (ro) ro.disconnect()
|
|
340
|
+
else window.removeEventListener("resize", update)
|
|
341
|
+
}
|
|
342
|
+
}, [connState, env, finalUrl])
|
|
343
|
+
|
|
344
|
+
const handleConnectClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
|
345
|
+
if (connState !== "ready" || !finalUrl || onboardingInProgress) {
|
|
346
|
+
e.preventDefault()
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const handleSaveManual = async () => {
|
|
351
|
+
if (!canSaveManual || onboardingInProgress) return
|
|
352
|
+
setOnboardingInProgress(true)
|
|
353
|
+
setConnState("loading")
|
|
354
|
+
setError(null)
|
|
355
|
+
|
|
356
|
+
try {
|
|
357
|
+
const res = await fetch(SAVE_CREDENTIALS_ENDPOINT, {
|
|
358
|
+
method: "POST",
|
|
359
|
+
headers: { "content-type": "application/json" },
|
|
360
|
+
body: JSON.stringify({
|
|
361
|
+
clientId: clientId.trim(),
|
|
362
|
+
clientSecret: secret.trim(),
|
|
363
|
+
environment: env,
|
|
364
|
+
}),
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
if (!res.ok) {
|
|
368
|
+
const txt = await res.text().catch(() => "")
|
|
369
|
+
throw new Error(txt || `Save credentials failed (${res.status})`)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const statusRes = await fetch(`${STATUS_ENDPOINT}?environment=${env}`, {
|
|
373
|
+
method: "GET",
|
|
374
|
+
})
|
|
375
|
+
const refreshedStatus = await statusRes.json().catch(() => ({}))
|
|
376
|
+
|
|
377
|
+
setConnState("connected")
|
|
378
|
+
setStatusInfo(refreshedStatus || null)
|
|
379
|
+
setShowManual(false)
|
|
380
|
+
|
|
381
|
+
try {
|
|
382
|
+
localStorage.removeItem(CACHE_KEY)
|
|
383
|
+
localStorage.removeItem(RELOAD_KEY)
|
|
384
|
+
} catch {}
|
|
385
|
+
} catch (e: any) {
|
|
386
|
+
console.error(e)
|
|
387
|
+
setConnState("error")
|
|
388
|
+
setError(e?.message || "Failed to save credentials.")
|
|
389
|
+
} finally {
|
|
390
|
+
setOnboardingInProgress(false)
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const handleDisconnect = async () => {
|
|
395
|
+
if (onboardingInProgress) return
|
|
396
|
+
if (!window.confirm("Disconnect PayPal for this environment?")) return
|
|
397
|
+
|
|
398
|
+
setOnboardingInProgress(true)
|
|
399
|
+
setConnState("loading")
|
|
400
|
+
setError(null)
|
|
401
|
+
setFinalUrl("")
|
|
402
|
+
setShowManual(false)
|
|
403
|
+
|
|
404
|
+
try {
|
|
405
|
+
const res = await fetch(DISCONNECT_ENDPOINT, {
|
|
406
|
+
method: "POST",
|
|
407
|
+
headers: { "content-type": "application/json" },
|
|
408
|
+
body: JSON.stringify({ environment: env }),
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
if (!res.ok) {
|
|
412
|
+
const t = await res.text().catch(() => "")
|
|
413
|
+
throw new Error(t || `Disconnect failed (${res.status})`)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
try {
|
|
417
|
+
localStorage.removeItem(CACHE_KEY)
|
|
418
|
+
localStorage.removeItem(RELOAD_KEY)
|
|
419
|
+
} catch {}
|
|
420
|
+
|
|
421
|
+
currentRunId.current = ++runIdRef.current
|
|
422
|
+
const runId = currentRunId.current
|
|
423
|
+
fetchFreshLink(runId)
|
|
424
|
+
} catch (e: any) {
|
|
425
|
+
console.error(e)
|
|
426
|
+
setConnState("error")
|
|
427
|
+
setError(e?.message || "Failed to disconnect.")
|
|
428
|
+
} finally {
|
|
429
|
+
setOnboardingInProgress(false)
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const handleEnvChange = async (e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
434
|
+
const next = e.target.value as "sandbox" | "live"
|
|
435
|
+
setEnv(next)
|
|
436
|
+
cachedUrl = null
|
|
437
|
+
|
|
438
|
+
try {
|
|
439
|
+
await fetch("/admin/paypal/environment", {
|
|
440
|
+
method: "POST",
|
|
441
|
+
headers: { "content-type": "application/json" },
|
|
442
|
+
body: JSON.stringify({ environment: next }),
|
|
443
|
+
})
|
|
444
|
+
} catch {}
|
|
445
|
+
|
|
446
|
+
try {
|
|
447
|
+
localStorage.removeItem(CACHE_KEY)
|
|
448
|
+
localStorage.removeItem(RELOAD_KEY)
|
|
449
|
+
} catch {}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
return (
|
|
453
|
+
<div className="p-6">
|
|
454
|
+
<div className="flex flex-col gap-6">
|
|
455
|
+
<h1 className="text-xl font-semibold">PayPal Gateway By Easy Payment</h1>
|
|
456
|
+
|
|
457
|
+
<PayPalTabs />
|
|
458
|
+
|
|
459
|
+
<div className="rounded-xl border border-ui-border-base bg-ui-bg-base shadow-sm">
|
|
460
|
+
<div className="grid grid-cols-1 gap-y-6 p-4 md:grid-cols-[260px_1fr] md:items-start">
|
|
461
|
+
<div className="text-sm font-medium pt-2">Environment</div>
|
|
462
|
+
<div className="max-w-xl">
|
|
463
|
+
<select
|
|
464
|
+
value={env}
|
|
465
|
+
onChange={handleEnvChange}
|
|
466
|
+
disabled={onboardingInProgress}
|
|
467
|
+
className="w-full rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm"
|
|
468
|
+
>
|
|
469
|
+
<option value="sandbox">Sandbox (Test Mode)</option>
|
|
470
|
+
<option value="live">Live (Production)</option>
|
|
471
|
+
</select>
|
|
472
|
+
</div>
|
|
473
|
+
|
|
474
|
+
<div className="text-sm font-medium pt-2">
|
|
475
|
+
{env === "sandbox" ? "Connect to PayPal (Sandbox)" : "Connect to PayPal"}
|
|
476
|
+
</div>
|
|
477
|
+
|
|
478
|
+
<div className="max-w-xl">
|
|
479
|
+
{connState === "connected" ? (
|
|
480
|
+
<div>
|
|
481
|
+
<div className="text-sm text-green-600 bg-green-50 p-3 rounded border border-green-200">
|
|
482
|
+
✅ Successfully connected to PayPal!
|
|
483
|
+
<a
|
|
484
|
+
data-paypal-button="true"
|
|
485
|
+
data-paypal-onboard-complete="onboardingCallback"
|
|
486
|
+
href="#"
|
|
487
|
+
style={{ display: "none" }}
|
|
488
|
+
>
|
|
489
|
+
PayPal
|
|
490
|
+
</a>
|
|
491
|
+
</div>
|
|
492
|
+
<div className="mt-3 rounded-md border border-ui-border-base bg-ui-bg-subtle p-3 text-xs text-ui-fg-subtle">
|
|
493
|
+
<div className="font-medium text-ui-fg-base">
|
|
494
|
+
Connected PayPal account
|
|
495
|
+
</div>
|
|
496
|
+
<div className="mt-1">
|
|
497
|
+
Email:{" "}
|
|
498
|
+
<span className="font-mono text-ui-fg-base">
|
|
499
|
+
{statusInfo?.seller_email || "Unavailable"}
|
|
500
|
+
</span>
|
|
501
|
+
</div>
|
|
502
|
+
</div>
|
|
503
|
+
<div className="mt-3 flex items-center gap-2">
|
|
504
|
+
<button
|
|
505
|
+
type="button"
|
|
506
|
+
onClick={handleDisconnect}
|
|
507
|
+
disabled={onboardingInProgress}
|
|
508
|
+
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"
|
|
509
|
+
>
|
|
510
|
+
Disconnect
|
|
511
|
+
</button>
|
|
512
|
+
</div>
|
|
513
|
+
</div>
|
|
514
|
+
) : (
|
|
515
|
+
<>
|
|
516
|
+
<div
|
|
517
|
+
ref={initLoaderRef}
|
|
518
|
+
id="init-loader"
|
|
519
|
+
className={`status-msg mb-4 ${
|
|
520
|
+
connState !== "loading" ? "hidden" : "block"
|
|
521
|
+
}`}
|
|
522
|
+
>
|
|
523
|
+
<div className="loader inline-block align-middle mr-2"></div>
|
|
524
|
+
<span id="loader-text" className="text-sm">
|
|
525
|
+
{onboardingInProgress
|
|
526
|
+
? "Configuring connection to PayPal…"
|
|
527
|
+
: "Checking connection..."}
|
|
528
|
+
</span>
|
|
529
|
+
</div>
|
|
530
|
+
|
|
531
|
+
<div className={`${connState === "ready" ? "block" : "hidden"}`}>
|
|
532
|
+
<a
|
|
533
|
+
ref={(node) => {
|
|
534
|
+
paypalButtonRef.current = node
|
|
535
|
+
ppBtnMeasureRef.current = node
|
|
536
|
+
}}
|
|
537
|
+
id="paypal-button"
|
|
538
|
+
data-paypal-button="true"
|
|
539
|
+
href={finalUrl || "#"}
|
|
540
|
+
data-paypal-onboard-complete="onboardingCallback"
|
|
541
|
+
onClick={handleConnectClick}
|
|
542
|
+
className="transition-fg relative inline-flex w-fit items-center justify-center overflow-hidden rounded-md outline-none no-underline 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"
|
|
543
|
+
style={{
|
|
544
|
+
cursor: onboardingInProgress ? "not-allowed" : "pointer",
|
|
545
|
+
opacity: onboardingInProgress ? 0.6 : 1,
|
|
546
|
+
pointerEvents: onboardingInProgress ? "none" : "auto",
|
|
547
|
+
}}
|
|
548
|
+
>
|
|
549
|
+
Connect to PayPal
|
|
550
|
+
</a>
|
|
551
|
+
|
|
552
|
+
<div
|
|
553
|
+
className="mt-2"
|
|
554
|
+
style={{
|
|
555
|
+
width: ppBtnWidth ? `${ppBtnWidth}px` : "auto",
|
|
556
|
+
marginTop: "20px",
|
|
557
|
+
marginBottom: "10px",
|
|
558
|
+
}}
|
|
559
|
+
>
|
|
560
|
+
<div className="flex justify-center">
|
|
561
|
+
<span className="text-[11px] text-ui-fg-muted leading-none">
|
|
562
|
+
OR
|
|
563
|
+
</span>
|
|
564
|
+
</div>
|
|
565
|
+
</div>
|
|
566
|
+
|
|
567
|
+
<div className="mt-1">
|
|
568
|
+
<button
|
|
569
|
+
type="button"
|
|
570
|
+
onClick={() => setShowManual(!showManual)}
|
|
571
|
+
disabled={onboardingInProgress}
|
|
572
|
+
className="text-sm text-ui-fg-interactive underline whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed"
|
|
573
|
+
>
|
|
574
|
+
Click here to insert credentials manually
|
|
575
|
+
</button>
|
|
576
|
+
</div>
|
|
577
|
+
</div>
|
|
578
|
+
|
|
579
|
+
<div className={`${connState === "ready" ? "hidden" : "block"} mt-3`}>
|
|
580
|
+
<button
|
|
581
|
+
type="button"
|
|
582
|
+
onClick={() => setShowManual(!showManual)}
|
|
583
|
+
disabled={onboardingInProgress}
|
|
584
|
+
className="text-sm text-ui-fg-interactive underline whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed"
|
|
585
|
+
>
|
|
586
|
+
Click here to insert credentials manually
|
|
587
|
+
</button>
|
|
588
|
+
</div>
|
|
589
|
+
|
|
590
|
+
<div
|
|
591
|
+
ref={errorLogRef}
|
|
592
|
+
id="error-log"
|
|
593
|
+
className={`mt-4 text-left text-xs bg-red-50 text-red-600 p-3 border border-red-200 rounded ${
|
|
594
|
+
connState === "error" && error ? "block" : "hidden"
|
|
595
|
+
}`}
|
|
596
|
+
>
|
|
597
|
+
{error}
|
|
598
|
+
</div>
|
|
599
|
+
</>
|
|
600
|
+
)}
|
|
601
|
+
</div>
|
|
602
|
+
|
|
603
|
+
{showManual && (
|
|
604
|
+
<div className="md:col-span-2">
|
|
605
|
+
<div className="ml-[260px] max-w-xl mt-4 grid grid-cols-1 gap-3 md:grid-cols-2">
|
|
606
|
+
<div className="flex flex-col gap-1">
|
|
607
|
+
<label className="text-sm font-medium">Client ID</label>
|
|
608
|
+
<input
|
|
609
|
+
type="text"
|
|
610
|
+
value={clientId}
|
|
611
|
+
onChange={(e) => setClientId(e.target.value)}
|
|
612
|
+
disabled={onboardingInProgress}
|
|
613
|
+
className="rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50"
|
|
614
|
+
placeholder={
|
|
615
|
+
env === "sandbox" ? "Sandbox Client ID" : "Live Client ID"
|
|
616
|
+
}
|
|
617
|
+
/>
|
|
618
|
+
</div>
|
|
619
|
+
|
|
620
|
+
<div className="flex flex-col gap-1">
|
|
621
|
+
<label className="text-sm font-medium">Secret</label>
|
|
622
|
+
<input
|
|
623
|
+
type="password"
|
|
624
|
+
value={secret}
|
|
625
|
+
onChange={(e) => setSecret(e.target.value)}
|
|
626
|
+
disabled={onboardingInProgress}
|
|
627
|
+
className="rounded-md border border-ui-border-base bg-transparent px-3 py-2 text-sm disabled:opacity-50"
|
|
628
|
+
placeholder={env === "sandbox" ? "Sandbox Secret" : "Live Secret"}
|
|
629
|
+
/>
|
|
630
|
+
</div>
|
|
631
|
+
|
|
632
|
+
<div className="md:col-span-2 rounded-md border border-ui-border-base bg-ui-bg-subtle p-4 text-sm text-ui-fg-subtle">
|
|
633
|
+
<p className="font-medium text-ui-fg-base">
|
|
634
|
+
Get your Client ID and Secret in 3 steps:
|
|
635
|
+
</p>
|
|
636
|
+
<ol className="mt-2 list-decimal space-y-2 pl-5">
|
|
637
|
+
<li>
|
|
638
|
+
Open{" "}
|
|
639
|
+
<a
|
|
640
|
+
href="https://developer.paypal.com/dashboard/"
|
|
641
|
+
target="_blank"
|
|
642
|
+
rel="noreferrer"
|
|
643
|
+
className="text-ui-fg-interactive underline"
|
|
644
|
+
>
|
|
645
|
+
Log in to Dashboard
|
|
646
|
+
</a>{" "}
|
|
647
|
+
and sign in or create an account.
|
|
648
|
+
</li>
|
|
649
|
+
<li>Select <span className="font-medium text-ui-fg-base">Apps & Credentials</span>, then choose <span className="font-medium text-ui-fg-base">Create App</span> if you need a new project.</li>
|
|
650
|
+
<li>Copy your app's <span className="font-medium text-ui-fg-base">Client ID</span> and <span className="font-medium text-ui-fg-base">Secret</span>, paste them above, then click <span className="font-medium text-ui-fg-base">Save credentials</span>.</li>
|
|
651
|
+
</ol>
|
|
652
|
+
</div>
|
|
653
|
+
|
|
654
|
+
<div className="md:col-span-2 flex items-center gap-2 mt-2">
|
|
655
|
+
<button
|
|
656
|
+
type="button"
|
|
657
|
+
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"
|
|
658
|
+
onClick={() => setShowManual(false)}
|
|
659
|
+
disabled={onboardingInProgress}
|
|
660
|
+
>
|
|
661
|
+
Cancel
|
|
662
|
+
</button>
|
|
663
|
+
|
|
664
|
+
<button
|
|
665
|
+
type="button"
|
|
666
|
+
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"
|
|
667
|
+
disabled={!canSaveManual || onboardingInProgress}
|
|
668
|
+
onClick={handleSaveManual}
|
|
669
|
+
>
|
|
670
|
+
Save credentials
|
|
671
|
+
</button>
|
|
672
|
+
</div>
|
|
673
|
+
</div>
|
|
674
|
+
</div>
|
|
675
|
+
)}
|
|
676
|
+
</div>
|
|
677
|
+
</div>
|
|
678
|
+
</div>
|
|
679
|
+
|
|
680
|
+
<style>{`
|
|
681
|
+
.loader {
|
|
682
|
+
border: 3px solid #f3f3f3;
|
|
683
|
+
border-top: 3px solid #0070ba;
|
|
684
|
+
border-radius: 50%;
|
|
685
|
+
width: 18px;
|
|
686
|
+
height: 18px;
|
|
687
|
+
animation: spin 1s linear infinite;
|
|
688
|
+
display: inline-block;
|
|
689
|
+
vertical-align: middle;
|
|
690
|
+
margin-right: 8px;
|
|
691
|
+
}
|
|
692
|
+
@keyframes spin {
|
|
693
|
+
0% { transform: rotate(0deg); }
|
|
694
|
+
100% { transform: rotate(360deg); }
|
|
695
|
+
}
|
|
696
|
+
`}</style>
|
|
697
|
+
</div>
|
|
698
|
+
)
|
|
699
|
+
}
|