@primer-io/react-native 2.45.0 → 3.0.0-beta.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/android/build.gradle +3 -1
- package/android/src/main/java/com/primerioreactnative/DefaultNativePrimerModule.kt +64 -0
- package/android/src/main/java/com/primerioreactnative/PrimerRNHeadlessUniversalCheckoutListener.kt +36 -2
- package/android/src/main/java/com/primerioreactnative/PrimerSdkPackage.kt +2 -0
- package/android/src/main/java/com/primerioreactnative/PrimerViewUtilsImpl.kt +33 -0
- package/android/src/main/java/com/primerioreactnative/components/datamodels/manager/raw/billingAddress/PrimerRNAddress.kt +29 -0
- package/android/src/main/java/com/primerioreactnative/components/datamodels/manager/raw/card/PrimerRNCardData.kt +3 -0
- package/android/src/main/java/com/primerioreactnative/components/manager/asset/PrimerRNHeadlessUniversalCheckoutAssetManager.kt +49 -0
- package/android/src/main/java/com/primerioreactnative/components/manager/raw/PrimerRNHeadlessUniversalCheckoutRawManager.kt +61 -3
- package/android/src/main/java/com/primerioreactnative/components/manager/vault/PrimerRNHeadlessUniversalCheckoutVaultManager.kt +6 -0
- package/android/src/main/java/com/primerioreactnative/datamodels/PrimerClientSessionRN.kt +7 -0
- package/android/src/main/java/com/primerioreactnative/datamodels/PrimerErrorRN.kt +1 -0
- package/android/src/main/java/com/primerioreactnative/extensions/PrimerClientSession.kt +14 -10
- package/android/src/main/java/com/primerioreactnative/utils/AnalyticsEventMapper.kt +115 -0
- package/android/src/newarch/java/com/primerioreactnative/NativePrimerModule.kt +28 -0
- package/android/src/newarch/java/com/primerioreactnative/PrimerViewUtilsModule.kt +24 -0
- package/android/src/oldarch/java/com/primerioreactnative/NativePrimerModule.kt +32 -0
- package/android/src/oldarch/java/com/primerioreactnative/PrimerViewUtilsModule.kt +27 -0
- package/android/src/test/java/com/primerioreactnative/utils/AnalyticsEventMapperTest.kt +351 -0
- package/ios/Sources/DataModels/PrimerAddress+Extension.swift +35 -0
- package/ios/Sources/DataModels/PrimerCardData+Extension.swift +9 -1
- package/ios/Sources/Headless Universal Checkout/Managers/Assets Manager/RNTAssetsManager.m +7 -0
- package/ios/Sources/Headless Universal Checkout/Managers/Assets Manager/RNTAssetsManager.swift +46 -13
- package/ios/Sources/Headless Universal Checkout/Managers/Payment Method Managers/RNPrimerHeadlessUniversalCheckoutVaultManager.m +2 -0
- package/ios/Sources/Headless Universal Checkout/Managers/Payment Method Managers/RNPrimerHeadlessUniversalCheckoutVaultManager.swift +12 -1
- package/ios/Sources/Headless Universal Checkout/Managers/Payment Method Managers/RNTRawDataManager.m +2 -0
- package/ios/Sources/Headless Universal Checkout/Managers/Payment Method Managers/RNTRawDataManager.swift +45 -2
- package/ios/Sources/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckout.swift +61 -3
- package/ios/Sources/NativePrimer/RCTNativePrimer.mm +47 -1
- package/ios/Sources/PrimerViewUtils/RCTPrimerViewUtils.h +10 -0
- package/ios/Sources/PrimerViewUtils/RCTPrimerViewUtils.mm +41 -0
- package/ios/Sources/PrimerViewUtils/RNTPrimerViewUtils.swift +23 -0
- package/ios/Sources/RNTPrimer.swift +88 -3
- package/ios/Sources/version.swift +1 -1
- package/lib/module/Components/PrimerAcceptedCardNetworks.js +73 -0
- package/lib/module/Components/PrimerAcceptedCardNetworks.js.map +1 -0
- package/lib/module/Components/PrimerBillingAddressForm.js +167 -0
- package/lib/module/Components/PrimerBillingAddressForm.js.map +1 -0
- package/lib/module/Components/PrimerCardForm.js +97 -0
- package/lib/module/Components/PrimerCardForm.js.map +1 -0
- package/lib/module/Components/PrimerCardNetworkSelector.js +164 -0
- package/lib/module/Components/PrimerCardNetworkSelector.js.map +1 -0
- package/lib/module/Components/PrimerCheckoutProvider.js +1059 -0
- package/lib/module/Components/PrimerCheckoutProvider.js.map +1 -0
- package/lib/module/Components/PrimerCheckoutSheet.js +28 -0
- package/lib/module/Components/PrimerCheckoutSheet.js.map +1 -0
- package/lib/module/Components/PrimerPaymentMethodList.js +80 -0
- package/lib/module/Components/PrimerPaymentMethodList.js.map +1 -0
- package/lib/module/Components/PrimerVaultedPaymentMethod.js +234 -0
- package/lib/module/Components/PrimerVaultedPaymentMethod.js.map +1 -0
- package/lib/module/Components/analytics.js +18 -0
- package/lib/module/Components/analytics.js.map +1 -0
- package/lib/module/Components/hooks/useCardNetworkDescriptor.js +25 -0
- package/lib/module/Components/hooks/useCardNetworkDescriptor.js.map +1 -0
- package/lib/module/Components/hooks/useCardNetworkIcons.js +44 -0
- package/lib/module/Components/hooks/useCardNetworkIcons.js.map +1 -0
- package/lib/module/Components/hooks/usePrimerBillingAddressForm.js +27 -0
- package/lib/module/Components/hooks/usePrimerBillingAddressForm.js.map +1 -0
- package/lib/module/Components/hooks/usePrimerCardForm.js +44 -0
- package/lib/module/Components/hooks/usePrimerCardForm.js.map +1 -0
- package/lib/module/Components/hooks/usePrimerCardNetwork.js +70 -0
- package/lib/module/Components/hooks/usePrimerCardNetwork.js.map +1 -0
- package/lib/module/Components/hooks/usePrimerCardNetworkSelection.js +70 -0
- package/lib/module/Components/hooks/usePrimerCardNetworkSelection.js.map +1 -0
- package/lib/module/Components/hooks/usePrimerCheckout.js +12 -0
- package/lib/module/Components/hooks/usePrimerCheckout.js.map +1 -0
- package/lib/module/Components/hooks/usePrimerPaymentMethod.js +94 -0
- package/lib/module/Components/hooks/usePrimerPaymentMethod.js.map +1 -0
- package/lib/module/Components/hooks/usePrimerPaymentMethods.js +159 -0
- package/lib/module/Components/hooks/usePrimerPaymentMethods.js.map +1 -0
- package/lib/module/Components/hooks/usePrimerVaultManager.js +85 -0
- package/lib/module/Components/hooks/usePrimerVaultManager.js.map +1 -0
- package/lib/module/Components/index.js +22 -0
- package/lib/module/Components/index.js.map +1 -0
- package/lib/module/Components/inputs/CountrySelectorRow.js +117 -0
- package/lib/module/Components/inputs/CountrySelectorRow.js.map +1 -0
- package/lib/module/Components/inputs/PrimerCVVInput.js +51 -0
- package/lib/module/Components/inputs/PrimerCVVInput.js.map +1 -0
- package/lib/module/Components/inputs/PrimerCardNumberInput.js +134 -0
- package/lib/module/Components/inputs/PrimerCardNumberInput.js.map +1 -0
- package/lib/module/Components/inputs/PrimerCardholderNameInput.js +33 -0
- package/lib/module/Components/inputs/PrimerCardholderNameInput.js.map +1 -0
- package/lib/module/Components/inputs/PrimerExpiryDateInput.js +92 -0
- package/lib/module/Components/inputs/PrimerExpiryDateInput.js.map +1 -0
- package/lib/module/Components/inputs/PrimerTextInput.js +182 -0
- package/lib/module/Components/inputs/PrimerTextInput.js.map +1 -0
- package/lib/module/Components/inputs/caret.js +37 -0
- package/lib/module/Components/inputs/caret.js.map +1 -0
- package/lib/module/Components/inputs/dimensions.js +18 -0
- package/lib/module/Components/inputs/dimensions.js.map +1 -0
- package/lib/module/Components/inputs/index.js +9 -0
- package/lib/module/Components/inputs/index.js.map +1 -0
- package/lib/module/Components/internal/CardNetworkBadge.js +113 -0
- package/lib/module/Components/internal/CardNetworkBadge.js.map +1 -0
- package/lib/module/Components/internal/Popover.js +85 -0
- package/lib/module/Components/internal/Popover.js.map +1 -0
- package/lib/module/Components/internal/PrimerCheckoutContext.js +5 -0
- package/lib/module/Components/internal/PrimerCheckoutContext.js.map +1 -0
- package/lib/module/Components/internal/applePay.js +14 -0
- package/lib/module/Components/internal/applePay.js.map +1 -0
- package/lib/module/Components/internal/billingAddressOptions.js +29 -0
- package/lib/module/Components/internal/billingAddressOptions.js.map +1 -0
- package/lib/module/Components/internal/cardFormat.js +41 -0
- package/lib/module/Components/internal/cardFormat.js.map +1 -0
- package/lib/module/Components/internal/cardNetwork.js +85 -0
- package/lib/module/Components/internal/cardNetwork.js.map +1 -0
- package/lib/module/Components/internal/cardNetworkIcons.js +28 -0
- package/lib/module/Components/internal/cardNetworkIcons.js.map +1 -0
- package/lib/module/Components/internal/checkout-flow/CheckoutFlow.js +129 -0
- package/lib/module/Components/internal/checkout-flow/CheckoutFlow.js.map +1 -0
- package/lib/module/Components/internal/checkout-flow/CheckoutFlowContext.js +12 -0
- package/lib/module/Components/internal/checkout-flow/CheckoutFlowContext.js.map +1 -0
- package/lib/module/Components/internal/checkout-flow/index.js +4 -0
- package/lib/module/Components/internal/checkout-flow/index.js.map +1 -0
- package/lib/module/Components/internal/checkout-sheet/CheckoutSheet.js +280 -0
- package/lib/module/Components/internal/checkout-sheet/CheckoutSheet.js.map +1 -0
- package/lib/module/Components/internal/checkout-sheet/SheetHeightContext.js +12 -0
- package/lib/module/Components/internal/checkout-sheet/SheetHeightContext.js.map +1 -0
- package/lib/module/Components/internal/checkout-sheet/index.js +5 -0
- package/lib/module/Components/internal/checkout-sheet/index.js.map +1 -0
- package/lib/module/Components/internal/checkout-sheet/types.js +4 -0
- package/lib/module/Components/internal/checkout-sheet/types.js.map +1 -0
- package/lib/module/Components/internal/countries.js +795 -0
- package/lib/module/Components/internal/countries.js.map +1 -0
- package/lib/module/Components/internal/currency/currencies.json +1 -0
- package/lib/module/Components/internal/currency/currency-metadata.js +52 -0
- package/lib/module/Components/internal/currency/currency-metadata.js.map +1 -0
- package/lib/module/Components/internal/currency/formatting.js +28 -0
- package/lib/module/Components/internal/currency/formatting.js.map +1 -0
- package/lib/module/Components/internal/currency/index.js +5 -0
- package/lib/module/Components/internal/currency/index.js.map +1 -0
- package/lib/module/Components/internal/debug.js +15 -0
- package/lib/module/Components/internal/debug.js.map +1 -0
- package/lib/module/Components/internal/flags.js +19 -0
- package/lib/module/Components/internal/flags.js.map +1 -0
- package/lib/module/Components/internal/form-state/BillingAddressFormStateProvider.js +221 -0
- package/lib/module/Components/internal/form-state/BillingAddressFormStateProvider.js.map +1 -0
- package/lib/module/Components/internal/form-state/CardFormStateProvider.js +271 -0
- package/lib/module/Components/internal/form-state/CardFormStateProvider.js.map +1 -0
- package/lib/module/Components/internal/form-state/index.js +5 -0
- package/lib/module/Components/internal/form-state/index.js.map +1 -0
- package/lib/module/Components/internal/googlePay.js +15 -0
- package/lib/module/Components/internal/googlePay.js.map +1 -0
- package/lib/module/Components/internal/localization/index.js +6 -0
- package/lib/module/Components/internal/localization/index.js.map +1 -0
- package/lib/module/Components/internal/localization/interpolation.js +13 -0
- package/lib/module/Components/internal/localization/interpolation.js.map +1 -0
- package/lib/module/Components/internal/localization/locale-resolver.js +40 -0
- package/lib/module/Components/internal/localization/locale-resolver.js.map +1 -0
- package/lib/module/Components/internal/localization/strings/ar.json +227 -0
- package/lib/module/Components/internal/localization/strings/az.json +227 -0
- package/lib/module/Components/internal/localization/strings/bg.json +227 -0
- package/lib/module/Components/internal/localization/strings/bs.json +227 -0
- package/lib/module/Components/internal/localization/strings/ca.json +227 -0
- package/lib/module/Components/internal/localization/strings/cs.json +227 -0
- package/lib/module/Components/internal/localization/strings/da.json +227 -0
- package/lib/module/Components/internal/localization/strings/de.json +227 -0
- package/lib/module/Components/internal/localization/strings/el.json +227 -0
- package/lib/module/Components/internal/localization/strings/en.json +256 -0
- package/lib/module/Components/internal/localization/strings/es-AR.json +227 -0
- package/lib/module/Components/internal/localization/strings/es-MX.json +227 -0
- package/lib/module/Components/internal/localization/strings/es.json +227 -0
- package/lib/module/Components/internal/localization/strings/et.json +227 -0
- package/lib/module/Components/internal/localization/strings/fa.json +227 -0
- package/lib/module/Components/internal/localization/strings/fi.json +227 -0
- package/lib/module/Components/internal/localization/strings/fil.json +227 -0
- package/lib/module/Components/internal/localization/strings/fr.json +227 -0
- package/lib/module/Components/internal/localization/strings/he.json +227 -0
- package/lib/module/Components/internal/localization/strings/hi.json +227 -0
- package/lib/module/Components/internal/localization/strings/hr.json +227 -0
- package/lib/module/Components/internal/localization/strings/hu.json +227 -0
- package/lib/module/Components/internal/localization/strings/hy.json +227 -0
- package/lib/module/Components/internal/localization/strings/id.json +227 -0
- package/lib/module/Components/internal/localization/strings/index.js +68 -0
- package/lib/module/Components/internal/localization/strings/index.js.map +1 -0
- package/lib/module/Components/internal/localization/strings/it.json +227 -0
- package/lib/module/Components/internal/localization/strings/ja.json +227 -0
- package/lib/module/Components/internal/localization/strings/ka.json +227 -0
- package/lib/module/Components/internal/localization/strings/kk.json +227 -0
- package/lib/module/Components/internal/localization/strings/ko.json +227 -0
- package/lib/module/Components/internal/localization/strings/ku.json +227 -0
- package/lib/module/Components/internal/localization/strings/ky.json +227 -0
- package/lib/module/Components/internal/localization/strings/lt.json +227 -0
- package/lib/module/Components/internal/localization/strings/lv.json +227 -0
- package/lib/module/Components/internal/localization/strings/mk.json +227 -0
- package/lib/module/Components/internal/localization/strings/ms.json +227 -0
- package/lib/module/Components/internal/localization/strings/nb.json +227 -0
- package/lib/module/Components/internal/localization/strings/nl-BE.json +227 -0
- package/lib/module/Components/internal/localization/strings/nl.json +227 -0
- package/lib/module/Components/internal/localization/strings/pl.json +227 -0
- package/lib/module/Components/internal/localization/strings/pt-BR.json +227 -0
- package/lib/module/Components/internal/localization/strings/pt.json +227 -0
- package/lib/module/Components/internal/localization/strings/ro.json +227 -0
- package/lib/module/Components/internal/localization/strings/ru.json +227 -0
- package/lib/module/Components/internal/localization/strings/sk.json +227 -0
- package/lib/module/Components/internal/localization/strings/sl.json +227 -0
- package/lib/module/Components/internal/localization/strings/sq.json +227 -0
- package/lib/module/Components/internal/localization/strings/sr.json +227 -0
- package/lib/module/Components/internal/localization/strings/sv.json +227 -0
- package/lib/module/Components/internal/localization/strings/th.json +227 -0
- package/lib/module/Components/internal/localization/strings/tr.json +227 -0
- package/lib/module/Components/internal/localization/strings/uk.json +227 -0
- package/lib/module/Components/internal/localization/strings/ur-PK.json +227 -0
- package/lib/module/Components/internal/localization/strings/uz.json +227 -0
- package/lib/module/Components/internal/localization/strings/vi.json +227 -0
- package/lib/module/Components/internal/localization/strings/zh-CN.json +227 -0
- package/lib/module/Components/internal/localization/strings/zh-HK.json +227 -0
- package/lib/module/Components/internal/localization/strings/zh-TW.json +227 -0
- package/lib/module/Components/internal/localization/translate.js +28 -0
- package/lib/module/Components/internal/localization/translate.js.map +1 -0
- package/lib/module/Components/internal/localization/types.js +2 -0
- package/lib/module/Components/internal/localization/types.js.map +1 -0
- package/lib/module/Components/internal/localization/usePrimerLocalization.js +22 -0
- package/lib/module/Components/internal/localization/usePrimerLocalization.js.map +1 -0
- package/lib/module/Components/internal/navigation/NavigationContainer.js +180 -0
- package/lib/module/Components/internal/navigation/NavigationContainer.js.map +1 -0
- package/lib/module/Components/internal/navigation/NavigationContext.js +6 -0
- package/lib/module/Components/internal/navigation/NavigationContext.js.map +1 -0
- package/lib/module/Components/internal/navigation/NavigationHeader.js +185 -0
- package/lib/module/Components/internal/navigation/NavigationHeader.js.map +1 -0
- package/lib/module/Components/internal/navigation/NavigationProvider.js +92 -0
- package/lib/module/Components/internal/navigation/NavigationProvider.js.map +1 -0
- package/lib/module/Components/internal/navigation/index.js +9 -0
- package/lib/module/Components/internal/navigation/index.js.map +1 -0
- package/lib/module/Components/internal/navigation/navigationReducer.js +52 -0
- package/lib/module/Components/internal/navigation/navigationReducer.js.map +1 -0
- package/lib/module/Components/internal/navigation/types.js +17 -0
- package/lib/module/Components/internal/navigation/types.js.map +1 -0
- package/lib/module/Components/internal/navigation/useNavigation.js +19 -0
- package/lib/module/Components/internal/navigation/useNavigation.js.map +1 -0
- package/lib/module/Components/internal/navigation/useRoute.js +17 -0
- package/lib/module/Components/internal/navigation/useRoute.js.map +1 -0
- package/lib/module/Components/internal/routeMethodSelection.js +30 -0
- package/lib/module/Components/internal/routeMethodSelection.js.map +1 -0
- package/lib/module/Components/internal/screens/CardFormScreen.js +226 -0
- package/lib/module/Components/internal/screens/CardFormScreen.js.map +1 -0
- package/lib/module/Components/internal/screens/CountrySelectorScreen.js +252 -0
- package/lib/module/Components/internal/screens/CountrySelectorScreen.js.map +1 -0
- package/lib/module/Components/internal/screens/ErrorScreen.js +75 -0
- package/lib/module/Components/internal/screens/ErrorScreen.js.map +1 -0
- package/lib/module/Components/internal/screens/LoadingScreen.js +41 -0
- package/lib/module/Components/internal/screens/LoadingScreen.js.map +1 -0
- package/lib/module/Components/internal/screens/MethodSelectionScreen.js +252 -0
- package/lib/module/Components/internal/screens/MethodSelectionScreen.js.map +1 -0
- package/lib/module/Components/internal/screens/SuccessScreen.js +49 -0
- package/lib/module/Components/internal/screens/SuccessScreen.js.map +1 -0
- package/lib/module/Components/internal/screens/VaultedMethodsScreen.js +525 -0
- package/lib/module/Components/internal/screens/VaultedMethodsScreen.js.map +1 -0
- package/lib/module/Components/internal/screens/assets/check-circle-large.png +0 -0
- package/lib/module/Components/internal/screens/assets/check-circle-large@2x.png +0 -0
- package/lib/module/Components/internal/screens/assets/check-circle-large@3x.png +0 -0
- package/lib/module/Components/internal/screens/assets/check.png +0 -0
- package/lib/module/Components/internal/screens/assets/check@2x.png +0 -0
- package/lib/module/Components/internal/screens/assets/check@3x.png +0 -0
- package/lib/module/Components/internal/screens/assets/chevron-down.png +0 -0
- package/lib/module/Components/internal/screens/assets/chevron-down@2x.png +0 -0
- package/lib/module/Components/internal/screens/assets/chevron-down@3x.png +0 -0
- package/lib/module/Components/internal/screens/assets/close.png +0 -0
- package/lib/module/Components/internal/screens/assets/close@2x.png +0 -0
- package/lib/module/Components/internal/screens/assets/close@3x.png +0 -0
- package/lib/module/Components/internal/screens/assets/done.png +0 -0
- package/lib/module/Components/internal/screens/assets/done@2x.png +0 -0
- package/lib/module/Components/internal/screens/assets/done@3x.png +0 -0
- package/lib/module/Components/internal/screens/assets/edit.png +0 -0
- package/lib/module/Components/internal/screens/assets/edit@2x.png +0 -0
- package/lib/module/Components/internal/screens/assets/edit@3x.png +0 -0
- package/lib/module/Components/internal/screens/assets/error-large.png +0 -0
- package/lib/module/Components/internal/screens/assets/error-large@2x.png +0 -0
- package/lib/module/Components/internal/screens/assets/error-large@3x.png +0 -0
- package/lib/module/Components/internal/screens/assets/lock.png +0 -0
- package/lib/module/Components/internal/screens/assets/lock@2x.png +0 -0
- package/lib/module/Components/internal/screens/assets/lock@3x.png +0 -0
- package/lib/module/Components/internal/screens/constants.js +4 -0
- package/lib/module/Components/internal/screens/constants.js.map +1 -0
- package/lib/module/Components/internal/screens/index.js +8 -0
- package/lib/module/Components/internal/screens/index.js.map +1 -0
- package/lib/module/Components/internal/screens/useBottomSafeArea.js +20 -0
- package/lib/module/Components/internal/screens/useBottomSafeArea.js.map +1 -0
- package/lib/module/Components/internal/screens/useKeyboardHeight.js +32 -0
- package/lib/module/Components/internal/screens/useKeyboardHeight.js.map +1 -0
- package/lib/module/Components/internal/screens/useKeyboardPadding.js +28 -0
- package/lib/module/Components/internal/screens/useKeyboardPadding.js.map +1 -0
- package/lib/module/Components/internal/screens/useStatusScreenHeight.js +14 -0
- package/lib/module/Components/internal/screens/useStatusScreenHeight.js.map +1 -0
- package/lib/module/Components/internal/theme/ThemeContext.js +5 -0
- package/lib/module/Components/internal/theme/ThemeContext.js.map +1 -0
- package/lib/module/Components/internal/theme/index.js +6 -0
- package/lib/module/Components/internal/theme/index.js.map +1 -0
- package/lib/module/Components/internal/theme/merge.js +39 -0
- package/lib/module/Components/internal/theme/merge.js.map +1 -0
- package/lib/module/Components/internal/theme/tokens/dark.js +108 -0
- package/lib/module/Components/internal/theme/tokens/dark.js.map +1 -0
- package/lib/module/Components/internal/theme/tokens/index.js +5 -0
- package/lib/module/Components/internal/theme/tokens/index.js.map +1 -0
- package/lib/module/Components/internal/theme/tokens/light.js +138 -0
- package/lib/module/Components/internal/theme/tokens/light.js.map +1 -0
- package/lib/module/Components/internal/theme/types.js +2 -0
- package/lib/module/Components/internal/theme/types.js.map +1 -0
- package/lib/module/Components/internal/theme/usePrimerTheme.js +14 -0
- package/lib/module/Components/internal/theme/usePrimerTheme.js.map +1 -0
- package/lib/module/Components/internal/ui/CheckoutButton.js +89 -0
- package/lib/module/Components/internal/ui/CheckoutButton.js.map +1 -0
- package/lib/module/Components/internal/ui/PaymentMethodButton.js +169 -0
- package/lib/module/Components/internal/ui/PaymentMethodButton.js.map +1 -0
- package/lib/module/Components/internal/ui/VaultedCardCvvRow.js +110 -0
- package/lib/module/Components/internal/ui/VaultedCardCvvRow.js.map +1 -0
- package/lib/module/Components/internal/ui/index.js +5 -0
- package/lib/module/Components/internal/ui/index.js.map +1 -0
- package/lib/module/Components/internal/utils/errors.js +12 -0
- package/lib/module/Components/internal/utils/errors.js.map +1 -0
- package/lib/module/Components/internal/utils/formatting.js +30 -0
- package/lib/module/Components/internal/utils/formatting.js.map +1 -0
- package/lib/module/Components/status/PrimerErrorScreen.js +69 -0
- package/lib/module/Components/status/PrimerErrorScreen.js.map +1 -0
- package/lib/module/Components/status/PrimerLoadingScreen.js +48 -0
- package/lib/module/Components/status/PrimerLoadingScreen.js.map +1 -0
- package/lib/module/Components/status/PrimerStatusScreenLayout.js +85 -0
- package/lib/module/Components/status/PrimerStatusScreenLayout.js.map +1 -0
- package/lib/module/Components/status/PrimerSuccessScreen.js +43 -0
- package/lib/module/Components/status/PrimerSuccessScreen.js.map +1 -0
- package/lib/module/Components/status/index.js +7 -0
- package/lib/module/Components/status/index.js.map +1 -0
- package/lib/module/Components/types/BillingAddressFormTypes.js +4 -0
- package/lib/module/Components/types/BillingAddressFormTypes.js.map +1 -0
- package/lib/module/Components/types/CardFormTypes.js +4 -0
- package/lib/module/Components/types/CardFormTypes.js.map +1 -0
- package/lib/module/Components/types/CardInputTypes.js +4 -0
- package/lib/module/Components/types/CardInputTypes.js.map +1 -0
- package/lib/module/Components/types/CardNetworkSelection.js +4 -0
- package/lib/module/Components/types/CardNetworkSelection.js.map +1 -0
- package/lib/module/Components/types/PaymentMethodTypes.js +4 -0
- package/lib/module/Components/types/PaymentMethodTypes.js.map +1 -0
- package/lib/module/Components/types/PrimerCardFormTypes.js +4 -0
- package/lib/module/Components/types/PrimerCardFormTypes.js.map +1 -0
- package/lib/module/Components/types/PrimerCheckoutProviderTypes.js +4 -0
- package/lib/module/Components/types/PrimerCheckoutProviderTypes.js.map +1 -0
- package/lib/module/Components/types/PrimerPaymentMethodListTypes.js +4 -0
- package/lib/module/Components/types/PrimerPaymentMethodListTypes.js.map +1 -0
- package/lib/module/Components/types/PrimerPaymentMethodTypes.js +4 -0
- package/lib/module/Components/types/PrimerPaymentMethodTypes.js.map +1 -0
- package/lib/module/Components/types/VaultedPaymentMethodTypes.js +4 -0
- package/lib/module/Components/types/VaultedPaymentMethodTypes.js.map +1 -0
- package/lib/module/HeadlessUniversalCheckout/Managers/AssetsManager.js +22 -0
- package/lib/module/HeadlessUniversalCheckout/Managers/AssetsManager.js.map +1 -1
- package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/AchManager.js +6 -6
- package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/AchManager.js.map +1 -1
- package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.js +6 -6
- package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.js.map +1 -1
- package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.js +23 -0
- package/lib/module/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.js.map +1 -1
- package/lib/module/HeadlessUniversalCheckout/Managers/VaultManager.js +11 -0
- package/lib/module/HeadlessUniversalCheckout/Managers/VaultManager.js.map +1 -1
- package/lib/module/HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.js +6 -6
- package/lib/module/HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.js.map +1 -1
- package/lib/module/Primer.js +11 -11
- package/lib/module/Primer.js.map +1 -1
- package/lib/module/RNPrimer.js +41 -0
- package/lib/module/RNPrimer.js.map +1 -1
- package/lib/module/assets/images/ic-card-placeholder.png +0 -0
- package/lib/module/assets/images/ic-card-placeholder@2x.png +0 -0
- package/lib/module/assets/images/ic-card-placeholder@3x.png +0 -0
- package/lib/module/assets/images/ic-cvv-hint.png +0 -0
- package/lib/module/assets/images/ic-cvv-hint@2x.png +0 -0
- package/lib/module/assets/images/ic-cvv-hint@3x.png +0 -0
- package/lib/module/assets/images/ic-expiry-calendar.png +0 -0
- package/lib/module/assets/images/ic-expiry-calendar@2x.png +0 -0
- package/lib/module/assets/images/ic-expiry-calendar@3x.png +0 -0
- package/lib/module/index.js +24 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/PrimerCheckoutData.js.map +1 -1
- package/lib/module/specs/NativePrimer.js.map +1 -1
- package/lib/module/specs/NativePrimerViewUtils.js +5 -0
- package/lib/module/specs/NativePrimerViewUtils.js.map +1 -0
- package/lib/module/utils/debounce.js +31 -0
- package/lib/module/utils/debounce.js.map +1 -0
- package/lib/module/utils/index.js +0 -8
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/src/Components/PrimerAcceptedCardNetworks.d.ts +9 -0
- package/lib/typescript/src/Components/PrimerAcceptedCardNetworks.d.ts.map +1 -0
- package/lib/typescript/src/Components/PrimerBillingAddressForm.d.ts +3 -0
- package/lib/typescript/src/Components/PrimerBillingAddressForm.d.ts.map +1 -0
- package/lib/typescript/src/Components/PrimerCardForm.d.ts +3 -0
- package/lib/typescript/src/Components/PrimerCardForm.d.ts.map +1 -0
- package/lib/typescript/src/Components/PrimerCardNetworkSelector.d.ts +5 -0
- package/lib/typescript/src/Components/PrimerCardNetworkSelector.d.ts.map +1 -0
- package/lib/typescript/src/Components/PrimerCheckoutProvider.d.ts +3 -0
- package/lib/typescript/src/Components/PrimerCheckoutProvider.d.ts.map +1 -0
- package/lib/typescript/src/Components/PrimerCheckoutSheet.d.ts +18 -0
- package/lib/typescript/src/Components/PrimerCheckoutSheet.d.ts.map +1 -0
- package/lib/typescript/src/Components/PrimerPaymentMethodList.d.ts +3 -0
- package/lib/typescript/src/Components/PrimerPaymentMethodList.d.ts.map +1 -0
- package/lib/typescript/src/Components/PrimerVaultedPaymentMethod.d.ts +5 -0
- package/lib/typescript/src/Components/PrimerVaultedPaymentMethod.d.ts.map +1 -0
- package/lib/typescript/src/Components/analytics.d.ts +7 -0
- package/lib/typescript/src/Components/analytics.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/useCardNetworkDescriptor.d.ts +8 -0
- package/lib/typescript/src/Components/hooks/useCardNetworkDescriptor.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/useCardNetworkIcons.d.ts +19 -0
- package/lib/typescript/src/Components/hooks/useCardNetworkIcons.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/usePrimerBillingAddressForm.d.ts +13 -0
- package/lib/typescript/src/Components/hooks/usePrimerBillingAddressForm.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/usePrimerCardForm.d.ts +12 -0
- package/lib/typescript/src/Components/hooks/usePrimerCardForm.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/usePrimerCardNetwork.d.ts +21 -0
- package/lib/typescript/src/Components/hooks/usePrimerCardNetwork.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/usePrimerCardNetworkSelection.d.ts +3 -0
- package/lib/typescript/src/Components/hooks/usePrimerCardNetworkSelection.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/usePrimerCheckout.d.ts +3 -0
- package/lib/typescript/src/Components/hooks/usePrimerCheckout.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/usePrimerPaymentMethod.d.ts +9 -0
- package/lib/typescript/src/Components/hooks/usePrimerPaymentMethod.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/usePrimerPaymentMethods.d.ts +3 -0
- package/lib/typescript/src/Components/hooks/usePrimerPaymentMethods.d.ts.map +1 -0
- package/lib/typescript/src/Components/hooks/usePrimerVaultManager.d.ts +3 -0
- package/lib/typescript/src/Components/hooks/usePrimerVaultManager.d.ts.map +1 -0
- package/lib/typescript/src/Components/index.d.ts +36 -0
- package/lib/typescript/src/Components/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/inputs/CountrySelectorRow.d.ts +21 -0
- package/lib/typescript/src/Components/inputs/CountrySelectorRow.d.ts.map +1 -0
- package/lib/typescript/src/Components/inputs/PrimerCVVInput.d.ts +3 -0
- package/lib/typescript/src/Components/inputs/PrimerCVVInput.d.ts.map +1 -0
- package/lib/typescript/src/Components/inputs/PrimerCardNumberInput.d.ts +3 -0
- package/lib/typescript/src/Components/inputs/PrimerCardNumberInput.d.ts.map +1 -0
- package/lib/typescript/src/Components/inputs/PrimerCardholderNameInput.d.ts +3 -0
- package/lib/typescript/src/Components/inputs/PrimerCardholderNameInput.d.ts.map +1 -0
- package/lib/typescript/src/Components/inputs/PrimerExpiryDateInput.d.ts +3 -0
- package/lib/typescript/src/Components/inputs/PrimerExpiryDateInput.d.ts.map +1 -0
- package/lib/typescript/src/Components/inputs/PrimerTextInput.d.ts +4 -0
- package/lib/typescript/src/Components/inputs/PrimerTextInput.d.ts.map +1 -0
- package/lib/typescript/src/Components/inputs/caret.d.ts +5 -0
- package/lib/typescript/src/Components/inputs/caret.d.ts.map +1 -0
- package/lib/typescript/src/Components/inputs/dimensions.d.ts +7 -0
- package/lib/typescript/src/Components/inputs/dimensions.d.ts.map +1 -0
- package/lib/typescript/src/Components/inputs/index.d.ts +8 -0
- package/lib/typescript/src/Components/inputs/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/CardNetworkBadge.d.ts +7 -0
- package/lib/typescript/src/Components/internal/CardNetworkBadge.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/Popover.d.ts +15 -0
- package/lib/typescript/src/Components/internal/Popover.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/PrimerCheckoutContext.d.ts +3 -0
- package/lib/typescript/src/Components/internal/PrimerCheckoutContext.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/applePay.d.ts +11 -0
- package/lib/typescript/src/Components/internal/applePay.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/billingAddressOptions.d.ts +9 -0
- package/lib/typescript/src/Components/internal/billingAddressOptions.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/cardFormat.d.ts +20 -0
- package/lib/typescript/src/Components/internal/cardFormat.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/cardNetwork.d.ts +55 -0
- package/lib/typescript/src/Components/internal/cardNetwork.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/cardNetworkIcons.d.ts +10 -0
- package/lib/typescript/src/Components/internal/cardNetworkIcons.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/checkout-flow/CheckoutFlow.d.ts +5 -0
- package/lib/typescript/src/Components/internal/checkout-flow/CheckoutFlow.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/checkout-flow/CheckoutFlowContext.d.ts +7 -0
- package/lib/typescript/src/Components/internal/checkout-flow/CheckoutFlowContext.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/checkout-flow/index.d.ts +2 -0
- package/lib/typescript/src/Components/internal/checkout-flow/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/checkout-sheet/CheckoutSheet.d.ts +3 -0
- package/lib/typescript/src/Components/internal/checkout-sheet/CheckoutSheet.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/checkout-sheet/SheetHeightContext.d.ts +14 -0
- package/lib/typescript/src/Components/internal/checkout-sheet/SheetHeightContext.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/checkout-sheet/index.d.ts +5 -0
- package/lib/typescript/src/Components/internal/checkout-sheet/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/checkout-sheet/types.d.ts +21 -0
- package/lib/typescript/src/Components/internal/checkout-sheet/types.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/countries.d.ts +751 -0
- package/lib/typescript/src/Components/internal/countries.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/currency/currency-metadata.d.ts +7 -0
- package/lib/typescript/src/Components/internal/currency/currency-metadata.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/currency/formatting.d.ts +10 -0
- package/lib/typescript/src/Components/internal/currency/formatting.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/currency/index.d.ts +3 -0
- package/lib/typescript/src/Components/internal/currency/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/debug.d.ts +3 -0
- package/lib/typescript/src/Components/internal/debug.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/flags.d.ts +2 -0
- package/lib/typescript/src/Components/internal/flags.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/form-state/BillingAddressFormStateProvider.d.ts +13 -0
- package/lib/typescript/src/Components/internal/form-state/BillingAddressFormStateProvider.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/form-state/CardFormStateProvider.d.ts +16 -0
- package/lib/typescript/src/Components/internal/form-state/CardFormStateProvider.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/form-state/index.d.ts +3 -0
- package/lib/typescript/src/Components/internal/form-state/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/googlePay.d.ts +12 -0
- package/lib/typescript/src/Components/internal/googlePay.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/localization/index.d.ts +6 -0
- package/lib/typescript/src/Components/internal/localization/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/localization/interpolation.d.ts +3 -0
- package/lib/typescript/src/Components/internal/localization/interpolation.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/localization/locale-resolver.d.ts +3 -0
- package/lib/typescript/src/Components/internal/localization/locale-resolver.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/localization/strings/index.d.ts +4 -0
- package/lib/typescript/src/Components/internal/localization/strings/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/localization/translate.d.ts +3 -0
- package/lib/typescript/src/Components/internal/localization/translate.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/localization/types.d.ts +7 -0
- package/lib/typescript/src/Components/internal/localization/types.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/localization/usePrimerLocalization.d.ts +9 -0
- package/lib/typescript/src/Components/internal/localization/usePrimerLocalization.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/navigation/NavigationContainer.d.ts +8 -0
- package/lib/typescript/src/Components/internal/navigation/NavigationContainer.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/navigation/NavigationContext.d.ts +12 -0
- package/lib/typescript/src/Components/internal/navigation/NavigationContext.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/navigation/NavigationHeader.d.ts +16 -0
- package/lib/typescript/src/Components/internal/navigation/NavigationHeader.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/navigation/NavigationProvider.d.ts +10 -0
- package/lib/typescript/src/Components/internal/navigation/NavigationProvider.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/navigation/index.d.ts +9 -0
- package/lib/typescript/src/Components/internal/navigation/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/navigation/navigationReducer.d.ts +3 -0
- package/lib/typescript/src/Components/internal/navigation/navigationReducer.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/navigation/types.d.ts +79 -0
- package/lib/typescript/src/Components/internal/navigation/types.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/navigation/useNavigation.d.ts +9 -0
- package/lib/typescript/src/Components/internal/navigation/useNavigation.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/navigation/useRoute.d.ts +6 -0
- package/lib/typescript/src/Components/internal/navigation/useRoute.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/routeMethodSelection.d.ts +17 -0
- package/lib/typescript/src/Components/internal/routeMethodSelection.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/CardFormScreen.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/CardFormScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/CountrySelectorScreen.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/CountrySelectorScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/ErrorScreen.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/ErrorScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/LoadingScreen.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/LoadingScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/MethodSelectionScreen.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/MethodSelectionScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/SuccessScreen.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/SuccessScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/VaultedMethodsScreen.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/VaultedMethodsScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/constants.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/constants.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/index.d.ts +6 -0
- package/lib/typescript/src/Components/internal/screens/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/useBottomSafeArea.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/useBottomSafeArea.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/useKeyboardHeight.d.ts +3 -0
- package/lib/typescript/src/Components/internal/screens/useKeyboardHeight.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/useKeyboardPadding.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/useKeyboardPadding.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/screens/useStatusScreenHeight.d.ts +2 -0
- package/lib/typescript/src/Components/internal/screens/useStatusScreenHeight.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/theme/ThemeContext.d.ts +8 -0
- package/lib/typescript/src/Components/internal/theme/ThemeContext.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/theme/index.d.ts +3 -0
- package/lib/typescript/src/Components/internal/theme/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/theme/merge.d.ts +5 -0
- package/lib/typescript/src/Components/internal/theme/merge.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/theme/tokens/dark.d.ts +3 -0
- package/lib/typescript/src/Components/internal/theme/tokens/dark.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/theme/tokens/index.d.ts +3 -0
- package/lib/typescript/src/Components/internal/theme/tokens/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/theme/tokens/light.d.ts +3 -0
- package/lib/typescript/src/Components/internal/theme/tokens/light.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/theme/types.d.ts +83 -0
- package/lib/typescript/src/Components/internal/theme/types.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/theme/usePrimerTheme.d.ts +3 -0
- package/lib/typescript/src/Components/internal/theme/usePrimerTheme.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/ui/CheckoutButton.d.ts +9 -0
- package/lib/typescript/src/Components/internal/ui/CheckoutButton.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/ui/PaymentMethodButton.d.ts +4 -0
- package/lib/typescript/src/Components/internal/ui/PaymentMethodButton.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/ui/VaultedCardCvvRow.d.ts +13 -0
- package/lib/typescript/src/Components/internal/ui/VaultedCardCvvRow.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/ui/index.d.ts +5 -0
- package/lib/typescript/src/Components/internal/ui/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/utils/errors.d.ts +8 -0
- package/lib/typescript/src/Components/internal/utils/errors.d.ts.map +1 -0
- package/lib/typescript/src/Components/internal/utils/formatting.d.ts +18 -0
- package/lib/typescript/src/Components/internal/utils/formatting.d.ts.map +1 -0
- package/lib/typescript/src/Components/status/PrimerErrorScreen.d.ts +12 -0
- package/lib/typescript/src/Components/status/PrimerErrorScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/status/PrimerLoadingScreen.d.ts +9 -0
- package/lib/typescript/src/Components/status/PrimerLoadingScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/status/PrimerStatusScreenLayout.d.ts +9 -0
- package/lib/typescript/src/Components/status/PrimerStatusScreenLayout.d.ts.map +1 -0
- package/lib/typescript/src/Components/status/PrimerSuccessScreen.d.ts +10 -0
- package/lib/typescript/src/Components/status/PrimerSuccessScreen.d.ts.map +1 -0
- package/lib/typescript/src/Components/status/index.d.ts +9 -0
- package/lib/typescript/src/Components/status/index.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/BillingAddressFormTypes.d.ts +59 -0
- package/lib/typescript/src/Components/types/BillingAddressFormTypes.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/CardFormTypes.d.ts +71 -0
- package/lib/typescript/src/Components/types/CardFormTypes.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/CardInputTypes.d.ts +82 -0
- package/lib/typescript/src/Components/types/CardInputTypes.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/CardNetworkSelection.d.ts +62 -0
- package/lib/typescript/src/Components/types/CardNetworkSelection.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/PaymentMethodTypes.d.ts +37 -0
- package/lib/typescript/src/Components/types/PaymentMethodTypes.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/PrimerCardFormTypes.d.ts +19 -0
- package/lib/typescript/src/Components/types/PrimerCardFormTypes.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/PrimerCheckoutProviderTypes.d.ts +149 -0
- package/lib/typescript/src/Components/types/PrimerCheckoutProviderTypes.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/PrimerPaymentMethodListTypes.d.ts +23 -0
- package/lib/typescript/src/Components/types/PrimerPaymentMethodListTypes.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/PrimerPaymentMethodTypes.d.ts +51 -0
- package/lib/typescript/src/Components/types/PrimerPaymentMethodTypes.d.ts.map +1 -0
- package/lib/typescript/src/Components/types/VaultedPaymentMethodTypes.d.ts +71 -0
- package/lib/typescript/src/Components/types/VaultedPaymentMethodTypes.d.ts.map +1 -0
- package/lib/typescript/src/HeadlessUniversalCheckout/Managers/AssetsManager.d.ts +17 -2
- package/lib/typescript/src/HeadlessUniversalCheckout/Managers/AssetsManager.d.ts.map +1 -1
- package/lib/typescript/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.d.ts +2 -0
- package/lib/typescript/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.d.ts.map +1 -1
- package/lib/typescript/src/HeadlessUniversalCheckout/Managers/VaultManager.d.ts +1 -0
- package/lib/typescript/src/HeadlessUniversalCheckout/Managers/VaultManager.d.ts.map +1 -1
- package/lib/typescript/src/RNPrimer.d.ts +6 -1
- package/lib/typescript/src/RNPrimer.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +39 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/models/PrimerCheckoutData.d.ts +2 -0
- package/lib/typescript/src/models/PrimerCheckoutData.d.ts.map +1 -1
- package/lib/typescript/src/models/PrimerClientSession.d.ts +20 -0
- package/lib/typescript/src/models/PrimerClientSession.d.ts.map +1 -1
- package/lib/typescript/src/models/PrimerHeadlessUniversalCheckoutPaymentMethod.d.ts +4 -2
- package/lib/typescript/src/models/PrimerHeadlessUniversalCheckoutPaymentMethod.d.ts.map +1 -1
- package/lib/typescript/src/models/PrimerRawData.d.ts +1 -0
- package/lib/typescript/src/models/PrimerRawData.d.ts.map +1 -1
- package/lib/typescript/src/models/PrimerSettings.d.ts +2 -1
- package/lib/typescript/src/models/PrimerSettings.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativePrimer.d.ts +4 -0
- package/lib/typescript/src/specs/NativePrimer.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativePrimerViewUtils.d.ts +7 -0
- package/lib/typescript/src/specs/NativePrimerViewUtils.d.ts.map +1 -0
- package/lib/typescript/src/utils/debounce.d.ts +6 -0
- package/lib/typescript/src/utils/debounce.d.ts.map +1 -0
- package/lib/typescript/src/utils/index.d.ts +0 -1
- package/lib/typescript/src/utils/index.d.ts.map +1 -1
- package/package.json +14 -28
- package/primer-io-react-native.podspec +1 -1
- package/src/Components/PrimerAcceptedCardNetworks.tsx +73 -0
- package/src/Components/PrimerBillingAddressForm.tsx +195 -0
- package/src/Components/PrimerCardForm.tsx +102 -0
- package/src/Components/PrimerCardNetworkSelector.tsx +164 -0
- package/src/Components/PrimerCheckoutProvider.tsx +1092 -0
- package/src/Components/PrimerCheckoutSheet.tsx +37 -0
- package/src/Components/PrimerPaymentMethodList.tsx +82 -0
- package/src/Components/PrimerVaultedPaymentMethod.tsx +234 -0
- package/src/Components/analytics.ts +19 -0
- package/src/Components/hooks/useCardNetworkDescriptor.ts +27 -0
- package/src/Components/hooks/useCardNetworkIcons.ts +57 -0
- package/src/Components/hooks/usePrimerBillingAddressForm.ts +37 -0
- package/src/Components/hooks/usePrimerCardForm.ts +50 -0
- package/src/Components/hooks/usePrimerCardNetwork.ts +74 -0
- package/src/Components/hooks/usePrimerCardNetworkSelection.ts +85 -0
- package/src/Components/hooks/usePrimerCheckout.ts +14 -0
- package/src/Components/hooks/usePrimerPaymentMethod.ts +91 -0
- package/src/Components/hooks/usePrimerPaymentMethods.ts +172 -0
- package/src/Components/hooks/usePrimerVaultManager.ts +114 -0
- package/src/Components/index.ts +77 -0
- package/src/Components/inputs/CountrySelectorRow.tsx +127 -0
- package/src/Components/inputs/PrimerCVVInput.tsx +53 -0
- package/src/Components/inputs/PrimerCardNumberInput.tsx +146 -0
- package/src/Components/inputs/PrimerCardholderNameInput.tsx +30 -0
- package/src/Components/inputs/PrimerExpiryDateInput.tsx +101 -0
- package/src/Components/inputs/PrimerTextInput.tsx +201 -0
- package/src/Components/inputs/caret.ts +37 -0
- package/src/Components/inputs/dimensions.ts +15 -0
- package/src/Components/inputs/index.ts +7 -0
- package/src/Components/internal/CardNetworkBadge.tsx +124 -0
- package/src/Components/internal/Popover.tsx +95 -0
- package/src/Components/internal/PrimerCheckoutContext.ts +4 -0
- package/src/Components/internal/applePay.ts +12 -0
- package/src/Components/internal/billingAddressOptions.ts +47 -0
- package/src/Components/internal/cardFormat.ts +39 -0
- package/src/Components/internal/cardNetwork.ts +128 -0
- package/src/Components/internal/cardNetworkIcons.ts +27 -0
- package/src/Components/internal/checkout-flow/CheckoutFlow.tsx +124 -0
- package/src/Components/internal/checkout-flow/CheckoutFlowContext.ts +16 -0
- package/src/Components/internal/checkout-flow/index.ts +1 -0
- package/src/Components/internal/checkout-sheet/CheckoutSheet.tsx +301 -0
- package/src/Components/internal/checkout-sheet/SheetHeightContext.ts +24 -0
- package/src/Components/internal/checkout-sheet/index.ts +4 -0
- package/src/Components/internal/checkout-sheet/types.ts +27 -0
- package/src/Components/internal/countries.ts +302 -0
- package/src/Components/internal/currency/currencies.json +1 -0
- package/src/Components/internal/currency/currency-metadata.ts +57 -0
- package/src/Components/internal/currency/formatting.ts +26 -0
- package/src/Components/internal/currency/index.ts +2 -0
- package/src/Components/internal/debug.ts +12 -0
- package/src/Components/internal/flags.ts +20 -0
- package/src/Components/internal/form-state/BillingAddressFormStateProvider.tsx +283 -0
- package/src/Components/internal/form-state/CardFormStateProvider.tsx +302 -0
- package/src/Components/internal/form-state/index.ts +2 -0
- package/src/Components/internal/googlePay.ts +13 -0
- package/src/Components/internal/localization/index.ts +5 -0
- package/src/Components/internal/localization/interpolation.ts +13 -0
- package/src/Components/internal/localization/locale-resolver.ts +37 -0
- package/src/Components/internal/localization/strings/ar.json +227 -0
- package/src/Components/internal/localization/strings/az.json +227 -0
- package/src/Components/internal/localization/strings/bg.json +227 -0
- package/src/Components/internal/localization/strings/bs.json +227 -0
- package/src/Components/internal/localization/strings/ca.json +227 -0
- package/src/Components/internal/localization/strings/cs.json +227 -0
- package/src/Components/internal/localization/strings/da.json +227 -0
- package/src/Components/internal/localization/strings/de.json +227 -0
- package/src/Components/internal/localization/strings/el.json +227 -0
- package/src/Components/internal/localization/strings/en.json +256 -0
- package/src/Components/internal/localization/strings/es-AR.json +227 -0
- package/src/Components/internal/localization/strings/es-MX.json +227 -0
- package/src/Components/internal/localization/strings/es.json +227 -0
- package/src/Components/internal/localization/strings/et.json +227 -0
- package/src/Components/internal/localization/strings/fa.json +227 -0
- package/src/Components/internal/localization/strings/fi.json +227 -0
- package/src/Components/internal/localization/strings/fil.json +227 -0
- package/src/Components/internal/localization/strings/fr.json +227 -0
- package/src/Components/internal/localization/strings/he.json +227 -0
- package/src/Components/internal/localization/strings/hi.json +227 -0
- package/src/Components/internal/localization/strings/hr.json +227 -0
- package/src/Components/internal/localization/strings/hu.json +227 -0
- package/src/Components/internal/localization/strings/hy.json +227 -0
- package/src/Components/internal/localization/strings/id.json +227 -0
- package/src/Components/internal/localization/strings/index.ts +69 -0
- package/src/Components/internal/localization/strings/it.json +227 -0
- package/src/Components/internal/localization/strings/ja.json +227 -0
- package/src/Components/internal/localization/strings/ka.json +227 -0
- package/src/Components/internal/localization/strings/kk.json +227 -0
- package/src/Components/internal/localization/strings/ko.json +227 -0
- package/src/Components/internal/localization/strings/ku.json +227 -0
- package/src/Components/internal/localization/strings/ky.json +227 -0
- package/src/Components/internal/localization/strings/lt.json +227 -0
- package/src/Components/internal/localization/strings/lv.json +227 -0
- package/src/Components/internal/localization/strings/mk.json +227 -0
- package/src/Components/internal/localization/strings/ms.json +227 -0
- package/src/Components/internal/localization/strings/nb.json +227 -0
- package/src/Components/internal/localization/strings/nl-BE.json +227 -0
- package/src/Components/internal/localization/strings/nl.json +227 -0
- package/src/Components/internal/localization/strings/pl.json +227 -0
- package/src/Components/internal/localization/strings/pt-BR.json +227 -0
- package/src/Components/internal/localization/strings/pt.json +227 -0
- package/src/Components/internal/localization/strings/ro.json +227 -0
- package/src/Components/internal/localization/strings/ru.json +227 -0
- package/src/Components/internal/localization/strings/sk.json +227 -0
- package/src/Components/internal/localization/strings/sl.json +227 -0
- package/src/Components/internal/localization/strings/sq.json +227 -0
- package/src/Components/internal/localization/strings/sr.json +227 -0
- package/src/Components/internal/localization/strings/sv.json +227 -0
- package/src/Components/internal/localization/strings/th.json +227 -0
- package/src/Components/internal/localization/strings/tr.json +227 -0
- package/src/Components/internal/localization/strings/uk.json +227 -0
- package/src/Components/internal/localization/strings/ur-PK.json +227 -0
- package/src/Components/internal/localization/strings/uz.json +227 -0
- package/src/Components/internal/localization/strings/vi.json +227 -0
- package/src/Components/internal/localization/strings/zh-CN.json +227 -0
- package/src/Components/internal/localization/strings/zh-HK.json +227 -0
- package/src/Components/internal/localization/strings/zh-TW.json +227 -0
- package/src/Components/internal/localization/translate.ts +28 -0
- package/src/Components/internal/localization/types.ts +8 -0
- package/src/Components/internal/localization/usePrimerLocalization.ts +27 -0
- package/src/Components/internal/navigation/NavigationContainer.tsx +176 -0
- package/src/Components/internal/navigation/NavigationContext.ts +21 -0
- package/src/Components/internal/navigation/NavigationHeader.tsx +182 -0
- package/src/Components/internal/navigation/NavigationProvider.tsx +94 -0
- package/src/Components/internal/navigation/index.ts +8 -0
- package/src/Components/internal/navigation/navigationReducer.ts +47 -0
- package/src/Components/internal/navigation/types.ts +48 -0
- package/src/Components/internal/navigation/useNavigation.ts +18 -0
- package/src/Components/internal/navigation/useRoute.ts +18 -0
- package/src/Components/internal/routeMethodSelection.ts +35 -0
- package/src/Components/internal/screens/CardFormScreen.tsx +223 -0
- package/src/Components/internal/screens/CountrySelectorScreen.tsx +253 -0
- package/src/Components/internal/screens/ErrorScreen.tsx +57 -0
- package/src/Components/internal/screens/LoadingScreen.tsx +43 -0
- package/src/Components/internal/screens/MethodSelectionScreen.tsx +251 -0
- package/src/Components/internal/screens/SuccessScreen.tsx +32 -0
- package/src/Components/internal/screens/VaultedMethodsScreen.tsx +528 -0
- package/src/Components/internal/screens/assets/check-circle-large.png +0 -0
- package/src/Components/internal/screens/assets/check-circle-large@2x.png +0 -0
- package/src/Components/internal/screens/assets/check-circle-large@3x.png +0 -0
- package/src/Components/internal/screens/assets/check.png +0 -0
- package/src/Components/internal/screens/assets/check@2x.png +0 -0
- package/src/Components/internal/screens/assets/check@3x.png +0 -0
- package/src/Components/internal/screens/assets/chevron-down.png +0 -0
- package/src/Components/internal/screens/assets/chevron-down@2x.png +0 -0
- package/src/Components/internal/screens/assets/chevron-down@3x.png +0 -0
- package/src/Components/internal/screens/assets/close.png +0 -0
- package/src/Components/internal/screens/assets/close@2x.png +0 -0
- package/src/Components/internal/screens/assets/close@3x.png +0 -0
- package/src/Components/internal/screens/assets/done.png +0 -0
- package/src/Components/internal/screens/assets/done@2x.png +0 -0
- package/src/Components/internal/screens/assets/done@3x.png +0 -0
- package/src/Components/internal/screens/assets/edit.png +0 -0
- package/src/Components/internal/screens/assets/edit@2x.png +0 -0
- package/src/Components/internal/screens/assets/edit@3x.png +0 -0
- package/src/Components/internal/screens/assets/error-large.png +0 -0
- package/src/Components/internal/screens/assets/error-large@2x.png +0 -0
- package/src/Components/internal/screens/assets/error-large@3x.png +0 -0
- package/src/Components/internal/screens/assets/lock.png +0 -0
- package/src/Components/internal/screens/assets/lock@2x.png +0 -0
- package/src/Components/internal/screens/assets/lock@3x.png +0 -0
- package/src/Components/internal/screens/constants.ts +1 -0
- package/src/Components/internal/screens/index.ts +5 -0
- package/src/Components/internal/screens/useBottomSafeArea.ts +22 -0
- package/src/Components/internal/screens/useKeyboardHeight.ts +33 -0
- package/src/Components/internal/screens/useKeyboardPadding.ts +29 -0
- package/src/Components/internal/screens/useStatusScreenHeight.ts +11 -0
- package/src/Components/internal/theme/ThemeContext.ts +9 -0
- package/src/Components/internal/theme/index.ts +12 -0
- package/src/Components/internal/theme/merge.ts +27 -0
- package/src/Components/internal/theme/tokens/dark.ts +89 -0
- package/src/Components/internal/theme/tokens/index.ts +2 -0
- package/src/Components/internal/theme/tokens/light.ts +88 -0
- package/src/Components/internal/theme/types.ts +89 -0
- package/src/Components/internal/theme/usePrimerTheme.ts +15 -0
- package/src/Components/internal/ui/CheckoutButton.tsx +84 -0
- package/src/Components/internal/ui/PaymentMethodButton.tsx +132 -0
- package/src/Components/internal/ui/VaultedCardCvvRow.tsx +114 -0
- package/src/Components/internal/ui/index.ts +4 -0
- package/src/Components/internal/utils/errors.ts +9 -0
- package/src/Components/internal/utils/formatting.ts +32 -0
- package/src/Components/status/PrimerErrorScreen.tsx +77 -0
- package/src/Components/status/PrimerLoadingScreen.tsx +43 -0
- package/src/Components/status/PrimerStatusScreenLayout.tsx +77 -0
- package/src/Components/status/PrimerSuccessScreen.tsx +39 -0
- package/src/Components/status/index.ts +8 -0
- package/src/Components/types/BillingAddressFormTypes.ts +77 -0
- package/src/Components/types/CardFormTypes.ts +83 -0
- package/src/Components/types/CardInputTypes.ts +90 -0
- package/src/Components/types/CardNetworkSelection.ts +64 -0
- package/src/Components/types/PaymentMethodTypes.ts +51 -0
- package/src/Components/types/PrimerCardFormTypes.ts +19 -0
- package/src/Components/types/PrimerCheckoutProviderTypes.ts +168 -0
- package/src/Components/types/PrimerPaymentMethodListTypes.ts +24 -0
- package/src/Components/types/PrimerPaymentMethodTypes.ts +55 -0
- package/src/Components/types/VaultedPaymentMethodTypes.ts +74 -0
- package/src/HeadlessUniversalCheckout/Managers/AssetsManager.ts +38 -2
- package/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/AchManager.ts +6 -6
- package/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/ComponentWithRedirectManager.ts +6 -6
- package/src/HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.ts +31 -0
- package/src/HeadlessUniversalCheckout/Managers/VaultManager.ts +12 -0
- package/src/HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.ts +6 -6
- package/src/Primer.ts +11 -11
- package/src/RNPrimer.ts +47 -1
- package/src/assets/images/ic-card-placeholder.png +0 -0
- package/src/assets/images/ic-card-placeholder@2x.png +0 -0
- package/src/assets/images/ic-card-placeholder@3x.png +0 -0
- package/src/assets/images/ic-cvv-hint.png +0 -0
- package/src/assets/images/ic-cvv-hint@2x.png +0 -0
- package/src/assets/images/ic-cvv-hint@3x.png +0 -0
- package/src/assets/images/ic-expiry-calendar.png +0 -0
- package/src/assets/images/ic-expiry-calendar@2x.png +0 -0
- package/src/assets/images/ic-expiry-calendar@3x.png +0 -0
- package/src/index.tsx +102 -2
- package/src/models/PrimerCheckoutData.ts +3 -0
- package/src/models/PrimerClientSession.ts +30 -0
- package/src/models/PrimerHeadlessUniversalCheckoutPaymentMethod.ts +5 -2
- package/src/models/PrimerRawData.ts +1 -0
- package/src/models/PrimerSettings.ts +2 -1
- package/src/specs/NativePrimer.ts +6 -0
- package/src/specs/NativePrimerViewUtils.ts +8 -0
- package/src/utils/debounce.ts +33 -0
- package/src/utils/index.ts +0 -9
|
@@ -0,0 +1,1059 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import PrimerHeadlessUniversalCheckoutAssetsManager from "../HeadlessUniversalCheckout/Managers/AssetsManager.js";
|
|
5
|
+
import PrimerHeadlessUniversalCheckoutRawDataManager from "../HeadlessUniversalCheckout/Managers/PaymentMethodManagers/RawDataManager.js";
|
|
6
|
+
import PrimerHeadlessUniversalCheckoutPaymentMethodNativeUIManager from "../HeadlessUniversalCheckout/Managers/PaymentMethodManagers/NativeUIManager.js";
|
|
7
|
+
import PrimerHeadlessUniversalCheckoutVaultManager from "../HeadlessUniversalCheckout/Managers/VaultManager.js";
|
|
8
|
+
import { PrimerHeadlessUniversalCheckout } from "../HeadlessUniversalCheckout/PrimerHeadlessUniversalCheckout.js";
|
|
9
|
+
import { PrimerError } from "../models/PrimerError.js";
|
|
10
|
+
import { PrimerAnalytics } from "./analytics.js";
|
|
11
|
+
import { PrimerSessionIntent } from "../models/PrimerSessionIntent.js";
|
|
12
|
+
import { fmt } from "./internal/debug.js";
|
|
13
|
+
import { PrimerCheckoutContext } from "./internal/PrimerCheckoutContext.js";
|
|
14
|
+
import { mergeTokens } from "./internal/theme/merge.js";
|
|
15
|
+
import { ThemeContext } from "./internal/theme/ThemeContext.js";
|
|
16
|
+
import { defaultDarkTokens, defaultLightTokens } from "./internal/theme/tokens/index.js";
|
|
17
|
+
import { toError } from "./internal/utils/errors.js";
|
|
18
|
+
import { GOOGLE_PAY, isGooglePaySupported } from "./internal/googlePay.js";
|
|
19
|
+
import { APPLE_PAY, isApplePaySupported } from "./internal/applePay.js";
|
|
20
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
21
|
+
const LOG = '[PrimerCheckoutProvider]';
|
|
22
|
+
const assetsManager = new PrimerHeadlessUniversalCheckoutAssetsManager();
|
|
23
|
+
const initialCardFormState = {
|
|
24
|
+
isValid: false,
|
|
25
|
+
errors: {},
|
|
26
|
+
binData: null,
|
|
27
|
+
metadata: null,
|
|
28
|
+
requiredFields: []
|
|
29
|
+
};
|
|
30
|
+
const initialState = {
|
|
31
|
+
isReady: false,
|
|
32
|
+
error: null,
|
|
33
|
+
clientSession: null,
|
|
34
|
+
acceptedCardNetworks: null,
|
|
35
|
+
availablePaymentMethods: [],
|
|
36
|
+
paymentMethodResources: [],
|
|
37
|
+
isLoadingResources: false,
|
|
38
|
+
resourcesError: null,
|
|
39
|
+
paymentOutcome: null,
|
|
40
|
+
nativeUiInFlightType: null,
|
|
41
|
+
activeMethod: null,
|
|
42
|
+
cardFormState: initialCardFormState,
|
|
43
|
+
vaultedMethods: [],
|
|
44
|
+
vaultedIconUrisById: {},
|
|
45
|
+
isLoadingVaulted: false,
|
|
46
|
+
vaultedError: null,
|
|
47
|
+
activeVaultedMethodId: null,
|
|
48
|
+
selectedCardNetwork: null,
|
|
49
|
+
vaultDisplayOverride: null,
|
|
50
|
+
requiresVaultedCardCvv: false,
|
|
51
|
+
cvvInputVisible: false
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Native `onCheckoutComplete` fires for every terminal checkout, including
|
|
56
|
+
* FAILED ones — so we inspect `payment.status` to pick the result screen.
|
|
57
|
+
*/
|
|
58
|
+
function buildPaymentOutcome(checkoutData) {
|
|
59
|
+
const payment = checkoutData?.payment;
|
|
60
|
+
if (payment?.status !== 'FAILED') {
|
|
61
|
+
return {
|
|
62
|
+
status: 'success',
|
|
63
|
+
data: checkoutData
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const errorCode = payment.paymentFailureReason ?? 'payment-failed';
|
|
67
|
+
const description = payment.id ? `Payment ${payment.id} failed` : 'Payment failed';
|
|
68
|
+
return {
|
|
69
|
+
status: 'error',
|
|
70
|
+
error: new PrimerError('payment-failed', errorCode, description, undefined, undefined),
|
|
71
|
+
data: checkoutData
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Native validation errors carry a free-form `errorId` like `invalid-card-number`. The table
|
|
76
|
+
// below routes each id to a `CardFormField`. First match wins. When native gains a typed
|
|
77
|
+
// `inputElementType` field on the error object, swap this for a direct enum-keyed lookup.
|
|
78
|
+
const ERROR_FIELD_TABLE = [{
|
|
79
|
+
test: id => id.includes('card') && id.includes('number'),
|
|
80
|
+
field: 'cardNumber'
|
|
81
|
+
}, {
|
|
82
|
+
test: id => id.includes('expir'),
|
|
83
|
+
field: 'expiryDate'
|
|
84
|
+
}, {
|
|
85
|
+
test: id => id.includes('cvv') || id.includes('cvc'),
|
|
86
|
+
field: 'cvv'
|
|
87
|
+
}, {
|
|
88
|
+
test: id => id.includes('cardholder') || id.includes('card_holder'),
|
|
89
|
+
field: 'cardholderName'
|
|
90
|
+
}];
|
|
91
|
+
|
|
92
|
+
/** Map native validation errors to per-field typed errors the UI can render. */
|
|
93
|
+
function parseValidationErrors(errors) {
|
|
94
|
+
const fieldErrors = {};
|
|
95
|
+
if (!errors) return fieldErrors;
|
|
96
|
+
for (const error of errors) {
|
|
97
|
+
const id = (error.errorId ?? '').toLowerCase();
|
|
98
|
+
const description = error.description ?? error.message ?? 'Invalid';
|
|
99
|
+
const match = ERROR_FIELD_TABLE.find(entry => entry.test(id));
|
|
100
|
+
if (match) fieldErrors[match.field] = description;
|
|
101
|
+
}
|
|
102
|
+
return fieldErrors;
|
|
103
|
+
}
|
|
104
|
+
export function PrimerCheckoutProvider({
|
|
105
|
+
clientToken,
|
|
106
|
+
settings,
|
|
107
|
+
theme,
|
|
108
|
+
onCheckoutComplete,
|
|
109
|
+
onTokenizationSuccess,
|
|
110
|
+
onBeforePaymentCreate,
|
|
111
|
+
onError,
|
|
112
|
+
children
|
|
113
|
+
}) {
|
|
114
|
+
const [state, setState] = useState(initialState);
|
|
115
|
+
const [lightTokens] = useState(() => mergeTokens(defaultLightTokens, theme?.light));
|
|
116
|
+
const [darkTokens] = useState(() => mergeTokens(defaultDarkTokens, theme?.dark));
|
|
117
|
+
|
|
118
|
+
// Refs keep init useEffect deps to [clientToken] only.
|
|
119
|
+
const settingsRef = useRef(settings);
|
|
120
|
+
settingsRef.current = settings;
|
|
121
|
+
const onCheckoutCompleteRef = useRef(onCheckoutComplete);
|
|
122
|
+
onCheckoutCompleteRef.current = onCheckoutComplete;
|
|
123
|
+
const onTokenizationSuccessRef = useRef(onTokenizationSuccess);
|
|
124
|
+
onTokenizationSuccessRef.current = onTokenizationSuccess;
|
|
125
|
+
const onBeforePaymentCreateRef = useRef(onBeforePaymentCreate);
|
|
126
|
+
onBeforePaymentCreateRef.current = onBeforePaymentCreate;
|
|
127
|
+
const onErrorRef = useRef(onError);
|
|
128
|
+
onErrorRef.current = onError;
|
|
129
|
+
|
|
130
|
+
// Snapshot of current state for stable callbacks that need activeMethod.
|
|
131
|
+
const stateRef = useRef(state);
|
|
132
|
+
stateRef.current = state;
|
|
133
|
+
|
|
134
|
+
// Analytics session state (reset per client token): SELECTION dedup + outcome correlation.
|
|
135
|
+
const selectionSentRef = useRef(new Set());
|
|
136
|
+
const lastAttemptedMethodRef = useRef(null);
|
|
137
|
+
const hadFailureRef = useRef(false);
|
|
138
|
+
const hadSuccessRef = useRef(false);
|
|
139
|
+
const becameReadyRef = useRef(false);
|
|
140
|
+
const trackSelection = useCallback(paymentMethod => {
|
|
141
|
+
if (selectionSentRef.current.has(paymentMethod)) return;
|
|
142
|
+
selectionSentRef.current.add(paymentMethod);
|
|
143
|
+
void PrimerAnalytics.trackEvent('PAYMENT_METHOD_SELECTION', {
|
|
144
|
+
paymentMethod
|
|
145
|
+
});
|
|
146
|
+
}, []);
|
|
147
|
+
|
|
148
|
+
// Attempt-start events shared by every pay path: REATTEMPTED (after failure), optional SUBMITTED, PROCESSING.
|
|
149
|
+
const trackAttemptStart = useCallback((paymentMethod, options) => {
|
|
150
|
+
lastAttemptedMethodRef.current = paymentMethod;
|
|
151
|
+
if (hadFailureRef.current) {
|
|
152
|
+
hadFailureRef.current = false;
|
|
153
|
+
void PrimerAnalytics.trackEvent('PAYMENT_REATTEMPTED', {
|
|
154
|
+
paymentMethod
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (options.submitted) {
|
|
158
|
+
void PrimerAnalytics.trackEvent('PAYMENT_SUBMITTED', {
|
|
159
|
+
paymentMethod
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
void PrimerAnalytics.trackEvent('PAYMENT_PROCESSING_STARTED', {
|
|
163
|
+
paymentMethod
|
|
164
|
+
});
|
|
165
|
+
}, []);
|
|
166
|
+
|
|
167
|
+
// Native manager. Lifecycle is driven by `state.activeMethod` — the method the user
|
|
168
|
+
// picked on the selection screen — so it survives the card-form view mount/unmount.
|
|
169
|
+
const managerRef = useRef(null);
|
|
170
|
+
// Vault manager is lazy — created on first vault fetch, reused across client-session updates,
|
|
171
|
+
// cleared on session teardown alongside `PrimerHeadlessUniversalCheckout.cleanUp()`.
|
|
172
|
+
const vaultManagerRef = useRef(null);
|
|
173
|
+
// Stashed so `retry()` can re-submit without needing the view to re-enter the form.
|
|
174
|
+
// Compensates for an iOS native bug (see the iOS-workaround note in `retry`), not a JS-side concern.
|
|
175
|
+
const lastRawDataRef = useRef(null);
|
|
176
|
+
// Shopper's co-badge pick. Ref (not just state) so `setRawData` reads it synchronously
|
|
177
|
+
// when merging it into each keystroke's payload — keeps the pick sticky without
|
|
178
|
+
// native-side state.
|
|
179
|
+
const selectedCardNetworkRef = useRef(null);
|
|
180
|
+
const lastManagerCallbacksRef = useRef(null);
|
|
181
|
+
// Marks the manager that `retry()` currently holds. Effect cleanup defers
|
|
182
|
+
// teardown of this manager so an in-flight submit/configure isn't destroyed.
|
|
183
|
+
const retryingManagerRef = useRef(null);
|
|
184
|
+
const pendingCleanupRef = useRef(null);
|
|
185
|
+
|
|
186
|
+
// -----------------------------------------------------------------------
|
|
187
|
+
// Session init — create headless checkout + wire session-level callbacks.
|
|
188
|
+
// -----------------------------------------------------------------------
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
setState(initialState);
|
|
191
|
+
selectionSentRef.current = new Set();
|
|
192
|
+
lastAttemptedMethodRef.current = null;
|
|
193
|
+
hadFailureRef.current = false;
|
|
194
|
+
hadSuccessRef.current = false;
|
|
195
|
+
becameReadyRef.current = false;
|
|
196
|
+
let cancelled = false;
|
|
197
|
+
const initStartedAt = Date.now();
|
|
198
|
+
async function init() {
|
|
199
|
+
const userCallbacks = settingsRef.current?.headlessUniversalCheckoutCallbacks;
|
|
200
|
+
const callbacks = {
|
|
201
|
+
onAvailablePaymentMethodsLoad: availablePaymentMethods => {
|
|
202
|
+
// Flip isLoadingResources: true atomically with the new list so the hook
|
|
203
|
+
// doesn't render for one frame with new methods + stale resources.
|
|
204
|
+
// The fetch effect picks it up on the next tick via methodTypesSignature.
|
|
205
|
+
setState(prev => ({
|
|
206
|
+
...prev,
|
|
207
|
+
availablePaymentMethods,
|
|
208
|
+
isLoadingResources: true,
|
|
209
|
+
resourcesError: null
|
|
210
|
+
}));
|
|
211
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onAvailablePaymentMethodsLoad?.(availablePaymentMethods);
|
|
212
|
+
},
|
|
213
|
+
onClientSessionUpdate: clientSession => {
|
|
214
|
+
setState(prev => ({
|
|
215
|
+
...prev,
|
|
216
|
+
clientSession
|
|
217
|
+
}));
|
|
218
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onClientSessionUpdate?.(clientSession);
|
|
219
|
+
},
|
|
220
|
+
onError: (error, checkoutData) => {
|
|
221
|
+
setState(prev => {
|
|
222
|
+
// Init-time errors → `error`. Payment-time errors → `paymentOutcome` → error
|
|
223
|
+
// screen. This includes Google Pay's 'payment-cancelled', surfaced as a failure.
|
|
224
|
+
if (prev.isReady) {
|
|
225
|
+
return {
|
|
226
|
+
...prev,
|
|
227
|
+
nativeUiInFlightType: null,
|
|
228
|
+
paymentOutcome: {
|
|
229
|
+
status: 'error',
|
|
230
|
+
error,
|
|
231
|
+
data: checkoutData ?? null
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
...prev,
|
|
237
|
+
error
|
|
238
|
+
};
|
|
239
|
+
});
|
|
240
|
+
onErrorRef.current?.(error, checkoutData);
|
|
241
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onError?.(error, checkoutData);
|
|
242
|
+
},
|
|
243
|
+
// Always-subscribed so paymentOutcome fires regardless of merchant callbacks.
|
|
244
|
+
onCheckoutComplete: checkoutData => {
|
|
245
|
+
// Native fires onCheckoutComplete for any finished checkout — including
|
|
246
|
+
// FAILED payments — so we have to read `payment.status` to decide which
|
|
247
|
+
// result screen to show. Backend statuses: SUCCESS | FAILED | PENDING.
|
|
248
|
+
setState(prev => ({
|
|
249
|
+
...prev,
|
|
250
|
+
nativeUiInFlightType: null,
|
|
251
|
+
paymentOutcome: buildPaymentOutcome(checkoutData)
|
|
252
|
+
}));
|
|
253
|
+
onCheckoutCompleteRef.current?.(checkoutData);
|
|
254
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onCheckoutComplete?.(checkoutData);
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
if (onTokenizationSuccessRef.current || userCallbacks?.onTokenizationSuccess) {
|
|
258
|
+
callbacks.onTokenizationSuccess = (paymentMethodTokenData, handler) => {
|
|
259
|
+
onTokenizationSuccessRef.current?.(paymentMethodTokenData, handler);
|
|
260
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onTokenizationSuccess?.(paymentMethodTokenData, handler);
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
if (userCallbacks?.onCheckoutResume) {
|
|
264
|
+
callbacks.onCheckoutResume = (resumeToken, handler) => {
|
|
265
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onCheckoutResume?.(resumeToken, handler);
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (onBeforePaymentCreateRef.current || userCallbacks?.onBeforePaymentCreate) {
|
|
269
|
+
callbacks.onBeforePaymentCreate = (checkoutPaymentMethodData, handler) => {
|
|
270
|
+
onBeforePaymentCreateRef.current?.(checkoutPaymentMethodData, handler);
|
|
271
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onBeforePaymentCreate?.(checkoutPaymentMethodData, handler);
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
if (userCallbacks?.onTokenizationStart) {
|
|
275
|
+
callbacks.onTokenizationStart = paymentMethodType => {
|
|
276
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onTokenizationStart?.(paymentMethodType);
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
if (userCallbacks?.onCheckoutPending) {
|
|
280
|
+
callbacks.onCheckoutPending = additionalInfo => {
|
|
281
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onCheckoutPending?.(additionalInfo);
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
if (userCallbacks?.onCheckoutAdditionalInfo) {
|
|
285
|
+
callbacks.onCheckoutAdditionalInfo = additionalInfo => {
|
|
286
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onCheckoutAdditionalInfo?.(additionalInfo);
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
if (userCallbacks?.onBeforeClientSessionUpdate) {
|
|
290
|
+
callbacks.onBeforeClientSessionUpdate = () => {
|
|
291
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onBeforeClientSessionUpdate?.();
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
if (userCallbacks?.onPreparationStart) {
|
|
295
|
+
callbacks.onPreparationStart = paymentMethodType => {
|
|
296
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onPreparationStart?.(paymentMethodType);
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
if (userCallbacks?.onPaymentMethodShow) {
|
|
300
|
+
callbacks.onPaymentMethodShow = paymentMethodType => {
|
|
301
|
+
settingsRef.current?.headlessUniversalCheckoutCallbacks?.onPaymentMethodShow?.(paymentMethodType);
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const mergedSettings = {
|
|
305
|
+
...settingsRef.current,
|
|
306
|
+
headlessUniversalCheckoutCallbacks: callbacks
|
|
307
|
+
};
|
|
308
|
+
const methods = await PrimerHeadlessUniversalCheckout.startWithClientToken(clientToken, mergedSettings);
|
|
309
|
+
if (!cancelled) {
|
|
310
|
+
// Setup must run after native init — Android's bridge resolves the SDK DI container here.
|
|
311
|
+
try {
|
|
312
|
+
await PrimerAnalytics.setup(clientToken);
|
|
313
|
+
void PrimerAnalytics.trackEvent('SDK_INIT_START');
|
|
314
|
+
void PrimerAnalytics.trackEvent('SDK_INIT_END');
|
|
315
|
+
void PrimerAnalytics.sendLog('Checkout components initialized', 'checkout-initialized', Date.now() - initStartedAt);
|
|
316
|
+
} catch (analyticsErr) {
|
|
317
|
+
console.warn(`${LOG} analytics setup failed ${fmt(analyticsErr)}`);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Seed isLoadingResources atomically with isReady so consumers don't see a
|
|
321
|
+
// brief "ready but no resources loading" window before the fetch effect runs.
|
|
322
|
+
setState(prev => ({
|
|
323
|
+
...prev,
|
|
324
|
+
isReady: true,
|
|
325
|
+
availablePaymentMethods: methods,
|
|
326
|
+
paymentMethodResources: [],
|
|
327
|
+
isLoadingResources: true,
|
|
328
|
+
resourcesError: null
|
|
329
|
+
}));
|
|
330
|
+
becameReadyRef.current = true;
|
|
331
|
+
void PrimerAnalytics.trackEvent('CHECKOUT_FLOW_STARTED');
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
init().catch(err => {
|
|
335
|
+
console.error(`${LOG} init failed ${fmt(err)}`);
|
|
336
|
+
// Best effort: setup may not have run yet (Android drops pre-init logs; iOS still ships).
|
|
337
|
+
const primerErr = err;
|
|
338
|
+
void PrimerAnalytics.setup(clientToken).then(() => PrimerAnalytics.sendErrorLog('Checkout initialization failed', 'checkout-init-failed', 'description' in primerErr ? primerErr.description : primerErr.message, primerErr instanceof Error ? primerErr.stack : undefined)).catch(() => {});
|
|
339
|
+
if (!cancelled) {
|
|
340
|
+
setState(prev => ({
|
|
341
|
+
...prev,
|
|
342
|
+
error: err
|
|
343
|
+
}));
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
return () => {
|
|
347
|
+
cancelled = true;
|
|
348
|
+
// Session ends without a completed payment (unmount or token change) → funnel exit.
|
|
349
|
+
if (becameReadyRef.current && !hadSuccessRef.current) {
|
|
350
|
+
void PrimerAnalytics.trackEvent('PAYMENT_FLOW_EXITED');
|
|
351
|
+
}
|
|
352
|
+
// Vault manager is tied to the native session — let the next session recreate it.
|
|
353
|
+
vaultManagerRef.current = null;
|
|
354
|
+
void PrimerHeadlessUniversalCheckout.cleanUp();
|
|
355
|
+
};
|
|
356
|
+
}, [clientToken]);
|
|
357
|
+
|
|
358
|
+
// Single choke point: every pay path lands in `paymentOutcome`, so SUCCESS/FAILURE emit once per attempt.
|
|
359
|
+
useEffect(() => {
|
|
360
|
+
const outcome = state.paymentOutcome;
|
|
361
|
+
if (outcome === null) return;
|
|
362
|
+
const paymentMethod = lastAttemptedMethodRef.current ?? 'UNKNOWN';
|
|
363
|
+
if (outcome.status === 'success') {
|
|
364
|
+
// PENDING reaches the 'success' outcome but isn't a completed payment — don't count it.
|
|
365
|
+
if (outcome.data?.payment?.status === 'PENDING') return;
|
|
366
|
+
hadSuccessRef.current = true;
|
|
367
|
+
void PrimerAnalytics.trackEvent('PAYMENT_SUCCESS', {
|
|
368
|
+
paymentMethod,
|
|
369
|
+
paymentId: outcome.data?.payment?.id ?? 'unknown'
|
|
370
|
+
});
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
hadFailureRef.current = true;
|
|
374
|
+
const paymentId = outcome.data?.payment?.id;
|
|
375
|
+
void PrimerAnalytics.trackEvent('PAYMENT_FAILURE', {
|
|
376
|
+
paymentMethod,
|
|
377
|
+
...(paymentId ? {
|
|
378
|
+
paymentId
|
|
379
|
+
} : null)
|
|
380
|
+
});
|
|
381
|
+
void PrimerAnalytics.sendErrorLog('Payment failed', 'failed-payment', outcome.error?.description ?? outcome.error?.message);
|
|
382
|
+
}, [state.paymentOutcome]);
|
|
383
|
+
|
|
384
|
+
// -----------------------------------------------------------------------
|
|
385
|
+
// Payment method resource fetch — re-runs whenever the set of available
|
|
386
|
+
// method types changes (init, or onAvailablePaymentMethodsLoad firing post-ready).
|
|
387
|
+
// -----------------------------------------------------------------------
|
|
388
|
+
const methodTypesSignature = useMemo(() => state.availablePaymentMethods.map(m => m.paymentMethodType).sort().join('|'), [state.availablePaymentMethods]);
|
|
389
|
+
useEffect(() => {
|
|
390
|
+
if (!state.isReady) return;
|
|
391
|
+
|
|
392
|
+
// No methods configured → nothing to fetch. Clear the loading flag so
|
|
393
|
+
// consumers don't hang on `isLoading: true` forever (init sets it
|
|
394
|
+
// optimistically before we know the method list is empty).
|
|
395
|
+
if (state.availablePaymentMethods.length === 0) {
|
|
396
|
+
setState(prev => prev.isLoadingResources || prev.paymentMethodResources.length > 0 ? {
|
|
397
|
+
...prev,
|
|
398
|
+
paymentMethodResources: [],
|
|
399
|
+
isLoadingResources: false
|
|
400
|
+
} : prev);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
let cancelled = false;
|
|
404
|
+
setState(prev => prev.isLoadingResources && prev.resourcesError === null ? prev : {
|
|
405
|
+
...prev,
|
|
406
|
+
isLoadingResources: true,
|
|
407
|
+
resourcesError: null
|
|
408
|
+
});
|
|
409
|
+
assetsManager.getPaymentMethodResources().then(resources => {
|
|
410
|
+
if (!cancelled) {
|
|
411
|
+
setState(prev => ({
|
|
412
|
+
...prev,
|
|
413
|
+
paymentMethodResources: resources,
|
|
414
|
+
isLoadingResources: false
|
|
415
|
+
}));
|
|
416
|
+
}
|
|
417
|
+
}).catch(err => {
|
|
418
|
+
console.warn(`${LOG} resources load failed ${fmt(err)}`);
|
|
419
|
+
if (!cancelled) {
|
|
420
|
+
setState(prev => ({
|
|
421
|
+
...prev,
|
|
422
|
+
isLoadingResources: false,
|
|
423
|
+
resourcesError: toError(err)
|
|
424
|
+
}));
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
return () => {
|
|
428
|
+
cancelled = true;
|
|
429
|
+
};
|
|
430
|
+
}, [state.isReady, methodTypesSignature]);
|
|
431
|
+
|
|
432
|
+
// Shared fetch + icon-resolve, used by both the initial-load effect and the post-delete refresh.
|
|
433
|
+
const refreshVaultedMethods = useCallback(async () => {
|
|
434
|
+
if (!vaultManagerRef.current) {
|
|
435
|
+
const vm = new PrimerHeadlessUniversalCheckoutVaultManager();
|
|
436
|
+
await vm.configure();
|
|
437
|
+
vaultManagerRef.current = vm;
|
|
438
|
+
let requiresCvv = false;
|
|
439
|
+
try {
|
|
440
|
+
requiresCvv = await vm.requiresVaultedCardCvv();
|
|
441
|
+
} catch (cvvErr) {
|
|
442
|
+
console.warn(`${LOG} requiresVaultedCardCvv failed; defaulting to false ${fmt(cvvErr)}`);
|
|
443
|
+
}
|
|
444
|
+
setState(prev => prev.requiresVaultedCardCvv === requiresCvv ? prev : {
|
|
445
|
+
...prev,
|
|
446
|
+
requiresVaultedCardCvv: requiresCvv
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
const methods = await vaultManagerRef.current.fetchVaultedPaymentMethods();
|
|
450
|
+
const iconEntries = await Promise.all(methods.map(async m => {
|
|
451
|
+
const network = m.paymentInstrumentData?.network;
|
|
452
|
+
if (!network) return [m.id, undefined];
|
|
453
|
+
try {
|
|
454
|
+
const uri = await assetsManager.getCardNetworkImageURL(network);
|
|
455
|
+
return [m.id, uri];
|
|
456
|
+
} catch (iconErr) {
|
|
457
|
+
console.warn(`${LOG} vault icon resolve failed for ${network} ${fmt(iconErr)}`);
|
|
458
|
+
return [m.id, undefined];
|
|
459
|
+
}
|
|
460
|
+
}));
|
|
461
|
+
const iconMap = {};
|
|
462
|
+
for (const [id, uri] of iconEntries) iconMap[id] = uri;
|
|
463
|
+
return {
|
|
464
|
+
methods,
|
|
465
|
+
iconMap
|
|
466
|
+
};
|
|
467
|
+
}, []);
|
|
468
|
+
|
|
469
|
+
// -----------------------------------------------------------------------
|
|
470
|
+
// Vaulted payment methods — lazy-configured after `isReady`, re-fetched on
|
|
471
|
+
// every client-session update. Brand-icon URIs are resolved at fetch time so
|
|
472
|
+
// the row can render synchronously.
|
|
473
|
+
// -----------------------------------------------------------------------
|
|
474
|
+
useEffect(() => {
|
|
475
|
+
// Key on `isReady` only. Native's `onClientSessionUpdate` only fires on session
|
|
476
|
+
// *mutation*, not on initial load, so waiting for `clientSession` would hang forever
|
|
477
|
+
// in the common case.
|
|
478
|
+
if (!state.isReady) return;
|
|
479
|
+
let cancelled = false;
|
|
480
|
+
setState(prev => prev.isLoadingVaulted && prev.vaultedError === null ? prev : {
|
|
481
|
+
...prev,
|
|
482
|
+
isLoadingVaulted: true,
|
|
483
|
+
vaultedError: null
|
|
484
|
+
});
|
|
485
|
+
void (async () => {
|
|
486
|
+
try {
|
|
487
|
+
const {
|
|
488
|
+
methods,
|
|
489
|
+
iconMap
|
|
490
|
+
} = await refreshVaultedMethods();
|
|
491
|
+
if (cancelled) return;
|
|
492
|
+
setState(prev => ({
|
|
493
|
+
...prev,
|
|
494
|
+
vaultedMethods: methods,
|
|
495
|
+
vaultedIconUrisById: iconMap,
|
|
496
|
+
isLoadingVaulted: false
|
|
497
|
+
}));
|
|
498
|
+
} catch (err) {
|
|
499
|
+
console.warn(`${LOG} vault fetch failed ${fmt(err)}`);
|
|
500
|
+
if (!cancelled) {
|
|
501
|
+
const vaultedError = toError(err);
|
|
502
|
+
setState(prev => ({
|
|
503
|
+
...prev,
|
|
504
|
+
isLoadingVaulted: false,
|
|
505
|
+
vaultedError
|
|
506
|
+
}));
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
})();
|
|
510
|
+
return () => {
|
|
511
|
+
cancelled = true;
|
|
512
|
+
};
|
|
513
|
+
}, [state.isReady, state.clientSession, refreshVaultedMethods]);
|
|
514
|
+
|
|
515
|
+
// Fetch the merchant's accepted card networks once the session is ready, and
|
|
516
|
+
// re-fetch when the client session mutates. Cached in context so chip-row consumers
|
|
517
|
+
// read synchronously.
|
|
518
|
+
useEffect(() => {
|
|
519
|
+
if (!state.isReady) return;
|
|
520
|
+
let cancelled = false;
|
|
521
|
+
assetsManager.getOrderedAllowedCardNetworks().then(networks => {
|
|
522
|
+
if (cancelled) return;
|
|
523
|
+
setState(prev => {
|
|
524
|
+
if (networks === null) {
|
|
525
|
+
return prev.acceptedCardNetworks === null ? prev : {
|
|
526
|
+
...prev,
|
|
527
|
+
acceptedCardNetworks: null
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
const same = prev.acceptedCardNetworks?.length === networks.length && prev.acceptedCardNetworks.every((n, i) => n === networks[i]);
|
|
531
|
+
return same ? prev : {
|
|
532
|
+
...prev,
|
|
533
|
+
acceptedCardNetworks: networks
|
|
534
|
+
};
|
|
535
|
+
});
|
|
536
|
+
}).catch(err => {
|
|
537
|
+
console.warn(`${LOG} getOrderedAllowedCardNetworks failed ${fmt(err)}`);
|
|
538
|
+
if (cancelled) return;
|
|
539
|
+
setState(prev => prev.acceptedCardNetworks === null ? prev : {
|
|
540
|
+
...prev,
|
|
541
|
+
acceptedCardNetworks: null
|
|
542
|
+
});
|
|
543
|
+
});
|
|
544
|
+
return () => {
|
|
545
|
+
cancelled = true;
|
|
546
|
+
};
|
|
547
|
+
}, [state.isReady, state.clientSession]);
|
|
548
|
+
|
|
549
|
+
// -----------------------------------------------------------------------
|
|
550
|
+
// Raw-data manager lifecycle.
|
|
551
|
+
//
|
|
552
|
+
// The effect creates a manager for the current `activeMethod` and tears it down in
|
|
553
|
+
// cleanup. Because `activeMethod` is set by the method-selection screen (user intent)
|
|
554
|
+
// rather than the card-form view's mount/unmount, the manager survives nav transitions
|
|
555
|
+
// through processing/success/error — exactly when retry needs it alive.
|
|
556
|
+
//
|
|
557
|
+
// The single cleanup handles all three teardown paths:
|
|
558
|
+
// • method change — effect re-runs, cleanup destroys old, body builds new
|
|
559
|
+
// • session end — `isReady` or `activeMethod` flips, effect re-runs, cleanup destroys
|
|
560
|
+
// • provider unmount — final cleanup destroys
|
|
561
|
+
// -----------------------------------------------------------------------
|
|
562
|
+
useEffect(() => {
|
|
563
|
+
if (!state.isReady || !state.activeMethod) {
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
const method = state.activeMethod;
|
|
567
|
+
let cancelled = false;
|
|
568
|
+
const manager = new PrimerHeadlessUniversalCheckoutRawDataManager();
|
|
569
|
+
managerRef.current = manager;
|
|
570
|
+
|
|
571
|
+
// Once per card-form session: first invalid → valid transition.
|
|
572
|
+
let detailsEnteredFired = false;
|
|
573
|
+
const callbacks = {
|
|
574
|
+
onValidation: (isValid, errors) => {
|
|
575
|
+
if (isValid && !detailsEnteredFired) {
|
|
576
|
+
detailsEnteredFired = true;
|
|
577
|
+
void PrimerAnalytics.trackEvent('PAYMENT_DETAILS_ENTERED', {
|
|
578
|
+
paymentMethod: method
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
const parsed = parseValidationErrors(errors);
|
|
582
|
+
setState(prev => ({
|
|
583
|
+
...prev,
|
|
584
|
+
cardFormState: {
|
|
585
|
+
...prev.cardFormState,
|
|
586
|
+
isValid,
|
|
587
|
+
errors: parsed
|
|
588
|
+
}
|
|
589
|
+
}));
|
|
590
|
+
},
|
|
591
|
+
onBinDataChange: binData => {
|
|
592
|
+
// A PAN edit can change the detected networks. If the shopper's co-badge
|
|
593
|
+
// pick is no longer among them, drop it and re-send the last payload
|
|
594
|
+
// without it — otherwise a stale `preferredNetwork` could reach
|
|
595
|
+
// tokenization (e.g. paste a new PAN and submit without another keystroke).
|
|
596
|
+
const pick = selectedCardNetworkRef.current;
|
|
597
|
+
const detected = binData.preferred ? [binData.preferred, ...binData.alternatives] : binData.alternatives;
|
|
598
|
+
const pickIsStale = pick !== null && !detected.some(n => n.network === pick);
|
|
599
|
+
if (pickIsStale) {
|
|
600
|
+
console.log(`${LOG} pick ${pick} not among detected networks — clearing`);
|
|
601
|
+
selectedCardNetworkRef.current = null;
|
|
602
|
+
const last = lastRawDataRef.current;
|
|
603
|
+
if (last && 'cardNetwork' in last) {
|
|
604
|
+
const stripped = {
|
|
605
|
+
...last
|
|
606
|
+
};
|
|
607
|
+
delete stripped.cardNetwork;
|
|
608
|
+
void setRawData(stripped).catch(err => console.warn(`${LOG} re-send after pick clear failed ${fmt(err)}`));
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
setState(prev => ({
|
|
612
|
+
...prev,
|
|
613
|
+
cardFormState: {
|
|
614
|
+
...prev.cardFormState,
|
|
615
|
+
binData
|
|
616
|
+
},
|
|
617
|
+
...(pickIsStale ? {
|
|
618
|
+
selectedCardNetwork: null
|
|
619
|
+
} : null)
|
|
620
|
+
}));
|
|
621
|
+
},
|
|
622
|
+
onMetadataChange: metadata => {
|
|
623
|
+
setState(prev => ({
|
|
624
|
+
...prev,
|
|
625
|
+
cardFormState: {
|
|
626
|
+
...prev.cardFormState,
|
|
627
|
+
metadata
|
|
628
|
+
}
|
|
629
|
+
}));
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
lastManagerCallbacksRef.current = callbacks;
|
|
633
|
+
void (async () => {
|
|
634
|
+
try {
|
|
635
|
+
await manager.configure({
|
|
636
|
+
paymentMethodType: method,
|
|
637
|
+
...callbacks
|
|
638
|
+
});
|
|
639
|
+
if (cancelled) return;
|
|
640
|
+
const requiredFields = await manager.getRequiredInputElementTypes();
|
|
641
|
+
if (cancelled) return;
|
|
642
|
+
setState(prev => ({
|
|
643
|
+
...prev,
|
|
644
|
+
cardFormState: {
|
|
645
|
+
...prev.cardFormState,
|
|
646
|
+
requiredFields
|
|
647
|
+
}
|
|
648
|
+
}));
|
|
649
|
+
} catch (err) {
|
|
650
|
+
console.error(`${LOG} manager configure failed ${fmt(err)}`);
|
|
651
|
+
}
|
|
652
|
+
})();
|
|
653
|
+
return () => {
|
|
654
|
+
cancelled = true;
|
|
655
|
+
// If retry() holds this manager, defer destroy until retry's finally
|
|
656
|
+
// runs — otherwise we'd cleanUp() between its awaited configure/submit.
|
|
657
|
+
if (retryingManagerRef.current === manager) {
|
|
658
|
+
pendingCleanupRef.current = manager;
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
manager.cleanUp().catch(err => console.warn(`${LOG} manager cleanUp failed ${fmt(err)}`));
|
|
662
|
+
manager.removeAllListeners();
|
|
663
|
+
if (managerRef.current === manager) {
|
|
664
|
+
managerRef.current = null;
|
|
665
|
+
}
|
|
666
|
+
lastManagerCallbacksRef.current = null;
|
|
667
|
+
selectedCardNetworkRef.current = null;
|
|
668
|
+
setState(prev => ({
|
|
669
|
+
...prev,
|
|
670
|
+
cardFormState: initialCardFormState,
|
|
671
|
+
selectedCardNetwork: null
|
|
672
|
+
}));
|
|
673
|
+
};
|
|
674
|
+
}, [state.activeMethod, state.isReady]);
|
|
675
|
+
|
|
676
|
+
// -----------------------------------------------------------------------
|
|
677
|
+
// Actions — stable identities.
|
|
678
|
+
// -----------------------------------------------------------------------
|
|
679
|
+
const setActiveMethod = useCallback(method => {
|
|
680
|
+
if (method !== null) {
|
|
681
|
+
trackSelection(method);
|
|
682
|
+
}
|
|
683
|
+
setState(prev => prev.activeMethod === method ? prev : {
|
|
684
|
+
...prev,
|
|
685
|
+
activeMethod: method
|
|
686
|
+
});
|
|
687
|
+
}, [trackSelection]);
|
|
688
|
+
const setRawData = useCallback(async data => {
|
|
689
|
+
// Keep the co-badge pick sticky: merge it into every card-data payload so it
|
|
690
|
+
// survives keystroke updates (native holds no selection state). The merged
|
|
691
|
+
// payload is what lands in `lastRawDataRef`, so `retry()` re-sends it too.
|
|
692
|
+
const network = selectedCardNetworkRef.current;
|
|
693
|
+
const payload = network && 'cardNumber' in data ? {
|
|
694
|
+
...data,
|
|
695
|
+
cardNetwork: network
|
|
696
|
+
} : data;
|
|
697
|
+
lastRawDataRef.current = payload;
|
|
698
|
+
const manager = managerRef.current;
|
|
699
|
+
if (!manager) {
|
|
700
|
+
console.warn(`${LOG} setRawData: no manager (activeMethod=${stateRef.current.activeMethod})`);
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
try {
|
|
704
|
+
await manager.setRawData(payload);
|
|
705
|
+
} catch (err) {
|
|
706
|
+
console.warn(`${LOG} setRawData failed: ${err instanceof PrimerError ? err.errorId : 'unknown'}`);
|
|
707
|
+
throw err;
|
|
708
|
+
}
|
|
709
|
+
}, []);
|
|
710
|
+
const setBillingAddress = useCallback(async address => {
|
|
711
|
+
const manager = managerRef.current;
|
|
712
|
+
if (!manager) {
|
|
713
|
+
console.warn(`${LOG} setBillingAddress: no manager (activeMethod=${stateRef.current.activeMethod})`);
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
try {
|
|
717
|
+
await manager.setBillingAddress(address);
|
|
718
|
+
} catch (err) {
|
|
719
|
+
console.warn(`${LOG} setBillingAddress failed ${fmt(err)}`);
|
|
720
|
+
throw err;
|
|
721
|
+
}
|
|
722
|
+
}, []);
|
|
723
|
+
const selectCardNetwork = useCallback(async identifier => {
|
|
724
|
+
const m = managerRef.current;
|
|
725
|
+
if (!m) {
|
|
726
|
+
console.warn(`${LOG} selectCardNetwork: no manager (activeMethod=${stateRef.current.activeMethod})`);
|
|
727
|
+
throw new PrimerError('NO_ACTIVE_CARD_FORM', undefined, 'No active card form', undefined, undefined);
|
|
728
|
+
}
|
|
729
|
+
selectedCardNetworkRef.current = identifier;
|
|
730
|
+
// Re-send the last raw data so the pick applies immediately.
|
|
731
|
+
if (lastRawDataRef.current) {
|
|
732
|
+
await setRawData(lastRawDataRef.current);
|
|
733
|
+
}
|
|
734
|
+
setState(prev => prev.selectedCardNetwork === identifier ? prev : {
|
|
735
|
+
...prev,
|
|
736
|
+
selectedCardNetwork: identifier
|
|
737
|
+
});
|
|
738
|
+
}, [setRawData]);
|
|
739
|
+
const submit = useCallback(async () => {
|
|
740
|
+
const manager = managerRef.current;
|
|
741
|
+
if (!manager) {
|
|
742
|
+
console.warn(`${LOG} submit: no manager`);
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
trackAttemptStart(stateRef.current.activeMethod ?? 'PAYMENT_CARD', {
|
|
746
|
+
submitted: true
|
|
747
|
+
});
|
|
748
|
+
await manager.submit();
|
|
749
|
+
}, [trackAttemptStart]);
|
|
750
|
+
const retry = useCallback(async () => {
|
|
751
|
+
const method = stateRef.current.activeMethod;
|
|
752
|
+
const manager = managerRef.current;
|
|
753
|
+
if (!method || !manager) {
|
|
754
|
+
console.warn(`${LOG} retry: no active method or manager ${fmt({
|
|
755
|
+
method,
|
|
756
|
+
hasManager: !!manager
|
|
757
|
+
})}`);
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
// iOS workaround: the native iOS RawDataManager nullifies its delegate on successful
|
|
761
|
+
// tokenization, so any post-tokenize failure would silently drop subsequent submit()
|
|
762
|
+
// outcomes. Reconfiguring here rebuilds the delegate binding; harmless on Android.
|
|
763
|
+
// (The "remove once the iOS SDK stops nullifying" reminder lives in the PR description.)
|
|
764
|
+
retryingManagerRef.current = manager;
|
|
765
|
+
try {
|
|
766
|
+
// Re-pass the original callbacks so the JS-wrapper's listeners get re-registered.
|
|
767
|
+
// Otherwise native would emit onValidation/onBinDataChange/onMetadataChange during
|
|
768
|
+
// the retry attempt with no JS-side subscribers → RN warns "no listeners registered".
|
|
769
|
+
const callbacks = lastManagerCallbacksRef.current;
|
|
770
|
+
await manager.configure(callbacks ? {
|
|
771
|
+
paymentMethodType: method,
|
|
772
|
+
...callbacks
|
|
773
|
+
} : {
|
|
774
|
+
paymentMethodType: method
|
|
775
|
+
});
|
|
776
|
+
if (lastRawDataRef.current) {
|
|
777
|
+
await manager.setRawData(lastRawDataRef.current);
|
|
778
|
+
}
|
|
779
|
+
// Clear the previous outcome so the transitioner fires for the new attempt.
|
|
780
|
+
setState(prev => prev.paymentOutcome === null ? prev : {
|
|
781
|
+
...prev,
|
|
782
|
+
paymentOutcome: null
|
|
783
|
+
});
|
|
784
|
+
trackAttemptStart(method, {
|
|
785
|
+
submitted: true
|
|
786
|
+
});
|
|
787
|
+
await manager.submit();
|
|
788
|
+
} catch (err) {
|
|
789
|
+
console.error(`${LOG} retry failed ${fmt(err)}`);
|
|
790
|
+
throw err;
|
|
791
|
+
} finally {
|
|
792
|
+
retryingManagerRef.current = null;
|
|
793
|
+
// Run a teardown that the effect cleanup deferred while retry was in flight.
|
|
794
|
+
const pending = pendingCleanupRef.current;
|
|
795
|
+
if (pending === manager) {
|
|
796
|
+
pendingCleanupRef.current = null;
|
|
797
|
+
pending.cleanUp().catch(err => console.warn(`${LOG} deferred cleanUp failed ${fmt(err)}`));
|
|
798
|
+
pending.removeAllListeners();
|
|
799
|
+
if (managerRef.current === pending) {
|
|
800
|
+
managerRef.current = null;
|
|
801
|
+
}
|
|
802
|
+
lastManagerCallbacksRef.current = null;
|
|
803
|
+
selectedCardNetworkRef.current = null;
|
|
804
|
+
setState(prev => ({
|
|
805
|
+
...prev,
|
|
806
|
+
cardFormState: initialCardFormState,
|
|
807
|
+
selectedCardNetwork: null
|
|
808
|
+
}));
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}, []);
|
|
812
|
+
const clearPaymentOutcome = useCallback(() => {
|
|
813
|
+
setState(prev => prev.paymentOutcome === null ? prev : {
|
|
814
|
+
...prev,
|
|
815
|
+
paymentOutcome: null
|
|
816
|
+
});
|
|
817
|
+
}, []);
|
|
818
|
+
|
|
819
|
+
// NATIVE_UI methods (Google Pay today; Apple Pay / PayPal / web-redirect APMs later) ride the
|
|
820
|
+
// existing Headless NATIVE_UI path: start the native flow by type; outcomes arrive through the
|
|
821
|
+
// shared onCheckoutComplete/onError. Only one native-UI flow runs at a time.
|
|
822
|
+
const startNativeUI = useCallback(async paymentMethodType => {
|
|
823
|
+
// Ignore re-entrant taps: the in-list method row isn't disabled while loading, so a fast
|
|
824
|
+
// double-tap would otherwise spawn two native flows.
|
|
825
|
+
if (stateRef.current.nativeUiInFlightType !== null) {
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
if (paymentMethodType === GOOGLE_PAY && !isGooglePaySupported(stateRef.current.availablePaymentMethods)) {
|
|
829
|
+
throw new PrimerError('google-pay-unavailable', 'google-pay-unavailable', 'Google Pay is not available on this device.', undefined, undefined);
|
|
830
|
+
}
|
|
831
|
+
if (paymentMethodType === APPLE_PAY && !isApplePaySupported(stateRef.current.availablePaymentMethods)) {
|
|
832
|
+
throw new PrimerError('apple-pay-unavailable', 'apple-pay-unavailable', 'Apple Pay is not available on this device.', undefined, undefined);
|
|
833
|
+
}
|
|
834
|
+
// Clear any stale outcome so the result screen re-fires for this attempt.
|
|
835
|
+
setState(prev => ({
|
|
836
|
+
...prev,
|
|
837
|
+
paymentOutcome: null,
|
|
838
|
+
nativeUiInFlightType: paymentMethodType
|
|
839
|
+
}));
|
|
840
|
+
// Wallet/APM handoff: select + hand off to native, no form so no SUBMITTED (matches Web).
|
|
841
|
+
trackSelection(paymentMethodType);
|
|
842
|
+
trackAttemptStart(paymentMethodType, {
|
|
843
|
+
submitted: false
|
|
844
|
+
});
|
|
845
|
+
try {
|
|
846
|
+
const manager = new PrimerHeadlessUniversalCheckoutPaymentMethodNativeUIManager();
|
|
847
|
+
await manager.configure(paymentMethodType);
|
|
848
|
+
await manager.showPaymentMethod(PrimerSessionIntent.CHECKOUT);
|
|
849
|
+
// Success / failure arrive via onCheckoutComplete / onError; shopper-cancel via
|
|
850
|
+
// onError('payment-cancelled'). nativeUiInFlightType is reset in those handlers.
|
|
851
|
+
} catch (err) {
|
|
852
|
+
console.warn(`${LOG} startNativeUI(${paymentMethodType}) failed ${fmt(err)}`);
|
|
853
|
+
const error = err instanceof PrimerError ? err : new PrimerError('native-ui-start-failed', undefined, toError(err).message, undefined, undefined);
|
|
854
|
+
void PrimerAnalytics.sendErrorLog('Unable to present payment method', 'unable-to-present-payment-method', `${paymentMethodType}: ${error.description ?? error.message}`);
|
|
855
|
+
setState(prev => ({
|
|
856
|
+
...prev,
|
|
857
|
+
nativeUiInFlightType: null,
|
|
858
|
+
paymentOutcome: {
|
|
859
|
+
status: 'error',
|
|
860
|
+
error,
|
|
861
|
+
data: null
|
|
862
|
+
}
|
|
863
|
+
}));
|
|
864
|
+
throw error;
|
|
865
|
+
}
|
|
866
|
+
}, [trackSelection, trackAttemptStart]);
|
|
867
|
+
const cancelNativeUI = useCallback(paymentMethodType => {
|
|
868
|
+
// The native sheet is a system surface JS can't force-close (FR-002b), so we only clear the
|
|
869
|
+
// in-flight flag, and only for the matching method. A real dismissal surfaces via
|
|
870
|
+
// onError('payment-cancelled').
|
|
871
|
+
setState(prev => prev.nativeUiInFlightType === paymentMethodType ? {
|
|
872
|
+
...prev,
|
|
873
|
+
nativeUiInFlightType: null
|
|
874
|
+
} : prev);
|
|
875
|
+
}, []);
|
|
876
|
+
const selectVaultedMethodId = useCallback(id => {
|
|
877
|
+
setState(prev => {
|
|
878
|
+
// The id must exist among the current methods to be honoured.
|
|
879
|
+
if (!prev.vaultedMethods.some(m => m.id === id)) {
|
|
880
|
+
console.warn(`${LOG} selectVaultedMethodId: id ${id} not present in vaultedMethods`);
|
|
881
|
+
return prev;
|
|
882
|
+
}
|
|
883
|
+
// Already lite-with-this-id (no override to clear) → nothing to do.
|
|
884
|
+
if (prev.activeVaultedMethodId === id && prev.vaultDisplayOverride === null) {
|
|
885
|
+
return prev;
|
|
886
|
+
}
|
|
887
|
+
// Any tap commits the user's choice and clears any prior expand-override.
|
|
888
|
+
return {
|
|
889
|
+
...prev,
|
|
890
|
+
activeVaultedMethodId: id,
|
|
891
|
+
vaultDisplayOverride: null
|
|
892
|
+
};
|
|
893
|
+
});
|
|
894
|
+
}, []);
|
|
895
|
+
const requestExpandedVaultDisplay = useCallback(() => {
|
|
896
|
+
setState(prev => prev.vaultDisplayOverride === 'expanded' ? prev : {
|
|
897
|
+
...prev,
|
|
898
|
+
vaultDisplayOverride: 'expanded'
|
|
899
|
+
});
|
|
900
|
+
}, []);
|
|
901
|
+
const setCvvInputVisible = useCallback(visible => {
|
|
902
|
+
setState(prev => prev.cvvInputVisible === visible ? prev : {
|
|
903
|
+
...prev,
|
|
904
|
+
cvvInputVisible: visible
|
|
905
|
+
});
|
|
906
|
+
}, []);
|
|
907
|
+
|
|
908
|
+
// Vanish fallback: if the user-selected method is no longer in `vaultedMethods`
|
|
909
|
+
// (mid-session client-session update removed it), clear the override so the
|
|
910
|
+
// hook falls back to the new originalDefault and the lite layout disappears.
|
|
911
|
+
useEffect(() => {
|
|
912
|
+
if (state.activeVaultedMethodId === null) return;
|
|
913
|
+
const stillPresent = state.vaultedMethods.some(m => m.id === state.activeVaultedMethodId);
|
|
914
|
+
if (stillPresent) return;
|
|
915
|
+
setState(prev => prev.activeVaultedMethodId === null && prev.vaultDisplayOverride === null ? prev : {
|
|
916
|
+
...prev,
|
|
917
|
+
activeVaultedMethodId: null,
|
|
918
|
+
vaultDisplayOverride: null
|
|
919
|
+
});
|
|
920
|
+
}, [state.activeVaultedMethodId, state.vaultedMethods]);
|
|
921
|
+
const payFromVault = useCallback(async (vaultedPaymentMethodId, additionalData) => {
|
|
922
|
+
const vm = vaultManagerRef.current;
|
|
923
|
+
if (!vm) {
|
|
924
|
+
console.warn(`${LOG} payFromVault: vault manager not configured`);
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
// Clear any stale outcome so PaymentOutcomeTransitioner re-fires for this attempt.
|
|
928
|
+
setState(prev => prev.paymentOutcome === null ? prev : {
|
|
929
|
+
...prev,
|
|
930
|
+
paymentOutcome: null
|
|
931
|
+
});
|
|
932
|
+
// Vaulted pay is a card payment: same SUBMITTED → PROCESSING → outcome sequence.
|
|
933
|
+
trackAttemptStart('PAYMENT_CARD', {
|
|
934
|
+
submitted: true
|
|
935
|
+
});
|
|
936
|
+
try {
|
|
937
|
+
await vm.startPaymentFlow(vaultedPaymentMethodId, additionalData);
|
|
938
|
+
} catch (err) {
|
|
939
|
+
console.error(`${LOG} payFromVault failed ${fmt(err)}`);
|
|
940
|
+
if (additionalData?.cvv) {
|
|
941
|
+
const errorId = err?.errorId != null ? String(err.errorId) : 'UNKNOWN';
|
|
942
|
+
void PrimerAnalytics.trackEvent('VAULT_CVV_SUBMISSION_FAILED', {
|
|
943
|
+
vaultedMethodId: vaultedPaymentMethodId,
|
|
944
|
+
errorId
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
const primerError = err;
|
|
948
|
+
setState(prev => ({
|
|
949
|
+
...prev,
|
|
950
|
+
paymentOutcome: {
|
|
951
|
+
status: 'error',
|
|
952
|
+
error: primerError,
|
|
953
|
+
data: null
|
|
954
|
+
}
|
|
955
|
+
}));
|
|
956
|
+
}
|
|
957
|
+
}, []);
|
|
958
|
+
const deleteVaultedPaymentMethod = useCallback(async vaultedPaymentMethodId => {
|
|
959
|
+
const vm = vaultManagerRef.current;
|
|
960
|
+
if (!vm) {
|
|
961
|
+
return Promise.reject({
|
|
962
|
+
errorId: 'VAULT_MANAGER_NOT_CONFIGURED',
|
|
963
|
+
description: 'Vault manager not configured'
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
if (!stateRef.current.vaultedMethods.some(m => m.id === vaultedPaymentMethodId)) {
|
|
967
|
+
return Promise.reject({
|
|
968
|
+
errorId: 'INVALID_VAULTED_METHOD_ID',
|
|
969
|
+
description: `No vaulted method with id ${vaultedPaymentMethodId}`
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
await vm.deleteVaultedPaymentMethod(vaultedPaymentMethodId);
|
|
973
|
+
// Refresh is best-effort: if it fails after a successful server-side delete,
|
|
974
|
+
// reconcile local state from what we know (drop the deleted id) rather than
|
|
975
|
+
// rejecting — otherwise the caller surfaces "delete failed" for a delete that
|
|
976
|
+
// actually succeeded.
|
|
977
|
+
let methods;
|
|
978
|
+
let iconMap;
|
|
979
|
+
try {
|
|
980
|
+
({
|
|
981
|
+
methods,
|
|
982
|
+
iconMap
|
|
983
|
+
} = await refreshVaultedMethods());
|
|
984
|
+
} catch (refreshErr) {
|
|
985
|
+
console.warn(`${LOG} deleteVaultedPaymentMethod refresh failed ${fmt(refreshErr)}`);
|
|
986
|
+
methods = stateRef.current.vaultedMethods.filter(m => m.id !== vaultedPaymentMethodId);
|
|
987
|
+
iconMap = {
|
|
988
|
+
...stateRef.current.vaultedIconUrisById
|
|
989
|
+
};
|
|
990
|
+
delete iconMap[vaultedPaymentMethodId];
|
|
991
|
+
}
|
|
992
|
+
// Promotion rule (matches iOS VaultedPaymentMethodManager.swift:18-31 and Android
|
|
993
|
+
// VaultViewModel.kt:136-148): if the deleted id was the user's explicit pick, replace it
|
|
994
|
+
// with the new top-of-list (or null when empty); otherwise leave the explicit pick alone.
|
|
995
|
+
setState(prev => {
|
|
996
|
+
const wasActive = prev.activeVaultedMethodId === vaultedPaymentMethodId;
|
|
997
|
+
const nextActiveId = wasActive ? methods[0]?.id ?? null : prev.activeVaultedMethodId;
|
|
998
|
+
const nextOverride = methods.length === 0 ? null : prev.vaultDisplayOverride;
|
|
999
|
+
return {
|
|
1000
|
+
...prev,
|
|
1001
|
+
vaultedMethods: methods,
|
|
1002
|
+
vaultedIconUrisById: iconMap,
|
|
1003
|
+
activeVaultedMethodId: nextActiveId,
|
|
1004
|
+
vaultDisplayOverride: nextOverride
|
|
1005
|
+
};
|
|
1006
|
+
});
|
|
1007
|
+
}, [refreshVaultedMethods]);
|
|
1008
|
+
const contextValue = useMemo(() => {
|
|
1009
|
+
return {
|
|
1010
|
+
isReady: state.isReady,
|
|
1011
|
+
error: state.error,
|
|
1012
|
+
clientSession: state.clientSession,
|
|
1013
|
+
acceptedCardNetworks: state.acceptedCardNetworks,
|
|
1014
|
+
availablePaymentMethods: state.availablePaymentMethods,
|
|
1015
|
+
paymentMethodResources: state.paymentMethodResources,
|
|
1016
|
+
isLoadingResources: state.isLoadingResources,
|
|
1017
|
+
resourcesError: state.resourcesError,
|
|
1018
|
+
settings: settingsRef.current,
|
|
1019
|
+
paymentOutcome: state.paymentOutcome,
|
|
1020
|
+
nativeUiInFlightType: state.nativeUiInFlightType,
|
|
1021
|
+
activeMethod: state.activeMethod,
|
|
1022
|
+
cardFormState: state.cardFormState,
|
|
1023
|
+
vaultedMethods: state.vaultedMethods,
|
|
1024
|
+
vaultedIconUrisById: state.vaultedIconUrisById,
|
|
1025
|
+
isLoadingVaulted: state.isLoadingVaulted,
|
|
1026
|
+
vaultedError: state.vaultedError,
|
|
1027
|
+
activeVaultedMethodId: state.activeVaultedMethodId,
|
|
1028
|
+
vaultDisplayOverride: state.vaultDisplayOverride,
|
|
1029
|
+
selectedCardNetwork: state.selectedCardNetwork,
|
|
1030
|
+
requiresVaultedCardCvv: state.requiresVaultedCardCvv,
|
|
1031
|
+
cvvInputVisible: state.cvvInputVisible,
|
|
1032
|
+
setActiveMethod,
|
|
1033
|
+
setRawData,
|
|
1034
|
+
setBillingAddress,
|
|
1035
|
+
selectCardNetwork,
|
|
1036
|
+
submit,
|
|
1037
|
+
retry,
|
|
1038
|
+
clearPaymentOutcome,
|
|
1039
|
+
startNativeUI,
|
|
1040
|
+
cancelNativeUI,
|
|
1041
|
+
payFromVault,
|
|
1042
|
+
selectVaultedMethodId,
|
|
1043
|
+
requestExpandedVaultDisplay,
|
|
1044
|
+
setCvvInputVisible,
|
|
1045
|
+
deleteVaultedPaymentMethod
|
|
1046
|
+
};
|
|
1047
|
+
}, [state, startNativeUI, cancelNativeUI, setActiveMethod, setRawData, setBillingAddress, selectCardNetwork, submit, retry, clearPaymentOutcome, payFromVault, selectVaultedMethodId, requestExpandedVaultDisplay, setCvvInputVisible, deleteVaultedPaymentMethod]);
|
|
1048
|
+
return /*#__PURE__*/_jsx(ThemeContext.Provider, {
|
|
1049
|
+
value: {
|
|
1050
|
+
lightTokens,
|
|
1051
|
+
darkTokens
|
|
1052
|
+
},
|
|
1053
|
+
children: /*#__PURE__*/_jsx(PrimerCheckoutContext.Provider, {
|
|
1054
|
+
value: contextValue,
|
|
1055
|
+
children: children
|
|
1056
|
+
})
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
//# sourceMappingURL=PrimerCheckoutProvider.js.map
|