Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CP Staging] feat: Improve KYC error handling #30103

Merged
merged 9 commits into from
Oct 22, 2023
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,7 @@ export default {
assignedCards: 'Assigned cards',
assignedCardsDescription: 'These are cards assigned by a Workspace admin to manage company spend.',
expensifyCard: 'Expensify Card',
walletActivationPending: "We're reviewing your information and we'll be in touch shortly.",
},
cardPage: {
expensifyCard: 'Expensify Card',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,7 @@ export default {
assignedCards: 'Tarjetas asignadas',
assignedCardsDescription: 'Son tarjetas asignadas por un administrador del Espacio de Trabajo para gestionar los gastos de la empresa.',
expensifyCard: 'Tarjeta Expensify',
walletActivationPending: 'Estamos revisando la información y nos pondremos en contacto contigo en breve.',
},
cardPage: {
expensifyCard: 'Tarjeta Expensify',
Expand Down
14 changes: 11 additions & 3 deletions src/libs/actions/Wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,9 @@ function acceptWalletTerms(parameters) {
const optimisticData = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: ONYXKEYS.USER_WALLET,
key: ONYXKEYS.WALLET_TERMS,
value: {
shouldShowWalletActivationSuccess: true,
submitting: true,
},
},
];
Expand All @@ -227,6 +227,7 @@ function acceptWalletTerms(parameters) {
key: ONYXKEYS.WALLET_TERMS,
value: {
errors: null,
submitting: false,
},
},
];
Expand All @@ -236,10 +237,17 @@ function acceptWalletTerms(parameters) {
onyxMethod: Onyx.METHOD.MERGE,
key: ONYXKEYS.USER_WALLET,
value: {
shouldShowWalletActivationSuccess: null,
isPendingOnfidoResult: null,
shouldShowFailedKYC: true,
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: ONYXKEYS.WALLET_TERMS,
value: {
submitting: false,
},
},
];

API.write('AcceptWalletTerms', {hasAcceptedTerms: parameters.hasAcceptedTerms, reportID: parameters.chatReportID}, {optimisticData, successData, failureData});
Expand Down
14 changes: 8 additions & 6 deletions src/pages/EnablePayments/EnablePaymentsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,19 @@ function EnablePaymentsPage({userWallet}) {
const {translate} = useLocalize();
const {isOffline} = useNetwork();

const {isPendingOnfidoResult} = userWallet;

useEffect(() => {
if (isOffline) {
return;
}

Wallet.openEnablePaymentsPage();
}, [isOffline]);
if (!isPendingOnfidoResult) {
Wallet.openEnablePaymentsPage();
} else {
Navigation.navigate(ROUTES.SETTINGS_WALLET, CONST.NAVIGATION.TYPE.UP);
}
}, [isOffline, isPendingOnfidoResult]);

if (_.isEmpty(userWallet)) {
return <FullScreenLoadingIndicator />;
Expand All @@ -64,10 +70,6 @@ function EnablePaymentsPage({userWallet}) {
);
}

if (userWallet.shouldShowWalletActivationSuccess) {
return <ActivateStep userWallet={userWallet} />;
}

const currentStep = userWallet.currentStep || CONST.WALLET.STEP.ADDITIONAL_DETAILS;

