import Button from '@mui/material/Button' import { AxiosError } from 'axios' import _identity from 'lodash/identity' import _isEmpty from 'lodash/isEmpty' import React, { useEffect, useState } from 'react' import { checkCustomerOrder, checkVerificationStatus, getNetverifyUrl, updateVerificationStatus, } from '../../api' import { GetNetverifyUrlResponseData, VerificationStatusResponseData, } from '../../types/verification' import { getQueryVariable, isBrowser, isJson } from '../../utils' import Modal from '../common/ModalComponent' import { VERIFICATION_MESSAGES, VERIFICATION_PROVIDERS, VERIFICATION_STATUSES, } from './constants' interface IDVerificationProps { onGetVerifyUrlSuccess?: (response: GetNetverifyUrlResponseData) => void; onGetVerifyUrlError?: (error: AxiosError) => void; onGetVerificationStatusSuccess?: (response: { data: VerificationStatusResponseData; }) => void; onGetVerificationStatusError?: (error: AxiosError) => void; onVerificationMessageModalClose?: (status: string | null) => void; onPassVerificationStepsSuccess?: () => void; onPassVerificationStepsError?: (error: AxiosError | null) => void; } export const IDVerification = (props: IDVerificationProps) => { const { onGetVerifyUrlSuccess = _identity, onGetVerifyUrlError = _identity, onGetVerificationStatusSuccess = _identity, onGetVerificationStatusError = _identity, onVerificationMessageModalClose = _identity, onPassVerificationStepsSuccess = _identity, onPassVerificationStepsError = _identity, } = props const [loadingStatus, setLoadingStatus] = useState(true) const [verificationStatus, setVerificationStatus] = useState(null) const [showModal, setShowModal] = useState(false) const [netverifyUrl, setNetverifyUrl] = useState(null) const [provider, setProvider] = useState(null) const [hasError, setHasError] = useState(false) const [lastError, setLastError] = useState(null) const [modalData, setModalData] = useState({ message: '', hideCancelBtn: true, displaModal: false, }) const isAccountVerifiedOrPending = (verificationStatus === VERIFICATION_STATUSES.APPROVED || verificationStatus === VERIFICATION_STATUSES.PENDING) && verificationStatus !== VERIFICATION_STATUSES.WRONG_CUSTOMER const handleClose = () => { setModalData({ message: '', displaModal: false, hideCancelBtn: true, }) onVerificationMessageModalClose(verificationStatus) } useEffect(() => { const callbackNetVerify = async (e: any) => { // Stripe Events if (e.data && e.origin === 'https://verify.stripe.com') { const { data } = e if (data.type === 'STRIPE_IDENTITY_CLOSE') { await getUrl() setShowModal(false) if (hasError) { setHasError(false) onPassVerificationStepsError(lastError) } else { setHasError(false) onPassVerificationStepsSuccess() } } else if (data.type === 'STRIPE_IDENTITY_ERROR') { setHasError(true) setLastError(data) } } if (e.data && isJson(e.data)) { try { const result = JSON.parse(e.data) if ( result.payload && (result.payload.value === 'success' || result.payload.transactionStatus === 'SUCCESS') ) { await updateVerificationStatus() onPassVerificationStepsSuccess() } else if ( result.payload && (result.payload.value === 'error' || result.payload.transactionStatus === 'ERROR') ) { setShowModal(false) onPassVerificationStepsError(result.payload) } } catch (e) { onPassVerificationStepsError(e) } } } window.addEventListener('message', callbackNetVerify) return () => { window.removeEventListener('message', callbackNetVerify) } }, []) const getUrl = async () => { try { const urlResponse = await getNetverifyUrl() setNetverifyUrl(urlResponse.netverifyUrl) setProvider(urlResponse.provider) onGetVerifyUrlSuccess(urlResponse) } catch (error) { onGetVerifyUrlError(error) } } useEffect(() => { let intervalId: any = null const orderHash = getQueryVariable('order_hash') || '' const getVerificationStatus = async () => { try { let verificationStatus = null // Gets te current status of the variable without modifying it setVerificationStatus(status => { verificationStatus = status return status }) let provider = null // Gets te current status of the variable without modifying it setProvider(state => { provider = state return provider }) let verifyUrl = null // Gets te current status of the variable without modifying it setNetverifyUrl(state => { verifyUrl = state return state }) const statusResponse = await checkVerificationStatus() const { status } = statusResponse.data.attributes const isApproved = status === VERIFICATION_STATUSES.APPROVED if (verificationStatus !== status) { setVerificationStatus(status) setModalData({ displaModal: isApproved || status === VERIFICATION_STATUSES.FAILED, hideCancelBtn: true, message: isApproved ? VERIFICATION_MESSAGES.APPROVED : status === VERIFICATION_STATUSES.FAILED ? VERIFICATION_MESSAGES.FAILED : status, }) } if ( provider === VERIFICATION_PROVIDERS.STRIPE && verifyUrl === null && !isApproved ) { getUrl() } onGetVerificationStatusSuccess(statusResponse) } catch (error) { onGetVerificationStatusError(error) } finally { setLoadingStatus(false) } } const getCustomerOrderStatus = async () => { const customerOrderResponse = await checkCustomerOrder(orderHash) return customerOrderResponse } const makeRequests = async () => { try { if (orderHash) { await getCustomerOrderStatus() } getUrl() getVerificationStatus() // Check the verification status every 30 seconds intervalId = setInterval(() => { getVerificationStatus() }, 10000) } catch (error) { if (error.response?.data?.message === VERIFICATION_MESSAGES.WRONG_CUSTOMER) { setVerificationStatus(VERIFICATION_STATUSES.WRONG_CUSTOMER) setModalData({ displaModal: true, hideCancelBtn: true, message: VERIFICATION_MESSAGES.WRONG_CUSTOMER, }) } } } makeRequests() // Clear the interval when the component unmounts return () => clearInterval(intervalId) }, []) const iframe = (netverifyUrl: string) => { // eslint-disable-next-line max-len const iframe = `` return { __html: iframe, } } useEffect(() => { const orderHash = getQueryVariable('order_hash') if (isBrowser) { const checkoutData = JSON.parse(window.localStorage.getItem('checkoutData') || '{}') if (_isEmpty(checkoutData) && orderHash) { window.localStorage.setItem('checkoutData', JSON.stringify({ hash: orderHash })) } } }, []) return (

Account Verification

{loadingStatus ? null : ( <> {!isAccountVerifiedOrPending && (
To complete the purchase, please verify your identity.
)} {verificationStatus === VERIFICATION_STATUSES.APPROVED && (
{VERIFICATION_MESSAGES.APPROVED}
)} {(verificationStatus === VERIFICATION_STATUSES.PENDING || (provider === VERIFICATION_PROVIDERS.STRIPE && netverifyUrl === null && verificationStatus !== VERIFICATION_STATUSES.APPROVED)) && (
{VERIFICATION_MESSAGES.PENDING}
)} {!isAccountVerifiedOrPending && netverifyUrl !== null && ( )} )} {modalData.displaModal && (
{modalData.message}
)} {showModal && ( { setShowModal(false) }, }, ]} >
)}
) }