diff --git a/src/libs/actions/BankAccounts.js b/src/libs/actions/BankAccounts.js
index 53fe6511b5d1..9f6f808e8cbc 100644
--- a/src/libs/actions/BankAccounts.js
+++ b/src/libs/actions/BankAccounts.js
@@ -310,17 +310,31 @@ function connectBankAccountManually(bankAccountID, accountNumber, routingNumber,
}, getVBBADataForOnyx());
}
+/**
+ * Verify the user's identity via Onfido
+ *
+ * @param {Number} bankAccountID
+ * @param {Object} onfidoData
+ */
+function verifyIdentityForBankAccount(bankAccountID, onfidoData) {
+ API.write('VerifyIdentityForBankAccount', {
+ bankAccountID,
+ onfidoData: JSON.stringify(onfidoData),
+ }, getVBBADataForOnyx());
+}
+
export {
addPersonalBankAccount,
connectBankAccountManually,
- deletePaymentBankAccount,
clearPersonalBankAccount,
clearPlaid,
clearOnfidoToken,
- updatePersonalInformationForBankAccount,
- validateBankAccount,
- updateCompanyInformationForBankAccount,
- updateBeneficialOwnersForBankAccount,
connectBankAccountWithPlaid,
+ deletePaymentBankAccount,
+ updateBeneficialOwnersForBankAccount,
+ updateCompanyInformationForBankAccount,
+ updatePersonalInformationForBankAccount,
updatePlaidData,
+ validateBankAccount,
+ verifyIdentityForBankAccount,
};
diff --git a/src/pages/ReimbursementAccount/BankAccountStep.js b/src/pages/ReimbursementAccount/BankAccountStep.js
index 59c94c7688a6..048f38fe3fd0 100644
--- a/src/pages/ReimbursementAccount/BankAccountStep.js
+++ b/src/pages/ReimbursementAccount/BankAccountStep.js
@@ -26,6 +26,7 @@ import CONFIG from '../../CONFIG';
import ROUTES from '../../ROUTES';
import Button from '../../components/Button';
import plaidDataPropTypes from './plaidDataPropTypes';
+import reimbursementAccountPropTypes from './reimbursementAccountPropTypes';
const propTypes = {
/** Contains plaid data */
@@ -37,6 +38,10 @@ const propTypes = {
/** During the OAuth flow we need to use the plaidLink token that we initially connected with */
plaidLinkOAuthToken: PropTypes.string,
+ /** The bank account currently in setup */
+ /* eslint-disable-next-line react/no-unused-prop-types */
+ reimbursementAccount: reimbursementAccountPropTypes,
+
/** Object with various information about the user */
user: PropTypes.shape({
/** Is the user account validated? */
@@ -52,6 +57,7 @@ const defaultProps = {
plaidData: {
isPlaidDisabled: false,
},
+ reimbursementAccount: {},
user: {},
};
diff --git a/src/pages/ReimbursementAccount/CompanyStep.js b/src/pages/ReimbursementAccount/CompanyStep.js
index ec3aef995f6b..0f122c1fbda4 100644
--- a/src/pages/ReimbursementAccount/CompanyStep.js
+++ b/src/pages/ReimbursementAccount/CompanyStep.js
@@ -26,8 +26,18 @@ import AddressForm from './AddressForm';
import ReimbursementAccountForm from './ReimbursementAccountForm';
import * as ReimbursementAccount from '../../libs/actions/ReimbursementAccount';
import * as ReimbursementAccountUtils from '../../libs/ReimbursementAccountUtils';
+import reimbursementAccountPropTypes from './reimbursementAccountPropTypes';
+import reimbursementAccountDraftPropTypes from './ReimbursementAccountDraftPropTypes';
const propTypes = {
+ /** The bank account currently in setup */
+ /* eslint-disable-next-line react/no-unused-prop-types */
+ reimbursementAccount: reimbursementAccountPropTypes.isRequired,
+
+ /** The draft values of the bank account being setup */
+ /* eslint-disable-next-line react/no-unused-prop-types */
+ reimbursementAccountDraft: reimbursementAccountDraftPropTypes.isRequired,
+
...withLocalizePropTypes,
};
diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountDraftPropTypes.js b/src/pages/ReimbursementAccount/ReimbursementAccountDraftPropTypes.js
index 2261c0b472d6..98cbd1fdc0da 100644
--- a/src/pages/ReimbursementAccount/ReimbursementAccountDraftPropTypes.js
+++ b/src/pages/ReimbursementAccount/ReimbursementAccountDraftPropTypes.js
@@ -33,7 +33,7 @@ export default PropTypes.shape({
requestorAddressZipCode: PropTypes.string,
dob: PropTypes.string,
ssnLast4: PropTypes.string,
- isControllingOfficer: PropTypes.string,
+ isControllingOfficer: PropTypes.bool,
isOnfidoSetupComplete: PropTypes.bool,
/** Props needed for ACHContractStep */
diff --git a/src/pages/ReimbursementAccount/RequestorOnfidoStep.js b/src/pages/ReimbursementAccount/RequestorOnfidoStep.js
new file mode 100644
index 000000000000..0101bd216c5f
--- /dev/null
+++ b/src/pages/ReimbursementAccount/RequestorOnfidoStep.js
@@ -0,0 +1,90 @@
+import React from 'react';
+import {ScrollView} from 'react-native';
+import {withOnyx} from 'react-native-onyx';
+import PropTypes from 'prop-types';
+import styles from '../../styles/styles';
+import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
+import * as BankAccounts from '../../libs/actions/BankAccounts';
+import Onfido from '../../components/Onfido';
+import compose from '../../libs/compose';
+import ONYXKEYS from '../../ONYXKEYS';
+import * as ReimbursementAccountUtils from '../../libs/ReimbursementAccountUtils';
+import Growl from '../../libs/Growl';
+import reimbursementAccountPropTypes from './reimbursementAccountPropTypes';
+import reimbursementAccountDraftPropTypes from './ReimbursementAccountDraftPropTypes';
+import CONST from '../../CONST';
+
+const propTypes = {
+ /** Bank account currently in setup */
+ /* eslint-disable-next-line react/no-unused-prop-types */
+ reimbursementAccount: reimbursementAccountPropTypes.isRequired,
+
+ /** The draft values of the bank account being setup */
+ /* eslint-disable-next-line react/no-unused-prop-types */
+ reimbursementAccountDraft: reimbursementAccountDraftPropTypes.isRequired,
+
+ /** The token required to initialize the Onfido SDK */
+ onfidoToken: PropTypes.string.isRequired,
+
+ /** A callback to call once the user completes the Onfido flow */
+ onComplete: PropTypes.func.isRequired,
+
+ ...withLocalizePropTypes,
+};
+
+const defaultProps = {};
+
+class RequestorOnfidoStep extends React.Component {
+ constructor(props) {
+ super(props);
+ this.submit = this.submit.bind(this);
+ }
+
+ submit(onfidoData) {
+ BankAccounts.verifyIdentityForBankAccount(
+ ReimbursementAccountUtils.getDefaultStateForField(this.props, 'bankAccountID', 0),
+ onfidoData,
+ );
+ this.props.onComplete();
+ }
+
+ render() {
+ return (
+
+ {
+ // We're taking the user back to the company step. They will need to come back to the requestor step to make the Onfido flow appear again.
+ BankAccounts.goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.COMPANY);
+ }}
+ onError={() => {
+ // In case of any unexpected error we log it to the server, show a growl, and return the user back to the company step so they can try again.
+ Growl.error(this.props.translate('onfidoStep.genericError'), 10000);
+ BankAccounts.goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.COMPANY);
+ }}
+ onSuccess={(onfidoData) => {
+ this.submit(onfidoData);
+ }}
+ />
+
+ );
+ }
+}
+
+RequestorOnfidoStep.propTypes = propTypes;
+RequestorOnfidoStep.defaultProps = defaultProps;
+
+export default compose(
+ withLocalize,
+ withOnyx({
+ reimbursementAccount: {
+ key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
+ },
+ onfidoToken: {
+ key: ONYXKEYS.ONFIDO_TOKEN,
+ },
+ reimbursementAccountDraft: {
+ key: ONYXKEYS.REIMBURSEMENT_ACCOUNT_DRAFT,
+ },
+ }),
+)(RequestorOnfidoStep);
diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js
index 6be190673464..70e00a46b96e 100644
--- a/src/pages/ReimbursementAccount/RequestorStep.js
+++ b/src/pages/ReimbursementAccount/RequestorStep.js
@@ -1,6 +1,6 @@
import React from 'react';
import lodashGet from 'lodash/get';
-import {ScrollView, View} from 'react-native';
+import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import moment from 'moment';
@@ -16,19 +16,26 @@ import Text from '../../components/Text';
import * as BankAccounts from '../../libs/actions/BankAccounts';
import IdentityForm from './IdentityForm';
import * as ValidationUtils from '../../libs/ValidationUtils';
-import Onfido from '../../components/Onfido';
import compose from '../../libs/compose';
import ONYXKEYS from '../../ONYXKEYS';
import * as ReimbursementAccountUtils from '../../libs/ReimbursementAccountUtils';
-import Growl from '../../libs/Growl';
import reimbursementAccountPropTypes from './reimbursementAccountPropTypes';
+import reimbursementAccountDraftPropTypes from './ReimbursementAccountDraftPropTypes';
import ReimbursementAccountForm from './ReimbursementAccountForm';
import * as Link from '../../libs/actions/Link';
+import RequestorOnfidoStep from './RequestorOnfidoStep';
const propTypes = {
- /** Bank account currently in setup */
+ /** The bank account currently in setup */
reimbursementAccount: reimbursementAccountPropTypes.isRequired,
+
+ /** The draft values of the bank account being setup */
+ /* eslint-disable-next-line react/no-unused-prop-types */
+ reimbursementAccountDraft: reimbursementAccountDraftPropTypes.isRequired,
+
+ /** The token required to initialize the Onfido SDK */
onfidoToken: PropTypes.string,
+
...withLocalizePropTypes,
};
@@ -42,6 +49,7 @@ class RequestorStep extends React.Component {
this.submit = this.submit.bind(this);
this.clearErrorsAndSetValues = this.clearErrorsAndSetValues.bind(this);
+ this.setOnfidoAsComplete = this.setOnfidoAsComplete.bind(this);
this.state = {
firstName: ReimbursementAccountUtils.getDefaultStateForField(props, 'firstName'),
@@ -53,7 +61,6 @@ class RequestorStep extends React.Component {
dob: ReimbursementAccountUtils.getDefaultStateForField(props, 'dob'),
ssnLast4: ReimbursementAccountUtils.getDefaultStateForField(props, 'ssnLast4'),
isControllingOfficer: ReimbursementAccountUtils.getDefaultStateForField(props, 'isControllingOfficer', false),
- onfidoData: lodashGet(props, ['reimbursementAccount', 'achData', 'onfidoData'], ''),
isOnfidoSetupComplete: lodashGet(props, ['achData', 'isOnfidoSetupComplete'], false),
};
@@ -74,6 +81,13 @@ class RequestorStep extends React.Component {
this.getErrors = () => ReimbursementAccountUtils.getErrors(this.props);
}
+ /**
+ * Update state to indicate that the user has completed the Onfido verification process
+ */
+ setOnfidoAsComplete() {
+ this.setState({isOnfidoSetupComplete: true});
+ }
+
/**
* Clear the errors associated to keys in values if found and store the new values in the state.
*
@@ -147,20 +161,6 @@ class RequestorStep extends React.Component {
BankAccounts.updatePersonalInformationForBankAccount(payload);
}
- submitOnfidoVerification() {
- if (!this.validate()) {
- return;
- }
-
- const payload = {
- bankAccountID: ReimbursementAccountUtils.getDefaultStateForField(this.props, 'bankAccountID', 0),
- ...this.state,
- dob: moment(this.state.dob).format(CONST.DATE.MOMENT_FORMAT_STRING),
- };
-
- BankAccounts.setupWithdrawalAccount(payload);
- }
-
render() {
const achData = this.props.reimbursementAccount.achData;
const shouldShowOnfido = achData.useOnfido && this.props.onfidoToken && !this.state.isOnfidoSetupComplete;
@@ -183,26 +183,9 @@ class RequestorStep extends React.Component {
onCloseButtonPress={Navigation.dismissModal}
/>
{shouldShowOnfido ? (
-
- {
- // We're taking the user back to the company step. They will need to come back to the requestor step to make the Onfido flow appear again.
- BankAccounts.goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.COMPANY);
- }}
- onError={() => {
- // In case of any unexpected error we log it to the server, show a growl, and return the user back to the company step so they can try again.
- Growl.error(this.props.translate('onfidoStep.genericError'), 10000);
- BankAccounts.goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.COMPANY);
- }}
- onSuccess={(onfidoData) => {
- this.setState({
- onfidoData,
- isOnfidoSetupComplete: true,
- }, this.submitOnfidoVerification);
- }}
- />
-
+
) : (