switch (currentStep) {
Expand Down
1 change: 1 addition & 0 deletions src/pages/EnablePayments/TermsStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ function TermsStep(props) {
}}
message={errorMessage}
isAlertVisible={error || Boolean(errorMessage)}
isLoading={!!props.walletTerms.submitting}
containerStyles={[styles.mh0, styles.mv4]}
/>
</ScrollView>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/EnablePayments/userWalletPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export default PropTypes.shape({
/** Status of wallet - e.g. SILVER or GOLD */
tierName: PropTypes.string,

/** Whether we should show the ActivateStep success view after the user finished the KYC flow */
shouldShowWalletActivationSuccess: PropTypes.bool,
/** Whether the kyc is pending and is yet to be confirmed */
isPendingOnfidoResult: PropTypes.bool,

/** The wallet's programID, used to show the correct terms. */
walletProgramID: PropTypes.string,
Expand Down
3 changes: 3 additions & 0 deletions src/pages/EnablePayments/walletTermsPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ export default PropTypes.shape({

/** When the user accepts the Wallet's terms in order to pay an IOU, this is the ID of the chatReport the IOU is linked to */
chatReportID: PropTypes.string,

/** Boolean to indicate whether the submission of wallet terms is being processed */
submitting: PropTypes.bool,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very small change, but I think we should call this isLoading to follow our naming patterns for bool props

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handled.

});
53 changes: 39 additions & 14 deletions src/pages/settings/Wallet/WalletPage/WalletPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import compose from '../../../../libs/compose';
import * as BankAccounts from '../../../../libs/actions/BankAccounts';
import Popover from '../../../../components/Popover';
import MenuItem from '../../../../components/MenuItem';
import Text from '../../../../components/Text';
import Icon from '../../../../components/Icon';
import * as PaymentMethods from '../../../../libs/actions/PaymentMethods';
import getClickedTargetLocation from '../../../../libs/getClickedTargetLocation';
import CurrentWalletBalance from '../../../../components/CurrentWalletBalance';
Expand Down Expand Up @@ -66,6 +68,8 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen
const hasAssignedCard = !_.isEmpty(cardList);
const shouldShowEmptyState = !hasBankAccount && !hasWallet && !hasAssignedCard;

const {isPendingOnfidoResult} = userWallet;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just confirming, if isPendingOnfidoResult doesn't exist in the userWallet, then it will be undefined so do we prefer lodashGet in these cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handled!


const updateShouldShowLoadingSpinner = useCallback(() => {
// In order to prevent a loop, only update state of the spinner if there is a change
const showLoadingSpinner = isLoadingPaymentMethods || false;
Expand Down Expand Up @@ -357,6 +361,7 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen
<CurrentWalletBalance balanceStyles={[styles.walletBalance]} />
</OfflineWithFeedback>
)}

<KYCWall
onSuccessfulKYC={(_iouPaymentType, source) => navigateToWalletOrTransferBalancePage(source)}
onSelectPaymentMethod={(selectedPaymentMethod) => {
Expand All @@ -373,18 +378,38 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen
source={hasActivatedWallet ? CONST.KYC_WALL_SOURCE.TRANSFER_BALANCE : CONST.KYC_WALL_SOURCE.ENABLE_WALLET}
shouldIncludeDebitCard={hasActivatedWallet}
>
{(triggerKYCFlow, buttonRef) =>
hasActivatedWallet ? (
<MenuItem
ref={buttonRef}
title={translate('common.transferBalance')}
icon={Expensicons.Transfer}
onPress={triggerKYCFlow}
shouldShowRightIcon
disabled={network.isOffline}
wrapperStyle={styles.transferBalance}
/>
) : (
{(triggerKYCFlow, buttonRef) => {
if (shouldShowLoadingSpinner) {
return null;
}

if (hasActivatedWallet) {
return (
<MenuItem
ref={buttonRef}
title={translate('common.transferBalance')}
icon={Expensicons.Transfer}
onPress={triggerKYCFlow}
shouldShowRightIcon
disabled={network.isOffline}
wrapperStyle={styles.transferBalance}
/>
);
}

if (isPendingOnfidoResult) {
return (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.w100, styles.ph5]}>
<Icon
src={Expensicons.Hourglass}
fill={themeColors.icon}
/>
<Text style={[styles.inlineSystemMessage, styles.flexShrink1]}>{translate('walletPage.walletActivationPending')}</Text>
</View>
);
}

return (
<Button
ref={buttonRef}
text={translate('walletPage.enableWallet')}
Expand All @@ -394,8 +419,8 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen
success
large
/>
)
}
);
}}
</KYCWall>
</>
</WalletSection>
Expand Down
4 changes: 2 additions & 2 deletions src/types/onyx/UserWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ type UserWallet = {
/** The user's wallet tier */
tier?: number;

/** Whether we should show the ActivateStep success view after the user finished the KYC flow */
shouldShowWalletActivationSuccess?: boolean;
/** Whether the kyc is pending and is yet to be confirmed */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Whether the kyc is pending and is yet to be confirmed */
/** Whether the Onfido result is pending. KYC is not complete and the wallet will not be activated until we have the Onfido verification result */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handled.

isPendingOnfidoResult?: boolean;

/** The ID of the linked account */
walletLinkedAccountID: number;
Expand Down
Loading