@adyen/adyen-web 6.19.0 → 6.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/adyen.css +10 -11
- package/dist/cjs/adyen.css.map +1 -1
- package/dist/cjs/index.cjs +2 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +43 -65
- package/dist/es/adyen.css +10 -11
- package/dist/es/adyen.css.map +1 -1
- package/dist/es/components/Ach/Ach.js +1 -1
- package/dist/es/components/Ach/Ach.js.map +1 -1
- package/dist/es/components/Ach/components/AchComponent.js +1 -1
- package/dist/es/components/Ach/components/AchComponent.js.map +1 -1
- package/dist/es/components/Ach/components/useSRPanelForACHErrors.js.map +1 -1
- package/dist/es/components/Card/Card.js +1 -1
- package/dist/es/components/Card/Card.js.map +1 -1
- package/dist/es/components/Card/components/CardInput/components/CardFieldsWrapper.js +1 -1
- package/dist/es/components/Card/components/CardInput/components/CardFieldsWrapper.js.map +1 -1
- package/dist/es/components/Card/components/CardInput/components/Installments/Installments.js +1 -1
- package/dist/es/components/Card/components/CardInput/components/Installments/Installments.js.map +1 -1
- package/dist/es/components/Card/components/CardInput/handlers.js.map +1 -1
- package/dist/es/components/Card/components/CardInput/useSRPanelForCardInputErrors.js.map +1 -1
- package/dist/es/components/Card/components/CardInput/utils.js +1 -1
- package/dist/es/components/Card/components/CardInput/utils.js.map +1 -1
- package/dist/es/components/Dropin/Dropin.js +1 -1
- package/dist/es/components/Dropin/Dropin.js.map +1 -1
- package/dist/es/components/Giftcard/components/useSRPanelForGiftcardErrors.js.map +1 -1
- package/dist/es/components/PayByBankPix/PayByBankPix.js +1 -1
- package/dist/es/components/PayByBankPix/PayByBankPix.js.map +1 -1
- package/dist/es/components/PayByBankPix/components/Enrollment/Enrollment.js +1 -1
- package/dist/es/components/PayByBankPix/components/Enrollment/Enrollment.js.map +1 -1
- package/dist/es/components/PayByBankPix/components/Enrollment/components/IssuerListIntroduction.js +1 -1
- package/dist/es/components/PayByBankPix/components/Enrollment/components/IssuerListIntroduction.js.map +1 -1
- package/dist/es/components/PayByBankPix/components/Enrollment/useIssuerWithLogo.js +1 -1
- package/dist/es/components/PayByBankPix/components/Enrollment/useIssuerWithLogo.js.map +1 -1
- package/dist/es/components/PayByBankPix/components/StoredPayment/StoredPayment.js +1 -1
- package/dist/es/components/PayByBankPix/components/StoredPayment/StoredPayment.js.map +1 -1
- package/dist/es/components/PayPal/utils/get-paypal-styles.js.map +1 -1
- package/dist/es/components/PayPalFastlane/FastlaneSDK.js.map +1 -1
- package/dist/es/components/ThreeDS2/components/Challenge/PrepareChallenge3DS2.js.map +1 -1
- package/dist/es/components/ThreeDS2/components/DeviceFingerprint/PrepareFingerprint3DS2.js.map +1 -1
- package/dist/es/components/UPI/UPI.js +1 -1
- package/dist/es/components/UPI/UPI.js.map +1 -1
- package/dist/es/components/UPI/components/UPIComponent/UPIComponent.js +1 -1
- package/dist/es/components/UPI/components/UPIComponent/UPIComponent.js.map +1 -1
- package/dist/es/components/UPI/components/UPIIntentAppList/UPIIntentAppItem/UPIIntentAppItem.js +1 -1
- package/dist/es/components/UPI/components/UPIIntentAppList/UPIIntentAppItem/UPIIntentAppItem.js.map +1 -1
- package/dist/es/components/UPI/components/UPIIntentAppList/UPIIntentAppList.js +1 -1
- package/dist/es/components/UPI/components/UPIIntentAppList/UPIIntentAppList.js.map +1 -1
- package/dist/es/components/UPI/constants.js +2 -0
- package/dist/es/components/UPI/constants.js.map +1 -0
- package/dist/es/components/internal/Address/Address.js.map +1 -1
- package/dist/es/components/internal/Alert/Alert.js +1 -1
- package/dist/es/components/internal/Alert/Alert.js.map +1 -1
- package/dist/es/components/internal/ClickToPay/models/ShopperCard.js +1 -1
- package/dist/es/components/internal/ClickToPay/models/ShopperCard.js.map +1 -1
- package/dist/es/components/internal/IbanInput/IbanInput.js.map +1 -1
- package/dist/es/components/internal/IssuerList/IssuerList.js +1 -1
- package/dist/es/components/internal/IssuerList/IssuerList.js.map +1 -1
- package/dist/es/components/internal/OpenInvoice/useSRPanelForOpenInvoiceErrors.js.map +1 -1
- package/dist/es/components/internal/PayButton/PayButton.js +1 -1
- package/dist/es/components/internal/PayButton/PayButton.js.map +1 -1
- package/dist/es/components/internal/PayButton/components/SecondaryButtonLabel.js.map +1 -1
- package/dist/es/components/internal/SecuredFields/SFP/SecuredFieldsProvider.js.map +1 -1
- package/dist/es/components/internal/SecuredFields/binLookup/createCardVariantSwitcher.js +1 -1
- package/dist/es/components/internal/SecuredFields/binLookup/createCardVariantSwitcher.js.map +1 -1
- package/dist/es/components/internal/SecuredFields/binLookup/extensions.js +1 -1
- package/dist/es/components/internal/SecuredFields/binLookup/extensions.js.map +1 -1
- package/dist/es/components/internal/SecuredFields/binLookup/triggerBinLookUp.js.map +1 -1
- package/dist/es/components/internal/SecuredFields/lib/CSF/extensions/handleIOSTouchEvents.js.map +1 -1
- package/dist/es/components/internal/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/es/components/internal/UIElement/UIElement.js +1 -1
- package/dist/es/components/internal/UIElement/UIElement.js.map +1 -1
- package/dist/es/components/internal/UIElement/utils.js.map +1 -1
- package/dist/es/core/Analytics/utils.js.map +1 -1
- package/dist/es/core/Errors/SRPanel.js.map +1 -1
- package/dist/es/core/Errors/utils.js.map +1 -1
- package/dist/es/core/Services/analytics/collect-id.js +1 -1
- package/dist/es/core/core.js +1 -1
- package/dist/es/core/core.registry.js.map +1 -1
- package/dist/es/core/utils.js.map +1 -1
- package/dist/es/external/preact/compat/dist/compat.js.map +1 -1
- package/dist/es/external/preact/dist/preact.js.map +1 -1
- package/dist/es/index.d.ts +43 -65
- package/dist/es/language/utils.js.map +1 -1
- package/dist/es/utils/clipboard.js.map +1 -1
- package/dist/es/utils/setFocus.js.map +1 -1
- package/dist/es/utils/useForm/reducer.js.map +1 -1
- package/dist/es-legacy/adyen.css +10 -11
- package/dist/es-legacy/adyen.css.map +1 -1
- package/dist/es-legacy/components/Ach/Ach.js +1 -1
- package/dist/es-legacy/components/Ach/Ach.js.map +1 -1
- package/dist/es-legacy/components/Ach/components/AchComponent.js +1 -1
- package/dist/es-legacy/components/Ach/components/AchComponent.js.map +1 -1
- package/dist/es-legacy/components/Ach/components/useSRPanelForACHErrors.js.map +1 -1
- package/dist/es-legacy/components/Card/Card.js +1 -1
- package/dist/es-legacy/components/Card/Card.js.map +1 -1
- package/dist/es-legacy/components/Card/components/CardInput/components/CardFieldsWrapper.js +1 -1
- package/dist/es-legacy/components/Card/components/CardInput/components/CardFieldsWrapper.js.map +1 -1
- package/dist/es-legacy/components/Card/components/CardInput/components/Installments/Installments.js +1 -1
- package/dist/es-legacy/components/Card/components/CardInput/components/Installments/Installments.js.map +1 -1
- package/dist/es-legacy/components/Card/components/CardInput/handlers.js.map +1 -1
- package/dist/es-legacy/components/Card/components/CardInput/useSRPanelForCardInputErrors.js.map +1 -1
- package/dist/es-legacy/components/Card/components/CardInput/utils.js +1 -1
- package/dist/es-legacy/components/Card/components/CardInput/utils.js.map +1 -1
- package/dist/es-legacy/components/Dropin/Dropin.js +1 -1
- package/dist/es-legacy/components/Dropin/Dropin.js.map +1 -1
- package/dist/es-legacy/components/Giftcard/components/useSRPanelForGiftcardErrors.js.map +1 -1
- package/dist/es-legacy/components/PayByBankPix/PayByBankPix.js +1 -1
- package/dist/es-legacy/components/PayByBankPix/PayByBankPix.js.map +1 -1
- package/dist/es-legacy/components/PayByBankPix/components/Enrollment/Enrollment.js +1 -1
- package/dist/es-legacy/components/PayByBankPix/components/Enrollment/Enrollment.js.map +1 -1
- package/dist/es-legacy/components/PayByBankPix/components/Enrollment/components/IssuerListIntroduction.js +1 -1
- package/dist/es-legacy/components/PayByBankPix/components/Enrollment/components/IssuerListIntroduction.js.map +1 -1
- package/dist/es-legacy/components/PayByBankPix/components/Enrollment/useIssuerWithLogo.js +1 -1
- package/dist/es-legacy/components/PayByBankPix/components/Enrollment/useIssuerWithLogo.js.map +1 -1
- package/dist/es-legacy/components/PayByBankPix/components/StoredPayment/StoredPayment.js +1 -1
- package/dist/es-legacy/components/PayByBankPix/components/StoredPayment/StoredPayment.js.map +1 -1
- package/dist/es-legacy/components/PayPal/utils/get-paypal-styles.js.map +1 -1
- package/dist/es-legacy/components/PayPalFastlane/FastlaneSDK.js.map +1 -1
- package/dist/es-legacy/components/ThreeDS2/components/Challenge/PrepareChallenge3DS2.js.map +1 -1
- package/dist/es-legacy/components/ThreeDS2/components/DeviceFingerprint/PrepareFingerprint3DS2.js.map +1 -1
- package/dist/es-legacy/components/UPI/UPI.js +1 -1
- package/dist/es-legacy/components/UPI/UPI.js.map +1 -1
- package/dist/es-legacy/components/UPI/components/UPIComponent/UPIComponent.js +1 -1
- package/dist/es-legacy/components/UPI/components/UPIComponent/UPIComponent.js.map +1 -1
- package/dist/es-legacy/components/UPI/components/UPIIntentAppList/UPIIntentAppItem/UPIIntentAppItem.js +1 -1
- package/dist/es-legacy/components/UPI/components/UPIIntentAppList/UPIIntentAppItem/UPIIntentAppItem.js.map +1 -1
- package/dist/es-legacy/components/UPI/components/UPIIntentAppList/UPIIntentAppList.js +1 -1
- package/dist/es-legacy/components/UPI/components/UPIIntentAppList/UPIIntentAppList.js.map +1 -1
- package/dist/es-legacy/components/UPI/constants.js +2 -0
- package/dist/es-legacy/components/UPI/constants.js.map +1 -0
- package/dist/es-legacy/components/internal/Address/Address.js.map +1 -1
- package/dist/es-legacy/components/internal/Alert/Alert.js +1 -1
- package/dist/es-legacy/components/internal/Alert/Alert.js.map +1 -1
- package/dist/es-legacy/components/internal/ClickToPay/models/ShopperCard.js +1 -1
- package/dist/es-legacy/components/internal/ClickToPay/models/ShopperCard.js.map +1 -1
- package/dist/es-legacy/components/internal/IbanInput/IbanInput.js.map +1 -1
- package/dist/es-legacy/components/internal/IssuerList/IssuerList.js +1 -1
- package/dist/es-legacy/components/internal/IssuerList/IssuerList.js.map +1 -1
- package/dist/es-legacy/components/internal/OpenInvoice/useSRPanelForOpenInvoiceErrors.js.map +1 -1
- package/dist/es-legacy/components/internal/PayButton/PayButton.js +1 -1
- package/dist/es-legacy/components/internal/PayButton/PayButton.js.map +1 -1
- package/dist/es-legacy/components/internal/PayButton/components/SecondaryButtonLabel.js.map +1 -1
- package/dist/es-legacy/components/internal/SecuredFields/SFP/SecuredFieldsProvider.js.map +1 -1
- package/dist/es-legacy/components/internal/SecuredFields/binLookup/createCardVariantSwitcher.js +1 -1
- package/dist/es-legacy/components/internal/SecuredFields/binLookup/createCardVariantSwitcher.js.map +1 -1
- package/dist/es-legacy/components/internal/SecuredFields/binLookup/extensions.js +1 -1
- package/dist/es-legacy/components/internal/SecuredFields/binLookup/extensions.js.map +1 -1
- package/dist/es-legacy/components/internal/SecuredFields/binLookup/triggerBinLookUp.js.map +1 -1
- package/dist/es-legacy/components/internal/SecuredFields/lib/CSF/extensions/handleIOSTouchEvents.js.map +1 -1
- package/dist/es-legacy/components/internal/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/es-legacy/components/internal/UIElement/UIElement.js +1 -1
- package/dist/es-legacy/components/internal/UIElement/UIElement.js.map +1 -1
- package/dist/es-legacy/components/internal/UIElement/utils.js.map +1 -1
- package/dist/es-legacy/core/Analytics/utils.js.map +1 -1
- package/dist/es-legacy/core/Errors/SRPanel.js.map +1 -1
- package/dist/es-legacy/core/Errors/utils.js.map +1 -1
- package/dist/es-legacy/core/Services/analytics/collect-id.js +1 -1
- package/dist/es-legacy/core/core.js +1 -1
- package/dist/es-legacy/core/core.registry.js.map +1 -1
- package/dist/es-legacy/core/utils.js.map +1 -1
- package/dist/es-legacy/external/preact/compat/dist/compat.js.map +1 -1
- package/dist/es-legacy/external/preact/dist/preact.js.map +1 -1
- package/dist/es-legacy/language/utils.js.map +1 -1
- package/dist/es-legacy/utils/clipboard.js.map +1 -1
- package/dist/es-legacy/utils/setFocus.js.map +1 -1
- package/dist/es-legacy/utils/useForm/reducer.js.map +1 -1
- package/package.json +159 -159
- package/styles/adyen.css +10 -11
- package/dist/es/components/UPI/components/UPIComponent/constants.js +0 -2
- package/dist/es/components/UPI/components/UPIComponent/constants.js.map +0 -1
- package/dist/es/components/UPI/components/UPIComponent/useUpiSegmentedControlOptions.js +0 -2
- package/dist/es/components/UPI/components/UPIComponent/useUpiSegmentedControlOptions.js.map +0 -1
- package/dist/es-legacy/components/UPI/components/UPIComponent/constants.js +0 -2
- package/dist/es-legacy/components/UPI/components/UPIComponent/constants.js.map +0 -1
- package/dist/es-legacy/components/UPI/components/UPIComponent/useUpiSegmentedControlOptions.js +0 -2
- package/dist/es-legacy/components/UPI/components/UPIComponent/useUpiSegmentedControlOptions.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecuredFieldsProvider.js","sources":["../../../../../../src/components/internal/SecuredFields/SFP/SecuredFieldsProvider.ts"],"sourcesContent":["import { Component } from 'preact';\nimport { getErrorObject, getFields, getErrorReducer, validFieldsReducer } from './SFPUtils';\nimport initCSF from '../lib/CSF';\nimport handlers from './SecuredFieldsProviderHandlers';\nimport defaultProps from './defaultProps';\nimport { SFPProps, SFPState, SingleBrandResetObject } from './types';\nimport {\n StylesObject,\n CardErrorData,\n CardFocusData,\n CardBrandData,\n CardAllValidData,\n CardFieldValidData,\n CardAutoCompleteData,\n CardConfigSuccessData,\n CardLoadData,\n SFKeyPressObj\n} from '../lib/types';\nimport { CSFReturnObject, CSFSetupObject } from '../lib/CSF/types';\nimport { CVC_POLICY_REQUIRED, DATE_POLICY_REQUIRED, DEDICATED_CARD_COMPONENTS, ENCRYPTED_CARD_NUMBER, ENCRYPTED_PWD_FIELD } from '../lib/constants';\nimport { BinLookupResponse } from '../../../Card/types';\nimport AdyenCheckoutError from '../../../../core/Errors/AdyenCheckoutError';\nimport { SFStateErrorObj } from '../../../Card/components/CardInput/types';\nimport { getErrorMessageFromCode } from '../../../../core/Errors/utils';\nimport { SF_ErrorCodes } from '../../../../core/Errors/constants';\n\n/**\n * SecuredFieldsProvider:\n * Initialises & handles the client-side part of SecuredFields\n */\nclass SecuredFieldsProvider extends Component<SFPProps, SFPState> {\n private csfLoadFailTimeout: number;\n private csfLoadFailTimeoutMS: number;\n private csfConfigFailTimeout: number;\n private csfConfigFailTimeoutMS: number;\n private numCharsInField: object;\n private rootNode;\n private numDateFields: number;\n private csf: CSFReturnObject;\n private handleOnLoad: (obj: CardLoadData) => void;\n private handleOnConfigSuccess: (obj: CardConfigSuccessData) => void;\n private handleOnFieldValid: (obj: CardFieldValidData) => void;\n private handleOnAllValid: (obj: CardAllValidData) => void;\n private handleOnBrand: (obj: CardBrandData) => void;\n private handleFocus: (obj: CardFocusData) => void;\n private handleOnError: (obj: CardErrorData, hasUnsupportedCard?: boolean) => void;\n private handleOnAutoComplete: (obj: CardAutoCompleteData) => void;\n private handleOnNoDataRequired: () => void;\n private handleOnTouchstartIOS: (obj) => void;\n private handleKeyPressed: (obj: SFKeyPressObj) => void;\n public state: SFPState;\n public props;\n private issuingCountryCode;\n\n constructor(props: SFPProps) {\n super(props);\n\n const stateObj: SFPState = {\n status: 'loading',\n brand: props.type,\n errors: {},\n valid: {},\n data: {},\n cvcPolicy: CVC_POLICY_REQUIRED,\n expiryDatePolicy: DATE_POLICY_REQUIRED,\n isSfpValid: false,\n hasKoreanFields: props.hasKoreanFields\n };\n this.state = stateObj;\n\n this.csfLoadFailTimeout = null;\n this.csfLoadFailTimeoutMS = 30000;\n\n this.csfConfigFailTimeout = null;\n this.csfConfigFailTimeoutMS = 15000;\n\n this.numCharsInField = {};\n\n // Handlers\n this.handleOnLoad = handlers.handleOnLoad.bind(this);\n this.handleOnConfigSuccess = handlers.handleOnConfigSuccess.bind(this);\n this.handleOnFieldValid = handlers.handleOnFieldValid.bind(this);\n this.handleOnAllValid = handlers.handleOnAllValid.bind(this);\n this.handleOnBrand = handlers.handleOnBrand.bind(this);\n this.handleFocus = handlers.handleFocus.bind(this);\n this.handleOnError = handlers.handleOnError.bind(this);\n this.handleOnNoDataRequired = handlers.handleOnNoDataRequired.bind(this);\n this.handleOnAutoComplete = handlers.handleOnAutoComplete.bind(this);\n this.handleOnTouchstartIOS = handlers.handleOnTouchstartIOS.bind(this); // Only called when iOS detected\n this.handleKeyPressed = handlers.handleKeyPressed.bind(this);\n\n this.processBinLookupResponse = this.processBinLookupResponse.bind(this);\n\n // Bindings for functions exposed to users of this component: SecuredFields & CardInput\n this.setFocusOn = this.setFocusOn.bind(this);\n this.updateStyles = this.updateStyles.bind(this);\n this.handleUnsupportedCard = this.handleUnsupportedCard.bind(this);\n this.showValidation = this.showValidation.bind(this);\n this.destroy = this.destroy.bind(this);\n }\n\n public static defaultProps = defaultProps;\n\n public componentDidMount(): void {\n // When SFP instantiated through SecuredFieldsInput c.f. CardInput\n if (this.props.rootNode) {\n this.setRootNode(this.props.rootNode);\n }\n\n // Find encryptedFields and map them to the values we use to store valid states\n const fields = getFields(this.rootNode);\n const valid = fields.reduce(validFieldsReducer, {});\n\n this.setState({ valid });\n\n // Populate numCharsInField object\n fields.forEach(field => {\n this.numCharsInField[field] = 0;\n });\n\n // Store how many dateFields we are dealing with visually\n this.numDateFields = fields.filter(f => f.match(/Expiry/)).length;\n\n if (fields.length) {\n this.destroy(); // TODO test if this solves the React double render problem.\n this.initializeCSF(this.rootNode);\n } else {\n this.handleOnNoDataRequired();\n }\n }\n\n public componentDidUpdate() {\n this.checkForKCPFields();\n // Pass all the state data up - Used right now for loading status\n this.props.onStateUpdate?.(this.state);\n }\n\n public componentWillUnmount(): void {\n this.csf = null;\n clearTimeout(this.csfLoadFailTimeout);\n clearTimeout(this.csfConfigFailTimeout);\n }\n\n private initializeCSF(root: HTMLElement): void {\n let loadingContext = this.props.loadingContext;\n\n // For loading securedFields from local server during development\n if (process.env.NODE_ENV === 'development' && process.env.__SF_ENV__ !== 'build') {\n loadingContext = process.env.__SF_ENV__;\n }\n\n const csfSetupObj: CSFSetupObject = {\n rootNode: root,\n type: this.props.type,\n clientKey: this.props.clientKey,\n cardGroupTypes: this.props.brands,\n autoFocus: this.props.autoFocus,\n trimTrailingSeparator: this.props.trimTrailingSeparator,\n loadingContext,\n keypadFix: this.props.keypadFix,\n showWarnings: this.props.showWarnings,\n iframeUIConfig: {\n sfStyles: this.props.styles\n },\n i18n: this.props.i18n,\n callbacks: {\n onLoad: this.handleOnLoad,\n onConfigSuccess: this.handleOnConfigSuccess,\n onFieldValid: this.handleOnFieldValid,\n onAllValid: this.handleOnAllValid,\n onBrand: this.handleOnBrand,\n onError: this.handleOnError,\n onFocus: this.handleFocus,\n onBinValue: this.props.onBinValue,\n onAutoComplete: this.handleOnAutoComplete,\n onAdditionalSFConfig: this.props.onAdditionalSFConfig,\n onAdditionalSFRemoved: this.props.onAdditionalSFRemoved,\n onTouchstartIOS: this.handleOnTouchstartIOS,\n onKeyPressed: this.handleKeyPressed\n },\n isKCP: this.state.hasKoreanFields,\n legacyInputMode: this.props.legacyInputMode,\n minimumExpiryDate: this.props.minimumExpiryDate,\n implementationType: this.props.implementationType || 'components', // to distinguish between 'regular' and 'custom' card component\n forceCompat: this.props.forceCompat,\n maskSecurityCode: this.props.maskSecurityCode,\n exposeExpiryDate: this.props.exposeExpiryDate,\n shouldDisableIOSArrowKeys: !!this.props.disableIOSArrowKeys, // convert whether function has been defined into a boolean\n placeholders: this.props.placeholders ?? {},\n showContextualElement: this.props.showContextualElement\n };\n\n this.csf = initCSF(csfSetupObj);\n\n /**\n * Expect to at least have had the handleOnLoad callback called within this time\n * - if this hasn't happened then something has happened to interrupt the loading of the securedFields\n * So we need to clear the loading spinner to see if the securedFields are reporting anything\n */\n // @ts-ignore - timout 'type' is a number\n this.csfLoadFailTimeout = setTimeout(() => {\n if (this.state.status !== 'ready') {\n // Hide the spinner\n this.setState({ status: 'csfLoadFailure' });\n // Report the error\n this.props.onError(new AdyenCheckoutError('ERROR', 'secured field iframes have failed to load'));\n }\n }, this.csfLoadFailTimeoutMS);\n }\n\n private checkForKCPFields() {\n let needsKoreanFields = false;\n if (this.props.koreanAuthenticationRequired) {\n needsKoreanFields = this.issuingCountryCode ? this.issuingCountryCode === 'kr' : this.props.countryCode === 'kr';\n }\n\n // Was korean, now isn't - hide password field\n if (this.state.hasKoreanFields && !needsKoreanFields) {\n // Clear any stored data\n const setRemovedFieldState = prevState => ({\n data: { ...prevState.data, [ENCRYPTED_PWD_FIELD]: undefined },\n valid: { ...prevState.valid, [ENCRYPTED_PWD_FIELD]: false },\n errors: { ...prevState.errors, [ENCRYPTED_PWD_FIELD]: false },\n hasKoreanFields: false\n });\n\n this.setState(setRemovedFieldState, () => {\n this.props.onChange(this.state);\n });\n\n this.csf.removeSecuredField(ENCRYPTED_PWD_FIELD);\n this.csf.setKCPStatus(false);\n }\n\n // Wasn't korean, now is - show password field\n if (!this.state.hasKoreanFields && needsKoreanFields) {\n const setAddedFieldState = prevState => ({\n valid: { ...prevState.valid, [ENCRYPTED_PWD_FIELD]: false },\n hasKoreanFields: true,\n isSfpValid: false\n });\n\n this.setState(setAddedFieldState, () => {\n this.props.onChange(this.state);\n });\n\n this.csf.addSecuredField(ENCRYPTED_PWD_FIELD);\n this.csf.setKCPStatus(true);\n }\n }\n\n public getChildContext(): object {\n return { i18n: this.props.i18n };\n }\n\n public handleUnsupportedCard(errObj: CardErrorData): boolean {\n const hasUnsupportedCard = !!errObj.error;\n\n // Store the brand(s) we detected and which we don't support\n if (hasUnsupportedCard) {\n this.setState({ detectedUnsupportedBrands: errObj.detectedBrands });\n }\n\n errObj.rootNode = this.rootNode; // Needed for CustomCard\n this.handleOnError(errObj, hasUnsupportedCard);\n // Inform CSF that the number field has an unsupportedCard error (or that it has been cleared)\n if (this.csf) {\n this.csf.hasUnsupportedCard(ENCRYPTED_CARD_NUMBER, errObj.error);\n }\n return hasUnsupportedCard;\n }\n\n public setFocusOn(frame: string): void {\n if (this.csf) this.csf.setFocusOnFrame(frame);\n }\n\n public updateStyles(stylesObj: StylesObject): void {\n if (this.csf) this.csf.updateStyles(stylesObj);\n }\n\n public sfIsOptionalOrHidden(fieldType: string): boolean {\n return this.csf.sfIsOptionalOrHidden(fieldType);\n }\n\n public destroy(): void {\n if (this.csf) this.csf.destroy();\n }\n\n public showValidation(): void {\n const { numDateFields, state }: SecuredFieldsProvider = this;\n\n Object.keys(state.valid)\n .reduce(getErrorReducer(numDateFields, state), [])\n .forEach(field => {\n // For each detected error pass an error object to the handler (calls error callback & sets state)\n const errorObj: CardErrorData = getErrorObject(field, this.rootNode, state);\n this.handleOnError(errorObj, !!state.detectedUnsupportedBrands);\n // Inform the secured-fields instance of which fields have been found to have errors\n if (this.csf && this.csf.isValidated) {\n this.csf.isValidated(field, errorObj.error);\n }\n });\n }\n\n /**\n * Map SF errors to ValidationRuleResult-like objects, for CardInput component\n */\n public mapErrorsToValidationRuleResult(): SFStateErrorObj {\n const fieldNames: string[] = Object.keys(this.state.errors);\n\n const sfStateErrorsObj = fieldNames.reduce((acc, fieldName) => {\n const errorCode = this.state.errors[fieldName];\n if (errorCode) {\n acc[fieldName] = {\n isValid: false,\n errorMessage: getErrorMessageFromCode(errorCode, SF_ErrorCodes), // this is the human-readable, untranslated, explanation of the error that will exist on the error object in card.state.errors\n // For v5 the object found in state.errors should also contain the additional properties that used to be sent to the onError callback\n // namely: translation, errorCode, a ref to rootNode &, in the case of failed binLookup, an array of the detectedBrands\n errorI18n: this.props.i18n.get(errorCode),\n error: errorCode,\n rootNode: this.rootNode,\n ...(this.state.detectedUnsupportedBrands && { detectedBrands: this.state.detectedUnsupportedBrands })\n };\n } else {\n acc[fieldName] = null;\n }\n return acc;\n }, {});\n return sfStateErrorsObj;\n }\n\n public processBinLookupResponse(binLookupResponse: BinLookupResponse, resetObject: SingleBrandResetObject): void {\n // If we were dealing with an unsupported card & now we have a valid /binLookup response (or a response triggering a reset of the UI),\n // - reset state to clear the error & the stored unsupportedBrands and, in the case of a valid /binLookup response, inform CSF (via handleUnsupportedCard)\n // (Scenario: from an unsupportedCard state the shopper has pasted another number long enough to trigger a /binLookup)\n if (this.state.detectedUnsupportedBrands) {\n this.setState(prevState => ({\n errors: { ...prevState.errors, [ENCRYPTED_CARD_NUMBER]: false },\n detectedUnsupportedBrands: null\n }));\n\n // If we have some sort of binLookupResponse object then this isn't the reset caused by digits dropping below a threshold\n // - so call handleUnsupportedCard to clear the error\n if (this.csf && binLookupResponse) {\n const errObj: CardErrorData = {\n type: 'card',\n fieldType: 'encryptedCardNumber',\n error: ''\n };\n this.handleUnsupportedCard(errObj);\n }\n }\n\n this.issuingCountryCode = binLookupResponse?.issuingCountryCode?.toLowerCase();\n\n const hasBrandedResetObj = resetObject?.brand;\n\n /**\n * Are we dealing with a \"dedicated\" card scenario i.e a card component created as: checkout.create('bcmc') but which can accept multiple brands\n * - in which case we will need to reset brand and pass on the resetObj to CSF\n */\n const mustResetDedicatedBrand = hasBrandedResetObj && DEDICATED_CARD_COMPONENTS.includes(resetObject.brand);\n\n if (mustResetDedicatedBrand) {\n // resetObject.brand will be the value of the brand whose logo we want to reshow in the UI\n this.setState(resetObject, () => {\n this.props.onChange(this.state);\n });\n }\n\n /**\n * Scenarios:\n *\n * - RESET (binLookupResponse === null): The number of digits in number field has dropped below threshold for BIN lookup\n * - RESULT (binLookupResponse.supportedBrands.length === 1): binLookup has found a result so inform CSF\n *\n * In the RESET scenario, for \"dedicated\" card components we also need to pass on the resetObject since this contains information about\n * the brand that CSF needs to reset to, internally.\n */\n if (this.csf) this.csf.brandsFromBinLookup(binLookupResponse, mustResetDedicatedBrand ? resetObject : null);\n }\n\n private setRootNode = (input: HTMLElement): void => {\n this.rootNode = input;\n };\n\n public render(props, state) {\n return props.render({ setRootNode: this.setRootNode, setFocusOn: this.setFocusOn }, state);\n }\n}\n\nexport default SecuredFieldsProvider;\n"],"names":["SecuredFieldsProvider","Component","componentDidMount","this","props","rootNode","setRootNode","fields","getFields","valid","reduce","validFieldsReducer","setState","forEach","field","numCharsInField","numDateFields","filter","f","match","length","destroy","initializeCSF","handleOnNoDataRequired","componentDidUpdate","checkForKCPFields","onStateUpdate","state","componentWillUnmount","csf","clearTimeout","csfLoadFailTimeout","csfConfigFailTimeout","root","loadingContext","csfSetupObj","type","clientKey","cardGroupTypes","brands","autoFocus","trimTrailingSeparator","keypadFix","showWarnings","iframeUIConfig","sfStyles","styles","i18n","callbacks","onLoad","handleOnLoad","onConfigSuccess","handleOnConfigSuccess","onFieldValid","handleOnFieldValid","onAllValid","handleOnAllValid","onBrand","handleOnBrand","onError","handleOnError","onFocus","handleFocus","onBinValue","onAutoComplete","handleOnAutoComplete","onAdditionalSFConfig","onAdditionalSFRemoved","onTouchstartIOS","handleOnTouchstartIOS","onKeyPressed","handleKeyPressed","isKCP","hasKoreanFields","legacyInputMode","minimumExpiryDate","implementationType","forceCompat","maskSecurityCode","exposeExpiryDate","shouldDisableIOSArrowKeys","disableIOSArrowKeys","placeholders","showContextualElement","initCSF","setTimeout","status","AdyenCheckoutError","csfLoadFailTimeoutMS","needsKoreanFields","koreanAuthenticationRequired","issuingCountryCode","countryCode","setRemovedFieldState","prevState","data","ENCRYPTED_PWD_FIELD","undefined","errors","onChange","removeSecuredField","setKCPStatus","setAddedFieldState","isSfpValid","addSecuredField","getChildContext","handleUnsupportedCard","errObj","hasUnsupportedCard","error","detectedUnsupportedBrands","detectedBrands","ENCRYPTED_CARD_NUMBER","setFocusOn","frame","setFocusOnFrame","updateStyles","stylesObj","sfIsOptionalOrHidden","fieldType","showValidation","Object","keys","getErrorReducer","errorObj","getErrorObject","isValidated","mapErrorsToValidationRuleResult","acc","fieldName","errorCode","isValid","errorMessage","getErrorMessageFromCode","SF_ErrorCodes","errorI18n","get","processBinLookupResponse","binLookupResponse","resetObject","toLowerCase","hasBrandedResetObj","brand","mustResetDedicatedBrand","DEDICATED_CARD_COMPONENTS","includes","brandsFromBinLookup","render","constructor","super","_define_property","csfConfigFailTimeoutMS","input","stateObj","cvcPolicy","CVC_POLICY_REQUIRED","expiryDatePolicy","DATE_POLICY_REQUIRED","handlers","bind","defaultProps"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SecuredFieldsProvider.js","sources":["../../../../../../src/components/internal/SecuredFields/SFP/SecuredFieldsProvider.ts"],"sourcesContent":["import { Component } from 'preact';\nimport { getErrorObject, getFields, getErrorReducer, validFieldsReducer } from './SFPUtils';\nimport initCSF from '../lib/CSF';\nimport handlers from './SecuredFieldsProviderHandlers';\nimport defaultProps from './defaultProps';\nimport { SFPProps, SFPState, SingleBrandResetObject } from './types';\nimport {\n StylesObject,\n CardErrorData,\n CardFocusData,\n CardBrandData,\n CardAllValidData,\n CardFieldValidData,\n CardAutoCompleteData,\n CardConfigSuccessData,\n CardLoadData,\n SFKeyPressObj\n} from '../lib/types';\nimport { CSFReturnObject, CSFSetupObject } from '../lib/CSF/types';\nimport { CVC_POLICY_REQUIRED, DATE_POLICY_REQUIRED, DEDICATED_CARD_COMPONENTS, ENCRYPTED_CARD_NUMBER, ENCRYPTED_PWD_FIELD } from '../lib/constants';\nimport { BinLookupResponse } from '../../../Card/types';\nimport AdyenCheckoutError from '../../../../core/Errors/AdyenCheckoutError';\nimport { SFStateErrorObj } from '../../../Card/components/CardInput/types';\nimport { getErrorMessageFromCode } from '../../../../core/Errors/utils';\nimport { SF_ErrorCodes } from '../../../../core/Errors/constants';\n\n/**\n * SecuredFieldsProvider:\n * Initialises & handles the client-side part of SecuredFields\n */\nclass SecuredFieldsProvider extends Component<SFPProps, SFPState> {\n private csfLoadFailTimeout: number;\n private csfLoadFailTimeoutMS: number;\n private csfConfigFailTimeout: number;\n private csfConfigFailTimeoutMS: number;\n private numCharsInField: object;\n private rootNode;\n private numDateFields: number;\n private csf: CSFReturnObject;\n private handleOnLoad: (obj: CardLoadData) => void;\n private handleOnConfigSuccess: (obj: CardConfigSuccessData) => void;\n private handleOnFieldValid: (obj: CardFieldValidData) => void;\n private handleOnAllValid: (obj: CardAllValidData) => void;\n private handleOnBrand: (obj: CardBrandData) => void;\n private handleFocus: (obj: CardFocusData) => void;\n private handleOnError: (obj: CardErrorData, hasUnsupportedCard?: boolean) => void;\n private handleOnAutoComplete: (obj: CardAutoCompleteData) => void;\n private handleOnNoDataRequired: () => void;\n private handleOnTouchstartIOS: (obj) => void;\n private handleKeyPressed: (obj: SFKeyPressObj) => void;\n public state: SFPState;\n public props;\n private issuingCountryCode;\n\n constructor(props: SFPProps) {\n super(props);\n\n const stateObj: SFPState = {\n status: 'loading',\n brand: props.type,\n errors: {},\n valid: {},\n data: {},\n cvcPolicy: CVC_POLICY_REQUIRED,\n expiryDatePolicy: DATE_POLICY_REQUIRED,\n isSfpValid: false,\n hasKoreanFields: props.hasKoreanFields\n };\n this.state = stateObj;\n\n this.csfLoadFailTimeout = null;\n this.csfLoadFailTimeoutMS = 30000;\n\n this.csfConfigFailTimeout = null;\n this.csfConfigFailTimeoutMS = 15000;\n\n this.numCharsInField = {};\n\n // Handlers\n this.handleOnLoad = handlers.handleOnLoad.bind(this);\n this.handleOnConfigSuccess = handlers.handleOnConfigSuccess.bind(this);\n this.handleOnFieldValid = handlers.handleOnFieldValid.bind(this);\n this.handleOnAllValid = handlers.handleOnAllValid.bind(this);\n this.handleOnBrand = handlers.handleOnBrand.bind(this);\n this.handleFocus = handlers.handleFocus.bind(this);\n this.handleOnError = handlers.handleOnError.bind(this);\n this.handleOnNoDataRequired = handlers.handleOnNoDataRequired.bind(this);\n this.handleOnAutoComplete = handlers.handleOnAutoComplete.bind(this);\n this.handleOnTouchstartIOS = handlers.handleOnTouchstartIOS.bind(this); // Only called when iOS detected\n this.handleKeyPressed = handlers.handleKeyPressed.bind(this);\n\n this.processBinLookupResponse = this.processBinLookupResponse.bind(this);\n\n // Bindings for functions exposed to users of this component: SecuredFields & CardInput\n this.setFocusOn = this.setFocusOn.bind(this);\n this.updateStyles = this.updateStyles.bind(this);\n this.handleUnsupportedCard = this.handleUnsupportedCard.bind(this);\n this.showValidation = this.showValidation.bind(this);\n this.destroy = this.destroy.bind(this);\n }\n\n public static defaultProps = defaultProps;\n\n public componentDidMount(): void {\n // When SFP instantiated through SecuredFieldsInput c.f. CardInput\n if (this.props.rootNode) {\n this.setRootNode(this.props.rootNode);\n }\n\n // Find encryptedFields and map them to the values we use to store valid states\n const fields = getFields(this.rootNode);\n const valid = fields.reduce(validFieldsReducer, {});\n\n this.setState({ valid });\n\n // Populate numCharsInField object\n fields.forEach(field => {\n this.numCharsInField[field] = 0;\n });\n\n // Store how many dateFields we are dealing with visually\n this.numDateFields = fields.filter(f => f.match(/Expiry/)).length;\n\n if (fields.length) {\n this.destroy(); // TODO test if this solves the React double render problem.\n this.initializeCSF(this.rootNode);\n } else {\n this.handleOnNoDataRequired();\n }\n }\n\n public componentDidUpdate() {\n this.checkForKCPFields();\n // Pass all the state data up - Used right now for loading status\n this.props.onStateUpdate?.(this.state);\n }\n\n public componentWillUnmount(): void {\n this.csf = null;\n clearTimeout(this.csfLoadFailTimeout);\n clearTimeout(this.csfConfigFailTimeout);\n }\n\n private initializeCSF(root: HTMLElement): void {\n let loadingContext = this.props.loadingContext;\n\n // For loading securedFields from local server during development\n if (process.env.NODE_ENV === 'development' && process.env.__SF_ENV__ !== 'build') {\n loadingContext = process.env.__SF_ENV__;\n }\n\n const csfSetupObj: CSFSetupObject = {\n rootNode: root,\n type: this.props.type,\n clientKey: this.props.clientKey,\n cardGroupTypes: this.props.brands,\n autoFocus: this.props.autoFocus,\n trimTrailingSeparator: this.props.trimTrailingSeparator,\n loadingContext,\n keypadFix: this.props.keypadFix,\n showWarnings: this.props.showWarnings,\n iframeUIConfig: {\n sfStyles: this.props.styles\n },\n i18n: this.props.i18n,\n callbacks: {\n onLoad: this.handleOnLoad,\n onConfigSuccess: this.handleOnConfigSuccess,\n onFieldValid: this.handleOnFieldValid,\n onAllValid: this.handleOnAllValid,\n onBrand: this.handleOnBrand,\n onError: this.handleOnError,\n onFocus: this.handleFocus,\n onBinValue: this.props.onBinValue,\n onAutoComplete: this.handleOnAutoComplete,\n onAdditionalSFConfig: this.props.onAdditionalSFConfig,\n onAdditionalSFRemoved: this.props.onAdditionalSFRemoved,\n onTouchstartIOS: this.handleOnTouchstartIOS,\n onKeyPressed: this.handleKeyPressed\n },\n isKCP: this.state.hasKoreanFields,\n legacyInputMode: this.props.legacyInputMode,\n minimumExpiryDate: this.props.minimumExpiryDate,\n implementationType: this.props.implementationType || 'components', // to distinguish between 'regular' and 'custom' card component\n forceCompat: this.props.forceCompat,\n maskSecurityCode: this.props.maskSecurityCode,\n exposeExpiryDate: this.props.exposeExpiryDate,\n shouldDisableIOSArrowKeys: !!this.props.disableIOSArrowKeys, // convert whether function has been defined into a boolean\n placeholders: this.props.placeholders ?? {},\n showContextualElement: this.props.showContextualElement\n };\n\n this.csf = initCSF(csfSetupObj);\n\n /**\n * Expect to at least have had the handleOnLoad callback called within this time\n * - if this hasn't happened then something has happened to interrupt the loading of the securedFields\n * So we need to clear the loading spinner to see if the securedFields are reporting anything\n */\n // @ts-ignore - timout 'type' is a number\n this.csfLoadFailTimeout = setTimeout(() => {\n if (this.state.status !== 'ready') {\n // Hide the spinner\n this.setState({ status: 'csfLoadFailure' });\n // Report the error\n this.props.onError(new AdyenCheckoutError('ERROR', 'secured field iframes have failed to load'));\n }\n }, this.csfLoadFailTimeoutMS);\n }\n\n private checkForKCPFields() {\n let needsKoreanFields = false;\n if (this.props.koreanAuthenticationRequired) {\n needsKoreanFields = this.issuingCountryCode ? this.issuingCountryCode === 'kr' : this.props.countryCode === 'kr';\n }\n\n // Was korean, now isn't - hide password field\n if (this.state.hasKoreanFields && !needsKoreanFields) {\n // Clear any stored data\n const setRemovedFieldState = prevState => ({\n data: { ...prevState.data, [ENCRYPTED_PWD_FIELD]: undefined },\n valid: { ...prevState.valid, [ENCRYPTED_PWD_FIELD]: false },\n errors: { ...prevState.errors, [ENCRYPTED_PWD_FIELD]: false },\n hasKoreanFields: false\n });\n\n this.setState(setRemovedFieldState, () => {\n this.props.onChange(this.state);\n });\n\n this.csf.removeSecuredField(ENCRYPTED_PWD_FIELD);\n this.csf.setKCPStatus(false);\n }\n\n // Wasn't korean, now is - show password field\n if (!this.state.hasKoreanFields && needsKoreanFields) {\n const setAddedFieldState = prevState => ({\n valid: { ...prevState.valid, [ENCRYPTED_PWD_FIELD]: false },\n hasKoreanFields: true,\n isSfpValid: false\n });\n\n this.setState(setAddedFieldState, () => {\n this.props.onChange(this.state);\n });\n\n this.csf.addSecuredField(ENCRYPTED_PWD_FIELD);\n this.csf.setKCPStatus(true);\n }\n }\n\n public getChildContext(): object {\n return { i18n: this.props.i18n };\n }\n\n public handleUnsupportedCard(errObj: CardErrorData): boolean {\n const hasUnsupportedCard = !!errObj.error;\n\n // Store the brand(s) we detected and which we don't support\n if (hasUnsupportedCard) {\n this.setState({ detectedUnsupportedBrands: errObj.detectedBrands });\n }\n\n errObj.rootNode = this.rootNode; // Needed for CustomCard\n this.handleOnError(errObj, hasUnsupportedCard);\n // Inform CSF that the number field has an unsupportedCard error (or that it has been cleared)\n if (this.csf) {\n this.csf.hasUnsupportedCard(ENCRYPTED_CARD_NUMBER, errObj.error);\n }\n return hasUnsupportedCard;\n }\n\n public setFocusOn(frame: string): void {\n if (this.csf) this.csf.setFocusOnFrame(frame);\n }\n\n public updateStyles(stylesObj: StylesObject): void {\n if (this.csf) this.csf.updateStyles(stylesObj);\n }\n\n public sfIsOptionalOrHidden(fieldType: string): boolean {\n return this.csf.sfIsOptionalOrHidden(fieldType);\n }\n\n public destroy(): void {\n if (this.csf) this.csf.destroy();\n }\n\n public showValidation(): void {\n const { numDateFields, state }: SecuredFieldsProvider = this;\n\n Object.keys(state.valid)\n .reduce(getErrorReducer(numDateFields, state), [])\n .forEach(field => {\n // For each detected error pass an error object to the handler (calls error callback & sets state)\n const errorObj: CardErrorData = getErrorObject(field, this.rootNode, state);\n this.handleOnError(errorObj, !!state.detectedUnsupportedBrands);\n // Inform the secured-fields instance of which fields have been found to have errors\n if (this.csf && this.csf.isValidated) {\n this.csf.isValidated(field, errorObj.error);\n }\n });\n }\n\n /**\n * Map SF errors to ValidationRuleResult-like objects, for CardInput component\n */\n public mapErrorsToValidationRuleResult(): SFStateErrorObj {\n const fieldNames: string[] = Object.keys(this.state.errors);\n\n const sfStateErrorsObj = fieldNames.reduce((acc, fieldName) => {\n const errorCode = this.state.errors[fieldName];\n if (errorCode) {\n acc[fieldName] = {\n isValid: false,\n errorMessage: getErrorMessageFromCode(errorCode, SF_ErrorCodes), // this is the human-readable, untranslated, explanation of the error that will exist on the error object in card.state.errors\n // For v5 the object found in state.errors should also contain the additional properties that used to be sent to the onError callback\n // namely: translation, errorCode, a ref to rootNode &, in the case of failed binLookup, an array of the detectedBrands\n errorI18n: this.props.i18n.get(errorCode),\n error: errorCode,\n rootNode: this.rootNode,\n ...(this.state.detectedUnsupportedBrands && { detectedBrands: this.state.detectedUnsupportedBrands })\n };\n } else {\n acc[fieldName] = null;\n }\n return acc;\n }, {});\n return sfStateErrorsObj;\n }\n\n public processBinLookupResponse(binLookupResponse: BinLookupResponse, resetObject: SingleBrandResetObject): void {\n // If we were dealing with an unsupported card & now we have a valid /binLookup response (or a response triggering a reset of the UI),\n // - reset state to clear the error & the stored unsupportedBrands and, in the case of a valid /binLookup response, inform CSF (via handleUnsupportedCard)\n // (Scenario: from an unsupportedCard state the shopper has pasted another number long enough to trigger a /binLookup)\n if (this.state.detectedUnsupportedBrands) {\n this.setState(prevState => ({\n errors: { ...prevState.errors, [ENCRYPTED_CARD_NUMBER]: false },\n detectedUnsupportedBrands: null\n }));\n\n // If we have some sort of binLookupResponse object then this isn't the reset caused by digits dropping below a threshold\n // - so call handleUnsupportedCard to clear the error\n if (this.csf && binLookupResponse) {\n const errObj: CardErrorData = {\n type: 'card',\n fieldType: 'encryptedCardNumber',\n error: ''\n };\n this.handleUnsupportedCard(errObj);\n }\n }\n\n this.issuingCountryCode = binLookupResponse?.issuingCountryCode?.toLowerCase();\n\n const hasBrandedResetObj = resetObject?.brand;\n\n /**\n * Are we dealing with a \"dedicated\" card scenario i.e a card component created as: checkout.create('bcmc') but which can accept multiple brands\n * - in which case we will need to reset brand and pass on the resetObj to CSF\n */\n const mustResetDedicatedBrand = hasBrandedResetObj && DEDICATED_CARD_COMPONENTS.includes(resetObject.brand);\n\n if (mustResetDedicatedBrand) {\n // resetObject.brand will be the value of the brand whose logo we want to reshow in the UI\n this.setState(resetObject, () => {\n this.props.onChange(this.state);\n });\n }\n\n /**\n * Scenarios:\n *\n * - RESET (binLookupResponse === null): The number of digits in number field has dropped below threshold for BIN lookup\n * - RESULT (binLookupResponse.supportedBrands.length === 1): binLookup has found a result so inform CSF\n *\n * In the RESET scenario, for \"dedicated\" card components we also need to pass on the resetObject since this contains information about\n * the brand that CSF needs to reset to, internally.\n */\n if (this.csf) this.csf.brandsFromBinLookup(binLookupResponse, mustResetDedicatedBrand ? resetObject : null);\n }\n\n private setRootNode = (input: HTMLElement): void => {\n this.rootNode = input;\n };\n\n public render(props, state) {\n return props.render({ setRootNode: this.setRootNode, setFocusOn: this.setFocusOn }, state);\n }\n}\n\nexport default SecuredFieldsProvider;\n"],"names":["SecuredFieldsProvider","Component","componentDidMount","this","props","rootNode","setRootNode","fields","getFields","valid","reduce","validFieldsReducer","setState","forEach","field","numCharsInField","numDateFields","filter","f","match","length","destroy","initializeCSF","handleOnNoDataRequired","componentDidUpdate","checkForKCPFields","onStateUpdate","state","componentWillUnmount","csf","clearTimeout","csfLoadFailTimeout","csfConfigFailTimeout","root","loadingContext","csfSetupObj","type","clientKey","cardGroupTypes","brands","autoFocus","trimTrailingSeparator","keypadFix","showWarnings","iframeUIConfig","sfStyles","styles","i18n","callbacks","onLoad","handleOnLoad","onConfigSuccess","handleOnConfigSuccess","onFieldValid","handleOnFieldValid","onAllValid","handleOnAllValid","onBrand","handleOnBrand","onError","handleOnError","onFocus","handleFocus","onBinValue","onAutoComplete","handleOnAutoComplete","onAdditionalSFConfig","onAdditionalSFRemoved","onTouchstartIOS","handleOnTouchstartIOS","onKeyPressed","handleKeyPressed","isKCP","hasKoreanFields","legacyInputMode","minimumExpiryDate","implementationType","forceCompat","maskSecurityCode","exposeExpiryDate","shouldDisableIOSArrowKeys","disableIOSArrowKeys","placeholders","showContextualElement","initCSF","setTimeout","status","AdyenCheckoutError","csfLoadFailTimeoutMS","needsKoreanFields","koreanAuthenticationRequired","issuingCountryCode","countryCode","setRemovedFieldState","prevState","data","ENCRYPTED_PWD_FIELD","undefined","errors","onChange","removeSecuredField","setKCPStatus","setAddedFieldState","isSfpValid","addSecuredField","getChildContext","handleUnsupportedCard","errObj","hasUnsupportedCard","error","detectedUnsupportedBrands","detectedBrands","ENCRYPTED_CARD_NUMBER","setFocusOn","frame","setFocusOnFrame","updateStyles","stylesObj","sfIsOptionalOrHidden","fieldType","showValidation","Object","keys","getErrorReducer","errorObj","getErrorObject","isValidated","mapErrorsToValidationRuleResult","acc","fieldName","errorCode","isValid","errorMessage","getErrorMessageFromCode","SF_ErrorCodes","errorI18n","get","processBinLookupResponse","binLookupResponse","resetObject","toLowerCase","hasBrandedResetObj","brand","mustResetDedicatedBrand","DEDICATED_CARD_COMPONENTS","includes","brandsFromBinLookup","render","constructor","super","_define_property","csfConfigFailTimeoutMS","input","stateObj","cvcPolicy","CVC_POLICY_REQUIRED","expiryDatePolicy","DATE_POLICY_REQUIRED","handlers","bind","defaultProps"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function d(d){const[
|
|
1
|
+
function d(d,e){const[a,n]=d;return{dualBrandSelectElements:[{id:a.brand,brandObject:a},{id:n.brand,brandObject:n}],selectedBrandValue:e?a.brand:"",leadBrand:a}}export{d as default};
|
|
2
2
|
//# sourceMappingURL=createCardVariantSwitcher.js.map
|
package/dist/es/components/internal/SecuredFields/binLookup/createCardVariantSwitcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createCardVariantSwitcher.js","sources":["../../../../../../src/components/internal/SecuredFields/binLookup/createCardVariantSwitcher.ts"],"sourcesContent":["import { BrandObject, DualBrandSelectElement } from '../../../Card/types';\n\n/**\n * Creates an object used for setting state - that will trigger the rendering of a select element to allow a choice between 2 different card variants\n * @param brandObjArr - array containing 2 card brands objects\n */\nexport default function createCardVariantSwitcher(brandObjArr: BrandObject[]) {\n const [leadBrand, subBrand] = brandObjArr;\n\n return {\n dualBrandSelectElements: [\n { id: leadBrand.brand, brandObject: leadBrand },\n { id: subBrand.brand, brandObject: subBrand }\n ] as DualBrandSelectElement[],\n selectedBrandValue: leadBrand.brand, // set to leadBrand.brand if an initial selection is to be made; else set to empty string\n leadBrand\n };\n}\n"],"names":["createCardVariantSwitcher","brandObjArr","leadBrand","subBrand","dualBrandSelectElements","id","brand","brandObject","selectedBrandValue"],"mappings":"AAMe,SAASA,EAA0BC,
|
|
1
|
+
{"version":3,"file":"createCardVariantSwitcher.js","sources":["../../../../../../src/components/internal/SecuredFields/binLookup/createCardVariantSwitcher.ts"],"sourcesContent":["import { BrandObject, DualBrandSelectElement } from '../../../Card/types';\n\n/**\n * Creates an object used for setting state - that will trigger the rendering of a select element to allow a choice between 2 different card variants\n * @param brandObjArr - array containing 2 card brands objects\n */\nexport default function createCardVariantSwitcher(brandObjArr: BrandObject[], preselectBrand: boolean) {\n const [leadBrand, subBrand] = brandObjArr;\n\n return {\n dualBrandSelectElements: [\n { id: leadBrand.brand, brandObject: leadBrand },\n { id: subBrand.brand, brandObject: subBrand }\n ] as DualBrandSelectElement[],\n selectedBrandValue: preselectBrand ? leadBrand.brand : '', // set to leadBrand.brand if an initial selection is to be made; else set to empty string\n leadBrand\n };\n}\n"],"names":["createCardVariantSwitcher","brandObjArr","preselectBrand","leadBrand","subBrand","dualBrandSelectElements","id","brand","brandObject","selectedBrandValue"],"mappings":"AAMe,SAASA,EAA0BC,EAA4BC,GAC1E,MAAOC,EAAWC,GAAYH,EAE9B,MAAO,CACHI,wBAAyB,CACrB,CAAEC,GAAIH,EAAUI,MAAOC,YAAaL,GACpC,CAAEG,GAAIF,EAASG,MAAOC,YAAaJ,IAEvCK,mBAAoBP,EAAiBC,EAAUI,MAAQ,GACvDJ,YAER"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"./createCardVariantSwitcher.js";import{BRAND_ICON_UI_EXCLUSION_LIST as n}from"../lib/constants.js";const
|
|
1
|
+
import e from"./createCardVariantSwitcher.js";import{BRAND_ICON_UI_EXCLUSION_LIST as n}from"../lib/constants.js";import{mustHandleDualBrandingAccordingToEURegulations as r}from"../../../Card/components/CardInput/utils.js";import{DUAL_BRANDS_THAT_NEED_SELECTION_MECHANISM as t}from"../../../Card/Card.js";const s=(e,n)=>e.reduce((e,r)=>e||n.includes(r.brand),!1),o=e=>e.map(e=>({...e})),a=(e,n="mc",r="visa")=>{const t=o(e);return t[0].brand!==n&&t[0].brand!==r&&t.reverse(),t.length=1,t};function d(d,u,c,i={}){const{type:p,cvcPolicy:l}=d,{sfp:C}=u,{dualBrandSelectElements:B,setDualBrandSelectElements:g,setSelectedBrandValue:b,issuingCountryCode:m,setIssuingCountryCode:y}=c;return{processBinLookup:(d,u)=>{const c=d?.issuingCountryCode?d.issuingCountryCode.toLowerCase():null;if(y(c),!d||!Object.keys(d).length){g([]),b("");const e=u&&"card"!==p?p:null;return C.current.processBinLookupResponse(d,{brand:e,cvcPolicy:l}),void(i.current=0)}if(d.supportedBrands?.length){const u=s(d.supportedBrands,n),c=u?a(d.supportedBrands):o(d.supportedBrands);if(c.length>1){const n=r(t,c,"brand"),s=e(c,n);g(s.dualBrandSelectElements),b(s.selectedBrandValue),C.current.processBinLookupResponse({issuingCountryCode:d.issuingCountryCode,supportedBrands:[s.leadBrand]}),s.leadBrand.panLength>0&&(i.current=s.leadBrand.panLength)}else g([]),b(""),u||b(c[0].brand),C.current.processBinLookupResponse({issuingCountryCode:d.issuingCountryCode,supportedBrands:c}),c[0].panLength>0&&(i.current=c[0].panLength)}},handleDualBrandSelection:e=>{let n=e;if(e instanceof Event){const r=e.target;n=r.getAttribute("data-value")||r.getAttribute("value")}let r=[];n&&(r=B.reduce((e,r)=>(r.brandObject.brand===n&&e.push(r.brandObject),e),[]),r.length&&(b(n),C.current.processBinLookupResponse({issuingCountryCode:m,supportedBrands:r,isDualBrandSelection:!0})))}}}export{o as cloneBrandsArr,s as containsExcludedBrand,d as default,a as removeExcludedBrand};
|
|
2
2
|
//# sourceMappingURL=extensions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions.js","sources":["../../../../../../src/components/internal/SecuredFields/binLookup/extensions.ts"],"sourcesContent":["import { SingleBrandResetObject } from '../SFP/types';\nimport { BrandObject } from '../../../Card/types';\nimport createCardVariantSwitcher from './createCardVariantSwitcher';\nimport { BRAND_ICON_UI_EXCLUSION_LIST } from '../lib/constants';\n\n// Externally testable utils\nexport const containsExcludedBrand = (brandsArr: BrandObject[], excludedBrands: string[]): boolean => {\n return brandsArr.reduce((acc, brandObj) => acc || excludedBrands.includes(brandObj.brand), false);\n};\n\nexport const cloneBrandsArr = (brandsArr: BrandObject[]): BrandObject[] => brandsArr.map(item => ({ ...item }));\n\nexport const removeExcludedBrand = (brandsArr: BrandObject[], mainBrand1 = 'mc', mainBrand2 = 'visa'): BrandObject[] => {\n const clonedBrands: BrandObject[] = cloneBrandsArr(brandsArr);\n\n if (clonedBrands[0].brand !== mainBrand1 && clonedBrands[0].brand !== mainBrand2) clonedBrands.reverse();\n clonedBrands.length = 1;\n return clonedBrands;\n};\n// --\n\nexport default function extensions(props, refs, states, hasPanLengthRef: Partial<{ current }> = {}) {\n // Destructure props, refs and state hooks\n const { type, cvcPolicy } = props;\n const { sfp } = refs;\n const { dualBrandSelectElements, setDualBrandSelectElements, setSelectedBrandValue, issuingCountryCode, setIssuingCountryCode } = states;\n\n return {\n /**\n * Handle the binLookup response object generated in triggerBinLookup and process it in relation to the CardInput and it's sub-components.\n * e.g. we might need to add/remove additional markup (a selector for brands), and inform SFP of the issuingCountryCode & detected brand(s).\n *\n * @param binLookupResponse -\n * @param isReset -\n */\n processBinLookup: (binLookupResponse, isReset) => {\n const issuingCode = binLookupResponse?.issuingCountryCode ? binLookupResponse.issuingCountryCode.toLowerCase() : null;\n setIssuingCountryCode(issuingCode);\n\n // Reset UI\n if (!binLookupResponse || !Object.keys(binLookupResponse).length) {\n setDualBrandSelectElements([]);\n setSelectedBrandValue('');\n\n // If /binLookup has 'reset' then for a generic card the internal regex will kick in to show the right brand icon - so set to null\n // However for a single-branded card we need to pass the \"base\" type so the brand logo is reset - so set to type\n const brandToReset = isReset && type !== 'card' ? type : null;\n\n sfp.current.processBinLookupResponse(binLookupResponse, {\n brand: brandToReset,\n cvcPolicy: cvcPolicy // undefined except for Bancontact\n } as SingleBrandResetObject);\n\n // Reset storage var\n hasPanLengthRef.current = 0;\n return;\n }\n\n // RESULT: binLookup has found a result so proceed accordingly\n if (binLookupResponse.supportedBrands?.length) {\n const hasExcludedBrand: boolean = containsExcludedBrand(binLookupResponse.supportedBrands, BRAND_ICON_UI_EXCLUSION_LIST);\n\n const supportedBrands: BrandObject[] = hasExcludedBrand\n ? removeExcludedBrand(binLookupResponse.supportedBrands)\n : cloneBrandsArr(binLookupResponse.supportedBrands);\n\n // 1) Multiple options found - add to the UI & inform SFP\n if (supportedBrands.length > 1) {\n // --\n const switcherObj = createCardVariantSwitcher(supportedBrands);\n\n // Set properties on state to trigger the dual branding icons in the UI\n setDualBrandSelectElements(switcherObj.dualBrandSelectElements);\n setSelectedBrandValue(switcherObj.selectedBrandValue); // initially this value from switcherObj will be ''\n\n // Pass an object through to SFP\n sfp.current.processBinLookupResponse({\n issuingCountryCode: binLookupResponse.issuingCountryCode,\n supportedBrands: [switcherObj.leadBrand]\n });\n\n // Store the fact the binLookup obj has a panLength prop\n if (switcherObj.leadBrand.panLength > 0) {\n hasPanLengthRef.current = switcherObj.leadBrand.panLength;\n }\n\n // 2) Single option found (binValueObject.supportedBrands.length === 1)\n } else {\n // Reset UI\n setDualBrandSelectElements([]);\n setSelectedBrandValue('');\n\n // Set (single) value from binLookup so it will be added to the 'brand' property in the paymentMethod object\n // EXCEPT - if we are dealing with a brand that we exclude from the UI\n if (!hasExcludedBrand) setSelectedBrandValue(supportedBrands[0].brand);\n\n // Pass object through to SFP\n sfp.current.processBinLookupResponse({\n issuingCountryCode: binLookupResponse.issuingCountryCode,\n supportedBrands\n });\n\n // Store the fact the binLookup obj has a panLength prop\n if (supportedBrands[0].panLength > 0) {\n hasPanLengthRef.current = supportedBrands[0].panLength;\n }\n }\n }\n },\n /**\n * Handler for clicks on the icons added in response to the /binLookup call\n * Inform SFP of the brand changes when these selections are made\n */\n handleDualBrandSelection: (e: Event | string): void => {\n let value: Event | string = e;\n if (e instanceof Event) {\n const target = e.target as HTMLLIElement;\n value = target.getAttribute('data-value') || target.getAttribute('value');\n }\n\n // Check if we have a value and whether that value corresponds to a brandObject we can propagate\n // If either are false then abandon the process\n let brandObjArr: BrandObject[] = [];\n if (value) {\n // Find the brandObject with the matching brand value and place into an array\n brandObjArr = dualBrandSelectElements.reduce((acc, item) => {\n if (item.brandObject.brand === value) {\n acc.push(item.brandObject);\n }\n return acc;\n }, []);\n\n if (!brandObjArr.length) {\n return; // no brand object associated with value was found\n }\n } else {\n return; // no value passed\n }\n\n setSelectedBrandValue(value);\n\n // Pass brand object into SecuredFields\n sfp.current.processBinLookupResponse({\n issuingCountryCode,\n supportedBrands: brandObjArr,\n isDualBrandSelection: true\n });\n }\n };\n}\n"],"names":["containsExcludedBrand","brandsArr","excludedBrands","reduce","acc","brandObj","includes","brand","cloneBrandsArr","map","item","removeExcludedBrand","mainBrand1","mainBrand2","clonedBrands","reverse","length","extensions","props","refs","states","hasPanLengthRef","type","cvcPolicy","sfp","dualBrandSelectElements","setDualBrandSelectElements","setSelectedBrandValue","issuingCountryCode","setIssuingCountryCode","processBinLookup","binLookupResponse","isReset","issuingCode","toLowerCase","Object","keys","brandToReset","current","processBinLookupResponse","supportedBrands","hasExcludedBrand","BRAND_ICON_UI_EXCLUSION_LIST","switcherObj","createCardVariantSwitcher","selectedBrandValue","leadBrand","panLength","handleDualBrandSelection","e","value","Event","target","getAttribute","brandObjArr","brandObject","push","isDualBrandSelection"],"mappings":"iHAMO,MAAMA,EAAwB,CAACC,EAA0BC,IACrDD,EAAUE,OAAO,CAACC,EAAKC,IAAaD,GAAOF,EAAeI,SAASD,EAASE,QAAQ,GAGlFC,EAAkBP,GAA4CA,EAAUQ,IAAIC,IAAAA,IAAcA,KAE1FC,EAAsB,CAACV,EAA0BW,EAAa,KAAMC,EAAa,UAC1F,MAAMC,EAA8BN,EAAeP,GAInD,OAFIa,EAAa,GAAGP,QAAUK,GAAcE,EAAa,GAAGP,QAAUM,GAAYC,EAAaC,UAC/FD,EAAaE,OAAS,EACfF,GAII,SAASG,EAAWC,EAAOC,EAAMC,EAAQC,EAAwC,CAAA,GAE5F,MAAMC,KAAEA,EAAIC,UAAEA,GAAcL,GACtBM,IAAEA,GAAQL,GACVM,wBAAEA,EAAuBC,2BAAEA,EAA0BC,sBAAEA,EAAqBC,mBAAEA,EAAkBC,sBAAEA,GAA0BT,EAElI,MAAO,CAQHU,iBAAkB,CAACC,EAAmBC,KAClC,MAAMC,EAAcF,GAAmBH,mBAAqBG,EAAkBH,mBAAmBM,cAAgB,KAIjH,GAHAL,EAAsBI,IAGjBF,IAAsBI,OAAOC,KAAKL,GAAmBf,OAAQ,CAC9DU,EAA2B,IAC3BC,EAAsB,IAItB,MAAMU,EAAeL,GAAoB,SAATV,EAAkBA,EAAO,KASzD,OAPAE,EAAIc,QAAQC,yBAAyBR,EAAmB,CACpDxB,MAAO8B,EACPd,UAAWA,SAIfF,EAAgBiB,QAAU,EAE9B,CAGA,GAAIP,EAAkBS,iBAAiBxB,OAAQ,CAC3C,MAAMyB,EAA4BzC,EAAsB+B,EAAkBS,gBAAiBE,GAErFF,EAAiCC,EACjC9B,EAAoBoB,EAAkBS,iBACtChC,EAAeuB,EAAkBS,iBAGvC,GAAIA,EAAgBxB,OAAS,EAAG,CAE5B,MAAM2B,EAAcC,EAA0BJ,GAG9Cd,EAA2BiB,EAAYlB,yBACvCE,EAAsBgB,EAAYE,oBAGlCrB,EAAIc,QAAQC,yBAAyB,CACjCX,mBAAoBG,EAAkBH,mBACtCY,gBAAiB,CAACG,EAAYG,aAI9BH,EAAYG,UAAUC,UAAY,IAClC1B,EAAgBiB,QAAUK,EAAYG,UAAUC,gBAMpDrB,EAA2B,IAC3BC,EAAsB,IAIjBc,GAAkBd,EAAsBa,EAAgB,GAAGjC,OAGhEiB,EAAIc,QAAQC,yBAAyB,CACjCX,mBAAoBG,EAAkBH,mBACtCY,oBAIAA,EAAgB,GAAGO,UAAY,IAC/B1B,EAAgBiB,QAAUE,EAAgB,GAAGO,UAGzD,GAMJC,yBAA2BC,IACvB,IAAIC,EAAwBD,EAC5B,GAAIA,aAAaE,MAAO,CACpB,MAAMC,EAASH,EAAEG,OACjBF,EAAQE,EAAOC,aAAa,eAAiBD,EAAOC,aAAa,QACrE,CAIA,IAAIC,EAA6B,GAC7BJ,IAEAI,EAAc7B,EAAwBtB,OAAO,CAACC,EAAKM,KAC3CA,EAAK6C,YAAYhD,QAAU2C,GAC3B9C,EAAIoD,KAAK9C,EAAK6C,aAEXnD,GACR,IAEEkD,EAAYtC,SAOrBW,EAAsBuB,GAGtB1B,EAAIc,QAAQC,yBAAyB,CACjCX,qBACAY,gBAAiBc,EACjBG,sBAAsB,OAItC"}
|
|
1
|
+
{"version":3,"file":"extensions.js","sources":["../../../../../../src/components/internal/SecuredFields/binLookup/extensions.ts"],"sourcesContent":["import { SingleBrandResetObject } from '../SFP/types';\nimport { BrandObject } from '../../../Card/types';\nimport createCardVariantSwitcher from './createCardVariantSwitcher';\nimport { BRAND_ICON_UI_EXCLUSION_LIST } from '../lib/constants';\nimport { mustHandleDualBrandingAccordingToEURegulations } from '../../../Card/components/CardInput/utils';\nimport { DUAL_BRANDS_THAT_NEED_SELECTION_MECHANISM } from '../../../Card/Card';\n\n// Externally testable utils\nexport const containsExcludedBrand = (brandsArr: BrandObject[], excludedBrands: string[]): boolean => {\n return brandsArr.reduce((acc, brandObj) => acc || excludedBrands.includes(brandObj.brand), false);\n};\n\nexport const cloneBrandsArr = (brandsArr: BrandObject[]): BrandObject[] => brandsArr.map(item => ({ ...item }));\n\nexport const removeExcludedBrand = (brandsArr: BrandObject[], mainBrand1 = 'mc', mainBrand2 = 'visa'): BrandObject[] => {\n const clonedBrands: BrandObject[] = cloneBrandsArr(brandsArr);\n\n if (clonedBrands[0].brand !== mainBrand1 && clonedBrands[0].brand !== mainBrand2) clonedBrands.reverse();\n clonedBrands.length = 1;\n return clonedBrands;\n};\n// --\n\nexport default function extensions(props, refs, states, hasPanLengthRef: Partial<{ current }> = {}) {\n // Destructure props, refs and state hooks\n const { type, cvcPolicy } = props;\n const { sfp } = refs;\n const { dualBrandSelectElements, setDualBrandSelectElements, setSelectedBrandValue, issuingCountryCode, setIssuingCountryCode } = states;\n\n return {\n /**\n * Handle the binLookup response object generated in triggerBinLookup and process it in relation to the CardInput and it's sub-components.\n * e.g. we might need to add/remove additional markup (a selector for brands), and inform SFP of the issuingCountryCode & detected brand(s).\n *\n * @param binLookupResponse -\n * @param isReset -\n */\n processBinLookup: (binLookupResponse, isReset) => {\n const issuingCode = binLookupResponse?.issuingCountryCode ? binLookupResponse.issuingCountryCode.toLowerCase() : null;\n setIssuingCountryCode(issuingCode);\n\n // Reset UI\n if (!binLookupResponse || !Object.keys(binLookupResponse).length) {\n setDualBrandSelectElements([]);\n setSelectedBrandValue('');\n\n // If /binLookup has 'reset' then for a generic card the internal regex will kick in to show the right brand icon - so set to null\n // However for a single-branded card we need to pass the \"base\" type so the brand logo is reset - so set to type\n const brandToReset = isReset && type !== 'card' ? type : null;\n\n sfp.current.processBinLookupResponse(binLookupResponse, {\n brand: brandToReset,\n cvcPolicy: cvcPolicy // undefined except for Bancontact\n } as SingleBrandResetObject);\n\n // Reset storage var\n hasPanLengthRef.current = 0;\n return;\n }\n\n // RESULT: binLookup has found a result so proceed accordingly\n if (binLookupResponse.supportedBrands?.length) {\n const hasExcludedBrand: boolean = containsExcludedBrand(binLookupResponse.supportedBrands, BRAND_ICON_UI_EXCLUSION_LIST);\n\n const supportedBrands: BrandObject[] = hasExcludedBrand\n ? removeExcludedBrand(binLookupResponse.supportedBrands)\n : cloneBrandsArr(binLookupResponse.supportedBrands);\n\n // 1) Multiple options found - add to the UI & inform SFP\n if (supportedBrands.length > 1) {\n // --\n\n // Only if the brands in DUAL_BRANDS_THAT_NEED_SELECTION_MECHANISM are present in the binLookup response should we handle dual branding based on EU regulations\n const preselectBrand = mustHandleDualBrandingAccordingToEURegulations(\n DUAL_BRANDS_THAT_NEED_SELECTION_MECHANISM,\n supportedBrands,\n 'brand'\n );\n\n const switcherObj = createCardVariantSwitcher(supportedBrands, preselectBrand);\n\n // Set properties on state to trigger the dual branding icons in the UI\n setDualBrandSelectElements(switcherObj.dualBrandSelectElements);\n setSelectedBrandValue(switcherObj.selectedBrandValue); // initially this value from switcherObj will be ''\n\n // Pass an object through to SFP\n sfp.current.processBinLookupResponse({\n issuingCountryCode: binLookupResponse.issuingCountryCode,\n supportedBrands: [switcherObj.leadBrand]\n });\n\n // Store the fact the binLookup obj has a panLength prop\n if (switcherObj.leadBrand.panLength > 0) {\n hasPanLengthRef.current = switcherObj.leadBrand.panLength;\n }\n\n // 2) Single option found (binValueObject.supportedBrands.length === 1)\n } else {\n // Reset UI\n setDualBrandSelectElements([]);\n setSelectedBrandValue('');\n\n // Set (single) value from binLookup so it will be added to the 'brand' property in the paymentMethod object\n // EXCEPT - if we are dealing with a brand that we exclude from the UI\n if (!hasExcludedBrand) setSelectedBrandValue(supportedBrands[0].brand);\n\n // Pass object through to SFP\n sfp.current.processBinLookupResponse({\n issuingCountryCode: binLookupResponse.issuingCountryCode,\n supportedBrands\n });\n\n // Store the fact the binLookup obj has a panLength prop\n if (supportedBrands[0].panLength > 0) {\n hasPanLengthRef.current = supportedBrands[0].panLength;\n }\n }\n }\n },\n /**\n * Handler for clicks on the icons added in response to the /binLookup call\n * Inform SFP of the brand changes when these selections are made\n */\n handleDualBrandSelection: (e: Event | string): void => {\n let value: Event | string = e;\n if (e instanceof Event) {\n const target = e.target as HTMLLIElement;\n value = target.getAttribute('data-value') || target.getAttribute('value');\n }\n\n // Check if we have a value and whether that value corresponds to a brandObject we can propagate\n // If either are false then abandon the process\n let brandObjArr: BrandObject[] = [];\n if (value) {\n // Find the brandObject with the matching brand value and place into an array\n brandObjArr = dualBrandSelectElements.reduce((acc, item) => {\n if (item.brandObject.brand === value) {\n acc.push(item.brandObject);\n }\n return acc;\n }, []);\n\n if (!brandObjArr.length) {\n return; // no brand object associated with value was found\n }\n } else {\n return; // no value passed\n }\n\n setSelectedBrandValue(value);\n\n // Pass brand object into SecuredFields\n sfp.current.processBinLookupResponse({\n issuingCountryCode,\n supportedBrands: brandObjArr,\n isDualBrandSelection: true\n });\n }\n };\n}\n"],"names":["containsExcludedBrand","brandsArr","excludedBrands","reduce","acc","brandObj","includes","brand","cloneBrandsArr","map","item","removeExcludedBrand","mainBrand1","mainBrand2","clonedBrands","reverse","length","extensions","props","refs","states","hasPanLengthRef","type","cvcPolicy","sfp","dualBrandSelectElements","setDualBrandSelectElements","setSelectedBrandValue","issuingCountryCode","setIssuingCountryCode","processBinLookup","binLookupResponse","isReset","issuingCode","toLowerCase","Object","keys","brandToReset","current","processBinLookupResponse","supportedBrands","hasExcludedBrand","BRAND_ICON_UI_EXCLUSION_LIST","preselectBrand","mustHandleDualBrandingAccordingToEURegulations","DUAL_BRANDS_THAT_NEED_SELECTION_MECHANISM","switcherObj","createCardVariantSwitcher","selectedBrandValue","leadBrand","panLength","handleDualBrandSelection","e","value","Event","target","getAttribute","brandObjArr","brandObject","push","isDualBrandSelection"],"mappings":"gTAQO,MAAMA,EAAwB,CAACC,EAA0BC,IACrDD,EAAUE,OAAO,CAACC,EAAKC,IAAaD,GAAOF,EAAeI,SAASD,EAASE,QAAQ,GAGlFC,EAAkBP,GAA4CA,EAAUQ,IAAIC,IAAAA,IAAcA,KAE1FC,EAAsB,CAACV,EAA0BW,EAAa,KAAMC,EAAa,UAC1F,MAAMC,EAA8BN,EAAeP,GAInD,OAFIa,EAAa,GAAGP,QAAUK,GAAcE,EAAa,GAAGP,QAAUM,GAAYC,EAAaC,UAC/FD,EAAaE,OAAS,EACfF,GAII,SAASG,EAAWC,EAAOC,EAAMC,EAAQC,EAAwC,CAAA,GAE5F,MAAMC,KAAEA,EAAIC,UAAEA,GAAcL,GACtBM,IAAEA,GAAQL,GACVM,wBAAEA,EAAuBC,2BAAEA,EAA0BC,sBAAEA,EAAqBC,mBAAEA,EAAkBC,sBAAEA,GAA0BT,EAElI,MAAO,CAQHU,iBAAkB,CAACC,EAAmBC,KAClC,MAAMC,EAAcF,GAAmBH,mBAAqBG,EAAkBH,mBAAmBM,cAAgB,KAIjH,GAHAL,EAAsBI,IAGjBF,IAAsBI,OAAOC,KAAKL,GAAmBf,OAAQ,CAC9DU,EAA2B,IAC3BC,EAAsB,IAItB,MAAMU,EAAeL,GAAoB,SAATV,EAAkBA,EAAO,KASzD,OAPAE,EAAIc,QAAQC,yBAAyBR,EAAmB,CACpDxB,MAAO8B,EACPd,UAAWA,SAIfF,EAAgBiB,QAAU,EAE9B,CAGA,GAAIP,EAAkBS,iBAAiBxB,OAAQ,CAC3C,MAAMyB,EAA4BzC,EAAsB+B,EAAkBS,gBAAiBE,GAErFF,EAAiCC,EACjC9B,EAAoBoB,EAAkBS,iBACtChC,EAAeuB,EAAkBS,iBAGvC,GAAIA,EAAgBxB,OAAS,EAAG,CAI5B,MAAM2B,EAAiBC,EACnBC,EACAL,EACA,SAGEM,EAAcC,EAA0BP,EAAiBG,GAG/DjB,EAA2BoB,EAAYrB,yBACvCE,EAAsBmB,EAAYE,oBAGlCxB,EAAIc,QAAQC,yBAAyB,CACjCX,mBAAoBG,EAAkBH,mBACtCY,gBAAiB,CAACM,EAAYG,aAI9BH,EAAYG,UAAUC,UAAY,IAClC7B,EAAgBiB,QAAUQ,EAAYG,UAAUC,UAIxD,MAEIxB,EAA2B,IAC3BC,EAAsB,IAIjBc,GAAkBd,EAAsBa,EAAgB,GAAGjC,OAGhEiB,EAAIc,QAAQC,yBAAyB,CACjCX,mBAAoBG,EAAkBH,mBACtCY,oBAIAA,EAAgB,GAAGU,UAAY,IAC/B7B,EAAgBiB,QAAUE,EAAgB,GAAGU,UAGzD,GAMJC,yBAA2BC,IACvB,IAAIC,EAAwBD,EAC5B,GAAIA,aAAaE,MAAO,CACpB,MAAMC,EAASH,EAAEG,OACjBF,EAAQE,EAAOC,aAAa,eAAiBD,EAAOC,aAAa,QACrE,CAIA,IAAIC,EAA6B,GAC7BJ,IAEAI,EAAchC,EAAwBtB,OAAO,CAACC,EAAKM,KAC3CA,EAAKgD,YAAYnD,QAAU8C,GAC3BjD,EAAIuD,KAAKjD,EAAKgD,aAEXtD,GACR,IAEEqD,EAAYzC,SAOrBW,EAAsB0B,GAGtB7B,EAAIc,QAAQC,yBAAyB,CACjCX,qBACAY,gBAAiBiB,EACjBG,sBAAsB,OAItC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triggerBinLookUp.js","sources":["../../../../../../src/components/internal/SecuredFields/binLookup/triggerBinLookUp.ts"],"sourcesContent":["import { httpPost } from '../../../../core/Services/http';\nimport { CardBinLookupData, CardBinValueData, CardErrorData } from '../lib/types';\nimport { DEFAULT_CARD_GROUP_TYPES } from '../lib/constants';\nimport { SF_ErrorCodes } from '../../../../core/Errors/constants';\nimport { BinLookupResponse, BinLookupResponseRaw } from '../../../Card/types';\n\nif (process.env.NODE_ENV === 'development') {\n window.mockBinCount = 0; // Set to 0 to turn off mocking, 1 to turn it on\n}\n\nexport default parent => {\n let currentRequestId = null;\n\n return (callbackObj: CardBinValueData) => {\n // Allow way for merchant to disallow binLookup by specifically setting the prop to false\n if (parent.props.doBinLookup === false) {\n if (parent.props.onBinValue) parent.props.onBinValue(callbackObj);\n return;\n }\n\n // Do binLookup when encryptedBin property is present (and only if the merchant is using a clientKey)\n if (callbackObj.encryptedBin && parent.props.clientKey) {\n // Store id of request we're about to make\n currentRequestId = callbackObj.uuid;\n\n void httpPost(\n {\n loadingContext: parent.props.loadingContext,\n path: `v3/bin/binLookup?token=${parent.props.clientKey}`\n },\n {\n type: parent.props.brand,\n supportedBrands: parent.props.brands || DEFAULT_CARD_GROUP_TYPES,\n encryptedBin: callbackObj.encryptedBin,\n requestId: callbackObj.uuid // Pass id of request\n }\n ).then((data: BinLookupResponseRaw) => {\n // If response is the one we were waiting for...\n if (data?.requestId === currentRequestId) {\n if (process.env.NODE_ENV === 'development') {\n // TODO mocking\n if (window.mockBinCount >= 1) {\n switch (window.mockBinCount) {\n case 1:\n console.log('\\n### triggerBinLookUp::mock first response:: ');\n data.brands = [\n {\n brand: 'mc',\n cvcPolicy: 'optional',\n enableLuhnCheck: true,\n // showExpiryDate: true, // deprecated in /binLookup v3\n expiryDatePolicy: 'optional',\n // panLength: 16,\n supported: true\n }\n ];\n // data.issuingCountryCode = 'KR'; // needed to mock korean_local_card\n // increment to alter second response\n window.mockBinCount++;\n\n break;\n case 2:\n console.log('\\n### triggerBinLookUp::mock second response:: ');\n // data.brands = null;\n data.brands = [\n {\n brand: 'maestro',\n cvcPolicy: 'required',\n enableLuhnCheck: true,\n showExpiryDate: true,\n supported: true,\n showSocialSecurityNumber: false\n // panLength: 16\n }\n ];\n break;\n default:\n }\n }\n // TODO end\n }\n\n if (data.brands?.length) {\n const mappedResponse = data.brands.reduce(\n (acc, item) => {\n // All brand strings end up in the detectedBrands array\n acc.detectedBrands.push(item.brand);\n // Also add the paymentMethodVariants (more granular description of the txvariant)\n acc.paymentMethodVariants.push(item.paymentMethodVariant);\n\n // Add supported brand objects to the supportedBrands array\n if (item.supported === true) {\n acc.supportedBrands.push(item);\n return acc;\n }\n\n return acc;\n },\n { supportedBrands: [], detectedBrands: [], paymentMethodVariants: [] }\n );\n\n /**\n * supportedBrands = merchant supports this brand(s); we have detected the card number to be of this brand(s); carry on!\n */\n if (mappedResponse.supportedBrands.length) {\n // ...call processBinLookupResponse with, a simplified, response object if it contains at least one supported brand\n parent.processBinLookupResponse({\n issuingCountryCode: data.issuingCountryCode,\n supportedBrands: mappedResponse.supportedBrands,\n ...(data.showSocialSecurityNumber ? { showSocialSecurityNumber: data.showSocialSecurityNumber } : {})\n } as BinLookupResponse);\n\n // Inform merchant of the result\n parent.onBinLookup({\n type: callbackObj.type,\n detectedBrands: mappedResponse.detectedBrands,\n // supportedBrands contains the subset of this.props.brands that matches the card number that the shopper has typed\n supportedBrands: mappedResponse.supportedBrands.map(item => item.brand),\n paymentMethodVariants: mappedResponse.paymentMethodVariants,\n supportedBrandsRaw: mappedResponse.supportedBrands, // full supportedBrands data (for customCard comp)\n brands: parent.props.brands || DEFAULT_CARD_GROUP_TYPES,\n issuingCountryCode: data.issuingCountryCode\n } as CardBinLookupData);\n\n return;\n }\n\n /**\n * detectedBrands = no brands the merchant supports were found; what we did detect the shopper to be entering was this brand;\n * error!\n */\n if (mappedResponse.detectedBrands.length) {\n const errObj: CardErrorData = {\n type: 'card',\n fieldType: 'encryptedCardNumber',\n error: SF_ErrorCodes.ERROR_MSG_UNSUPPORTED_CARD_ENTERED,\n detectedBrands: mappedResponse.detectedBrands\n };\n parent.handleUnsupportedCard(errObj);\n\n // Inform merchant of the result\n parent.onBinLookup({\n type: callbackObj.type,\n detectedBrands: mappedResponse.detectedBrands,\n supportedBrands: null,\n paymentMethodVariants: mappedResponse.paymentMethodVariants,\n brands: parent.props.brands || DEFAULT_CARD_GROUP_TYPES\n } as CardBinLookupData);\n\n return;\n }\n } else {\n /**\n * BIN not in DB (a failed lookup will just contain a requestId)\n */\n parent.onBinLookup({\n type: callbackObj.type,\n detectedBrands: null,\n supportedBrands: null,\n paymentMethodVariants: null,\n brands: parent.props.brands || DEFAULT_CARD_GROUP_TYPES\n } as CardBinLookupData);\n\n // Reset the UI and let the native, regex branding happen (for the generic card)\n // For a single-branded card we need to pass a boolean to prompt resetting the brand logo to the 'base' type\n parent.processBinLookupResponse({}, true);\n }\n } else {\n if (!data?.requestId) {\n // Some other kind of error on the backend\n parent.props.onError(data || { errorType: 'binLookup', message: 'unknownError' });\n }\n // Else - response with wrong requestId\n }\n });\n } else if (currentRequestId) {\n /**\n * If onBinValue callback is called AND we have been doing binLookup BUT passed object doesn't have an encryptedBin property\n * - then THE NUMBER OF DIGITS IN NUMBER FIELD HAS DROPPED BELOW THRESHOLD for BIN lookup - so reset the UI\n */\n parent.processBinLookupResponse(null, true);\n\n currentRequestId = null; // Ignore any pending responses\n\n // Reset any errors\n const errObj: CardErrorData = {\n type: 'card',\n fieldType: 'encryptedCardNumber',\n error: ''\n };\n parent.handleUnsupportedCard(errObj);\n\n // CustomCard needs this to reset the UI\n parent.onBinLookup({\n isReset: true\n } as CardBinLookupData);\n }\n\n if (parent.props.onBinValue) parent.props.onBinValue(callbackObj);\n };\n};\n"],"names":["triggerBinLookUp","parent","currentRequestId","callbackObj","props","doBinLookup","encryptedBin","clientKey","uuid","httpPost","loadingContext","path","type","brand","supportedBrands","brands","DEFAULT_CARD_GROUP_TYPES","requestId","then","data","length","mappedResponse","reduce","acc","item","detectedBrands","push","paymentMethodVariants","paymentMethodVariant","supported","processBinLookupResponse","issuingCountryCode","showSocialSecurityNumber","onBinLookup","map","supportedBrandsRaw","errObj","fieldType","error","SF_ErrorCodes","ERROR_MSG_UNSUPPORTED_CARD_ENTERED","handleUnsupportedCard","onError","errorType","message","isReset","onBinValue"],"mappings":"iMAUA,IAAAA,EAAeC,IACX,IAAIC,EAAmB,KAEvB,OAAQC,IAEJ,IAAiC,IAA7BF,EAAOG,MAAMC,YAAjB,CAMA,GAAIF,EAAYG,cAAgBL,EAAOG,MAAMG,UAEzCL,EAAmBC,EAAYK,KAE1BC,EACD,CACIC,eAAgBT,EAAOG,MAAMM,eAC7BC,KAAM,0BAA0BV,EAAOG,MAAMG,aAEjD,CACIK,KAAMX,EAAOG,MAAMS,MACnBC,gBAAiBb,EAAOG,MAAMW,QAAUC,EACxCV,aAAcH,EAAYG,aAC1BW,UAAWd,EAAYK,OAE7BU,KAAMC,IAEJ,GAAIA,GAAMF,YAAcf,EA4CpB,GAAIiB,EAAKJ,QAAQK,OAAQ,CACrB,MAAMC,EAAiBF,EAAKJ,OAAOO,OAC/B,CAACC,EAAKC,KAEFD,EAAIE,eAAeC,KAAKF,EAAKX,OAE7BU,EAAII,sBAAsBD,KAAKF,EAAKI,uBAGb,IAAnBJ,EAAKK,WACLN,EAAIT,gBAAgBY,KAAKF,GAClBD,GAGJA,GAEX,CAAET,gBAAiB,GAAIW,eAAgB,GAAIE,sBAAuB,KAMtE,GAAIN,EAAeP,gBAAgBM,OAoB/B,OAlBAnB,EAAO6B,yBAAyB,CAC5BC,mBAAoBZ,EAAKY,mBACzBjB,gBAAiBO,EAAeP,mBAC5BK,EAAKa,yBAA2B,CAAEA,yBAA0Bb,EAAKa,0BAA6B,CAAA,SAItG/B,EAAOgC,YAAY,CACfrB,KAAMT,EAAYS,KAClBa,eAAgBJ,EAAeI,eAE/BX,gBAAiBO,EAAeP,gBAAgBoB,IAAIV,GAAQA,EAAKX,OACjEc,sBAAuBN,EAAeM,sBACtCQ,mBAAoBd,EAAeP,gBACnCC,OAAQd,EAAOG,MAAMW,QAAUC,EAC/Be,mBAAoBZ,EAAKY,qBAUjC,GAAIV,EAAeI,eAAeL,OAAQ,CACtC,MAAMgB,EAAwB,CAC1BxB,KAAM,OACNyB,UAAW,sBACXC,MAAOC,EAAcC,mCACrBf,eAAgBJ,EAAeI,gBAanC,OAXAxB,EAAOwC,sBAAsBL,QAG7BnC,EAAOgC,YAAY,CACfrB,KAAMT,EAAYS,KAClBa,eAAgBJ,EAAeI,eAC/BX,gBAAiB,KACjBa,sBAAuBN,EAAeM,sBACtCZ,OAAQd,EAAOG,MAAMW,QAAUC,GAIvC,OAKAf,EAAOgC,YAAY,CACfrB,KAAMT,EAAYS,KAClBa,eAAgB,KAChBX,gBAAiB,KACjBa,sBAAuB,KACvBZ,OAAQd,EAAOG,MAAMW,QAAUC,IAKnCf,EAAO6B,yBAAyB,CAAA,GAAI,QAGnCX,GAAMF,WAEPhB,EAAOG,MAAMsC,QAAQvB,GAAQ,CAAEwB,UAAW,YAAaC,QAAS,wBAKzE,GAAI1C,EAAkB,CAKzBD,EAAO6B,yBAAyB,MAAM,GAEtC5B,EAAmB,KAGnB,MAAMkC,EAAwB,CAC1BxB,KAAM,OACNyB,UAAW,sBACXC,MAAO,IAEXrC,EAAOwC,sBAAsBL,GAG7BnC,EAAOgC,YAAY,CACfY,SAAS,GAEjB,CAEI5C,EAAOG,MAAM0C,YAAY7C,EAAOG,MAAM0C,WAAW3C,EApLrD,MAFQF,EAAOG,MAAM0C,YAAY7C,EAAOG,MAAM0C,WAAW3C,GAwLjE"}
|
|
1
|
+
{"version":3,"file":"triggerBinLookUp.js","sources":["../../../../../../src/components/internal/SecuredFields/binLookup/triggerBinLookUp.ts"],"sourcesContent":["import { httpPost } from '../../../../core/Services/http';\nimport { CardBinLookupData, CardBinValueData, CardErrorData } from '../lib/types';\nimport { DEFAULT_CARD_GROUP_TYPES } from '../lib/constants';\nimport { SF_ErrorCodes } from '../../../../core/Errors/constants';\nimport { BinLookupResponse, BinLookupResponseRaw } from '../../../Card/types';\n\nif (process.env.NODE_ENV === 'development') {\n window.mockBinCount = 0; // Set to 0 to turn off mocking, 1 to turn it on\n}\n\nexport default parent => {\n let currentRequestId = null;\n\n return (callbackObj: CardBinValueData) => {\n // Allow way for merchant to disallow binLookup by specifically setting the prop to false\n if (parent.props.doBinLookup === false) {\n if (parent.props.onBinValue) parent.props.onBinValue(callbackObj);\n return;\n }\n\n // Do binLookup when encryptedBin property is present (and only if the merchant is using a clientKey)\n if (callbackObj.encryptedBin && parent.props.clientKey) {\n // Store id of request we're about to make\n currentRequestId = callbackObj.uuid;\n\n void httpPost(\n {\n loadingContext: parent.props.loadingContext,\n path: `v3/bin/binLookup?token=${parent.props.clientKey}`\n },\n {\n type: parent.props.brand,\n supportedBrands: parent.props.brands || DEFAULT_CARD_GROUP_TYPES,\n encryptedBin: callbackObj.encryptedBin,\n requestId: callbackObj.uuid // Pass id of request\n }\n ).then((data: BinLookupResponseRaw) => {\n // If response is the one we were waiting for...\n if (data?.requestId === currentRequestId) {\n if (process.env.NODE_ENV === 'development') {\n // TODO mocking\n if (window.mockBinCount >= 1) {\n switch (window.mockBinCount) {\n case 1:\n console.log('\\n### triggerBinLookUp::mock first response:: ');\n data.brands = [\n {\n brand: 'mc',\n cvcPolicy: 'optional',\n enableLuhnCheck: true,\n // showExpiryDate: true, // deprecated in /binLookup v3\n expiryDatePolicy: 'optional',\n // panLength: 16,\n supported: true\n }\n ];\n // data.issuingCountryCode = 'KR'; // needed to mock korean_local_card\n // increment to alter second response\n window.mockBinCount++;\n\n break;\n case 2:\n console.log('\\n### triggerBinLookUp::mock second response:: ');\n // data.brands = null;\n data.brands = [\n {\n brand: 'maestro',\n cvcPolicy: 'required',\n enableLuhnCheck: true,\n showExpiryDate: true,\n supported: true,\n showSocialSecurityNumber: false\n // panLength: 16\n }\n ];\n break;\n default:\n }\n }\n // TODO end\n }\n\n if (data.brands?.length) {\n const mappedResponse = data.brands.reduce(\n (acc, item) => {\n // All brand strings end up in the detectedBrands array\n acc.detectedBrands.push(item.brand);\n // Also add the paymentMethodVariants (more granular description of the txvariant)\n acc.paymentMethodVariants.push(item.paymentMethodVariant);\n\n // Add supported brand objects to the supportedBrands array\n if (item.supported === true) {\n acc.supportedBrands.push(item);\n return acc;\n }\n\n return acc;\n },\n { supportedBrands: [], detectedBrands: [], paymentMethodVariants: [] }\n );\n\n /**\n * supportedBrands = merchant supports this brand(s); we have detected the card number to be of this brand(s); carry on!\n */\n if (mappedResponse.supportedBrands.length) {\n // ...call processBinLookupResponse with, a simplified, response object if it contains at least one supported brand\n parent.processBinLookupResponse({\n issuingCountryCode: data.issuingCountryCode,\n supportedBrands: mappedResponse.supportedBrands,\n ...(data.showSocialSecurityNumber ? { showSocialSecurityNumber: data.showSocialSecurityNumber } : {})\n } as BinLookupResponse);\n\n // Inform merchant of the result\n parent.onBinLookup({\n type: callbackObj.type,\n detectedBrands: mappedResponse.detectedBrands,\n // supportedBrands contains the subset of this.props.brands that matches the card number that the shopper has typed\n supportedBrands: mappedResponse.supportedBrands.map(item => item.brand),\n paymentMethodVariants: mappedResponse.paymentMethodVariants,\n supportedBrandsRaw: mappedResponse.supportedBrands, // full supportedBrands data (for customCard comp)\n brands: parent.props.brands || DEFAULT_CARD_GROUP_TYPES,\n issuingCountryCode: data.issuingCountryCode\n } as CardBinLookupData);\n\n return;\n }\n\n /**\n * detectedBrands = no brands the merchant supports were found; what we did detect the shopper to be entering was this brand;\n * error!\n */\n if (mappedResponse.detectedBrands.length) {\n const errObj: CardErrorData = {\n type: 'card',\n fieldType: 'encryptedCardNumber',\n error: SF_ErrorCodes.ERROR_MSG_UNSUPPORTED_CARD_ENTERED,\n detectedBrands: mappedResponse.detectedBrands\n };\n parent.handleUnsupportedCard(errObj);\n\n // Inform merchant of the result\n parent.onBinLookup({\n type: callbackObj.type,\n detectedBrands: mappedResponse.detectedBrands,\n supportedBrands: null,\n paymentMethodVariants: mappedResponse.paymentMethodVariants,\n brands: parent.props.brands || DEFAULT_CARD_GROUP_TYPES\n } as CardBinLookupData);\n\n return;\n }\n } else {\n /**\n * BIN not in DB (a failed lookup will just contain a requestId)\n */\n parent.onBinLookup({\n type: callbackObj.type,\n detectedBrands: null,\n supportedBrands: null,\n paymentMethodVariants: null,\n brands: parent.props.brands || DEFAULT_CARD_GROUP_TYPES\n } as CardBinLookupData);\n\n // Reset the UI and let the native, regex branding happen (for the generic card)\n // For a single-branded card we need to pass a boolean to prompt resetting the brand logo to the 'base' type\n parent.processBinLookupResponse({}, true);\n }\n } else {\n if (!data?.requestId) {\n // Some other kind of error on the backend\n parent.props.onError(data || { errorType: 'binLookup', message: 'unknownError' });\n }\n // Else - response with wrong requestId\n }\n });\n } else if (currentRequestId) {\n /**\n * If onBinValue callback is called AND we have been doing binLookup BUT passed object doesn't have an encryptedBin property\n * - then THE NUMBER OF DIGITS IN NUMBER FIELD HAS DROPPED BELOW THRESHOLD for BIN lookup - so reset the UI\n */\n parent.processBinLookupResponse(null, true);\n\n currentRequestId = null; // Ignore any pending responses\n\n // Reset any errors\n const errObj: CardErrorData = {\n type: 'card',\n fieldType: 'encryptedCardNumber',\n error: ''\n };\n parent.handleUnsupportedCard(errObj);\n\n // CustomCard needs this to reset the UI\n parent.onBinLookup({\n isReset: true\n } as CardBinLookupData);\n }\n\n if (parent.props.onBinValue) parent.props.onBinValue(callbackObj);\n };\n};\n"],"names":["triggerBinLookUp","parent","currentRequestId","callbackObj","props","doBinLookup","encryptedBin","clientKey","uuid","httpPost","loadingContext","path","type","brand","supportedBrands","brands","DEFAULT_CARD_GROUP_TYPES","requestId","then","data","length","mappedResponse","reduce","acc","item","detectedBrands","push","paymentMethodVariants","paymentMethodVariant","supported","processBinLookupResponse","issuingCountryCode","showSocialSecurityNumber","onBinLookup","map","supportedBrandsRaw","errObj","fieldType","error","SF_ErrorCodes","ERROR_MSG_UNSUPPORTED_CARD_ENTERED","handleUnsupportedCard","onError","errorType","message","isReset","onBinValue"],"mappings":"iMAUA,IAAAA,EAAeC,IACX,IAAIC,EAAmB,KAEvB,OAAQC,IAEJ,IAAiC,IAA7BF,EAAOG,MAAMC,YAAjB,CAMA,GAAIF,EAAYG,cAAgBL,EAAOG,MAAMG,UAEzCL,EAAmBC,EAAYK,KAE1BC,EACD,CACIC,eAAgBT,EAAOG,MAAMM,eAC7BC,KAAM,0BAA0BV,EAAOG,MAAMG,aAEjD,CACIK,KAAMX,EAAOG,MAAMS,MACnBC,gBAAiBb,EAAOG,MAAMW,QAAUC,EACxCV,aAAcH,EAAYG,aAC1BW,UAAWd,EAAYK,OAE7BU,KAAMC,IAEJ,GAAIA,GAAMF,YAAcf,EA4CpB,GAAIiB,EAAKJ,QAAQK,OAAQ,CACrB,MAAMC,EAAiBF,EAAKJ,OAAOO,OAC/B,CAACC,EAAKC,KAEFD,EAAIE,eAAeC,KAAKF,EAAKX,OAE7BU,EAAII,sBAAsBD,KAAKF,EAAKI,uBAGb,IAAnBJ,EAAKK,WACLN,EAAIT,gBAAgBY,KAAKF,GAClBD,GAGJA,GAEX,CAAET,gBAAiB,GAAIW,eAAgB,GAAIE,sBAAuB,KAMtE,GAAIN,EAAeP,gBAAgBM,OAoB/B,OAlBAnB,EAAO6B,yBAAyB,CAC5BC,mBAAoBZ,EAAKY,mBACzBjB,gBAAiBO,EAAeP,mBAC5BK,EAAKa,yBAA2B,CAAEA,yBAA0Bb,EAAKa,0BAA6B,CAAA,SAItG/B,EAAOgC,YAAY,CACfrB,KAAMT,EAAYS,KAClBa,eAAgBJ,EAAeI,eAE/BX,gBAAiBO,EAAeP,gBAAgBoB,IAAIV,GAAQA,EAAKX,OACjEc,sBAAuBN,EAAeM,sBACtCQ,mBAAoBd,EAAeP,gBACnCC,OAAQd,EAAOG,MAAMW,QAAUC,EAC/Be,mBAAoBZ,EAAKY,qBAUjC,GAAIV,EAAeI,eAAeL,OAAQ,CACtC,MAAMgB,EAAwB,CAC1BxB,KAAM,OACNyB,UAAW,sBACXC,MAAOC,EAAcC,mCACrBf,eAAgBJ,EAAeI,gBAanC,OAXAxB,EAAOwC,sBAAsBL,QAG7BnC,EAAOgC,YAAY,CACfrB,KAAMT,EAAYS,KAClBa,eAAgBJ,EAAeI,eAC/BX,gBAAiB,KACjBa,sBAAuBN,EAAeM,sBACtCZ,OAAQd,EAAOG,MAAMW,QAAUC,GAIvC,CACJ,MAIIf,EAAOgC,YAAY,CACfrB,KAAMT,EAAYS,KAClBa,eAAgB,KAChBX,gBAAiB,KACjBa,sBAAuB,KACvBZ,OAAQd,EAAOG,MAAMW,QAAUC,IAKnCf,EAAO6B,yBAAyB,CAAA,GAAI,QAGnCX,GAAMF,WAEPhB,EAAOG,MAAMsC,QAAQvB,GAAQ,CAAEwB,UAAW,YAAaC,QAAS,wBAKzE,GAAI1C,EAAkB,CAKzBD,EAAO6B,yBAAyB,MAAM,GAEtC5B,EAAmB,KAGnB,MAAMkC,EAAwB,CAC1BxB,KAAM,OACNyB,UAAW,sBACXC,MAAO,IAEXrC,EAAOwC,sBAAsBL,GAG7BnC,EAAOgC,YAAY,CACfY,SAAS,GAEjB,CAEI5C,EAAOG,MAAM0C,YAAY7C,EAAOG,MAAM0C,WAAW3C,EApLrD,MAFQF,EAAOG,MAAM0C,YAAY7C,EAAOG,MAAM0C,WAAW3C,GAwLjE"}
|
package/dist/es/components/internal/SecuredFields/lib/CSF/extensions/handleIOSTouchEvents.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleIOSTouchEvents.js","sources":["../../../../../../../../src/components/internal/SecuredFields/lib/CSF/extensions/handleIOSTouchEvents.ts"],"sourcesContent":["import { selectOne } from '../../utilities/dom';\nimport ua from '../utils/userAgent';\nimport { on, off } from '../../../../../../utils/listenerUtils';\n\nconst getCaretPos = (pNode: HTMLInputElement | HTMLTextAreaElement): number => {\n if ('selectionStart' in pNode) {\n return pNode.selectionStart;\n }\n return 0;\n};\n\n/**\n * Detect if touched element is an input or textArea.\n * - If it is do some quirky shit to set focus and caret position on this element\n * - Else do some quirky shit to make the iOS keyboard retract\n *\n * Always then remove this listener and set var saying we have done so (read in CSF...handleFocus)\n * Tell all securedFields some other element now has focus so they can blur themselves\n *\n * @param e -\n */\nfunction touchendListener(e: Event): void {\n const targetEl: EventTarget = e.target;\n\n // If other element is Input or TextArea\n if (targetEl instanceof HTMLInputElement || (HTMLTextAreaElement && targetEl instanceof HTMLTextAreaElement)) {\n // Force caret to show - 'requires' resetting field's value\n const val: string = targetEl.value;\n\n let caretPos: number = getCaretPos(targetEl);\n\n let adjFlag = false;\n\n // For some annoying, iOS Safari, reason if caretPos is at the end of the string then it won't show up\n // - so first decrease it; then set it again, asynchronously\n if (caretPos === val.length) {\n caretPos -= 1;\n adjFlag = true;\n }\n\n targetEl.value = val;\n\n /**\n * If the input element is of an unexpected type (perhaps the merchant is using a custom button that is an input element, type=\"button\", or,\n * it is something presented in the 3DS2 flow - both, TBC) then this next line will not work.\n * However, the input element still has a setSelectionRange property of type \"function\", but trying to call it will throw an error...\n * so, try, to see if setSelectionRange can be called\n */\n try {\n if (targetEl.setSelectionRange) {\n targetEl.focus();\n targetEl.setSelectionRange(caretPos, caretPos);\n\n // Quirky! (see comment about iOS Safari, above)\n if (adjFlag) {\n caretPos += 1;\n setTimeout(() => {\n targetEl.setSelectionRange(caretPos, caretPos);\n }, 0);\n }\n }\n /* eslint-disable-next-line */\n } catch (e) {}\n } else {\n /**\n * Workaround for iOS/Safari bug where keypad doesn't retract when SF paymentMethod is no longer active\n */\n const hasKeypadFix: boolean = this.config.keypadFix; // to avoid linting no-lonely-if\n if (hasKeypadFix) {\n // Create an input we can add focus to.\n // Otherwise 2nd & sub times the caret gets left in the SF even though it has lost focus and cannot be typed into\n const rootNode: HTMLElement = this.props.rootNode;\n const nuInput: HTMLInputElement = document.createElement('input');\n nuInput.style.width = '1px';\n nuInput.style.height = '1px';\n nuInput.style.opacity = '0';\n nuInput.style.fontSize = '18px'; // prevents zoom\n rootNode.appendChild(nuInput);\n nuInput.focus(); // Takes caret from SF\n rootNode.removeChild(nuInput); // Without this numpad will be replaced with text pad\n }\n }\n\n // Remove listener - it gets reset by next call to handleAdditionalFields from handleFocus\n this.destroyTouchendListener();\n\n // Store the fact we have unset the listener\n this.state.registerFieldForIos = false;\n\n // Clear focus on secured field inputs now this checkout element has gained focus\n this.postMessageToAllIframes({ fieldType: 'webInternalElement', fieldClick: true });\n}\n\n/**\n * re. Disabling arrow keys in iOS - need to enable all fields in the form and tell SFs to disable\n *\n * NOTE: Only called when iOS detected & this.props.shouldDisableIOSArrowKeys = true\n */\nfunction touchstartListener(e: Event): void {\n this.hasGenuineTouchEvents = true;\n const targetEl: EventTarget = e.target;\n // If other element is Input or Span (i.e. label text) TODO apply to other types of el?\n if (targetEl instanceof HTMLInputElement || targetEl instanceof HTMLSpanElement) {\n this.postMessageToAllIframes({ fieldType: 'webInternalElement', checkoutTouchEvent: true });\n\n const name = targetEl.getAttribute('name') ?? targetEl.getAttribute('data-id'); // if targetEl is a label's span it will only have a data-id\n this.callbacks.onTouchstartIOS?.({ fieldType: 'webInternalElement', name });\n }\n}\n\n/**\n * This works with the touchend handler to allow us to catch (click) events on non-securedFields elements\n * (re. http://gravitydept.com/blog/js-click-event-bubbling-on-ios - events don't bubble unless the click takes place on a link or input)\n *\n * We can use this event to:\n * 1. Set focus on these other elements, and\n * 2. Tell SecuredFields that this has happened so they can blur themselves\n * (see note in adyen-secured-fields...inputBase.js - \"Blur event never fires on input field\")\n *\n * NOTE: Only called when iOS detected\n */\nfunction handleTouchend(): void {\n const bodyEl: HTMLBodyElement = selectOne(document, 'body');\n bodyEl.style.cursor = 'pointer';\n\n on(bodyEl, 'touchend', this.touchendListener);\n\n // Store the fact we have set the listener\n this.state.registerFieldForIos = true;\n}\n\nfunction destroyTouchendListener(): boolean {\n if (!ua.__IS_IOS) return false; // For when fn is called as result of destroy being called on main csf instance\n\n const bodyEl: HTMLBodyElement = selectOne(document, 'body');\n bodyEl.style.cursor = 'auto';\n off(bodyEl, 'touchend', this.touchendListener);\n return true;\n}\n\nfunction destroyTouchstartListener(): boolean {\n if (!ua.__IS_IOS) return false; // For when fn is called as result of destroy being called on main csf instance\n\n off(document, 'touchstart', this.touchstartListener);\n return true;\n}\n\nexport default {\n touchendListener,\n touchstartListener,\n handleTouchend,\n destroyTouchendListener,\n destroyTouchstartListener\n};\n"],"names":["handleIOSTouchEvents","touchendListener","e","targetEl","target","HTMLInputElement","HTMLTextAreaElement","val","value","caretPos","pNode","selectionStart","adjFlag","length","setSelectionRange","focus","setTimeout","this","config","keypadFix","rootNode","props","nuInput","document","createElement","style","width","height","opacity","fontSize","appendChild","removeChild","destroyTouchendListener","state","registerFieldForIos","postMessageToAllIframes","fieldType","fieldClick","touchstartListener","hasGenuineTouchEvents","HTMLSpanElement","checkoutTouchEvent","name","getAttribute","callbacks","onTouchstartIOS","handleTouchend","bodyEl","selectOne","cursor","on","ua","__IS_IOS","off","destroyTouchstartListener"],"mappings":"+JAmJA,IAAAA,EAAe,CACXC,iBA/HJ,SAA0BC,GACtB,MAAMC,EAAwBD,EAAEE,OAGhC,GAAID,aAAoBE,kBAAqBC,qBAAuBH,aAAoBG,oBAAsB,CAE1G,MAAMC,EAAcJ,EAASK,MAE7B,IAAIC,EAxBJ,mBADaC,EAyBsBP,GAvB5BO,EAAMC,eAEV,EAuBCC,GAAU,EAIVH,IAAaF,EAAIM,SACjBJ,GAAY,EACZG,GAAU,GAGdT,EAASK,MAAQD,EAQjB,IACQJ,EAASW,oBACTX,EAASY,QACTZ,EAASW,kBAAkBL,EAAUA,GAGjCG,IACAH,GAAY,EACZO,WAAW,KACPb,EAASW,kBAAkBL,EAAUA,IACtC,
|
|
1
|
+
{"version":3,"file":"handleIOSTouchEvents.js","sources":["../../../../../../../../src/components/internal/SecuredFields/lib/CSF/extensions/handleIOSTouchEvents.ts"],"sourcesContent":["import { selectOne } from '../../utilities/dom';\nimport ua from '../utils/userAgent';\nimport { on, off } from '../../../../../../utils/listenerUtils';\n\nconst getCaretPos = (pNode: HTMLInputElement | HTMLTextAreaElement): number => {\n if ('selectionStart' in pNode) {\n return pNode.selectionStart;\n }\n return 0;\n};\n\n/**\n * Detect if touched element is an input or textArea.\n * - If it is do some quirky shit to set focus and caret position on this element\n * - Else do some quirky shit to make the iOS keyboard retract\n *\n * Always then remove this listener and set var saying we have done so (read in CSF...handleFocus)\n * Tell all securedFields some other element now has focus so they can blur themselves\n *\n * @param e -\n */\nfunction touchendListener(e: Event): void {\n const targetEl: EventTarget = e.target;\n\n // If other element is Input or TextArea\n if (targetEl instanceof HTMLInputElement || (HTMLTextAreaElement && targetEl instanceof HTMLTextAreaElement)) {\n // Force caret to show - 'requires' resetting field's value\n const val: string = targetEl.value;\n\n let caretPos: number = getCaretPos(targetEl);\n\n let adjFlag = false;\n\n // For some annoying, iOS Safari, reason if caretPos is at the end of the string then it won't show up\n // - so first decrease it; then set it again, asynchronously\n if (caretPos === val.length) {\n caretPos -= 1;\n adjFlag = true;\n }\n\n targetEl.value = val;\n\n /**\n * If the input element is of an unexpected type (perhaps the merchant is using a custom button that is an input element, type=\"button\", or,\n * it is something presented in the 3DS2 flow - both, TBC) then this next line will not work.\n * However, the input element still has a setSelectionRange property of type \"function\", but trying to call it will throw an error...\n * so, try, to see if setSelectionRange can be called\n */\n try {\n if (targetEl.setSelectionRange) {\n targetEl.focus();\n targetEl.setSelectionRange(caretPos, caretPos);\n\n // Quirky! (see comment about iOS Safari, above)\n if (adjFlag) {\n caretPos += 1;\n setTimeout(() => {\n targetEl.setSelectionRange(caretPos, caretPos);\n }, 0);\n }\n }\n /* eslint-disable-next-line */\n } catch (e) {}\n } else {\n /**\n * Workaround for iOS/Safari bug where keypad doesn't retract when SF paymentMethod is no longer active\n */\n const hasKeypadFix: boolean = this.config.keypadFix; // to avoid linting no-lonely-if\n if (hasKeypadFix) {\n // Create an input we can add focus to.\n // Otherwise 2nd & sub times the caret gets left in the SF even though it has lost focus and cannot be typed into\n const rootNode: HTMLElement = this.props.rootNode;\n const nuInput: HTMLInputElement = document.createElement('input');\n nuInput.style.width = '1px';\n nuInput.style.height = '1px';\n nuInput.style.opacity = '0';\n nuInput.style.fontSize = '18px'; // prevents zoom\n rootNode.appendChild(nuInput);\n nuInput.focus(); // Takes caret from SF\n rootNode.removeChild(nuInput); // Without this numpad will be replaced with text pad\n }\n }\n\n // Remove listener - it gets reset by next call to handleAdditionalFields from handleFocus\n this.destroyTouchendListener();\n\n // Store the fact we have unset the listener\n this.state.registerFieldForIos = false;\n\n // Clear focus on secured field inputs now this checkout element has gained focus\n this.postMessageToAllIframes({ fieldType: 'webInternalElement', fieldClick: true });\n}\n\n/**\n * re. Disabling arrow keys in iOS - need to enable all fields in the form and tell SFs to disable\n *\n * NOTE: Only called when iOS detected & this.props.shouldDisableIOSArrowKeys = true\n */\nfunction touchstartListener(e: Event): void {\n this.hasGenuineTouchEvents = true;\n const targetEl: EventTarget = e.target;\n // If other element is Input or Span (i.e. label text) TODO apply to other types of el?\n if (targetEl instanceof HTMLInputElement || targetEl instanceof HTMLSpanElement) {\n this.postMessageToAllIframes({ fieldType: 'webInternalElement', checkoutTouchEvent: true });\n\n const name = targetEl.getAttribute('name') ?? targetEl.getAttribute('data-id'); // if targetEl is a label's span it will only have a data-id\n this.callbacks.onTouchstartIOS?.({ fieldType: 'webInternalElement', name });\n }\n}\n\n/**\n * This works with the touchend handler to allow us to catch (click) events on non-securedFields elements\n * (re. http://gravitydept.com/blog/js-click-event-bubbling-on-ios - events don't bubble unless the click takes place on a link or input)\n *\n * We can use this event to:\n * 1. Set focus on these other elements, and\n * 2. Tell SecuredFields that this has happened so they can blur themselves\n * (see note in adyen-secured-fields...inputBase.js - \"Blur event never fires on input field\")\n *\n * NOTE: Only called when iOS detected\n */\nfunction handleTouchend(): void {\n const bodyEl: HTMLBodyElement = selectOne(document, 'body');\n bodyEl.style.cursor = 'pointer';\n\n on(bodyEl, 'touchend', this.touchendListener);\n\n // Store the fact we have set the listener\n this.state.registerFieldForIos = true;\n}\n\nfunction destroyTouchendListener(): boolean {\n if (!ua.__IS_IOS) return false; // For when fn is called as result of destroy being called on main csf instance\n\n const bodyEl: HTMLBodyElement = selectOne(document, 'body');\n bodyEl.style.cursor = 'auto';\n off(bodyEl, 'touchend', this.touchendListener);\n return true;\n}\n\nfunction destroyTouchstartListener(): boolean {\n if (!ua.__IS_IOS) return false; // For when fn is called as result of destroy being called on main csf instance\n\n off(document, 'touchstart', this.touchstartListener);\n return true;\n}\n\nexport default {\n touchendListener,\n touchstartListener,\n handleTouchend,\n destroyTouchendListener,\n destroyTouchstartListener\n};\n"],"names":["handleIOSTouchEvents","touchendListener","e","targetEl","target","HTMLInputElement","HTMLTextAreaElement","val","value","caretPos","pNode","selectionStart","adjFlag","length","setSelectionRange","focus","setTimeout","this","config","keypadFix","rootNode","props","nuInput","document","createElement","style","width","height","opacity","fontSize","appendChild","removeChild","destroyTouchendListener","state","registerFieldForIos","postMessageToAllIframes","fieldType","fieldClick","touchstartListener","hasGenuineTouchEvents","HTMLSpanElement","checkoutTouchEvent","name","getAttribute","callbacks","onTouchstartIOS","handleTouchend","bodyEl","selectOne","cursor","on","ua","__IS_IOS","off","destroyTouchstartListener"],"mappings":"+JAmJA,IAAAA,EAAe,CACXC,iBA/HJ,SAA0BC,GACtB,MAAMC,EAAwBD,EAAEE,OAGhC,GAAID,aAAoBE,kBAAqBC,qBAAuBH,aAAoBG,oBAAsB,CAE1G,MAAMC,EAAcJ,EAASK,MAE7B,IAAIC,EAxBJ,mBADaC,EAyBsBP,GAvB5BO,EAAMC,eAEV,EAuBCC,GAAU,EAIVH,IAAaF,EAAIM,SACjBJ,GAAY,EACZG,GAAU,GAGdT,EAASK,MAAQD,EAQjB,IACQJ,EAASW,oBACTX,EAASY,QACTZ,EAASW,kBAAkBL,EAAUA,GAGjCG,IACAH,GAAY,EACZO,WAAW,KACPb,EAASW,kBAAkBL,EAAUA,IACtC,IAIf,CAAE,MAAOP,GAAI,CACjB,KAAO,CAKH,GAD8Be,KAAKC,OAAOC,UACxB,CAGd,MAAMC,EAAwBH,KAAKI,MAAMD,SACnCE,EAA4BC,SAASC,cAAc,SACzDF,EAAQG,MAAMC,MAAQ,MACtBJ,EAAQG,MAAME,OAAS,MACvBL,EAAQG,MAAMG,QAAU,IACxBN,EAAQG,MAAMI,SAAW,OACzBT,EAASU,YAAYR,GACrBA,EAAQP,QACRK,EAASW,YAAYT,EACzB,CACJ,CA7EgB,IAACZ,EAgFjBO,KAAKe,0BAGLf,KAAKgB,MAAMC,qBAAsB,EAGjCjB,KAAKkB,wBAAwB,CAAEC,UAAW,qBAAsBC,YAAY,GAChF,EA0DIC,mBAnDJ,SAA4BpC,GACxBe,KAAKsB,uBAAwB,EAC7B,MAAMpC,EAAwBD,EAAEE,OAEhC,GAAID,aAAoBE,kBAAoBF,aAAoBqC,gBAAiB,CAC7EvB,KAAKkB,wBAAwB,CAAEC,UAAW,qBAAsBK,oBAAoB,IAEpF,MAAMC,EAAOvC,EAASwC,aAAa,SAAWxC,EAASwC,aAAa,WACpE1B,KAAK2B,UAAUC,kBAAkB,CAAET,UAAW,qBAAsBM,QACxE,CACJ,EA0CII,eA7BJ,WACI,MAAMC,EAA0BC,EAAUzB,SAAU,QACpDwB,EAAOtB,MAAMwB,OAAS,UAEtBC,EAAGH,EAAQ,WAAY9B,KAAKhB,kBAG5BgB,KAAKgB,MAAMC,qBAAsB,CACrC,EAsBIF,wBApBJ,WACI,IAAKmB,EAAGC,SAAU,OAAO,EAEzB,MAAML,EAA0BC,EAAUzB,SAAU,QAGpD,OAFAwB,EAAOtB,MAAMwB,OAAS,OACtBI,EAAIN,EAAQ,WAAY9B,KAAKhB,mBACtB,CACX,EAcIqD,0BAZJ,WACI,QAAKH,EAAGC,WAERC,EAAI9B,SAAU,aAAcN,KAAKqB,qBAC1B,EACX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentedControl.js","sources":["../../../../../src/components/internal/SegmentedControl/SegmentedControl.tsx"],"sourcesContent":["import { h } from 'preact';\nimport cx from 'classnames';\nimport './SegmentedControl.scss';\n\
|
|
1
|
+
{"version":3,"file":"SegmentedControl.js","sources":["../../../../../src/components/internal/SegmentedControl/SegmentedControl.tsx"],"sourcesContent":["import { h } from 'preact';\nimport cx from 'classnames';\nimport './SegmentedControl.scss';\n\nexport interface SegmentedControlOption<T> {\n label: string;\n value: T;\n id: string;\n controls: string;\n htmlProps?: {};\n}\n\nexport type SegmentedControlOptions<T> = Array<SegmentedControlOption<T>>;\n\nexport interface SegmentedControlProps<T> {\n classNameModifiers?: string[];\n selectedValue: T;\n disabled?: boolean;\n options: SegmentedControlOptions<T>;\n onChange(value: T, event: MouseEvent): void;\n}\n\n/**\n *\n * example:\n * <SegmentedControl\n * onChange={(value) = setMode(value)}\n * selectedValue={mode}\n * disabled={status === 'loading'}\n * classNameModifiers={['css-class']}\n * options={segmentedControlOptions}\n * />\n *\n * @param classNameModifiers\n * @param selectedValue\n * @param disabled\n * @param options\n * @param onChange\n * @constructor\n */\nfunction SegmentedControl<T>({ classNameModifiers = [], selectedValue, disabled = false, options, onChange }: SegmentedControlProps<T>) {\n if (!options || options.length === 0) {\n return null;\n }\n\n return (\n <div\n className={cx(\n 'adyen-checkout__segmented-control',\n { 'adyen-checkout__segmented-control--disabled': disabled },\n ...classNameModifiers.map(modifier => `adyen-checkout__segmented-control--${modifier}`)\n )}\n role=\"group\"\n >\n {options.map(({ label, value, controls, htmlProps }: SegmentedControlOption<T>) => (\n <button\n disabled={disabled}\n key={value}\n onClick={(event: MouseEvent) => onChange(value, event)}\n className={cx('adyen-checkout__segmented-control-segment', {\n 'adyen-checkout__segmented-control-segment--selected': selectedValue === value\n })}\n aria-controls={controls}\n aria-expanded={selectedValue === value}\n type=\"button\"\n {...htmlProps}\n >\n {selectedValue === value && <span className=\"adyen-checkout-checkmark\"></span>}\n {label}\n </button>\n ))}\n </div>\n );\n}\n\nexport default SegmentedControl;\n"],"names":["SegmentedControl","classNameModifiers","selectedValue","disabled","options","onChange","length","h","div","className","cx","map","modifier","role","label","value","controls","htmlProps","button","key","onClick","event","aria-controls","aria-expanded","type","span"],"mappings":"kHAwCA,SAASA,GAAoBC,mBAAEA,EAAqB,GAAEC,cAAEA,EAAaC,SAAEA,GAAW,EAAKC,QAAEA,EAAOC,SAAEA,IAC9F,OAAKD,GAA8B,IAAnBA,EAAQE,OAKpBC,EAACC,MAAAA,CACGC,UAAWC,EACP,oCACA,CAAE,8CAA+CP,MAC9CF,EAAmBU,IAAIC,GAAY,sCAAsCA,MAEhFC,KAAK,SAEJT,EAAQO,IAAI,EAAGG,QAAOC,QAAOC,WAAUC,eACpCV,EAACW,SAAAA,CACGf,SAAUA,EACVgB,IAAKJ,EACLK,QAAUC,GAAsBhB,EAASU,EAAOM,GAChDZ,UAAWC,EAAG,4CAA6C,CACvD,sDAAuDR,IAAkBa,IAE7EO,gBAAeN,EACfO,gBAAerB,IAAkBa,EACjCS,KAAK,YACDP,GAEHf,IAAkBa,GAASR,EAACkB,OAAAA,CAAKhB,UAAU,6BAC3CK,KA1BN,IA+Bf"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createElement as t}from"../../../external/preact/dist/preact.js";import e from"../BaseElement/BaseElement.js";import s from"../PayButton/PayButton.js";import{assertIsDropin as i,getRegulatoryDefaults as n,sanitizeResponse as o,verifyPaymentDidNotFail as r,cleanupFinalResult as a}from"./utils.js";import h,{NETWORK_ERROR as l}from"../../../core/Errors/AdyenCheckoutError.js";import{hasOwnProperty as d}from"../../../utils/hasOwnProperty.js";import{ANALYTICS_SUBMIT_STR as c,ANALYTICS_ERROR_TYPE as p}from"../../../core/Analytics/constants.js";import m from"../../../core/Errors/CancelError.js";import{AnalyticsLogEvent as u}from"../../../core/Analytics/AnalyticsLogEvent.js";import{AnalyticsErrorEvent as y}from"../../../core/Analytics/AnalyticsErrorEvent.js";function f(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}class R extends e{buildElementProps(t){const e={showPayButton:!0,...this.core.getCorePropsForComponent(),...!!t?.isStoredPaymentMethod?{}:this.getPaymentMethodFromPaymentMethodsResponse(t?.type),...t},s=i(this);this.props=this.formatProps({...this.constructor.defaultProps,...n(this.core.options.countryCode,s),...e})}getPaymentMethodFromPaymentMethodsResponse(t){return this.core.paymentMethodsResponse
|
|
1
|
+
import{createElement as t}from"../../../external/preact/dist/preact.js";import e from"../BaseElement/BaseElement.js";import s from"../PayButton/PayButton.js";import{assertIsDropin as i,getRegulatoryDefaults as n,sanitizeResponse as o,verifyPaymentDidNotFail as r,cleanupFinalResult as a}from"./utils.js";import h,{NETWORK_ERROR as l}from"../../../core/Errors/AdyenCheckoutError.js";import{hasOwnProperty as d}from"../../../utils/hasOwnProperty.js";import{ANALYTICS_SUBMIT_STR as c,ANALYTICS_ERROR_TYPE as p}from"../../../core/Analytics/constants.js";import m from"../../../core/Errors/CancelError.js";import{AnalyticsLogEvent as u}from"../../../core/Analytics/AnalyticsLogEvent.js";import{AnalyticsErrorEvent as y}from"../../../core/Analytics/AnalyticsErrorEvent.js";function f(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}class R extends e{buildElementProps(t){const e={showPayButton:!0,...this.core.getCorePropsForComponent(),...!!t?.isStoredPaymentMethod?{}:this.getPaymentMethodFromPaymentMethodsResponse(t?.type),...t},s=i(this);this.props=this.formatProps({...this.constructor.defaultProps,...n(this.core.options.countryCode,s),...e})}getPaymentMethodFromPaymentMethodsResponse(t){return this.core.paymentMethodsResponse?.find(t||this.constructor.type)}storeElementRefOnCore(t){t?.isDropin||this.core.storeElementReference(this)}isAvailable(){return Promise.resolve()}setState(t){this.state={...this.state,...t},this.onChange()}showValidation(){return this.componentRef&&this.componentRef.showValidation&&this.componentRef.showValidation(),this}setElementStatus(t,e){return this.elementRef?.setStatus(t,e),this}setStatus(t,e){return this.componentRef?.setStatus&&this.componentRef.setStatus(t,e),this}onChange(){this.props.onChange?.({data:this.data,isValid:this.isValid,errors:this.state.errors,valid:this.state.valid},this.elementRef)}setUpAnalytics(t){const e=this.props.session?.id;return this.props.modules.analytics.setUp({...t,...e&&{sessionId:e}})}submitAnalytics(t){try{t.component=this.getComponent(t),this.props.modules.analytics.sendAnalytics(t)}catch(t){console.warn("Failed to submit the analytics event. Error:",t)}}getComponent({component:t}){return t||(this.constructor.analyticsType?this.constructor.analyticsType:"scheme"===this.constructor.type||"bcmc"===this.constructor.type?this.constructor.type:this.type)}submit(){this.isValid?this.makePaymentsCall().then(o).then(r).then(this.handleResponse).catch(t=>{t instanceof m?this.setElementStatus("ready"):this.handleFailedResult(t)}):this.showValidation()}makePaymentsCall(){if(this.setElementStatus("loading"),this.props.onSubmit)return this.submitUsingAdvancedFlow();if(this.core.session){return(this.props.beforeSubmit?new Promise((t,e)=>this.props.beforeSubmit(this.data,this.elementRef,{resolve:t,reject:()=>e(new m("beforeSubmitRejected"))})):Promise.resolve(this.data)).then(this.submitUsingSessionsFlow)}this.handleError(new h("IMPLEMENTATION_ERROR",'It can not perform /payments call. Callback "onSubmit" is missing or Checkout session is not available'))}async submitUsingAdvancedFlow(){return new Promise((t,e)=>{const s=new u({type:c,message:"Shopper clicked pay"});this.submitAnalytics(s),this.props.onSubmit({data:this.data,isValid:this.isValid},this.elementRef,{resolve:t,reject:e})})}async submitUsingSessionsFlow(t){const e=new u({type:c,message:"Shopper clicked pay"});this.submitAnalytics(e);try{return await this.core.session.submitPayment(t)}catch(t){return t instanceof h?this.handleError(t):this.handleError(new h("ERROR","Error when making /payments call",{cause:t})),Promise.reject(t)}}onComplete(t){this.props.onComplete&&this.props.onComplete(t,this.elementRef)}handleAdditionalDetails(t){this.makeAdditionalDetailsCall(t).then(o).then(r).then(this.handleResponse).catch(this.handleFailedResult)}makeAdditionalDetailsCall(t){return this.props.onAdditionalDetails?new Promise((e,s)=>{this.props.onAdditionalDetails(t,this.elementRef,{resolve:e,reject:s})}):this.core.session?this.submitAdditionalDetailsUsingSessionsFlow(t.data):void this.handleError(new h("IMPLEMENTATION_ERROR",'It can not perform /payments/details call. Callback "onAdditionalDetails" is missing or Checkout session is not available'))}async submitAdditionalDetailsUsingSessionsFlow(t){try{return await this.core.session.submitDetails(t)}catch(t){return t instanceof h?this.handleError(t):this.handleError(new h("ERROR","Error when making /details call",{cause:t})),Promise.reject(t)}}handleAction(t,e={}){if(!t||!t.type){if(d(t,"action")&&d(t,"resultCode"))throw new Error('handleAction::Invalid Action - the passed action object itself has an "action" property and a "resultCode": have you passed in the whole response object by mistake?');throw new Error('handleAction::Invalid Action - the passed action object does not have a "type" property')}const s=this.core.createFromAction(t,{...this.elementRef.props,...e,onAdditionalDetails:this.handleAdditionalDetails});return s?(this.unmount(),s.mount(this._node)):null}onActionHandled(t){this.props?.onActionHandled?.({originalAction:this.props.originalAction,...t})}handleResponse(t){t.action?this.elementRef.handleAction(t.action):t.order?.remainingAmount?.value>0?this.handleOrder(t):this.handleSuccessResult(t)}handleKeyPress(t){"Enter"!==t.key&&"Enter"!==t.code||(t.preventDefault(),this.onEnterKeyPressed(document?.activeElement,this))}onEnterKeyPressed(t,e){this.props.onEnterKeyPressed?this.props.onEnterKeyPressed(t,e):(t.blur(),this.submit())}updateParent(t={}){return this.elementRef.core.update(t)}get isValid(){return!1}get icon(){const t=this.props.paymentMethodType||this.type;return this.props.icon??this.resources.getImage()(t)}get displayName(){const t=this.core.paymentMethodsResponse?.paymentMethods?.find(t=>t.type===this.type);return this.props.name||t?.name||this.type}get accessibleName(){return this.displayName}get additionalInfo(){return null}get type(){return this.props.type||this.constructor.type}async handleAdvanceFlowPaymentMethodsUpdate(t,e){return new Promise((e,s)=>{if(!this.props.onPaymentMethodsRequest)return e();this.props.onPaymentMethodsRequest({...t&&{order:{orderData:t.orderData,pspReference:t.pspReference}},locale:this.core.options.locale},{resolve:e,reject:s})}).catch(t=>{this.handleError(new h("IMPLEMENTATION_ERROR","Something failed during payment methods update or onPaymentMethodsRequest was not implemented",{cause:t}))}).then(s=>this.core.update({...s&&{paymentMethodsResponse:s},order:t,amount:t?t.remainingAmount:e}))}constructor(e,n){super(e,n),f(this,"componentRef",void 0),f(this,"resources",void 0),f(this,"elementRef",void 0),f(this,"handleError",t=>{if(this.setElementStatus("ready"),t.name===l&&t.options.code){const e=new y({errorType:p.apiError,code:t.options.code});this.submitAnalytics(e)}this.props.onError&&this.props.onError(t,this.elementRef)}),f(this,"handleOrder",t=>{const{order:e}=t;(this.core.session?this.core.update({order:e}):this.handleAdvanceFlowPaymentMethodsUpdate(e)).then(()=>{this.props.onOrderUpdated?.({order:e})})}),f(this,"handleFailedResult",t=>{i(this.elementRef)&&this.elementRef.displayFinalAnimation("error"),a(t),this.props.onPaymentFailed?.(t,this.elementRef)}),f(this,"handleSuccessResult",t=>{i(this.elementRef)&&this.elementRef.displayFinalAnimation("success"),a(t),this.props.onPaymentCompleted?.(t,this.elementRef)}),f(this,"setComponentRef",t=>{this.componentRef=t}),f(this,"payButton",e=>t(s,{...e,amount:this.props.amount,secondaryAmount:this.props.secondaryAmount,onClick:this.submit})),this.core.register(this.constructor),this.submit=this.submit.bind(this),this.setState=this.setState.bind(this),this.onComplete=this.onComplete.bind(this),this.handleAction=this.handleAction.bind(this),this.handleOrder=this.handleOrder.bind(this),this.handleAdditionalDetails=this.handleAdditionalDetails.bind(this),this.handleResponse=this.handleResponse.bind(this),this.setElementStatus=this.setElementStatus.bind(this),this.submitAnalytics=this.submitAnalytics.bind(this),this.makePaymentsCall=this.makePaymentsCall.bind(this),this.makeAdditionalDetailsCall=this.makeAdditionalDetailsCall.bind(this),this.submitUsingSessionsFlow=this.submitUsingSessionsFlow.bind(this),this.elementRef=n&&n.elementRef||this,this.resources=this.props.modules?this.props.modules.resources:void 0,this.storeElementRefOnCore(this.props),this.onEnterKeyPressed=this.onEnterKeyPressed.bind(this),this.onActionHandled=this.onActionHandled.bind(this)}}f(R,"type",void 0),f(R,"txVariants",[]);export{R as UIElement,R as default};
|
|
2
2
|
//# sourceMappingURL=UIElement.js.map
|