@spare-technologies/spare-link 0.1.0-beta.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -63
- package/lib/commonjs/core/models/payment-return-params.js +245 -20
- package/lib/commonjs/core/models/payment-return-params.js.map +1 -1
- package/lib/commonjs/core/models/pending-session-record.js +2 -0
- package/lib/commonjs/core/models/pending-session-record.js.map +1 -0
- package/lib/commonjs/core/services/hosted-flow-controller.js +333 -0
- package/lib/commonjs/core/services/hosted-flow-controller.js.map +1 -0
- package/lib/commonjs/core/services/hosted-flow-state.js +96 -0
- package/lib/commonjs/core/services/hosted-flow-state.js.map +1 -0
- package/lib/commonjs/index.js +42 -164
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internal/hosted/bridge-message.js +107 -0
- package/lib/commonjs/internal/hosted/bridge-message.js.map +1 -0
- package/lib/commonjs/internal/hosted/hosted-url.js +41 -0
- package/lib/commonjs/internal/hosted/hosted-url.js.map +1 -0
- package/lib/commonjs/internal/index.js +0 -7
- package/lib/commonjs/internal/index.js.map +1 -1
- package/lib/commonjs/internal/redact-uri.js +59 -15
- package/lib/commonjs/internal/redact-uri.js.map +1 -1
- package/lib/commonjs/internal/secure-store-pending-session-store.js +20 -25
- package/lib/commonjs/internal/secure-store-pending-session-store.js.map +1 -1
- package/lib/commonjs/internal/url-parts.js +145 -0
- package/lib/commonjs/internal/url-parts.js.map +1 -0
- package/lib/commonjs/public/index.js +0 -37
- package/lib/commonjs/public/index.js.map +1 -1
- package/lib/commonjs/public/payment-result.js +16 -4
- package/lib/commonjs/public/payment-result.js.map +1 -1
- package/lib/commonjs/public/recovery-result.js +7 -18
- package/lib/commonjs/public/recovery-result.js.map +1 -1
- package/lib/commonjs/public/spare-link-config.js +41 -16
- package/lib/commonjs/public/spare-link-config.js.map +1 -1
- package/lib/commonjs/public/spare-link-event.js +27 -33
- package/lib/commonjs/public/spare-link-event.js.map +1 -1
- package/lib/commonjs/public/spare-link-instance.js +67 -77
- package/lib/commonjs/public/spare-link-instance.js.map +1 -1
- package/lib/commonjs/public/spare-link-session.js +2 -9
- package/lib/commonjs/public/spare-link-session.js.map +1 -1
- package/lib/commonjs/public/spare-link.js +0 -12
- package/lib/commonjs/public/spare-link.js.map +1 -1
- package/lib/commonjs/ui/hooks/{use-payment-flow-state.js → use-hosted-flow-state.js} +4 -4
- package/lib/commonjs/ui/hooks/use-hosted-flow-state.js.map +1 -0
- package/lib/commonjs/ui/hosted/hosted-payment-page.js +177 -0
- package/lib/commonjs/ui/hosted/hosted-payment-page.js.map +1 -0
- package/lib/commonjs/ui/hosted/hosted-payment-webview.js +168 -0
- package/lib/commonjs/ui/hosted/hosted-payment-webview.js.map +1 -0
- package/lib/commonjs/ui/screens/index.js +3 -17
- package/lib/commonjs/ui/screens/index.js.map +1 -1
- package/lib/commonjs/ui/screens/page-unavailable-screen.js +101 -0
- package/lib/commonjs/ui/screens/page-unavailable-screen.js.map +1 -0
- package/lib/commonjs/ui/spare-link-host.js +220 -234
- package/lib/commonjs/ui/spare-link-host.js.map +1 -1
- package/lib/commonjs/ui/widgets/index.js +3 -10
- package/lib/commonjs/ui/widgets/index.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/core/models/payment-return-params.js +235 -20
- package/lib/module/core/models/payment-return-params.js.map +1 -1
- package/lib/module/core/models/pending-session-record.js +2 -0
- package/lib/module/core/models/pending-session-record.js.map +1 -0
- package/lib/module/core/services/hosted-flow-controller.js +328 -0
- package/lib/module/core/services/hosted-flow-controller.js.map +1 -0
- package/lib/module/core/services/hosted-flow-state.js +91 -0
- package/lib/module/core/services/hosted-flow-state.js.map +1 -0
- package/lib/module/index.js +8 -22
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal/hosted/bridge-message.js +104 -0
- package/lib/module/internal/hosted/bridge-message.js.map +1 -0
- package/lib/module/internal/hosted/hosted-url.js +36 -0
- package/lib/module/internal/hosted/hosted-url.js.map +1 -0
- package/lib/module/internal/index.js +0 -1
- package/lib/module/internal/index.js.map +1 -1
- package/lib/module/internal/redact-uri.js +59 -15
- package/lib/module/internal/redact-uri.js.map +1 -1
- package/lib/module/internal/secure-store-pending-session-store.js +20 -25
- package/lib/module/internal/secure-store-pending-session-store.js.map +1 -1
- package/lib/module/internal/url-parts.js +139 -0
- package/lib/module/internal/url-parts.js.map +1 -0
- package/lib/module/public/index.js +2 -3
- package/lib/module/public/index.js.map +1 -1
- package/lib/module/public/payment-result.js +16 -4
- package/lib/module/public/payment-result.js.map +1 -1
- package/lib/module/public/recovery-result.js +7 -17
- package/lib/module/public/recovery-result.js.map +1 -1
- package/lib/module/public/spare-link-config.js +42 -15
- package/lib/module/public/spare-link-config.js.map +1 -1
- package/lib/module/public/spare-link-event.js +27 -33
- package/lib/module/public/spare-link-event.js.map +1 -1
- package/lib/module/public/spare-link-instance.js +68 -72
- package/lib/module/public/spare-link-instance.js.map +1 -1
- package/lib/module/public/spare-link-session.js +2 -9
- package/lib/module/public/spare-link-session.js.map +1 -1
- package/lib/module/public/spare-link.js +1 -1
- package/lib/module/public/spare-link.js.map +1 -1
- package/lib/module/ui/hooks/{use-payment-flow-state.js → use-hosted-flow-state.js} +3 -3
- package/lib/module/ui/hooks/use-hosted-flow-state.js.map +1 -0
- package/lib/module/ui/hosted/hosted-payment-page.js +175 -0
- package/lib/module/ui/hosted/hosted-payment-page.js.map +1 -0
- package/lib/module/ui/hosted/hosted-payment-webview.js +163 -0
- package/lib/module/ui/hosted/hosted-payment-webview.js.map +1 -0
- package/lib/module/ui/screens/index.js +1 -3
- package/lib/module/ui/screens/index.js.map +1 -1
- package/lib/module/ui/screens/page-unavailable-screen.js +97 -0
- package/lib/module/ui/screens/page-unavailable-screen.js.map +1 -0
- package/lib/module/ui/spare-link-host.js +221 -236
- package/lib/module/ui/spare-link-host.js.map +1 -1
- package/lib/module/ui/widgets/index.js +1 -2
- package/lib/module/ui/widgets/index.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/commonjs/core/models/index.d.ts +1 -123
- package/lib/typescript/commonjs/core/models/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/core/models/payment-return-params.d.ts +91 -8
- package/lib/typescript/commonjs/core/models/payment-return-params.d.ts.map +1 -1
- package/lib/typescript/commonjs/core/models/pending-session-record.d.ts +11 -0
- package/lib/typescript/commonjs/core/models/pending-session-record.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/services/hosted-flow-controller.d.ts +119 -0
- package/lib/typescript/commonjs/core/services/hosted-flow-controller.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/services/hosted-flow-state.d.ts +75 -0
- package/lib/typescript/commonjs/core/services/hosted-flow-state.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +5 -14
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts +44 -0
- package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts.map +1 -0
- package/lib/typescript/commonjs/internal/hosted/hosted-url.d.ts +30 -0
- package/lib/typescript/commonjs/internal/hosted/hosted-url.d.ts.map +1 -0
- package/lib/typescript/commonjs/internal/index.d.ts +0 -1
- package/lib/typescript/commonjs/internal/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/internal/redact-uri.d.ts +21 -1
- package/lib/typescript/commonjs/internal/redact-uri.d.ts.map +1 -1
- package/lib/typescript/commonjs/internal/secure-store-pending-session-store.d.ts +3 -2
- package/lib/typescript/commonjs/internal/secure-store-pending-session-store.d.ts.map +1 -1
- package/lib/typescript/commonjs/internal/url-parts.d.ts +46 -0
- package/lib/typescript/commonjs/internal/url-parts.d.ts.map +1 -0
- package/lib/typescript/commonjs/public/index.d.ts +4 -6
- package/lib/typescript/commonjs/public/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/public/payment-result.d.ts +50 -12
- package/lib/typescript/commonjs/public/payment-result.d.ts.map +1 -1
- package/lib/typescript/commonjs/public/recovery-result.d.ts +11 -20
- package/lib/typescript/commonjs/public/recovery-result.d.ts.map +1 -1
- package/lib/typescript/commonjs/public/spare-link-config.d.ts +13 -31
- package/lib/typescript/commonjs/public/spare-link-config.d.ts.map +1 -1
- package/lib/typescript/commonjs/public/spare-link-event.d.ts +29 -31
- package/lib/typescript/commonjs/public/spare-link-event.d.ts.map +1 -1
- package/lib/typescript/commonjs/public/spare-link-host-api.d.ts +1 -12
- package/lib/typescript/commonjs/public/spare-link-host-api.d.ts.map +1 -1
- package/lib/typescript/commonjs/public/spare-link-instance.d.ts +26 -20
- package/lib/typescript/commonjs/public/spare-link-instance.d.ts.map +1 -1
- package/lib/typescript/commonjs/public/spare-link-session.d.ts +3 -8
- package/lib/typescript/commonjs/public/spare-link-session.d.ts.map +1 -1
- package/lib/typescript/commonjs/public/spare-link.d.ts +1 -1
- package/lib/typescript/commonjs/public/spare-link.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/use-hosted-flow-state.d.ts +9 -0
- package/lib/typescript/commonjs/ui/hooks/use-hosted-flow-state.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/hosted/hosted-payment-page.d.ts +17 -0
- package/lib/typescript/commonjs/ui/hosted/hosted-payment-page.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts +43 -0
- package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/index.d.ts +1 -3
- package/lib/typescript/commonjs/ui/screens/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/page-unavailable-screen.d.ts +18 -0
- package/lib/typescript/commonjs/ui/screens/page-unavailable-screen.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/spare-link-host.d.ts +4 -5
- package/lib/typescript/commonjs/ui/spare-link-host.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/widgets/index.d.ts +1 -2
- package/lib/typescript/commonjs/ui/widgets/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/version.d.ts +1 -1
- package/lib/typescript/commonjs/version.d.ts.map +1 -1
- package/lib/typescript/module/core/models/index.d.ts +1 -123
- package/lib/typescript/module/core/models/index.d.ts.map +1 -1
- package/lib/typescript/module/core/models/payment-return-params.d.ts +91 -8
- package/lib/typescript/module/core/models/payment-return-params.d.ts.map +1 -1
- package/lib/typescript/module/core/models/pending-session-record.d.ts +11 -0
- package/lib/typescript/module/core/models/pending-session-record.d.ts.map +1 -0
- package/lib/typescript/module/core/services/hosted-flow-controller.d.ts +119 -0
- package/lib/typescript/module/core/services/hosted-flow-controller.d.ts.map +1 -0
- package/lib/typescript/module/core/services/hosted-flow-state.d.ts +75 -0
- package/lib/typescript/module/core/services/hosted-flow-state.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +5 -14
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/internal/hosted/bridge-message.d.ts +44 -0
- package/lib/typescript/module/internal/hosted/bridge-message.d.ts.map +1 -0
- package/lib/typescript/module/internal/hosted/hosted-url.d.ts +30 -0
- package/lib/typescript/module/internal/hosted/hosted-url.d.ts.map +1 -0
- package/lib/typescript/module/internal/index.d.ts +0 -1
- package/lib/typescript/module/internal/index.d.ts.map +1 -1
- package/lib/typescript/module/internal/redact-uri.d.ts +21 -1
- package/lib/typescript/module/internal/redact-uri.d.ts.map +1 -1
- package/lib/typescript/module/internal/secure-store-pending-session-store.d.ts +3 -2
- package/lib/typescript/module/internal/secure-store-pending-session-store.d.ts.map +1 -1
- package/lib/typescript/module/internal/url-parts.d.ts +46 -0
- package/lib/typescript/module/internal/url-parts.d.ts.map +1 -0
- package/lib/typescript/module/public/index.d.ts +4 -6
- package/lib/typescript/module/public/index.d.ts.map +1 -1
- package/lib/typescript/module/public/payment-result.d.ts +50 -12
- package/lib/typescript/module/public/payment-result.d.ts.map +1 -1
- package/lib/typescript/module/public/recovery-result.d.ts +11 -20
- package/lib/typescript/module/public/recovery-result.d.ts.map +1 -1
- package/lib/typescript/module/public/spare-link-config.d.ts +13 -31
- package/lib/typescript/module/public/spare-link-config.d.ts.map +1 -1
- package/lib/typescript/module/public/spare-link-event.d.ts +29 -31
- package/lib/typescript/module/public/spare-link-event.d.ts.map +1 -1
- package/lib/typescript/module/public/spare-link-host-api.d.ts +1 -12
- package/lib/typescript/module/public/spare-link-host-api.d.ts.map +1 -1
- package/lib/typescript/module/public/spare-link-instance.d.ts +26 -20
- package/lib/typescript/module/public/spare-link-instance.d.ts.map +1 -1
- package/lib/typescript/module/public/spare-link-session.d.ts +3 -8
- package/lib/typescript/module/public/spare-link-session.d.ts.map +1 -1
- package/lib/typescript/module/public/spare-link.d.ts +1 -1
- package/lib/typescript/module/public/spare-link.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/use-hosted-flow-state.d.ts +9 -0
- package/lib/typescript/module/ui/hooks/use-hosted-flow-state.d.ts.map +1 -0
- package/lib/typescript/module/ui/hosted/hosted-payment-page.d.ts +17 -0
- package/lib/typescript/module/ui/hosted/hosted-payment-page.d.ts.map +1 -0
- package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts +43 -0
- package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/index.d.ts +1 -3
- package/lib/typescript/module/ui/screens/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/page-unavailable-screen.d.ts +18 -0
- package/lib/typescript/module/ui/screens/page-unavailable-screen.d.ts.map +1 -0
- package/lib/typescript/module/ui/spare-link-host.d.ts +4 -5
- package/lib/typescript/module/ui/spare-link-host.d.ts.map +1 -1
- package/lib/typescript/module/ui/widgets/index.d.ts +1 -2
- package/lib/typescript/module/ui/widgets/index.d.ts.map +1 -1
- package/lib/typescript/module/version.d.ts +1 -1
- package/lib/typescript/module/version.d.ts.map +1 -1
- package/package.json +24 -22
- package/plugins/with-spare-link.js +6 -26
- package/src/core/models/index.ts +1 -139
- package/src/core/models/payment-return-params.ts +269 -21
- package/src/core/models/pending-session-record.ts +10 -0
- package/src/core/services/hosted-flow-controller.ts +374 -0
- package/src/core/services/hosted-flow-state.ts +123 -0
- package/src/index.ts +20 -89
- package/src/internal/hosted/bridge-message.ts +106 -0
- package/src/internal/hosted/hosted-url.ts +33 -0
- package/src/internal/index.ts +0 -1
- package/src/internal/redact-uri.ts +69 -15
- package/src/internal/secure-store-pending-session-store.ts +28 -49
- package/src/internal/url-parts.ts +134 -0
- package/src/public/index.ts +2 -24
- package/src/public/payment-result.ts +50 -12
- package/src/public/recovery-result.ts +16 -25
- package/src/public/spare-link-config.ts +56 -43
- package/src/public/spare-link-event.ts +33 -42
- package/src/public/spare-link-host-api.ts +1 -14
- package/src/public/spare-link-instance.ts +57 -65
- package/src/public/spare-link-session.ts +4 -16
- package/src/public/spare-link.ts +1 -1
- package/src/ui/hooks/use-hosted-flow-state.ts +16 -0
- package/src/ui/hosted/hosted-payment-page.tsx +178 -0
- package/src/ui/hosted/hosted-payment-webview.tsx +164 -0
- package/src/ui/screens/index.ts +4 -6
- package/src/ui/screens/page-unavailable-screen.tsx +94 -0
- package/src/ui/spare-link-host.tsx +227 -247
- package/src/ui/widgets/index.ts +1 -2
- package/src/version.ts +1 -1
- package/CHANGELOG.md +0 -25
- package/lib/commonjs/core/client/link-api-client.js +0 -297
- package/lib/commonjs/core/client/link-api-client.js.map +0 -1
- package/lib/commonjs/core/errors/payment-api-error.js +0 -35
- package/lib/commonjs/core/errors/payment-api-error.js.map +0 -1
- package/lib/commonjs/core/models/link-session-status.js +0 -14
- package/lib/commonjs/core/models/link-session-status.js.map +0 -1
- package/lib/commonjs/core/models/payment-type.js +0 -45
- package/lib/commonjs/core/models/payment-type.js.map +0 -1
- package/lib/commonjs/core/models/wire-mappers.js +0 -277
- package/lib/commonjs/core/models/wire-mappers.js.map +0 -1
- package/lib/commonjs/core/services/consent-presenter.js +0 -150
- package/lib/commonjs/core/services/consent-presenter.js.map +0 -1
- package/lib/commonjs/core/services/execute-resume-if-needed.js +0 -216
- package/lib/commonjs/core/services/execute-resume-if-needed.js.map +0 -1
- package/lib/commonjs/core/services/multi-payment-rules-presenter.js +0 -151
- package/lib/commonjs/core/services/multi-payment-rules-presenter.js.map +0 -1
- package/lib/commonjs/core/services/payment-flow-controller.js +0 -547
- package/lib/commonjs/core/services/payment-flow-controller.js.map +0 -1
- package/lib/commonjs/core/services/payment-flow-state.js +0 -110
- package/lib/commonjs/core/services/payment-flow-state.js.map +0 -1
- package/lib/commonjs/core/services/payment-result-mapper.js +0 -49
- package/lib/commonjs/core/services/payment-result-mapper.js.map +0 -1
- package/lib/commonjs/core/services/presentation-utils.js +0 -11
- package/lib/commonjs/core/services/presentation-utils.js.map +0 -1
- package/lib/commonjs/core/services/redirect-buffer.js +0 -40
- package/lib/commonjs/core/services/redirect-buffer.js.map +0 -1
- package/lib/commonjs/core/services/user-friendly-messages.js +0 -46
- package/lib/commonjs/core/services/user-friendly-messages.js.map +0 -1
- package/lib/commonjs/internal/telemetry-collector.js +0 -80
- package/lib/commonjs/internal/telemetry-collector.js.map +0 -1
- package/lib/commonjs/public/constants.js +0 -21
- package/lib/commonjs/public/constants.js.map +0 -1
- package/lib/commonjs/public/spare-link-callbacks.js +0 -6
- package/lib/commonjs/public/spare-link-callbacks.js.map +0 -1
- package/lib/commonjs/ui/consent/charge-bearer-display.js +0 -99
- package/lib/commonjs/ui/consent/charge-bearer-display.js.map +0 -1
- package/lib/commonjs/ui/consent/consent-accordion.js +0 -94
- package/lib/commonjs/ui/consent/consent-accordion.js.map +0 -1
- package/lib/commonjs/ui/consent/consent-summary-section.js +0 -27
- package/lib/commonjs/ui/consent/consent-summary-section.js.map +0 -1
- package/lib/commonjs/ui/consent/cop-information.js +0 -168
- package/lib/commonjs/ui/consent/cop-information.js.map +0 -1
- package/lib/commonjs/ui/consent/international-payment-summary.js +0 -98
- package/lib/commonjs/ui/consent/international-payment-summary.js.map +0 -1
- package/lib/commonjs/ui/consent/label-value-rows.js +0 -59
- package/lib/commonjs/ui/consent/label-value-rows.js.map +0 -1
- package/lib/commonjs/ui/consent/multi-payment-rules-list.js +0 -130
- package/lib/commonjs/ui/consent/multi-payment-rules-list.js.map +0 -1
- package/lib/commonjs/ui/consent/multi-payment-summary.js +0 -99
- package/lib/commonjs/ui/consent/multi-payment-summary.js.map +0 -1
- package/lib/commonjs/ui/consent/single-payment-summary.js +0 -158
- package/lib/commonjs/ui/consent/single-payment-summary.js.map +0 -1
- package/lib/commonjs/ui/consent/terms-link.js +0 -35
- package/lib/commonjs/ui/consent/terms-link.js.map +0 -1
- package/lib/commonjs/ui/hooks/use-payment-flow-state.js.map +0 -1
- package/lib/commonjs/ui/payment-flow-page.js +0 -235
- package/lib/commonjs/ui/payment-flow-page.js.map +0 -1
- package/lib/commonjs/ui/screens/bank-selection-screen.js +0 -215
- package/lib/commonjs/ui/screens/bank-selection-screen.js.map +0 -1
- package/lib/commonjs/ui/screens/consent-details-screen.js +0 -124
- package/lib/commonjs/ui/screens/consent-details-screen.js.map +0 -1
- package/lib/commonjs/ui/screens/mandate-setup-success-screen.js +0 -79
- package/lib/commonjs/ui/screens/mandate-setup-success-screen.js.map +0 -1
- package/lib/commonjs/ui/widgets/layout-w-header.js +0 -106
- package/lib/commonjs/ui/widgets/layout-w-header.js.map +0 -1
- package/lib/commonjs/ui/widgets/stepper.js +0 -124
- package/lib/commonjs/ui/widgets/stepper.js.map +0 -1
- package/lib/module/core/client/link-api-client.js +0 -292
- package/lib/module/core/client/link-api-client.js.map +0 -1
- package/lib/module/core/errors/payment-api-error.js +0 -29
- package/lib/module/core/errors/payment-api-error.js.map +0 -1
- package/lib/module/core/models/link-session-status.js +0 -10
- package/lib/module/core/models/link-session-status.js.map +0 -1
- package/lib/module/core/models/payment-type.js +0 -36
- package/lib/module/core/models/payment-type.js.map +0 -1
- package/lib/module/core/models/wire-mappers.js +0 -263
- package/lib/module/core/models/wire-mappers.js.map +0 -1
- package/lib/module/core/services/consent-presenter.js +0 -140
- package/lib/module/core/services/consent-presenter.js.map +0 -1
- package/lib/module/core/services/execute-resume-if-needed.js +0 -211
- package/lib/module/core/services/execute-resume-if-needed.js.map +0 -1
- package/lib/module/core/services/multi-payment-rules-presenter.js +0 -146
- package/lib/module/core/services/multi-payment-rules-presenter.js.map +0 -1
- package/lib/module/core/services/payment-flow-controller.js +0 -544
- package/lib/module/core/services/payment-flow-controller.js.map +0 -1
- package/lib/module/core/services/payment-flow-state.js +0 -106
- package/lib/module/core/services/payment-flow-state.js.map +0 -1
- package/lib/module/core/services/payment-result-mapper.js +0 -45
- package/lib/module/core/services/payment-result-mapper.js.map +0 -1
- package/lib/module/core/services/presentation-utils.js +0 -7
- package/lib/module/core/services/presentation-utils.js.map +0 -1
- package/lib/module/core/services/redirect-buffer.js +0 -33
- package/lib/module/core/services/redirect-buffer.js.map +0 -1
- package/lib/module/core/services/user-friendly-messages.js +0 -42
- package/lib/module/core/services/user-friendly-messages.js.map +0 -1
- package/lib/module/internal/telemetry-collector.js +0 -75
- package/lib/module/internal/telemetry-collector.js.map +0 -1
- package/lib/module/public/constants.js +0 -17
- package/lib/module/public/constants.js.map +0 -1
- package/lib/module/public/spare-link-callbacks.js +0 -4
- package/lib/module/public/spare-link-callbacks.js.map +0 -1
- package/lib/module/ui/consent/charge-bearer-display.js +0 -95
- package/lib/module/ui/consent/charge-bearer-display.js.map +0 -1
- package/lib/module/ui/consent/consent-accordion.js +0 -90
- package/lib/module/ui/consent/consent-accordion.js.map +0 -1
- package/lib/module/ui/consent/consent-summary-section.js +0 -23
- package/lib/module/ui/consent/consent-summary-section.js.map +0 -1
- package/lib/module/ui/consent/cop-information.js +0 -165
- package/lib/module/ui/consent/cop-information.js.map +0 -1
- package/lib/module/ui/consent/international-payment-summary.js +0 -94
- package/lib/module/ui/consent/international-payment-summary.js.map +0 -1
- package/lib/module/ui/consent/label-value-rows.js +0 -55
- package/lib/module/ui/consent/label-value-rows.js.map +0 -1
- package/lib/module/ui/consent/multi-payment-rules-list.js +0 -125
- package/lib/module/ui/consent/multi-payment-rules-list.js.map +0 -1
- package/lib/module/ui/consent/multi-payment-summary.js +0 -95
- package/lib/module/ui/consent/multi-payment-summary.js.map +0 -1
- package/lib/module/ui/consent/single-payment-summary.js +0 -154
- package/lib/module/ui/consent/single-payment-summary.js.map +0 -1
- package/lib/module/ui/consent/terms-link.js +0 -31
- package/lib/module/ui/consent/terms-link.js.map +0 -1
- package/lib/module/ui/hooks/use-payment-flow-state.js.map +0 -1
- package/lib/module/ui/payment-flow-page.js +0 -232
- package/lib/module/ui/payment-flow-page.js.map +0 -1
- package/lib/module/ui/screens/bank-selection-screen.js +0 -211
- package/lib/module/ui/screens/bank-selection-screen.js.map +0 -1
- package/lib/module/ui/screens/consent-details-screen.js +0 -120
- package/lib/module/ui/screens/consent-details-screen.js.map +0 -1
- package/lib/module/ui/screens/mandate-setup-success-screen.js +0 -75
- package/lib/module/ui/screens/mandate-setup-success-screen.js.map +0 -1
- package/lib/module/ui/widgets/layout-w-header.js +0 -102
- package/lib/module/ui/widgets/layout-w-header.js.map +0 -1
- package/lib/module/ui/widgets/stepper.js +0 -120
- package/lib/module/ui/widgets/stepper.js.map +0 -1
- package/lib/typescript/commonjs/core/client/link-api-client.d.ts +0 -70
- package/lib/typescript/commonjs/core/client/link-api-client.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/errors/payment-api-error.d.ts +0 -15
- package/lib/typescript/commonjs/core/errors/payment-api-error.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/models/link-session-status.d.ts +0 -6
- package/lib/typescript/commonjs/core/models/link-session-status.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/models/payment-type.d.ts +0 -18
- package/lib/typescript/commonjs/core/models/payment-type.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/models/wire-mappers.d.ts +0 -19
- package/lib/typescript/commonjs/core/models/wire-mappers.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/services/consent-presenter.d.ts +0 -67
- package/lib/typescript/commonjs/core/services/consent-presenter.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/services/execute-resume-if-needed.d.ts +0 -32
- package/lib/typescript/commonjs/core/services/execute-resume-if-needed.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/services/multi-payment-rules-presenter.d.ts +0 -9
- package/lib/typescript/commonjs/core/services/multi-payment-rules-presenter.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/services/payment-flow-controller.d.ts +0 -146
- package/lib/typescript/commonjs/core/services/payment-flow-controller.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/services/payment-flow-state.d.ts +0 -64
- package/lib/typescript/commonjs/core/services/payment-flow-state.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/services/payment-result-mapper.d.ts +0 -5
- package/lib/typescript/commonjs/core/services/payment-result-mapper.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/services/presentation-utils.d.ts +0 -5
- package/lib/typescript/commonjs/core/services/presentation-utils.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/services/redirect-buffer.d.ts +0 -6
- package/lib/typescript/commonjs/core/services/redirect-buffer.d.ts.map +0 -1
- package/lib/typescript/commonjs/core/services/user-friendly-messages.d.ts +0 -6
- package/lib/typescript/commonjs/core/services/user-friendly-messages.d.ts.map +0 -1
- package/lib/typescript/commonjs/internal/telemetry-collector.d.ts +0 -2
- package/lib/typescript/commonjs/internal/telemetry-collector.d.ts.map +0 -1
- package/lib/typescript/commonjs/public/constants.d.ts +0 -12
- package/lib/typescript/commonjs/public/constants.d.ts.map +0 -1
- package/lib/typescript/commonjs/public/spare-link-callbacks.d.ts +0 -14
- package/lib/typescript/commonjs/public/spare-link-callbacks.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/charge-bearer-display.d.ts +0 -5
- package/lib/typescript/commonjs/ui/consent/charge-bearer-display.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/consent-accordion.d.ts +0 -10
- package/lib/typescript/commonjs/ui/consent/consent-accordion.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/consent-summary-section.d.ts +0 -6
- package/lib/typescript/commonjs/ui/consent/consent-summary-section.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/cop-information.d.ts +0 -6
- package/lib/typescript/commonjs/ui/consent/cop-information.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/international-payment-summary.d.ts +0 -6
- package/lib/typescript/commonjs/ui/consent/international-payment-summary.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/label-value-rows.d.ts +0 -10
- package/lib/typescript/commonjs/ui/consent/label-value-rows.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/multi-payment-rules-list.d.ts +0 -15
- package/lib/typescript/commonjs/ui/consent/multi-payment-rules-list.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/multi-payment-summary.d.ts +0 -6
- package/lib/typescript/commonjs/ui/consent/multi-payment-summary.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/single-payment-summary.d.ts +0 -6
- package/lib/typescript/commonjs/ui/consent/single-payment-summary.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/consent/terms-link.d.ts +0 -2
- package/lib/typescript/commonjs/ui/consent/terms-link.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/hooks/use-payment-flow-state.d.ts +0 -9
- package/lib/typescript/commonjs/ui/hooks/use-payment-flow-state.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/payment-flow-page.d.ts +0 -20
- package/lib/typescript/commonjs/ui/payment-flow-page.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/screens/bank-selection-screen.d.ts +0 -15
- package/lib/typescript/commonjs/ui/screens/bank-selection-screen.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/screens/consent-details-screen.d.ts +0 -13
- package/lib/typescript/commonjs/ui/screens/consent-details-screen.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/screens/mandate-setup-success-screen.d.ts +0 -10
- package/lib/typescript/commonjs/ui/screens/mandate-setup-success-screen.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/widgets/layout-w-header.d.ts +0 -20
- package/lib/typescript/commonjs/ui/widgets/layout-w-header.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/widgets/stepper.d.ts +0 -15
- package/lib/typescript/commonjs/ui/widgets/stepper.d.ts.map +0 -1
- package/lib/typescript/module/core/client/link-api-client.d.ts +0 -70
- package/lib/typescript/module/core/client/link-api-client.d.ts.map +0 -1
- package/lib/typescript/module/core/errors/payment-api-error.d.ts +0 -15
- package/lib/typescript/module/core/errors/payment-api-error.d.ts.map +0 -1
- package/lib/typescript/module/core/models/link-session-status.d.ts +0 -6
- package/lib/typescript/module/core/models/link-session-status.d.ts.map +0 -1
- package/lib/typescript/module/core/models/payment-type.d.ts +0 -18
- package/lib/typescript/module/core/models/payment-type.d.ts.map +0 -1
- package/lib/typescript/module/core/models/wire-mappers.d.ts +0 -19
- package/lib/typescript/module/core/models/wire-mappers.d.ts.map +0 -1
- package/lib/typescript/module/core/services/consent-presenter.d.ts +0 -67
- package/lib/typescript/module/core/services/consent-presenter.d.ts.map +0 -1
- package/lib/typescript/module/core/services/execute-resume-if-needed.d.ts +0 -32
- package/lib/typescript/module/core/services/execute-resume-if-needed.d.ts.map +0 -1
- package/lib/typescript/module/core/services/multi-payment-rules-presenter.d.ts +0 -9
- package/lib/typescript/module/core/services/multi-payment-rules-presenter.d.ts.map +0 -1
- package/lib/typescript/module/core/services/payment-flow-controller.d.ts +0 -146
- package/lib/typescript/module/core/services/payment-flow-controller.d.ts.map +0 -1
- package/lib/typescript/module/core/services/payment-flow-state.d.ts +0 -64
- package/lib/typescript/module/core/services/payment-flow-state.d.ts.map +0 -1
- package/lib/typescript/module/core/services/payment-result-mapper.d.ts +0 -5
- package/lib/typescript/module/core/services/payment-result-mapper.d.ts.map +0 -1
- package/lib/typescript/module/core/services/presentation-utils.d.ts +0 -5
- package/lib/typescript/module/core/services/presentation-utils.d.ts.map +0 -1
- package/lib/typescript/module/core/services/redirect-buffer.d.ts +0 -6
- package/lib/typescript/module/core/services/redirect-buffer.d.ts.map +0 -1
- package/lib/typescript/module/core/services/user-friendly-messages.d.ts +0 -6
- package/lib/typescript/module/core/services/user-friendly-messages.d.ts.map +0 -1
- package/lib/typescript/module/internal/telemetry-collector.d.ts +0 -2
- package/lib/typescript/module/internal/telemetry-collector.d.ts.map +0 -1
- package/lib/typescript/module/public/constants.d.ts +0 -12
- package/lib/typescript/module/public/constants.d.ts.map +0 -1
- package/lib/typescript/module/public/spare-link-callbacks.d.ts +0 -14
- package/lib/typescript/module/public/spare-link-callbacks.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/charge-bearer-display.d.ts +0 -5
- package/lib/typescript/module/ui/consent/charge-bearer-display.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/consent-accordion.d.ts +0 -10
- package/lib/typescript/module/ui/consent/consent-accordion.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/consent-summary-section.d.ts +0 -6
- package/lib/typescript/module/ui/consent/consent-summary-section.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/cop-information.d.ts +0 -6
- package/lib/typescript/module/ui/consent/cop-information.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/international-payment-summary.d.ts +0 -6
- package/lib/typescript/module/ui/consent/international-payment-summary.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/label-value-rows.d.ts +0 -10
- package/lib/typescript/module/ui/consent/label-value-rows.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/multi-payment-rules-list.d.ts +0 -15
- package/lib/typescript/module/ui/consent/multi-payment-rules-list.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/multi-payment-summary.d.ts +0 -6
- package/lib/typescript/module/ui/consent/multi-payment-summary.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/single-payment-summary.d.ts +0 -6
- package/lib/typescript/module/ui/consent/single-payment-summary.d.ts.map +0 -1
- package/lib/typescript/module/ui/consent/terms-link.d.ts +0 -2
- package/lib/typescript/module/ui/consent/terms-link.d.ts.map +0 -1
- package/lib/typescript/module/ui/hooks/use-payment-flow-state.d.ts +0 -9
- package/lib/typescript/module/ui/hooks/use-payment-flow-state.d.ts.map +0 -1
- package/lib/typescript/module/ui/payment-flow-page.d.ts +0 -20
- package/lib/typescript/module/ui/payment-flow-page.d.ts.map +0 -1
- package/lib/typescript/module/ui/screens/bank-selection-screen.d.ts +0 -15
- package/lib/typescript/module/ui/screens/bank-selection-screen.d.ts.map +0 -1
- package/lib/typescript/module/ui/screens/consent-details-screen.d.ts +0 -13
- package/lib/typescript/module/ui/screens/consent-details-screen.d.ts.map +0 -1
- package/lib/typescript/module/ui/screens/mandate-setup-success-screen.d.ts +0 -10
- package/lib/typescript/module/ui/screens/mandate-setup-success-screen.d.ts.map +0 -1
- package/lib/typescript/module/ui/widgets/layout-w-header.d.ts +0 -20
- package/lib/typescript/module/ui/widgets/layout-w-header.d.ts.map +0 -1
- package/lib/typescript/module/ui/widgets/stepper.d.ts +0 -15
- package/lib/typescript/module/ui/widgets/stepper.d.ts.map +0 -1
- package/src/core/client/link-api-client.ts +0 -414
- package/src/core/errors/payment-api-error.ts +0 -35
- package/src/core/models/link-session-status.ts +0 -7
- package/src/core/models/payment-type.ts +0 -54
- package/src/core/models/wire-mappers.ts +0 -315
- package/src/core/services/consent-presenter.ts +0 -213
- package/src/core/services/execute-resume-if-needed.ts +0 -243
- package/src/core/services/multi-payment-rules-presenter.ts +0 -158
- package/src/core/services/payment-flow-controller.ts +0 -607
- package/src/core/services/payment-flow-state.ts +0 -124
- package/src/core/services/payment-result-mapper.ts +0 -41
- package/src/core/services/presentation-utils.ts +0 -4
- package/src/core/services/redirect-buffer.ts +0 -34
- package/src/core/services/user-friendly-messages.ts +0 -39
- package/src/internal/telemetry-collector.ts +0 -90
- package/src/public/constants.ts +0 -14
- package/src/public/spare-link-callbacks.ts +0 -20
- package/src/ui/consent/charge-bearer-display.tsx +0 -68
- package/src/ui/consent/consent-accordion.tsx +0 -89
- package/src/ui/consent/consent-summary-section.tsx +0 -19
- package/src/ui/consent/cop-information.tsx +0 -121
- package/src/ui/consent/international-payment-summary.tsx +0 -83
- package/src/ui/consent/label-value-rows.tsx +0 -50
- package/src/ui/consent/multi-payment-rules-list.tsx +0 -138
- package/src/ui/consent/multi-payment-summary.tsx +0 -82
- package/src/ui/consent/single-payment-summary.tsx +0 -123
- package/src/ui/consent/terms-link.tsx +0 -27
- package/src/ui/hooks/use-payment-flow-state.ts +0 -16
- package/src/ui/payment-flow-page.tsx +0 -254
- package/src/ui/screens/bank-selection-screen.tsx +0 -209
- package/src/ui/screens/consent-details-screen.tsx +0 -106
- package/src/ui/screens/mandate-setup-success-screen.tsx +0 -72
- package/src/ui/widgets/layout-w-header.tsx +0 -89
- package/src/ui/widgets/stepper.tsx +0 -126
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useSyncExternalStore } from 'react';
|
|
2
|
+
import type { HostedFlowController } from '../../core/services/hosted-flow-controller';
|
|
3
|
+
import type { HostedFlowState } from '../../core/services/hosted-flow-state';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* React hook that bridges {@link HostedFlowController}'s observable to the
|
|
7
|
+
* component tree via `useSyncExternalStore`. Re-renders when the controller
|
|
8
|
+
* notifies a new state.
|
|
9
|
+
*/
|
|
10
|
+
export function useHostedFlowState(controller: HostedFlowController): HostedFlowState {
|
|
11
|
+
return useSyncExternalStore(
|
|
12
|
+
(notify) => controller.subscribe(notify),
|
|
13
|
+
() => controller.state,
|
|
14
|
+
() => controller.state,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
2
|
+
import { ActivityIndicator, StyleSheet, Text, View } from 'react-native';
|
|
3
|
+
import type { HostedFlowController } from '../../core/services/hosted-flow-controller';
|
|
4
|
+
import { isTerminalPhase } from '../../core/services/hosted-flow-state';
|
|
5
|
+
import { useHostedFlowState } from '../hooks/use-hosted-flow-state';
|
|
6
|
+
import { PageUnavailableScreen } from '../screens/page-unavailable-screen';
|
|
7
|
+
import { RedirectHandoffScreen } from '../screens/redirect-handoff-screen';
|
|
8
|
+
import { ResultScreen } from '../screens/result-screen';
|
|
9
|
+
import { ResumeProcessingScreen } from '../screens/resume-processing-screen';
|
|
10
|
+
import { Colors, Spacing, Typography } from '../theme';
|
|
11
|
+
import { HostedPaymentWebView } from './hosted-payment-webview';
|
|
12
|
+
|
|
13
|
+
/** How long a resolved outcome stays on screen before the flow hands back. */
|
|
14
|
+
const RESULT_DWELL_MS = 1200;
|
|
15
|
+
|
|
16
|
+
export interface HostedPaymentPageProps {
|
|
17
|
+
controller: HostedFlowController;
|
|
18
|
+
/** Resolved API base URL — the hosted page is served from the same host. */
|
|
19
|
+
baseUrl: string;
|
|
20
|
+
/** Called once the outcome has been shown and the flow should hand back. */
|
|
21
|
+
onResolved: () => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The screen a payer sees for the whole flow.
|
|
26
|
+
*
|
|
27
|
+
* Most of it is the hosted page. The native screens cover the moments the page
|
|
28
|
+
* cannot: while it loads, while the payer is away at their bank, and once there is
|
|
29
|
+
* an outcome to report.
|
|
30
|
+
*/
|
|
31
|
+
export function HostedPaymentPage(props: HostedPaymentPageProps): JSX.Element {
|
|
32
|
+
const { controller, baseUrl, onResolved } = props;
|
|
33
|
+
const state = useHostedFlowState(controller);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* When the payer left for the bank.
|
|
37
|
+
*
|
|
38
|
+
* Held here rather than in the waiting screen because returning from the browser
|
|
39
|
+
* can remount it, and a fresh component would otherwise restart the wait from
|
|
40
|
+
* zero and never offer the payer a way out.
|
|
41
|
+
*/
|
|
42
|
+
const awaitingSinceMs = useRef<number | undefined>(undefined);
|
|
43
|
+
if (state.phase === 'awaitingCallback' && awaitingSinceMs.current === undefined) {
|
|
44
|
+
awaitingSinceMs.current = Date.now();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Only a page that was *never reached* gets the recovery treatment: the payer
|
|
48
|
+
// already read why and chose to leave, so there is nothing to report back and no
|
|
49
|
+
// reason to show a result screen on the way out.
|
|
50
|
+
//
|
|
51
|
+
// A page that failed after it was working (`page_lost`) is a different case. It
|
|
52
|
+
// is terminal, so a retry there would render a button that does nothing, and the
|
|
53
|
+
// payer has not read anything yet — they get the result screen.
|
|
54
|
+
const wasNeverReached = state.errorCode === 'page_unavailable';
|
|
55
|
+
|
|
56
|
+
// Leaves the outcome on screen briefly, then hands it to the caller. Resolving in
|
|
57
|
+
// the same frame the outcome arrives would flash the result past a payer who has
|
|
58
|
+
// been waiting on it.
|
|
59
|
+
const resolved = isTerminalPhase(state.phase);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (!resolved) return;
|
|
62
|
+
const timer = setTimeout(onResolved, wasNeverReached ? 0 : RESULT_DWELL_MS);
|
|
63
|
+
return () => clearTimeout(timer);
|
|
64
|
+
}, [resolved, onResolved, wasNeverReached]);
|
|
65
|
+
|
|
66
|
+
const handleBridgeMessage = useCallback(
|
|
67
|
+
(message: unknown) => {
|
|
68
|
+
void controller.handleBridgeMessage(message);
|
|
69
|
+
},
|
|
70
|
+
[controller],
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const handleLoadFailure = useCallback(() => {
|
|
74
|
+
controller.failToLoad();
|
|
75
|
+
}, [controller]);
|
|
76
|
+
|
|
77
|
+
const handlePageMounted = useCallback(() => {
|
|
78
|
+
controller.reportPageMounted();
|
|
79
|
+
}, [controller]);
|
|
80
|
+
|
|
81
|
+
const handleRetry = useCallback(() => {
|
|
82
|
+
controller.retry();
|
|
83
|
+
}, [controller]);
|
|
84
|
+
|
|
85
|
+
const handleGiveUp = useCallback(() => {
|
|
86
|
+
controller.giveUp();
|
|
87
|
+
}, [controller]);
|
|
88
|
+
|
|
89
|
+
switch (state.phase) {
|
|
90
|
+
case 'loading':
|
|
91
|
+
case 'hosted':
|
|
92
|
+
return (
|
|
93
|
+
<View style={styles.fill}>
|
|
94
|
+
<View
|
|
95
|
+
style={styles.fill}
|
|
96
|
+
// While covered the page is not just invisible but unreachable: left
|
|
97
|
+
// in the tree, a screen reader could act on content nobody can see.
|
|
98
|
+
accessibilityElementsHidden={state.phase === 'loading'}
|
|
99
|
+
importantForAccessibility={state.phase === 'loading' ? 'no-hide-descendants' : 'auto'}
|
|
100
|
+
>
|
|
101
|
+
<HostedPaymentWebView
|
|
102
|
+
// Keyed on the attempt so a retry mounts a fresh webview. Reusing the
|
|
103
|
+
// instance that failed would show the payer the same dead frame.
|
|
104
|
+
key={state.attempt}
|
|
105
|
+
baseUrl={baseUrl}
|
|
106
|
+
reference={controller.reference}
|
|
107
|
+
onBridgeMessage={handleBridgeMessage}
|
|
108
|
+
onLoadFailure={handleLoadFailure}
|
|
109
|
+
onMounted={handlePageMounted}
|
|
110
|
+
/>
|
|
111
|
+
</View>
|
|
112
|
+
{/*
|
|
113
|
+
The webview is a blank frame until the page paints, and a retry starts
|
|
114
|
+
that over. Covered rather than tinted, so the payer sees something
|
|
115
|
+
happening instead of a white void they cannot interpret.
|
|
116
|
+
*/}
|
|
117
|
+
{state.phase === 'loading' ? (
|
|
118
|
+
<View style={styles.loadingCover} testID="hosted-payment-loading">
|
|
119
|
+
{/*
|
|
120
|
+
Not GradientSpinner: its stops run white → teal → white and its
|
|
121
|
+
no-SVG fallback draws a white top border, so on a white cover
|
|
122
|
+
most of the arc would be invisible — the opposite of the point.
|
|
123
|
+
*/}
|
|
124
|
+
<ActivityIndicator
|
|
125
|
+
size="large"
|
|
126
|
+
color={Colors.spareBlue}
|
|
127
|
+
testID="hosted-payment-loading-spinner"
|
|
128
|
+
/>
|
|
129
|
+
<Text style={[Typography.bodyMuted, styles.loadingLabel]}>
|
|
130
|
+
{state.attempt > 1 ? 'Trying again…' : 'Loading your payment…'}
|
|
131
|
+
</Text>
|
|
132
|
+
</View>
|
|
133
|
+
) : null}
|
|
134
|
+
</View>
|
|
135
|
+
);
|
|
136
|
+
case 'unreachable':
|
|
137
|
+
return <PageUnavailableScreen onRetry={handleRetry} onCancel={handleGiveUp} />;
|
|
138
|
+
case 'redirecting':
|
|
139
|
+
return <RedirectHandoffScreen />;
|
|
140
|
+
case 'awaitingCallback':
|
|
141
|
+
return (
|
|
142
|
+
<ResumeProcessingScreen
|
|
143
|
+
{...(awaitingSinceMs.current !== undefined
|
|
144
|
+
? { awaitingCallbackStartedAtMs: awaitingSinceMs.current }
|
|
145
|
+
: {})}
|
|
146
|
+
// The bank may never send the payer back. This is their way out of a
|
|
147
|
+
// screen that would otherwise wait forever. It reports the flow as
|
|
148
|
+
// unresolved rather than cancelled, because a payer who authorized and
|
|
149
|
+
// then lost the return has still paid.
|
|
150
|
+
onCancel={() => controller.abandon()}
|
|
151
|
+
/>
|
|
152
|
+
);
|
|
153
|
+
case 'succeeded':
|
|
154
|
+
return <ResultScreen title="Payment complete" isSuccess onDone={onResolved} />;
|
|
155
|
+
case 'failed':
|
|
156
|
+
return wasNeverReached ? (
|
|
157
|
+
<PageUnavailableScreen onRetry={handleRetry} onCancel={handleGiveUp} />
|
|
158
|
+
) : (
|
|
159
|
+
<ResultScreen title="Payment failed" isSuccess={false} onDone={onResolved} />
|
|
160
|
+
);
|
|
161
|
+
case 'cancelled':
|
|
162
|
+
return <ResultScreen title="Payment cancelled" isSuccess={false} onDone={onResolved} />;
|
|
163
|
+
case 'abandoned':
|
|
164
|
+
return <ResultScreen title="Payment not completed" isSuccess={false} onDone={onResolved} />;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const styles = StyleSheet.create({
|
|
169
|
+
fill: { flex: 1, backgroundColor: Colors.surfacePage },
|
|
170
|
+
loadingCover: {
|
|
171
|
+
...StyleSheet.absoluteFillObject,
|
|
172
|
+
alignItems: 'center',
|
|
173
|
+
justifyContent: 'center',
|
|
174
|
+
gap: Spacing.lg,
|
|
175
|
+
backgroundColor: Colors.surfacePage,
|
|
176
|
+
},
|
|
177
|
+
loadingLabel: { textAlign: 'center' },
|
|
178
|
+
});
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { useCallback, useEffect } from 'react';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
|
+
import { WebView, type WebViewMessageEvent } from 'react-native-webview';
|
|
4
|
+
import { buildHostedPaymentUrl, isHostedOriginUrl } from '../../internal/hosted/hosted-url';
|
|
5
|
+
import { createLogger } from '../../internal/logger';
|
|
6
|
+
import { parseUrlParts } from '../../internal/url-parts';
|
|
7
|
+
import { Colors } from '../theme';
|
|
8
|
+
|
|
9
|
+
const log = createLogger('HostedPaymentWebView');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Reduces a URL to scheme and host for logging.
|
|
13
|
+
*
|
|
14
|
+
* The path carries the payment request reference, which is the flow's only
|
|
15
|
+
* credential and stays out of the log. Scheme and host are what distinguish a
|
|
16
|
+
* misconfigured environment from a service that is down.
|
|
17
|
+
*/
|
|
18
|
+
function safeOrigin(url: string): string {
|
|
19
|
+
const parts = parseUrlParts(url);
|
|
20
|
+
return parts ? `${parts.scheme}://${parts.host}` : '[unparseable URL]';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Whether a navigation the WebView is about to make should be allowed.
|
|
25
|
+
*
|
|
26
|
+
* Only the hosted origin may load in-frame. Bank authentication deliberately
|
|
27
|
+
* happens in a real browser, so a bank URL arriving here means the page's handoff
|
|
28
|
+
* did not reach us — following it would put the payer on a bank page with no
|
|
29
|
+
* address bar, which is the signal they rely on to tell a real one from a copy.
|
|
30
|
+
* Kept as a plain function because the WebView does not render under Jest, and
|
|
31
|
+
* this is the part worth testing.
|
|
32
|
+
*/
|
|
33
|
+
export function shouldAllowHostedNavigation(args: { baseUrl: string; url: string }): boolean {
|
|
34
|
+
return isHostedOriginUrl(args);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface HostedPaymentWebViewProps {
|
|
38
|
+
/** Resolved API base URL — the hosted page is served from the same host. */
|
|
39
|
+
baseUrl: string;
|
|
40
|
+
/** The payment request this flow is paying. */
|
|
41
|
+
reference: string;
|
|
42
|
+
/**
|
|
43
|
+
* Called with each raw message the page posts. Parsing belongs to the caller so
|
|
44
|
+
* this component stays a transport.
|
|
45
|
+
*/
|
|
46
|
+
onBridgeMessage: (message: unknown) => void;
|
|
47
|
+
/** Called when the page itself could not be loaded. */
|
|
48
|
+
onLoadFailure?: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Called once this webview is on screen.
|
|
51
|
+
*
|
|
52
|
+
* Starts the clock the page has to become interactive, measured from here so
|
|
53
|
+
* that whatever the host did before rendering is not charged against it.
|
|
54
|
+
*/
|
|
55
|
+
onMounted?: () => void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Hosts the hosted payment page.
|
|
60
|
+
*
|
|
61
|
+
* The page owns bank selection, the payee check and the consent screen, so this
|
|
62
|
+
* component carries no payment logic of its own: it loads one URL, forwards what
|
|
63
|
+
* the page reports, and refuses to navigate anywhere else.
|
|
64
|
+
*/
|
|
65
|
+
export function HostedPaymentWebView(props: HostedPaymentWebViewProps): JSX.Element {
|
|
66
|
+
const { baseUrl, reference, onBridgeMessage, onLoadFailure, onMounted } = props;
|
|
67
|
+
const uri = buildHostedPaymentUrl({ baseUrl, reference });
|
|
68
|
+
|
|
69
|
+
// This reports that *this* webview exists, and a retry mounts a fresh instance
|
|
70
|
+
// which reports itself anew. Re-running on a new callback identity would
|
|
71
|
+
// restart the page's clock without a new page having been asked for.
|
|
72
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: mount-only by design
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
onMounted?.();
|
|
75
|
+
}, []);
|
|
76
|
+
|
|
77
|
+
const handleMessage = useCallback(
|
|
78
|
+
(event: WebViewMessageEvent) => {
|
|
79
|
+
onBridgeMessage(event.nativeEvent.data);
|
|
80
|
+
},
|
|
81
|
+
[onBridgeMessage],
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Every navigation is routed through here rather than through `originWhitelist`.
|
|
85
|
+
// A URL that fails the whitelist is handed to `Linking.openURL` by
|
|
86
|
+
// react-native-webview with no scheme check of its own and without consulting
|
|
87
|
+
// this callback, which would let the page reach `intent://` or any registered
|
|
88
|
+
// scheme on the device. Whitelisting everything keeps that branch unreachable
|
|
89
|
+
// and leaves the decision here, where an off-origin navigation is refused
|
|
90
|
+
// outright and the bank arrives over the bridge instead.
|
|
91
|
+
const handleShouldStartLoad = useCallback(
|
|
92
|
+
({ url }: { url: string }) => shouldAllowHostedNavigation({ baseUrl, url }),
|
|
93
|
+
[baseUrl],
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
// The page is a full-bleed document that knows nothing about this device's
|
|
98
|
+
// notch or home indicator. `SpareLinkHost` holds the inset out for the whole
|
|
99
|
+
// modal, so this fills what it is given.
|
|
100
|
+
<View style={styles.container} testID="hosted-payment-webview">
|
|
101
|
+
<WebView
|
|
102
|
+
source={{ uri }}
|
|
103
|
+
onMessage={handleMessage}
|
|
104
|
+
originWhitelist={ALLOW_ALL_ORIGINS}
|
|
105
|
+
onShouldStartLoadWithRequest={handleShouldStartLoad}
|
|
106
|
+
// react-native-webview reports only main-frame failures: `onHttpError` is
|
|
107
|
+
// guarded by `isForMainFrame`, and it overrides the main-frame-only
|
|
108
|
+
// `onReceivedError` overload. So a 404 on a favicon the WebView asked for
|
|
109
|
+
// on its own cannot fail the payment.
|
|
110
|
+
//
|
|
111
|
+
// What went wrong is logged before it is collapsed into
|
|
112
|
+
// `page_unavailable`, which on its own cannot tell a service that is down
|
|
113
|
+
// from a host that was never reachable.
|
|
114
|
+
onError={({ nativeEvent }) => {
|
|
115
|
+
log.severe(
|
|
116
|
+
`could not load the payment page from ${safeOrigin(uri)} ` +
|
|
117
|
+
`(${nativeEvent.description ?? `code ${nativeEvent.code}`})`,
|
|
118
|
+
);
|
|
119
|
+
onLoadFailure?.();
|
|
120
|
+
}}
|
|
121
|
+
onHttpError={({ nativeEvent }) => {
|
|
122
|
+
log.severe(
|
|
123
|
+
`the payment page at ${safeOrigin(uri)} answered ` + `HTTP ${nativeEvent.statusCode}`,
|
|
124
|
+
);
|
|
125
|
+
onLoadFailure?.();
|
|
126
|
+
}}
|
|
127
|
+
// A webview whose process dies reports neither of the callbacks above: the
|
|
128
|
+
// frame simply goes blank and stays blank. iOS terminates the content
|
|
129
|
+
// process under memory pressure and Android's renderer can be reclaimed
|
|
130
|
+
// outright, so both are treated as the page having failed to load.
|
|
131
|
+
onContentProcessDidTerminate={() => {
|
|
132
|
+
log.severe('the payment page process was terminated by the system (iOS)');
|
|
133
|
+
onLoadFailure?.();
|
|
134
|
+
}}
|
|
135
|
+
onRenderProcessGone={({ nativeEvent }) => {
|
|
136
|
+
log.severe(
|
|
137
|
+
`the payment page renderer was lost (Android, crashed=${nativeEvent.didCrash})`,
|
|
138
|
+
);
|
|
139
|
+
onLoadFailure?.();
|
|
140
|
+
}}
|
|
141
|
+
style={styles.webview}
|
|
142
|
+
javaScriptEnabled
|
|
143
|
+
domStorageEnabled
|
|
144
|
+
// The page holds a payment in progress and nothing else should share its
|
|
145
|
+
// storage, on this device or between payers on it.
|
|
146
|
+
incognito
|
|
147
|
+
// The bank is handed to the OS browser over the bridge, so nothing here
|
|
148
|
+
// needs popups.
|
|
149
|
+
setSupportMultipleWindows={false}
|
|
150
|
+
allowFileAccess={false}
|
|
151
|
+
allowUniversalAccessFromFileURLs={false}
|
|
152
|
+
allowFileAccessFromFileURLs={false}
|
|
153
|
+
testID="hosted-payment-webview-instance"
|
|
154
|
+
/>
|
|
155
|
+
</View>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const ALLOW_ALL_ORIGINS = ['*'];
|
|
160
|
+
|
|
161
|
+
const styles = StyleSheet.create({
|
|
162
|
+
container: { flex: 1, backgroundColor: Colors.surfacePage },
|
|
163
|
+
webview: { flex: 1, backgroundColor: Colors.surfacePage },
|
|
164
|
+
});
|
package/src/ui/screens/index.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
1
|
+
export {
|
|
2
|
+
PageUnavailableScreen,
|
|
3
|
+
type PageUnavailableScreenProps,
|
|
4
|
+
} from './page-unavailable-screen';
|
|
3
5
|
export { RedirectHandoffScreen } from './redirect-handoff-screen';
|
|
4
6
|
export {
|
|
5
7
|
ResumeProcessingScreen,
|
|
6
8
|
type ResumeProcessingScreenProps,
|
|
7
9
|
} from './resume-processing-screen';
|
|
8
10
|
export { ResultScreen, type ResultScreenProps } from './result-screen';
|
|
9
|
-
export {
|
|
10
|
-
MandateSetupSuccessScreen,
|
|
11
|
-
type MandateSetupSuccessScreenProps,
|
|
12
|
-
} from './mandate-setup-success-screen';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Ionicons } from '@expo/vector-icons';
|
|
2
|
+
import { Pressable, StyleSheet, Text, View } from 'react-native';
|
|
3
|
+
import { Colors, Spacing, Typography } from '../theme';
|
|
4
|
+
|
|
5
|
+
export interface PageUnavailableScreenProps {
|
|
6
|
+
/** Asks for the payment page again. */
|
|
7
|
+
onRetry: () => void;
|
|
8
|
+
/** Gives up and hands the outcome back to the caller. */
|
|
9
|
+
onCancel: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Shown when the payment page could not be loaded, or loaded and never became
|
|
14
|
+
* interactive.
|
|
15
|
+
*
|
|
16
|
+
* It deliberately does not say the payment failed. Nothing has been attempted at
|
|
17
|
+
* this point — no consent, no bank, no money — and telling a payer their payment
|
|
18
|
+
* failed when the app could not open the page is the one thing they must not be
|
|
19
|
+
* told. It says what is true, says nothing has been taken, and offers the page
|
|
20
|
+
* again, because an unreachable service is usually unreachable briefly.
|
|
21
|
+
*/
|
|
22
|
+
export function PageUnavailableScreen(props: PageUnavailableScreenProps): JSX.Element {
|
|
23
|
+
return (
|
|
24
|
+
<View style={styles.container} testID="page-unavailable-screen">
|
|
25
|
+
<View style={styles.iconBubble}>
|
|
26
|
+
<Ionicons name="cloud-offline-outline" size={36} color={Colors.textMuted} />
|
|
27
|
+
</View>
|
|
28
|
+
<Text style={Typography.title} testID="page-unavailable-message">
|
|
29
|
+
We couldn't reach the payment service
|
|
30
|
+
</Text>
|
|
31
|
+
<Text style={[Typography.bodyMuted, styles.centered]}>
|
|
32
|
+
No payment has been taken. Check your connection and try again.
|
|
33
|
+
</Text>
|
|
34
|
+
<Pressable
|
|
35
|
+
onPress={props.onRetry}
|
|
36
|
+
accessibilityRole="button"
|
|
37
|
+
testID="page-unavailable-retry-btn"
|
|
38
|
+
style={[styles.button, styles.retryButton]}
|
|
39
|
+
>
|
|
40
|
+
<Text style={[Typography.button, styles.retryLabel]}>Try again</Text>
|
|
41
|
+
</Pressable>
|
|
42
|
+
<Pressable
|
|
43
|
+
onPress={props.onCancel}
|
|
44
|
+
accessibilityRole="button"
|
|
45
|
+
testID="page-unavailable-cancel-btn"
|
|
46
|
+
style={[styles.button, styles.cancelButton]}
|
|
47
|
+
>
|
|
48
|
+
<Text style={[Typography.button, styles.cancelLabel]}>Cancel</Text>
|
|
49
|
+
</Pressable>
|
|
50
|
+
</View>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const styles = StyleSheet.create({
|
|
55
|
+
container: {
|
|
56
|
+
flex: 1,
|
|
57
|
+
alignItems: 'center',
|
|
58
|
+
justifyContent: 'center',
|
|
59
|
+
padding: Spacing.xl,
|
|
60
|
+
gap: Spacing.lg,
|
|
61
|
+
backgroundColor: Colors.surfacePage,
|
|
62
|
+
},
|
|
63
|
+
iconBubble: {
|
|
64
|
+
width: 72,
|
|
65
|
+
height: 72,
|
|
66
|
+
borderRadius: 36,
|
|
67
|
+
alignItems: 'center',
|
|
68
|
+
justifyContent: 'center',
|
|
69
|
+
backgroundColor: Colors.surfaceMuted,
|
|
70
|
+
},
|
|
71
|
+
centered: {
|
|
72
|
+
textAlign: 'center',
|
|
73
|
+
},
|
|
74
|
+
button: {
|
|
75
|
+
paddingHorizontal: Spacing.xl,
|
|
76
|
+
paddingVertical: Spacing.md,
|
|
77
|
+
borderRadius: 12,
|
|
78
|
+
minWidth: 160,
|
|
79
|
+
alignItems: 'center',
|
|
80
|
+
},
|
|
81
|
+
retryButton: {
|
|
82
|
+
marginTop: Spacing.md,
|
|
83
|
+
backgroundColor: Colors.spareBlue,
|
|
84
|
+
},
|
|
85
|
+
retryLabel: {
|
|
86
|
+
color: '#FFFFFF',
|
|
87
|
+
},
|
|
88
|
+
cancelButton: {
|
|
89
|
+
backgroundColor: Colors.surfaceMuted,
|
|
90
|
+
},
|
|
91
|
+
cancelLabel: {
|
|
92
|
+
color: Colors.textPrimary,
|
|
93
|
+
},
|
|
94
|
+
});
|