From 995b84603e3889fcd30b3142b453391a84eb3bd7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Tue, 25 Nov 2025 08:14:28 +0100
Subject: [PATCH 01/27] feat: 75707 gather KYB files for USD flow

---
 src/languages/en.ts                           |  3 +
 .../USD/Documents/index.tsx                   | 74 +++++++++++++++++++
 .../USD/USDVerifiedBankAccountFlow.tsx        | 14 ++--
 3 files changed, 85 insertions(+), 6 deletions(-)
 create mode 100644 src/pages/ReimbursementAccount/USD/Documents/index.tsx

diff --git a/src/languages/en.ts b/src/languages/en.ts
index 26c35982959a..d939e8d1dc0e 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -3550,6 +3550,9 @@ const translations = {
         weTake: 'We take your security seriously. Please set up 2FA now to add an extra layer of protection to your account.',
         secure: 'Secure your account',
     },
+    documentsStep: {
+        subheader: 'Bank info',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: 'One moment',
         explanationLine: "We’re taking a look at your information. You'll be able to continue with next steps shortly.",
diff --git a/src/pages/ReimbursementAccount/USD/Documents/index.tsx b/src/pages/ReimbursementAccount/USD/Documents/index.tsx
new file mode 100644
index 000000000000..63d2d2f8d46c
--- /dev/null
+++ b/src/pages/ReimbursementAccount/USD/Documents/index.tsx
@@ -0,0 +1,74 @@
+import React, {useCallback} from 'react';
+import FormProvider from '@components/Form/FormProvider';
+import InputWrapper from '@components/Form/InputWrapper';
+import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
+import Text from '@components/Text';
+import UploadFile from '@components/UploadFile';
+import useLocalize from '@hooks/useLocalize';
+import useOnyx from '@hooks/useOnyx';
+import useThemeStyles from '@hooks/useThemeStyles';
+import CONST from '@src/CONST';
+import ONYXKEYS from '@src/ONYXKEYS';
+
+type DocumentsProps = {
+    /** Goes to the previous step */
+    onBackButtonPress: () => void;
+};
+
+function Documents({onBackButtonPress}: DocumentsProps) {
+    const {translate} = useLocalize();
+    const styles = useThemeStyles();
+
+    const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: false});
+    const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT, {canBeMissing: true});
+
+    const validate = () => {};
+
+    const submit = useCallback(() => {
+        console.log('submit');
+    }, []);
+
+    return (
+        <InteractiveStepWrapper
+            wrapperID={Documents.displayName}
+            shouldEnablePickerAvoiding={false}
+            shouldEnableMaxHeight
+            headerTitle={translate('documentsStep.subheader')}
+            handleBackButtonPress={onBackButtonPress}
+        >
+            <FormProvider
+                formID={ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM}
+                submitButtonText={translate('common.submit')}
+                onSubmit={submit}
+                validate={validate}
+                style={[styles.mh5, styles.flexGrow1]}
+                submitButtonStyles={[styles.mb0]}
+                enabledWhenOffline={false}
+            >
+                <Text style={[styles.textHeadlineH2, styles.colorMuted, styles.mb10]}>{translate('docusignStep.pleaseUpload')}</Text>
+                <InputWrapper
+                    InputComponent={UploadFile}
+                    buttonText={translate('common.chooseFile')}
+                    uploadedFiles={uploadedFiles}
+                    onUpload={(files) => {
+                        handleSelectFile(files);
+                    }}
+                    onRemove={(fileName) => {
+                        handleRemoveFile(fileName);
+                    }}
+                    acceptedFileTypes={[...CONST.NON_USD_BANK_ACCOUNT.ALLOWED_FILE_TYPES]}
+                    value={uploadedFiles}
+                    inputID={inputID as string}
+                    setError={(error) => {
+                        setUploadError(error);
+                    }}
+                    fileLimit={1}
+                />
+            </FormProvider>
+        </InteractiveStepWrapper>
+    );
+}
+
+Documents.displayName = 'Documents';
+
+export default Documents;
diff --git a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
index f3ca3b9c65d9..10c6735ab67f 100644
--- a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
+++ b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
@@ -10,6 +10,7 @@ import BusinessInfo from './BusinessInfo/BusinessInfo';
 import CompleteVerification from './CompleteVerification/CompleteVerification';
 import ConnectBankAccount from './ConnectBankAccount/ConnectBankAccount';
 import Country from './Country';
+import Documents from './Documents';
 import RequestorStep from './Requestor/RequestorStep';
 
 type USDVerifiedBankAccountFlowProps = {
@@ -38,12 +39,13 @@ function USDVerifiedBankAccountFlow({
     switch (USDBankAccountStep) {
         case CONST.BANK_ACCOUNT.STEP.COUNTRY:
             CurrentStep = (
-                <Country
-                    onBackButtonPress={onBackButtonPress}
-                    policyID={policyID}
-                    setUSDBankAccountStep={setUSDBankAccountStep}
-                    stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
-                />
+                <Documents onBackButtonPress={onBackButtonPress} />
+                // <Country
+                //     onBackButtonPress={onBackButtonPress}
+                //     policyID={policyID}
+                //     setUSDBankAccountStep={setUSDBankAccountStep}
+                //     stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
+                // />
             );
             break;
         case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:

From b9d72c4bb619dc23a20edbfd05fa583ae285d431 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Tue, 25 Nov 2025 15:51:54 +0100
Subject: [PATCH 02/27] feat: step v1

---
 src/languages/en.ts                           |  30 +++-
 .../USD/Documents/index.tsx                   | 155 +++++++++++++++---
 2 files changed, 161 insertions(+), 24 deletions(-)

diff --git a/src/languages/en.ts b/src/languages/en.ts
index d939e8d1dc0e..c711c77fa3f9 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -3551,7 +3551,35 @@ const translations = {
         secure: 'Secure your account',
     },
     documentsStep: {
-        subheader: 'Bank info',
+        beforeYouGo: 'Before you go, we need some documents to verify some things',
+        subheader: 'Verification',
+        verificationFailed: "The verification failed, so we'll need some extra documents to verify you and your business",
+        taxIDVerification: 'Tax ID Verification',
+        taxIDVerificationDescription: dedent(`
+            Please upload one of the following files:
+            • IRS TIN/EIN Assignment Letter
+            • IRS TIN/EIN Application confirmation (Normally states "Congratulations! The EIN has been successfully assigned")
+            • IRS tax exemption letter that lists your company name and EIN`),
+        nameChangeDocument: 'Name Change Document',
+        nameChangeDocumentDescription: 'If your company’s name has changed since filing for the TIN/EIN we need this document to verify the Tax ID number you provided',
+        companyAddressVerification: 'Company address verification',
+        companyAddressVerificationDescription: dedent(`
+            Please upload one of the following files:
+            • Recent utility bill showing company name and address
+            • Bank Statement showing company name and address
+            • Current Lease/Rental Agreement including the signature page showing your company name and current address
+            • Insurance Statement showing company name and address
+            • TIN assignment doc showing company name and address`),
+        userAddressVerification: 'Address verification',
+        userAddressVerificationDescription: dedent(`
+            Please upload one of the following files:
+            • Voter Registration Card
+            • Drivers License
+            • Bank Statement
+            • Utility Bill`),
+        userDOBVerification: 'Date of birth verification',
+        userDOBVerificationDescription: 'Please upload a US issued ID',
+        finishViaChat: 'Finish via chat',
     },
     reimbursementAccountLoadingAnimation: {
         oneMoment: 'One moment',
diff --git a/src/pages/ReimbursementAccount/USD/Documents/index.tsx b/src/pages/ReimbursementAccount/USD/Documents/index.tsx
index 63d2d2f8d46c..8c27fd6dcdcb 100644
--- a/src/pages/ReimbursementAccount/USD/Documents/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/Documents/index.tsx
@@ -1,14 +1,19 @@
-import React, {useCallback} from 'react';
+import React, {useCallback, useMemo, useState} from 'react';
+import {View} from 'react-native';
+import Button from '@components/Button';
 import FormProvider from '@components/Form/FormProvider';
 import InputWrapper from '@components/Form/InputWrapper';
+import type {FormInputErrors, FormOnyxValues} from '@components/Form/types';
 import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
 import Text from '@components/Text';
 import UploadFile from '@components/UploadFile';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
+import {clearErrorFields, setDraftValues, setErrorFields} from '@userActions/FormActions';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
+import type {FileObject} from '@src/types/utils/Attachment';
 
 type DocumentsProps = {
     /** Goes to the previous step */
@@ -22,12 +27,112 @@ function Documents({onBackButtonPress}: DocumentsProps) {
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: false});
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT, {canBeMissing: true});
 
-    const validate = () => {};
-
     const submit = useCallback(() => {
         console.log('submit');
     }, []);
 
+    const DOCUMENTS_CONFIG = useMemo(
+        () =>
+            [
+                {
+                    inputID: 'companyTaxID',
+                    title: 'documentsStep.taxIDVerification',
+                    description: 'documentsStep.taxIDVerificationDescription',
+                    required: true,
+                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('companyTaxID') ?? false,
+                },
+                {
+                    inputID: 'nameChangeDocument',
+                    title: 'documentsStep.nameChangeDocument',
+                    description: 'documentsStep.nameChangeDocumentDescription',
+                    required: true,
+                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('nameChangeDocument') ?? false,
+                },
+                {
+                    inputID: 'companyAddressVerification',
+                    title: 'documentsStep.companyAddressVerification',
+                    description: 'documentsStep.companyAddressVerificationDescription',
+                    required: true,
+                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('companyAddressVerification') ?? false,
+                },
+                {
+                    inputID: 'userAddressVerification',
+                    title: 'documentsStep.userAddressVerification',
+                    description: 'documentsStep.userAddressVerificationDescription',
+                    required: true,
+                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('userAddressVerification') ?? false,
+                },
+                {
+                    inputID: 'userDOBVerification',
+                    title: 'documentsStep.userDOBVerification',
+                    description: 'documentsStep.userDOBVerificationDescription',
+                    required: true,
+                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('userDOBVerification') ?? false,
+                },
+            ] as const,
+        [],
+    );
+
+    const [uploadedFiles, setUploadedFiles] = useState<Record<string, FileObject[]>>({
+        companyTaxID: [],
+        nameChangeDocument: [],
+        companyAddressVerification: [],
+        userAddressVerification: [],
+        userDOBVerification: [],
+    });
+
+    const validate = useCallback(
+        (values: FormOnyxValues<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> => {
+            const errors: FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> = {};
+
+            DOCUMENTS_CONFIG.filter((document) => document.required).forEach((document) => {
+                const files = values[document.inputID] as FileObject[] | undefined;
+                if (!files || files.length === 0) {
+                    errors[document.inputID] = translate('common.error.fieldRequired');
+                }
+            });
+
+            return errors;
+        },
+        [DOCUMENTS_CONFIG, translate],
+    );
+
+    const handleSelectFile = useCallback(
+        (files: FileObject[], inputID: string) => {
+            const updatedFiles = [...uploadedFiles[inputID], ...files];
+            setUploadedFiles((prev) => ({...prev, [inputID]: updatedFiles}));
+            setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: updatedFiles});
+        },
+        [uploadedFiles],
+    );
+
+    const handleRemoveFile = useCallback(
+        (fileName: string, inputID: string) => {
+            const updatedFiles = uploadedFiles[inputID].filter((file) => file.name !== fileName);
+            setUploadedFiles((prev) => ({...prev, [inputID]: updatedFiles}));
+            setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: updatedFiles});
+        },
+        [uploadedFiles],
+    );
+
+    const setUploadError = useCallback((error: string, inputID: string) => {
+        if (!error) {
+            clearErrorFields(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM);
+            return;
+        }
+        setErrorFields(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: {onUpload: error}});
+    }, []);
+
+    const requiredDocuments = DOCUMENTS_CONFIG.filter((document) => document.required);
+    const footer = (
+        <Button
+            large
+            style={[styles.mv3]}
+            text={translate('documentsStep.finishViaChat')}
+            onPress={() => {}}
+        />
+    );
+
     return (
         <InteractiveStepWrapper
             wrapperID={Documents.displayName}
@@ -38,32 +143,36 @@ function Documents({onBackButtonPress}: DocumentsProps) {
         >
             <FormProvider
                 formID={ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM}
-                submitButtonText={translate('common.submit')}
+                submitButtonText={translate('common.verify')}
                 onSubmit={submit}
                 validate={validate}
                 style={[styles.mh5, styles.flexGrow1]}
                 submitButtonStyles={[styles.mb0]}
                 enabledWhenOffline={false}
+                shouldRenderFooterAboveSubmit
+                footerContent={footer}
             >
-                <Text style={[styles.textHeadlineH2, styles.colorMuted, styles.mb10]}>{translate('docusignStep.pleaseUpload')}</Text>
-                <InputWrapper
-                    InputComponent={UploadFile}
-                    buttonText={translate('common.chooseFile')}
-                    uploadedFiles={uploadedFiles}
-                    onUpload={(files) => {
-                        handleSelectFile(files);
-                    }}
-                    onRemove={(fileName) => {
-                        handleRemoveFile(fileName);
-                    }}
-                    acceptedFileTypes={[...CONST.NON_USD_BANK_ACCOUNT.ALLOWED_FILE_TYPES]}
-                    value={uploadedFiles}
-                    inputID={inputID as string}
-                    setError={(error) => {
-                        setUploadError(error);
-                    }}
-                    fileLimit={1}
-                />
+                <Text style={[styles.textHeadlineLineHeightXXL, styles.mb5]}>{translate('documentsStep.beforeYouGo')}</Text>
+                <Text style={[styles.textSupporting, styles.mb5]}>{translate('documentsStep.verificationFailed')}</Text>
+                {requiredDocuments.map((document, index) => (
+                    <View key={document.inputID}>
+                        <Text style={[styles.textNormalThemeText, styles.textLineHeightNormal, styles.textStrong, styles.mb3]}>{translate(document.title)}</Text>
+                        <InputWrapper
+                            InputComponent={UploadFile}
+                            buttonText={translate('common.chooseFile')}
+                            uploadedFiles={uploadedFiles[document.inputID]}
+                            onUpload={(files) => handleSelectFile(files, document.inputID)}
+                            onRemove={(fileName) => handleRemoveFile(fileName, document.inputID)}
+                            setError={(error) => setUploadError(error, document.inputID)}
+                            fileLimit={CONST.NON_USD_BANK_ACCOUNT.FILE_LIMIT}
+                            acceptedFileTypes={[...CONST.NON_USD_BANK_ACCOUNT.ALLOWED_FILE_TYPES]}
+                            value={uploadedFiles[document.inputID]}
+                            inputID={document.inputID}
+                        />
+                        <Text style={[styles.mutedTextLabel, styles.mt3]}>{translate(document.description)}</Text>
+                        {requiredDocuments.length > index + 1 && <View style={[styles.sectionDividerLine, styles.mv6]} />}
+                    </View>
+                ))}
             </FormProvider>
         </InteractiveStepWrapper>
     );

From 3f2f9023c4242ff35971893f3e87768a71122482 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Fri, 5 Dec 2025 15:56:17 +0100
Subject: [PATCH 03/27] feat: new step

---
 src/CONST/index.ts                               |  1 +
 .../USD/USDVerifiedBankAccountFlow.tsx           | 16 +++++++++-------
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index fa1f11d6fe69..16b73dc4dd74 100755
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -519,6 +519,7 @@ const CONST = {
             ACH_CONTRACT: 'ACHContractStep',
             VALIDATION: 'ValidationStep',
             ENABLE: 'EnableStep',
+            KYB_DOCS: 'UploadKYBDocs',
         },
         STEP_NAMES: ['1', '2', '3', '4', '5', '6'],
         SUBSTEP: {
diff --git a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
index 10c6735ab67f..d4c1cd401547 100644
--- a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
+++ b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
@@ -39,13 +39,12 @@ function USDVerifiedBankAccountFlow({
     switch (USDBankAccountStep) {
         case CONST.BANK_ACCOUNT.STEP.COUNTRY:
             CurrentStep = (
-                <Documents onBackButtonPress={onBackButtonPress} />
-                // <Country
-                //     onBackButtonPress={onBackButtonPress}
-                //     policyID={policyID}
-                //     setUSDBankAccountStep={setUSDBankAccountStep}
-                //     stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
-                // />
+                <Country
+                    onBackButtonPress={onBackButtonPress}
+                    policyID={policyID}
+                    setUSDBankAccountStep={setUSDBankAccountStep}
+                    stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
+                />
             );
             break;
         case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:
@@ -84,6 +83,9 @@ function USDVerifiedBankAccountFlow({
                 />
             );
             break;
+        case CONST.BANK_ACCOUNT.STEP.KYB_DOCS:
+            CurrentStep = <Documents onBackButtonPress={onBackButtonPress} />;
+            break;
         default:
             CurrentStep = null;
             break;

From d5bac0cfc068d0b63951987e62b96e0e5d532b19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Fri, 12 Dec 2025 14:48:46 +0100
Subject: [PATCH 04/27] feat: file types

---
 .../Address.tsx                               |  2 +-
 .../USD/{Documents => KYBDocuments}/index.tsx | 29 ++++++++-----------
 .../USD/USDVerifiedBankAccountFlow.tsx        |  4 +--
 src/types/onyx/ReimbursementAccount.ts        | 24 +++++++++++++++
 4 files changed, 39 insertions(+), 20 deletions(-)
 rename src/pages/ReimbursementAccount/USD/{Documents => KYBDocuments}/index.tsx (86%)

diff --git a/src/pages/ReimbursementAccount/NonUSD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormSubSteps/Address.tsx b/src/pages/ReimbursementAccount/NonUSD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormSubSteps/Address.tsx
index 14ad08dd1bee..d9e796d3d7ca 100644
--- a/src/pages/ReimbursementAccount/NonUSD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormSubSteps/Address.tsx
+++ b/src/pages/ReimbursementAccount/NonUSD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormSubSteps/Address.tsx
@@ -68,7 +68,7 @@ function Address({onNext, isEditing, onMove, isUserEnteringHisOwnData, ownerBein
         // owner is US citizen so we need to gather last four digits of his SSN
         if (nationality === CONST.COUNTRY.US) {
             onNext();
-            // currency is set to GBP and owner is UK citizen, so we skip SSN and Documents step
+            // currency is set to GBP and owner is UK citizen, so we skip SSN and KYBDocuments step
         } else if (countryStepCountryValue === CONST.COUNTRY.GB && nationality === CONST.COUNTRY.GB) {
             onMove(7, false);
             // owner is not US citizen so we skip SSN step
diff --git a/src/pages/ReimbursementAccount/USD/Documents/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
similarity index 86%
rename from src/pages/ReimbursementAccount/USD/Documents/index.tsx
rename to src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index 8c27fd6dcdcb..1dfa9b614f6d 100644
--- a/src/pages/ReimbursementAccount/USD/Documents/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -15,12 +15,12 @@ import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import type {FileObject} from '@src/types/utils/Attachment';
 
-type DocumentsProps = {
+type KYBDocumentsProps = {
     /** Goes to the previous step */
     onBackButtonPress: () => void;
 };
 
-function Documents({onBackButtonPress}: DocumentsProps) {
+function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
@@ -38,36 +38,31 @@ function Documents({onBackButtonPress}: DocumentsProps) {
                     inputID: 'companyTaxID',
                     title: 'documentsStep.taxIDVerification',
                     description: 'documentsStep.taxIDVerificationDescription',
-                    required: true,
-                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('companyTaxID') ?? false,
+                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.companyTaxID?.status !== 'pass',
                 },
                 {
                     inputID: 'nameChangeDocument',
                     title: 'documentsStep.nameChangeDocument',
                     description: 'documentsStep.nameChangeDocumentDescription',
-                    required: true,
-                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('nameChangeDocument') ?? false,
+                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.lexisNexisInstantIDResult?.status !== 'pass',
                 },
                 {
                     inputID: 'companyAddressVerification',
                     title: 'documentsStep.companyAddressVerification',
                     description: 'documentsStep.companyAddressVerificationDescription',
-                    required: true,
-                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('companyAddressVerification') ?? false,
+                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.lexisNexisInstantIDResult?.status !== 'pass',
                 },
                 {
                     inputID: 'userAddressVerification',
                     title: 'documentsStep.userAddressVerification',
                     description: 'documentsStep.userAddressVerificationDescription',
-                    required: true,
-                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('userAddressVerification') ?? false,
+                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.requestorIdentityID?.status !== 'pass',
                 },
                 {
                     inputID: 'userDOBVerification',
                     title: 'documentsStep.userDOBVerification',
                     description: 'documentsStep.userDOBVerificationDescription',
-                    required: true,
-                    // required: reimbursementAccount?.achData?.requiredDocuments?.includes('userDOBVerification') ?? false,
+                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.requestorIdentityID?.status !== 'pass',
                 },
             ] as const,
         [],
@@ -85,12 +80,12 @@ function Documents({onBackButtonPress}: DocumentsProps) {
         (values: FormOnyxValues<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> => {
             const errors: FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> = {};
 
-            DOCUMENTS_CONFIG.filter((document) => document.required).forEach((document) => {
+            for (const document of DOCUMENTS_CONFIG.filter((documentItem) => documentItem.required)) {
                 const files = values[document.inputID] as FileObject[] | undefined;
                 if (!files || files.length === 0) {
                     errors[document.inputID] = translate('common.error.fieldRequired');
                 }
-            });
+            }
 
             return errors;
         },
@@ -135,7 +130,7 @@ function Documents({onBackButtonPress}: DocumentsProps) {
 
     return (
         <InteractiveStepWrapper
-            wrapperID={Documents.displayName}
+            wrapperID={KYBDocuments.displayName}
             shouldEnablePickerAvoiding={false}
             shouldEnableMaxHeight
             headerTitle={translate('documentsStep.subheader')}
@@ -178,6 +173,6 @@ function Documents({onBackButtonPress}: DocumentsProps) {
     );
 }
 
-Documents.displayName = 'Documents';
+KYBDocuments.displayName = 'KYBDocuments';
 
-export default Documents;
+export default KYBDocuments;
diff --git a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
index c47bde9f7bd0..d860d361715b 100644
--- a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
+++ b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
@@ -10,7 +10,7 @@ import BusinessInfo from './BusinessInfo/BusinessInfo';
 import CompleteVerification from './CompleteVerification/CompleteVerification';
 import ConnectBankAccount from './ConnectBankAccount/ConnectBankAccount';
 import Country from './Country';
-import Documents from './Documents';
+import KYBDocuments from './KYBDocuments';
 import RequestorStep from './Requestor/RequestorStep';
 
 type USDVerifiedBankAccountFlowProps = {
@@ -84,7 +84,7 @@ function USDVerifiedBankAccountFlow({
             );
             break;
         case CONST.BANK_ACCOUNT.STEP.KYB_DOCS:
-            CurrentStep = <Documents onBackButtonPress={onBackButtonPress} />;
+            CurrentStep = <KYBDocuments onBackButtonPress={onBackButtonPress} />;
             break;
         default:
             CurrentStep = null;
diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts
index 730c2f9c6f1a..a47fd0c801b6 100644
--- a/src/types/onyx/ReimbursementAccount.ts
+++ b/src/types/onyx/ReimbursementAccount.ts
@@ -196,6 +196,30 @@ type ACHData = Partial<BeneficialOwnersStepProps & CompanyStepProps & RequestorS
 
     /** Date the corpay bank account was created */
     created?: string;
+
+    /** Statuses of additional checks hinting at missing documents user still needs to upload */
+    verifications?: {
+        /** points towards one of external providers */
+        externalApiResponse?: {
+            /** provider name */
+            companyTaxID?: {
+                /** status of check */
+                status: string;
+            };
+            /** provider name */
+            lexisNexisInstantIDResult?: {
+                /** status of check */
+                status: string;
+            };
+            /** provider name */
+            requestorIdentityID?: {
+                /** status of check */
+                status: string;
+                /** fields that failed */
+                errors: Record<string, string>;
+            };
+        };
+    };
 };
 
 /** The step in an reimbursement account's ach data */

From 76926e724211d69dd6c30aed4aec79e685b610cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Tue, 16 Dec 2025 12:51:35 +0100
Subject: [PATCH 05/27] feat: pause

---
 src/CONST/index.ts                            | 24 +++++++++++++++
 .../USD/KYBDocuments/index.tsx                | 30 +++++++++++++------
 .../isUserAddressVerificationRequired.ts      | 20 +++++++++++++
 .../utils/isUserDOBVerificationRequired.ts    | 20 +++++++++++++
 src/types/onyx/ReimbursementAccount.ts        | 15 ++++++++--
 5 files changed, 98 insertions(+), 11 deletions(-)
 create mode 100644 src/pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired.ts
 create mode 100644 src/pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired.ts

diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index d1f6fa6f37e0..2ca46c4fb35b 100755
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -574,6 +574,30 @@ const CONST = {
             BUSINESS: 'BUSINESS',
             PERSONAL: 'PERSONAL',
         },
+        KYB_REQUESTOR_IDENTITY_ERROR: {
+            ADDRESS: [
+                'resultcode.address.does.not.match',
+                'resultcode.street.name.does.not.match',
+                'resultcode.street.number.does.not.match',
+                'resultcode.zip.does.not.match',
+                'resultcode.state.does.not.match',
+                'resultcode.alternate.address.alert',
+                'resultcode.input.address.is.po.box',
+                'resultcode.located.address.is.po.box',
+                'resultcode.warm.address.alert',
+            ],
+            DOB: [
+                'resultcode.coppa.alert',
+                'resultcode.age.below.minimum',
+                'resultcode.dob.does.not.match',
+                'resultcode.yob.does.not.match',
+                'resultcode.yob.within.one.year',
+                'resultcode.mob.does.not.match',
+                'resultcode.no.mob.available',
+                'resultcode.no.dob.available',
+                'resultcode.ssn.issued.prior.to.dob',
+            ],
+        },
     },
     NON_USD_BANK_ACCOUNT: {
         ALLOWED_FILE_TYPES: ['pdf', 'jpg', 'jpeg', 'png'],
diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index 1dfa9b614f6d..44b9f31e6607 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -10,6 +10,8 @@ import UploadFile from '@components/UploadFile';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
+import isUserAddressVerificationRequired from '@pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired';
+import isUserDOBVerificationRequired from '@pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired';
 import {clearErrorFields, setDraftValues, setErrorFields} from '@userActions/FormActions';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -26,10 +28,9 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
 
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: false});
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT, {canBeMissing: true});
+    const reimbursementAccountData = reimbursementAccount?.achData?.verifications?.externalApiResponse;
 
-    const submit = useCallback(() => {
-        console.log('submit');
-    }, []);
+    const submit = useCallback(() => {}, []);
 
     const DOCUMENTS_CONFIG = useMemo(
         () =>
@@ -38,34 +39,45 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
                     inputID: 'companyTaxID',
                     title: 'documentsStep.taxIDVerification',
                     description: 'documentsStep.taxIDVerificationDescription',
-                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.companyTaxID?.status !== 'pass',
+                    required: reimbursementAccountData?.companyTaxID?.status !== 'pass',
                 },
                 {
                     inputID: 'nameChangeDocument',
                     title: 'documentsStep.nameChangeDocument',
                     description: 'documentsStep.nameChangeDocumentDescription',
-                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.lexisNexisInstantIDResult?.status !== 'pass',
+                    required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
                 },
                 {
                     inputID: 'companyAddressVerification',
                     title: 'documentsStep.companyAddressVerification',
                     description: 'documentsStep.companyAddressVerificationDescription',
-                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.lexisNexisInstantIDResult?.status !== 'pass',
+                    required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
                 },
                 {
                     inputID: 'userAddressVerification',
                     title: 'documentsStep.userAddressVerification',
                     description: 'documentsStep.userAddressVerificationDescription',
-                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.requestorIdentityID?.status !== 'pass',
+                    required: isUserAddressVerificationRequired(
+                        reimbursementAccountData?.requestorIdentityID?.status,
+                        reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
+                    ),
                 },
                 {
                     inputID: 'userDOBVerification',
                     title: 'documentsStep.userDOBVerification',
                     description: 'documentsStep.userDOBVerificationDescription',
-                    required: reimbursementAccount?.achData?.verifications?.externalApiResponse?.requestorIdentityID?.status !== 'pass',
+                    required: isUserDOBVerificationRequired(
+                        reimbursementAccountData?.requestorIdentityID?.status,
+                        reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
+                    ),
                 },
             ] as const,
-        [],
+        [
+            reimbursementAccountData?.companyTaxID?.status,
+            reimbursementAccountData?.lexisNexisInstantIDResult?.status,
+            reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
+            reimbursementAccountData?.requestorIdentityID?.status,
+        ],
     );
 
     const [uploadedFiles, setUploadedFiles] = useState<Record<string, FileObject[]>>({
diff --git a/src/pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired.ts b/src/pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired.ts
new file mode 100644
index 000000000000..2968a5e618f9
--- /dev/null
+++ b/src/pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired.ts
@@ -0,0 +1,20 @@
+import CONST from '@src/CONST';
+
+/** Compares error keys and searches for overlap. Based on the result we decide whether to gather extra file
+ * @param status - status of the check
+ * @param qualifiers - errors returned after the check
+ * @returns boolean - whether to gather additional address verification file
+ */
+function isUserAddressVerificationRequired(
+    status: string | undefined,
+    qualifiers:
+        | Array<{
+              key: string;
+              message: string;
+          }>
+        | undefined,
+): boolean {
+    return status !== 'pass' && !!CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.ADDRESS.find((error) => qualifiers?.map((qualifier) => qualifier.key).includes(error));
+}
+
+export default isUserAddressVerificationRequired;
diff --git a/src/pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired.ts b/src/pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired.ts
new file mode 100644
index 000000000000..1b5da4d14934
--- /dev/null
+++ b/src/pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired.ts
@@ -0,0 +1,20 @@
+import CONST from '@src/CONST';
+
+/** Compares error keys and searches for overlap. Based on the result we decide whether to gather extra file
+ * @param status - status of the check
+ * @param qualifiers - errors returned after the check
+ * @returns boolean - whether to gather additional DOB verification file
+ */
+function isUserDOBVerificationRequired(
+    status: string | undefined,
+    qualifiers:
+        | Array<{
+              key: string;
+              message: string;
+          }>
+        | undefined,
+): boolean {
+    return status !== 'pass' && !!CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.DOB.find((error) => qualifiers?.map((qualifier) => qualifier.key).includes(error));
+}
+
+export default isUserDOBVerificationRequired;
diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts
index a47fd0c801b6..718363f618b4 100644
--- a/src/types/onyx/ReimbursementAccount.ts
+++ b/src/types/onyx/ReimbursementAccount.ts
@@ -215,8 +215,19 @@ type ACHData = Partial<BeneficialOwnersStepProps & CompanyStepProps & RequestorS
             requestorIdentityID?: {
                 /** status of check */
                 status: string;
-                /** fields that failed */
-                errors: Record<string, string>;
+                /** result with validation errors */
+                apiResult?: {
+                    /** contains validation qualifiers that provide additional details about the identity verification result */
+                    qualifiers: {
+                        /** array of individual validation checks that were flagged during identity verification */
+                        qualifier: Array<{
+                            /** Unique code of the error */
+                            key: string;
+                            /** Message of the error */
+                            message: string;
+                        }>;
+                    };
+                };
             };
         };
     };

From 88ab4a4af91d4f0f59dca84852080865e7de02f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Fri, 19 Dec 2025 15:36:12 +0100
Subject: [PATCH 06/27] feat: types

---
 .../API/parameters/UploadUserKYBDocsParams.ts    |  6 ++++++
 src/libs/API/parameters/index.ts                 |  1 +
 src/libs/API/types.ts                            |  3 +++
 src/libs/actions/BankAccounts.ts                 |  6 ++++++
 src/types/form/ReimbursementAccountForm.ts       | 16 ++++++++++++++++
 5 files changed, 32 insertions(+)
 create mode 100644 src/libs/API/parameters/UploadUserKYBDocsParams.ts

diff --git a/src/libs/API/parameters/UploadUserKYBDocsParams.ts b/src/libs/API/parameters/UploadUserKYBDocsParams.ts
new file mode 100644
index 000000000000..faedf9495941
--- /dev/null
+++ b/src/libs/API/parameters/UploadUserKYBDocsParams.ts
@@ -0,0 +1,6 @@
+type UploadUserKYBDocsParams = {
+    bankAccountID: string;
+    inputs: string;
+};
+
+export default UploadUserKYBDocsParams;
diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts
index f27feccfaf62..fe066ba7d09a 100644
--- a/src/libs/API/parameters/index.ts
+++ b/src/libs/API/parameters/index.ts
@@ -450,3 +450,4 @@ export type {default as UpdateSamlEnabledParams} from './UpdateSamlEnabledParams
 export type {default as UpdateSamlRequiredParams} from './UpdateSamlRequiredParams';
 export type {default as SetPolicyRequireCompanyCardsEnabledParams} from './SetPolicyRequireCompanyCardsEnabled';
 export type {default as SetTechnicalContactEmailParams} from './SetTechnicalContactEmailParams';
+export type {default as UploadUserKYBDocsParams} from './UploadUserKYBDocsParams';
diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts
index 2da2814ba411..a828f30a5885 100644
--- a/src/libs/API/types.ts
+++ b/src/libs/API/types.ts
@@ -5,6 +5,7 @@ import type {EmptyObject} from '@src/types/utils/EmptyObject';
 // We have to disable eslint for this import because otherwise the import will be 300 lines long
 // eslint-disable-next-line no-restricted-syntax
 import type * as Parameters from './parameters';
+import {UploadUserKYBDocsParams} from './parameters';
 import type SignInUserParams from './parameters/SignInUserParams';
 import type UpdateBeneficialOwnersForBankAccountParams from './parameters/UpdateBeneficialOwnersForBankAccountParams';
 
@@ -528,6 +529,7 @@ const WRITE_COMMANDS = {
     UPDATE_SAML_REQUIRED: 'UpdateSAMLRequired',
     CREATE_DOMAIN: 'CreateDomain',
     SET_TECHNICAL_CONTACT_EMAIL: 'SetTechnicalContactEmail',
+    UPLOAD_USER_KYB_DOCS: 'UploadUserKYBDocs',
 } as const;
 
 type WriteCommand = ValueOf<typeof WRITE_COMMANDS>;
@@ -907,6 +909,7 @@ type WriteCommandParameters = {
     [WRITE_COMMANDS.ENABLE_GLOBAL_REIMBURSEMENTS_FOR_USD_BANK_ACCOUNT]: Parameters.EnableGlobalReimbursementsForUSDBankAccountParams;
     [WRITE_COMMANDS.REOPEN_REPORT]: Parameters.ReopenReportParams;
     [WRITE_COMMANDS.SEND_SCHEDULE_CALL_NUDGE]: Parameters.SendScheduleCallNudgeParams;
+    [WRITE_COMMANDS.UPLOAD_USER_KYB_DOCS]: Parameters.UploadUserKYBDocsParams;
 
     [WRITE_COMMANDS.DELETE_MONEY_REQUEST_ON_SEARCH]: Parameters.DeleteMoneyRequestOnSearchParams;
     [WRITE_COMMANDS.REJECT_MONEY_REQUEST_IN_BULK]: Parameters.RejectMoneyRequestInBulkParams;
diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts
index 0486c3bd07af..60587402ec1e 100644
--- a/src/libs/actions/BankAccounts.ts
+++ b/src/libs/actions/BankAccounts.ts
@@ -14,6 +14,7 @@ import type {
     OpenReimbursementAccountPageParams,
     SaveCorpayOnboardingBeneficialOwnerParams,
     SendReminderForCorpaySignerInformationParams,
+    UploadUserKYBDocsParams,
     ValidateBankAccountWithTransactionsParams,
     VerifyIdentityForBankAccountParams,
 } from '@libs/API/parameters';
@@ -1121,6 +1122,10 @@ function verifyIdentityForBankAccount(bankAccountID: number, onfidoData: OnfidoD
     API.write(WRITE_COMMANDS.VERIFY_IDENTITY_FOR_BANK_ACCOUNT, parameters, getVBBADataForOnyx());
 }
 
+function uploadUserKYBDocs(parameters: UploadUserKYBDocsParams) {
+    API.write(WRITE_COMMANDS.UPLOAD_USER_KYB_DOCS, parameters, getVBBADataForOnyx());
+}
+
 function openWorkspaceView(policyID: string | undefined) {
     API.read(
         READ_COMMANDS.OPEN_WORKSPACE_VIEW,
@@ -1339,4 +1344,5 @@ export {
     sendReminderForCorpaySignerInformation,
     clearReimbursementAccountSendReminderForCorpaySignerInformation,
     getBankAccountFromID,
+    uploadUserKYBDocs,
 };
diff --git a/src/types/form/ReimbursementAccountForm.ts b/src/types/form/ReimbursementAccountForm.ts
index 5334edcc5a65..da2b9ff645d6 100644
--- a/src/types/form/ReimbursementAccountForm.ts
+++ b/src/types/form/ReimbursementAccountForm.ts
@@ -67,6 +67,13 @@ const INPUT_IDS = {
         DOWNLOADED_PDS_AND_FSG: 'downloadedPDSandFSG',
         SECOND_SIGNER_EMAIL: 'secondSignerEmail',
     },
+    KYB_DOCUMENTS: {
+        COMPANY_TAX_ID: 'companyTaxID',
+        NAME_CHANGE_DOCUMENT: 'nameChangeDocument',
+        COMPANY_ADDRESS_VERIFICATION: 'companyAddressVerification',
+        USER_ADDRESS_VERIFICATION: 'userAddressVerification',
+        USER_DOB_VERIFICATION: 'userDOBVerification',
+    },
     AMOUNT1: 'amount1',
     AMOUNT2: 'amount2',
     AMOUNT3: 'amount3',
@@ -218,6 +225,14 @@ type ACHContractStepProps = {
     [INPUT_IDS.COMPLETE_VERIFICATION.IS_AUTHORIZED_TO_USE_BANK_ACCOUNT]: boolean;
 };
 
+type KYBDocumentsStepProps = {
+    [INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID]: FileObject[];
+    [INPUT_IDS.KYB_DOCUMENTS.NAME_CHANGE_DOCUMENT]: FileObject[];
+    [INPUT_IDS.KYB_DOCUMENTS.COMPANY_ADDRESS_VERIFICATION]: FileObject[];
+    [INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID]: FileObject[];
+    [INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID]: FileObject[];
+};
+
 type ReimbursementAccountProps = {
     [INPUT_IDS.BANK_INFO_STEP.IS_SAVINGS]: boolean;
     [INPUT_IDS.BANK_INFO_STEP.BANK_NAME]: string;
@@ -446,6 +461,7 @@ type ReimbursementAccountForm = ReimbursementAccountFormExtraProps &
             CompanyStepProps &
             RequestorStepProps &
             ACHContractStepProps &
+            KYBDocumentsStepProps &
             ReimbursementAccountProps &
             NonUSDReimbursementAccountAdditionalProps
     >;

From f0f43046515d3272547b9a03c80954aa39c4cf2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Mon, 29 Dec 2025 15:28:13 +0100
Subject: [PATCH 07/27] feat: submit

---
 src/languages/de.ts                           | 32 ++++++++++++++
 src/languages/es.ts                           | 31 ++++++++++++++
 src/languages/fr.ts                           | 32 ++++++++++++++
 src/languages/it.ts                           | 32 ++++++++++++++
 src/languages/ja.ts                           | 31 ++++++++++++++
 src/languages/nl.ts                           | 31 ++++++++++++++
 src/languages/pl.ts                           | 31 ++++++++++++++
 src/languages/pt-BR.ts                        | 31 ++++++++++++++
 src/languages/zh-hans.ts                      | 31 ++++++++++++++
 .../API/parameters/UploadUserKYBDocsParams.ts |  2 +-
 src/libs/actions/BankAccounts.ts              | 41 +++++++++++++++++-
 .../USD/KYBDocuments/index.tsx                | 42 +++++++++++++++----
 src/types/form/ReimbursementAccountForm.ts    |  6 +--
 src/types/onyx/ReimbursementAccount.ts        |  3 ++
 14 files changed, 362 insertions(+), 14 deletions(-)

diff --git a/src/languages/de.ts b/src/languages/de.ts
index 38639ee12c4b..d48168eedeb1 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -3614,6 +3614,38 @@ ${
         weTake: 'Wir nehmen Ihre Sicherheit ernst. Bitte richten Sie jetzt 2FA ein, um Ihr Konto mit einer zusätzlichen Schutzebene zu versehen.',
         secure: 'Sichern Sie Ihr Konto',
     },
+    documentsStep: {
+        beforeYouGo: 'Bevor du fortfährst, benötigen wir einige Dokumente, um bestimmte Angaben zu überprüfen',
+        subheader: 'Verifizierung',
+        verificationFailed: 'Die Verifizierung ist fehlgeschlagen, daher benötigen wir zusätzliche Dokumente, um dich und dein Unternehmen zu überprüfen',
+        taxIDVerification: 'Steuer-ID-Verifizierung',
+        taxIDVerificationDescription: dedent(`
+        Bitte lade eine der folgenden Dateien hoch:
+        • IRS TIN/EIN-Zuweisungsschreiben
+        • IRS TIN/EIN-Antragsbestätigung (enthält normalerweise „Congratulations! The EIN has been successfully assigned“)
+        • IRS-Steuerbefreiungsschreiben mit Firmenname und EIN`),
+        nameChangeDocument: 'Dokument zur Namensänderung',
+        nameChangeDocumentDescription:
+            'Wenn sich der Name deines Unternehmens seit der Beantragung der TIN/EIN geändert hat, benötigen wir dieses Dokument zur Verifizierung der angegebenen Steuer-ID',
+        companyAddressVerification: 'Verifizierung der Unternehmensadresse',
+        companyAddressVerificationDescription: dedent(`
+        Bitte lade eine der folgenden Dateien hoch:
+        • Aktuelle Strom-, Wasser- oder Gasrechnung mit Firmenname und Adresse
+        • Kontoauszug mit Firmenname und Adresse
+        • Aktueller Miet- oder Leasingvertrag inkl. Unterschriftsseite mit Firmenname und aktueller Adresse
+        • Versicherungsnachweis mit Firmenname und Adresse
+        • TIN-Zuweisungsdokument mit Firmenname und Adresse`),
+        userAddressVerification: 'Adressverifizierung',
+        userAddressVerificationDescription: dedent(`
+        Bitte lade eine der folgenden Dateien hoch:
+        • Wählerregistrierungskarte
+        • Führerschein
+        • Kontoauszug
+        • Versorgungsrechnung`),
+        userDOBVerification: 'Geburtsdatumsverifizierung',
+        userDOBVerificationDescription: 'Bitte lade einen in den USA ausgestellten Ausweis hoch',
+        finishViaChat: 'Über Chat abschließen',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: 'Einen Moment',
         explanationLine: 'Wir überprüfen gerade deine Angaben. Du kannst in Kürze mit den nächsten Schritten fortfahren.',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 1523187bbc45..d8962ce0dfa5 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -3266,6 +3266,37 @@ ${amount} para ${merchant} - ${date}`,
         weTake: 'Nos tomamos su seguridad en serio. Por favor, configure 2FA ahora para agregar una capa adicional de protección a su cuenta.',
         secure: 'Asegure su cuenta',
     },
+    documentsStep: {
+        beforeYouGo: 'Antes de continuar, necesitamos algunos documentos para verificar cierta información',
+        subheader: 'Verificación',
+        verificationFailed: 'La verificación falló, por lo que necesitaremos documentos adicionales para verificarte a ti y a tu empresa',
+        taxIDVerification: 'Verificación del ID fiscal',
+        taxIDVerificationDescription: dedent(`
+        Por favor, sube uno de los siguientes archivos:
+        • Carta de asignación de TIN/EIN del IRS
+        • Confirmación de solicitud de TIN/EIN del IRS (normalmente indica "Congratulations! The EIN has been successfully assigned")
+        • Carta de exención fiscal del IRS que incluya el nombre de la empresa y el EIN`),
+        nameChangeDocument: 'Documento de cambio de nombre',
+        nameChangeDocumentDescription: 'Si el nombre de tu empresa cambió desde que solicitaste el TIN/EIN, necesitamos este documento para verificar el número de ID fiscal proporcionado',
+        companyAddressVerification: 'Verificación de la dirección de la empresa',
+        companyAddressVerificationDescription: dedent(`
+        Por favor, sube uno de los siguientes archivos:
+        • Factura reciente de servicios públicos con nombre y dirección de la empresa
+        • Estado de cuenta bancario con nombre y dirección de la empresa
+        • Contrato de arrendamiento vigente con página de firmas que muestre el nombre y la dirección actual de la empresa
+        • Estado de seguro con nombre y dirección de la empresa
+        • Documento de asignación de TIN con nombre y dirección de la empresa`),
+        userAddressVerification: 'Verificación de dirección',
+        userAddressVerificationDescription: dedent(`
+        Por favor, sube uno de los siguientes archivos:
+        • Tarjeta de registro de votante
+        • Licencia de conducir
+        • Estado de cuenta bancario
+        • Factura de servicios públicos`),
+        userDOBVerification: 'Verificación de fecha de nacimiento',
+        userDOBVerificationDescription: 'Por favor, sube una identificación emitida en EE. UU.',
+        finishViaChat: 'Finalizar por chat',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: 'Un momento',
         explanationLine: 'Estamos verificando tu información y podrás continuar con los siguientes pasos en unos momentos.',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 5fe5aaa831b3..47bf41aedebc 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -3620,6 +3620,38 @@ ${
         weTake: 'Nous prenons votre sécurité au sérieux. Veuillez configurer l’A2F maintenant afin d’ajouter une couche supplémentaire de protection à votre compte.',
         secure: 'Sécurisez votre compte',
     },
+    documentsStep: {
+        beforeYouGo: 'Avant de continuer, nous avons besoin de certains documents pour vérifier certaines informations',
+        subheader: 'Vérification',
+        verificationFailed: 'La vérification a échoué, nous aurons donc besoin de documents supplémentaires pour te vérifier ainsi que ton entreprise',
+        taxIDVerification: 'Vérification de l’identifiant fiscal',
+        taxIDVerificationDescription: dedent(`
+        Veuillez téléverser l’un des fichiers suivants :
+        • Lettre d’attribution TIN/EIN de l’IRS
+        • Confirmation de demande TIN/EIN de l’IRS (indique généralement « Congratulations! The EIN has been successfully assigned »)
+        • Lettre d’exonération fiscale de l’IRS indiquant le nom de l’entreprise et l’EIN`),
+        nameChangeDocument: 'Document de changement de nom',
+        nameChangeDocumentDescription:
+            'Si le nom de ton entreprise a changé depuis la demande du TIN/EIN, ce document est nécessaire pour vérifier le numéro d’identification fiscale fourni',
+        companyAddressVerification: 'Vérification de l’adresse de l’entreprise',
+        companyAddressVerificationDescription: dedent(`
+        Veuillez téléverser l’un des fichiers suivants :
+        • Facture récente de services publics indiquant le nom et l’adresse de l’entreprise
+        • Relevé bancaire indiquant le nom et l’adresse de l’entreprise
+        • Contrat de location en cours incluant la page de signature avec le nom et l’adresse actuelle de l’entreprise
+        • Attestation d’assurance indiquant le nom et l’adresse de l’entreprise
+        • Document d’attribution TIN indiquant le nom et l’adresse de l’entreprise`),
+        userAddressVerification: 'Vérification de l’adresse',
+        userAddressVerificationDescription: dedent(`
+        Veuillez téléverser l’un des fichiers suivants :
+        • Carte d’inscription électorale
+        • Permis de conduire
+        • Relevé bancaire
+        • Facture de services publics`),
+        userDOBVerification: 'Vérification de la date de naissance',
+        userDOBVerificationDescription: 'Veuillez téléverser une pièce d’identité délivrée aux États-Unis',
+        finishViaChat: 'Finaliser via le chat',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: 'Un instant',
         explanationLine: 'Nous examinons vos informations. Vous pourrez poursuivre les prochaines étapes sous peu.',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 50fe5beb0e63..3d10bdd8b91a 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -3599,6 +3599,38 @@ ${
         weTake: 'Prendiamo molto sul serio la tua sicurezza. Imposta subito l’autenticazione a due fattori (2FA) per aggiungere un ulteriore livello di protezione al tuo account.',
         secure: 'Proteggi il tuo account',
     },
+    documentsStep: {
+        beforeYouGo: 'Prima di continuare, abbiamo bisogno di alcuni documenti per verificare alcune informazioni',
+        subheader: 'Verifica',
+        verificationFailed: 'La verifica non è riuscita, quindi avremo bisogno di documenti aggiuntivi per verificare te e la tua azienda',
+        taxIDVerification: 'Verifica dell’ID fiscale',
+        taxIDVerificationDescription: dedent(`
+        Carica uno dei seguenti file:
+        • Lettera di assegnazione TIN/EIN dell’IRS
+        • Conferma della richiesta TIN/EIN dell’IRS (di solito indica "Congratulations! The EIN has been successfully assigned")
+        • Lettera di esenzione fiscale dell’IRS con nome dell’azienda ed EIN`),
+        nameChangeDocument: 'Documento di cambio nome',
+        nameChangeDocumentDescription:
+            'Se il nome della tua azienda è cambiato dopo la richiesta del TIN/EIN, abbiamo bisogno di questo documento per verificare il numero di ID fiscale fornito',
+        companyAddressVerification: 'Verifica dell’indirizzo aziendale',
+        companyAddressVerificationDescription: dedent(`
+        Carica uno dei seguenti file:
+        • Bolletta recente con nome e indirizzo dell’azienda
+        • Estratto conto bancario con nome e indirizzo dell’azienda
+        • Contratto di locazione attuale con pagina firme che mostri nome e indirizzo attuale dell’azienda
+        • Documento assicurativo con nome e indirizzo dell’azienda
+        • Documento di assegnazione TIN con nome e indirizzo dell’azienda`),
+        userAddressVerification: 'Verifica dell’indirizzo',
+        userAddressVerificationDescription: dedent(`
+        Carica uno dei seguenti file:
+        • Tessera elettorale
+        • Patente di guida
+        • Estratto conto bancario
+        • Bolletta`),
+        userDOBVerification: 'Verifica della data di nascita',
+        userDOBVerificationDescription: 'Carica un documento di identità rilasciato negli Stati Uniti',
+        finishViaChat: 'Completa via chat',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: 'Un momento',
         explanationLine: 'Stiamo esaminando le tue informazioni. Potrai procedere con i prossimi passaggi a breve.',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 8b13494ec0bb..a300a0c1f9f8 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -3589,6 +3589,37 @@ ${
         weTake: 'お客様のセキュリティを真剣に考えています。アカウントをさらに保護するために、今すぐ2要素認証（2FA）を設定してください。',
         secure: 'アカウントを保護する',
     },
+    documentsStep: {
+        beforeYouGo: '続行する前に、いくつかの情報を確認するための書類が必要です',
+        subheader: '確認',
+        verificationFailed: '確認に失敗したため、追加の書類で本人および事業の確認が必要です',
+        taxIDVerification: '納税者番号の確認',
+        taxIDVerificationDescription: dedent(`
+        以下のいずれかの書類をアップロードしてください：
+        • IRS TIN/EIN 割当通知書
+        • IRS TIN/EIN 申請確認書（通常「Congratulations! The EIN has been successfully assigned」と記載）
+        • 会社名と EIN が記載された IRS の免税通知書`),
+        nameChangeDocument: '名称変更書類',
+        nameChangeDocumentDescription: 'TIN/EIN 申請後に会社名が変更された場合、提供された納税者番号を確認するためにこの書類が必要です',
+        companyAddressVerification: '会社住所の確認',
+        companyAddressVerificationDescription: dedent(`
+        以下のいずれかの書類をアップロードしてください：
+        • 会社名と住所が記載された最近の公共料金請求書
+        • 会社名と住所が記載された銀行取引明細書
+        • 署名ページを含む現行の賃貸契約書（会社名と現住所が記載されたもの）
+        • 会社名と住所が記載された保険証書
+        • 会社名と住所が記載された TIN 割当書類`),
+        userAddressVerification: '住所確認',
+        userAddressVerificationDescription: dedent(`
+        以下のいずれかの書類をアップロードしてください：
+        • 有権者登録カード
+        • 運転免許証
+        • 銀行取引明細書
+        • 公共料金請求書`),
+        userDOBVerification: '生年月日の確認',
+        userDOBVerificationDescription: '米国発行の身分証明書をアップロードしてください',
+        finishViaChat: 'チャットで完了',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: '少々お待ちください',
         explanationLine: 'お客様の情報を確認しています。まもなく次のステップに進むことができます。',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index d461fa20aa09..7091dc7cc5b2 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -3597,6 +3597,37 @@ ${
         weTake: 'We nemen uw beveiliging serieus. Stel nu 2FA in om een extra beveiligingslaag aan uw account toe te voegen.',
         secure: 'Beveilig je account',
     },
+    documentsStep: {
+        beforeYouGo: 'Voordat je verdergaat, hebben we enkele documenten nodig om bepaalde gegevens te verifiëren',
+        subheader: 'Verificatie',
+        verificationFailed: 'De verificatie is mislukt, daarom hebben we extra documenten nodig om jou en je bedrijf te verifiëren',
+        taxIDVerification: 'Belastingnummerverificatie',
+        taxIDVerificationDescription: dedent(`
+        Upload een van de volgende bestanden:
+        • IRS TIN/EIN-toewijzingsbrief
+        • IRS TIN/EIN-aanvraagbevestiging (bevat meestal "Congratulations! The EIN has been successfully assigned")
+        • IRS-belastingvrijstellingsbrief met bedrijfsnaam en EIN`),
+        nameChangeDocument: 'Document naamswijziging',
+        nameChangeDocumentDescription: 'Als de naam van je bedrijf is gewijzigd sinds de TIN/EIN-aanvraag, hebben we dit document nodig om het opgegeven belastingnummer te verifiëren',
+        companyAddressVerification: 'Verificatie van bedrijfsadres',
+        companyAddressVerificationDescription: dedent(`
+        Upload een van de volgende bestanden:
+        • Recente energierekening met bedrijfsnaam en adres
+        • Bankafschrift met bedrijfsnaam en adres
+        • Huidige huur- of leaseovereenkomst inclusief ondertekeningspagina met bedrijfsnaam en huidig adres
+        • Verzekeringsverklaring met bedrijfsnaam en adres
+        • TIN-toewijzingsdocument met bedrijfsnaam en adres`),
+        userAddressVerification: 'Adresverificatie',
+        userAddressVerificationDescription: dedent(`
+        Upload een van de volgende bestanden:
+        • Kiezersregistratiekaart
+        • Rijbewijs
+        • Bankafschrift
+        • Energierekening`),
+        userDOBVerification: 'Verificatie van geboortedatum',
+        userDOBVerificationDescription: 'Upload een in de VS uitgegeven identiteitsbewijs',
+        finishViaChat: 'Afronden via chat',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: 'Een moment',
         explanationLine: 'We controleren je gegevens. Je kunt binnenkort doorgaan met de volgende stappen.',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 859934be424f..43496e380a93 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -3594,6 +3594,37 @@ ${
         weTake: 'Poważnie traktujemy Twoje bezpieczeństwo. Skonfiguruj teraz 2FA, aby dodać dodatkową warstwę ochrony swojego konta.',
         secure: 'Zabezpiecz swoje konto',
     },
+    documentsStep: {
+        beforeYouGo: 'Zanim przejdziesz dalej, potrzebujemy kilku dokumentów do weryfikacji informacji',
+        subheader: 'Weryfikacja',
+        verificationFailed: 'Weryfikacja nie powiodła się, dlatego potrzebujemy dodatkowych dokumentów do potwierdzenia Twojej tożsamości i firmy',
+        taxIDVerification: 'Weryfikacja numeru podatkowego',
+        taxIDVerificationDescription: dedent(`
+        Prześlij jeden z poniższych plików:
+        • List przydziału TIN/EIN z IRS
+        • Potwierdzenie wniosku TIN/EIN z IRS (zwykle zawiera „Congratulations! The EIN has been successfully assigned”)
+        • Pismo o zwolnieniu podatkowym z IRS zawierające nazwę firmy i EIN`),
+        nameChangeDocument: 'Dokument zmiany nazwy',
+        nameChangeDocumentDescription: 'Jeśli nazwa firmy zmieniła się od momentu złożenia wniosku o TIN/EIN, dokument ten jest wymagany do weryfikacji podanego numeru podatkowego',
+        companyAddressVerification: 'Weryfikacja adresu firmy',
+        companyAddressVerificationDescription: dedent(`
+        Prześlij jeden z poniższych plików:
+        • Aktualny rachunek za media z nazwą i adresem firmy
+        • Wyciąg bankowy z nazwą i adresem firmy
+        • Aktualna umowa najmu z podpisaną stroną zawierającą nazwę i adres firmy
+        • Dokument ubezpieczeniowy z nazwą i adresem firmy
+        • Dokument przydziału TIN z nazwą i adresem firmy`),
+        userAddressVerification: 'Weryfikacja adresu',
+        userAddressVerificationDescription: dedent(`
+        Prześlij jeden z poniższych plików:
+        • Karta rejestracji wyborcy
+        • Prawo jazdy
+        • Wyciąg bankowy
+        • Rachunek za media`),
+        userDOBVerification: 'Weryfikacja daty urodzenia',
+        userDOBVerificationDescription: 'Prześlij dokument tożsamości wydany w USA',
+        finishViaChat: 'Zakończ przez czat',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: 'Chwileczkę',
         explanationLine: 'Sprawdzamy teraz Twoje informacje. Wkrótce będziesz mógł kontynuować kolejne kroki.',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 4f67d07d2e6b..4c64e9c822c0 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -3593,6 +3593,37 @@ ${
         weTake: 'Levamos sua segurança a sério. Configure a autenticação em duas etapas (2FA) agora para adicionar uma camada extra de proteção à sua conta.',
         secure: 'Proteja sua conta',
     },
+    documentsStep: {
+        beforeYouGo: 'Antes de continuar, precisamos de alguns documentos para verificar algumas informações',
+        subheader: 'Verificação',
+        verificationFailed: 'A verificação falhou, então precisaremos de documentos adicionais para verificar você e sua empresa',
+        taxIDVerification: 'Verificação de ID fiscal',
+        taxIDVerificationDescription: dedent(`
+        Envie um dos seguintes arquivos:
+        • Carta de atribuição de TIN/EIN do IRS
+        • Confirmação de solicitação de TIN/EIN do IRS (normalmente contém "Congratulations! The EIN has been successfully assigned")
+        • Carta de isenção fiscal do IRS com o nome da empresa e o EIN`),
+        nameChangeDocument: 'Documento de alteração de nome',
+        nameChangeDocumentDescription: 'Se o nome da sua empresa mudou desde a solicitação do TIN/EIN, precisamos deste documento para verificar o número de identificação fiscal informado',
+        companyAddressVerification: 'Verificação de endereço da empresa',
+        companyAddressVerificationDescription: dedent(`
+        Envie um dos seguintes arquivos:
+        • Conta recente de serviços públicos com nome e endereço da empresa
+        • Extrato bancário com nome e endereço da empresa
+        • Contrato de locação atual incluindo a página de assinatura com nome e endereço atual da empresa
+        • Apólice ou declaração de seguro com nome e endereço da empresa
+        • Documento de atribuição de TIN com nome e endereço da empresa`),
+        userAddressVerification: 'Verificação de endereço',
+        userAddressVerificationDescription: dedent(`
+        Envie um dos seguintes arquivos:
+        • Título de eleitor
+        • Carteira de motorista
+        • Extrato bancário
+        • Conta de serviços públicos`),
+        userDOBVerification: 'Verificação de data de nascimento',
+        userDOBVerificationDescription: 'Envie um documento de identidade emitido nos EUA',
+        finishViaChat: 'Finalizar pelo chat',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: 'Um momento',
         explanationLine: 'Estamos analisando suas informações. Em breve você poderá continuar com as próximas etapas.',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 23c246d3d493..239c068bc33a 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -3543,6 +3543,37 @@ ${
         weTake: '我们非常重视您的账户安全。请立即设置双重认证（2FA），为您的账户增加一层额外保护。',
         secure: '保护您的账户',
     },
+    documentsStep: {
+        beforeYouGo: '在继续之前，我们需要一些文件来验证相关信息',
+        subheader: '验证',
+        verificationFailed: '验证失败，因此我们需要额外的文件来验证你及你的企业',
+        taxIDVerification: '税务识别号验证',
+        taxIDVerificationDescription: dedent(`
+        请上传以下任一文件：
+        • IRS TIN/EIN 分配函
+        • IRS TIN/EIN 申请确认函（通常包含“Congratulations! The EIN has been successfully assigned”）
+        • 显示公司名称和 EIN 的 IRS 免税函`),
+        nameChangeDocument: '名称变更文件',
+        nameChangeDocumentDescription: '如果你的公司名称在申请 TIN/EIN 后发生更改，我们需要此文件来验证你提供的税务识别号',
+        companyAddressVerification: '公司地址验证',
+        companyAddressVerificationDescription: dedent(`
+        请上传以下任一文件：
+        • 显示公司名称和地址的近期水电账单
+        • 显示公司名称和地址的银行对账单
+        • 包含签字页的有效租赁协议，显示公司名称和当前地址
+        • 显示公司名称和地址的保险声明
+        • 显示公司名称和地址的 TIN 分配文件`),
+        userAddressVerification: '地址验证',
+        userAddressVerificationDescription: dedent(`
+        请上传以下任一文件：
+        • 选民登记卡
+        • 驾驶证
+        • 银行对账单
+        • 水电账单`),
+        userDOBVerification: '出生日期验证',
+        userDOBVerificationDescription: '请上传美国签发的身份证件',
+        finishViaChat: '通过聊天完成',
+    },
     reimbursementAccountLoadingAnimation: {
         oneMoment: '请稍候',
         explanationLine: '我们正在查看您的信息。您很快就可以继续下一步了。',
diff --git a/src/libs/API/parameters/UploadUserKYBDocsParams.ts b/src/libs/API/parameters/UploadUserKYBDocsParams.ts
index faedf9495941..4006596933bd 100644
--- a/src/libs/API/parameters/UploadUserKYBDocsParams.ts
+++ b/src/libs/API/parameters/UploadUserKYBDocsParams.ts
@@ -1,5 +1,5 @@
 type UploadUserKYBDocsParams = {
-    bankAccountID: string;
+    bankAccountID: number;
     inputs: string;
 };
 
diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts
index eecda7afd120..45a625c24528 100644
--- a/src/libs/actions/BankAccounts.ts
+++ b/src/libs/actions/BankAccounts.ts
@@ -991,6 +991,10 @@ function clearReimbursementAccountSendReminderForCorpaySignerInformation() {
     Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {isSuccess: null, isSendingReminderForCorpaySignerInformation: null});
 }
 
+function clearReimbursementAccountUploadKYBDocuments() {
+    Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {isSuccess: null, isUploadingKYBDocuments: null});
+}
+
 /**
  * Function to display and fetch data for Reimbursement Account step
  * @param stepToOpen - current step to open
@@ -1125,7 +1129,41 @@ function verifyIdentityForBankAccount(bankAccountID: number, onfidoData: OnfidoD
 }
 
 function uploadUserKYBDocs(parameters: UploadUserKYBDocsParams) {
-    API.write(WRITE_COMMANDS.UPLOAD_USER_KYB_DOCS, parameters, getVBBADataForOnyx());
+    const onyxData: OnyxData = {
+        optimisticData: [
+            {
+                onyxMethod: Onyx.METHOD.MERGE,
+                key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
+                value: {
+                    isUploadingKYBDocuments: true,
+                    errors: null,
+                },
+            },
+        ],
+        successData: [
+            {
+                onyxMethod: Onyx.METHOD.MERGE,
+                key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
+                value: {
+                    isUploadingKYBDocuments: false,
+                    isSuccess: true,
+                },
+            },
+        ],
+        failureData: [
+            {
+                onyxMethod: Onyx.METHOD.MERGE,
+                key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
+                value: {
+                    isUploadingKYBDocuments: false,
+                    isSuccess: false,
+                    errors: getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
+                },
+            },
+        ],
+    };
+
+    API.write(WRITE_COMMANDS.UPLOAD_USER_KYB_DOCS, parameters, onyxData);
 }
 
 function openWorkspaceView(policyID: string | undefined) {
@@ -1438,4 +1476,5 @@ export {
     openBankAccountSharePage,
     clearShareBankAccountErrors,
     uploadUserKYBDocs,
+    clearReimbursementAccountUploadKYBDocuments,
 };
diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index 44b9f31e6607..a6211130066d 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -1,4 +1,4 @@
-import React, {useCallback, useMemo, useState} from 'react';
+import React, {useCallback, useEffect, useMemo, useState} from 'react';
 import {View} from 'react-native';
 import Button from '@components/Button';
 import FormProvider from '@components/Form/FormProvider';
@@ -12,6 +12,7 @@ import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
 import isUserAddressVerificationRequired from '@pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired';
 import isUserDOBVerificationRequired from '@pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired';
+import {clearReimbursementAccountUploadKYBDocuments, uploadUserKYBDocs} from '@userActions/BankAccounts';
 import {clearErrorFields, setDraftValues, setErrorFields} from '@userActions/FormActions';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -29,8 +30,15 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: false});
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT, {canBeMissing: true});
     const reimbursementAccountData = reimbursementAccount?.achData?.verifications?.externalApiResponse;
+    const bankAccountID = reimbursementAccount?.achData?.bankAccountID ?? CONST.DEFAULT_NUMBER_ID;
 
-    const submit = useCallback(() => {}, []);
+    const defaultValues = {
+        companyTaxID: reimbursementAccountDraft?.companyTaxID ?? [],
+        nameChangeDocument: reimbursementAccountDraft?.nameChangeDocument ?? [],
+        companyAddressVerification: reimbursementAccountDraft?.companyAddressVerification ?? [],
+        userAddressVerification: reimbursementAccountDraft?.userAddressVerification ?? [],
+        userDOBVerification: reimbursementAccountDraft?.userDOBVerification ?? [],
+    } as Record<string, FileObject[]>;
 
     const DOCUMENTS_CONFIG = useMemo(
         () =>
@@ -80,13 +88,7 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
         ],
     );
 
-    const [uploadedFiles, setUploadedFiles] = useState<Record<string, FileObject[]>>({
-        companyTaxID: [],
-        nameChangeDocument: [],
-        companyAddressVerification: [],
-        userAddressVerification: [],
-        userDOBVerification: [],
-    });
+    const [uploadedFiles, setUploadedFiles] = useState<Record<string, FileObject[]>>(defaultValues);
 
     const validate = useCallback(
         (values: FormOnyxValues<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> => {
@@ -130,6 +132,13 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
         setErrorFields(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: {onUpload: error}});
     }, []);
 
+    const submit = useCallback(() => {
+        uploadUserKYBDocs({
+            inputs: JSON.stringify(uploadedFiles),
+            bankAccountID,
+        });
+    }, [bankAccountID, uploadedFiles]);
+
     const requiredDocuments = DOCUMENTS_CONFIG.filter((document) => document.required);
     const footer = (
         <Button
@@ -140,6 +149,21 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
         />
     );
 
+    useEffect(() => {
+        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
+        if (reimbursementAccount?.errors || reimbursementAccount?.isUploadingKYBDocuments || !reimbursementAccount?.isSuccess) {
+            return;
+        }
+
+        if (reimbursementAccount?.isSuccess) {
+            clearReimbursementAccountUploadKYBDocuments();
+        }
+
+        return () => {
+            clearReimbursementAccountUploadKYBDocuments();
+        };
+    }, [reimbursementAccount?.errors, reimbursementAccount?.isUploadingKYBDocuments, reimbursementAccount?.isSuccess]);
+
     return (
         <InteractiveStepWrapper
             wrapperID={KYBDocuments.displayName}
diff --git a/src/types/form/ReimbursementAccountForm.ts b/src/types/form/ReimbursementAccountForm.ts
index da2b9ff645d6..2e626899daa1 100644
--- a/src/types/form/ReimbursementAccountForm.ts
+++ b/src/types/form/ReimbursementAccountForm.ts
@@ -68,7 +68,7 @@ const INPUT_IDS = {
         SECOND_SIGNER_EMAIL: 'secondSignerEmail',
     },
     KYB_DOCUMENTS: {
-        COMPANY_TAX_ID: 'companyTaxID',
+        COMPANY_TAX_ID: 'companyTaxId',
         NAME_CHANGE_DOCUMENT: 'nameChangeDocument',
         COMPANY_ADDRESS_VERIFICATION: 'companyAddressVerification',
         USER_ADDRESS_VERIFICATION: 'userAddressVerification',
@@ -229,8 +229,8 @@ type KYBDocumentsStepProps = {
     [INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID]: FileObject[];
     [INPUT_IDS.KYB_DOCUMENTS.NAME_CHANGE_DOCUMENT]: FileObject[];
     [INPUT_IDS.KYB_DOCUMENTS.COMPANY_ADDRESS_VERIFICATION]: FileObject[];
-    [INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID]: FileObject[];
-    [INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID]: FileObject[];
+    [INPUT_IDS.KYB_DOCUMENTS.USER_DOB_VERIFICATION]: FileObject[];
+    [INPUT_IDS.KYB_DOCUMENTS.USER_ADDRESS_VERIFICATION]: FileObject[];
 };
 
 type ReimbursementAccountProps = {
diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts
index 718363f618b4..f4b2aab477d2 100644
--- a/src/types/onyx/ReimbursementAccount.ts
+++ b/src/types/onyx/ReimbursementAccount.ts
@@ -283,6 +283,9 @@ type ReimbursementAccount = OnyxCommon.OnyxValueWithOfflineFeedback<{
     /** Whether we are sending a reminder about filling signer information via the API */
     isSendingReminderForCorpaySignerInformation?: boolean;
 
+    /** Whether we are uploading KYB documents via the API */
+    isUploadingKYBDocuments?: boolean;
+
     /** Where the request is successful */
     isSuccess?: boolean;
 

From 6faea26e37fc5c01be097251402c80633c4e9f8f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Mon, 29 Dec 2025 15:57:14 +0100
Subject: [PATCH 08/27] fix: checks

---
 src/libs/API/types.ts                         |   1 -
 .../USD/KYBDocuments/index.tsx                | 139 ++++++++----------
 2 files changed, 59 insertions(+), 81 deletions(-)

diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts
index 7093e5d0b32c..8007226699e0 100644
--- a/src/libs/API/types.ts
+++ b/src/libs/API/types.ts
@@ -5,7 +5,6 @@ import type {EmptyObject} from '@src/types/utils/EmptyObject';
 // We have to disable eslint for this import because otherwise the import will be 300 lines long
 // eslint-disable-next-line no-restricted-syntax
 import type * as Parameters from './parameters';
-import {UploadUserKYBDocsParams} from './parameters';
 import type SignInUserParams from './parameters/SignInUserParams';
 import type UpdateBeneficialOwnersForBankAccountParams from './parameters/UpdateBeneficialOwnersForBankAccountParams';
 
diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index a6211130066d..26b71477a235 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -1,4 +1,4 @@
-import React, {useCallback, useEffect, useMemo, useState} from 'react';
+import React, {useEffect, useState} from 'react';
 import {View} from 'react-native';
 import Button from '@components/Button';
 import FormProvider from '@components/Form/FormProvider';
@@ -40,104 +40,83 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
         userDOBVerification: reimbursementAccountDraft?.userDOBVerification ?? [],
     } as Record<string, FileObject[]>;
 
-    const DOCUMENTS_CONFIG = useMemo(
-        () =>
-            [
-                {
-                    inputID: 'companyTaxID',
-                    title: 'documentsStep.taxIDVerification',
-                    description: 'documentsStep.taxIDVerificationDescription',
-                    required: reimbursementAccountData?.companyTaxID?.status !== 'pass',
-                },
-                {
-                    inputID: 'nameChangeDocument',
-                    title: 'documentsStep.nameChangeDocument',
-                    description: 'documentsStep.nameChangeDocumentDescription',
-                    required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
-                },
-                {
-                    inputID: 'companyAddressVerification',
-                    title: 'documentsStep.companyAddressVerification',
-                    description: 'documentsStep.companyAddressVerificationDescription',
-                    required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
-                },
-                {
-                    inputID: 'userAddressVerification',
-                    title: 'documentsStep.userAddressVerification',
-                    description: 'documentsStep.userAddressVerificationDescription',
-                    required: isUserAddressVerificationRequired(
-                        reimbursementAccountData?.requestorIdentityID?.status,
-                        reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
-                    ),
-                },
-                {
-                    inputID: 'userDOBVerification',
-                    title: 'documentsStep.userDOBVerification',
-                    description: 'documentsStep.userDOBVerificationDescription',
-                    required: isUserDOBVerificationRequired(
-                        reimbursementAccountData?.requestorIdentityID?.status,
-                        reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
-                    ),
-                },
-            ] as const,
-        [
-            reimbursementAccountData?.companyTaxID?.status,
-            reimbursementAccountData?.lexisNexisInstantIDResult?.status,
-            reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
-            reimbursementAccountData?.requestorIdentityID?.status,
-        ],
-    );
+    const DOCUMENTS_CONFIG = [
+        {
+            inputID: 'companyTaxID',
+            title: 'documentsStep.taxIDVerification',
+            description: 'documentsStep.taxIDVerificationDescription',
+            required: reimbursementAccountData?.companyTaxID?.status !== 'pass',
+        },
+        {
+            inputID: 'nameChangeDocument',
+            title: 'documentsStep.nameChangeDocument',
+            description: 'documentsStep.nameChangeDocumentDescription',
+            required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
+        },
+        {
+            inputID: 'companyAddressVerification',
+            title: 'documentsStep.companyAddressVerification',
+            description: 'documentsStep.companyAddressVerificationDescription',
+            required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
+        },
+        {
+            inputID: 'userAddressVerification',
+            title: 'documentsStep.userAddressVerification',
+            description: 'documentsStep.userAddressVerificationDescription',
+            required: isUserAddressVerificationRequired(
+                reimbursementAccountData?.requestorIdentityID?.status,
+                reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
+            ),
+        },
+        {
+            inputID: 'userDOBVerification',
+            title: 'documentsStep.userDOBVerification',
+            description: 'documentsStep.userDOBVerificationDescription',
+            required: isUserDOBVerificationRequired(reimbursementAccountData?.requestorIdentityID?.status, reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier),
+        },
+    ] as const;
 
     const [uploadedFiles, setUploadedFiles] = useState<Record<string, FileObject[]>>(defaultValues);
 
-    const validate = useCallback(
-        (values: FormOnyxValues<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> => {
-            const errors: FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> = {};
+    const validate = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> => {
+        const errors: FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> = {};
 
-            for (const document of DOCUMENTS_CONFIG.filter((documentItem) => documentItem.required)) {
-                const files = values[document.inputID] as FileObject[] | undefined;
-                if (!files || files.length === 0) {
-                    errors[document.inputID] = translate('common.error.fieldRequired');
-                }
+        for (const document of DOCUMENTS_CONFIG.filter((documentItem) => documentItem.required)) {
+            const files = values[document.inputID] as FileObject[] | undefined;
+            if (!files || files.length === 0) {
+                errors[document.inputID] = translate('common.error.fieldRequired');
             }
+        }
 
-            return errors;
-        },
-        [DOCUMENTS_CONFIG, translate],
-    );
+        return errors;
+    };
 
-    const handleSelectFile = useCallback(
-        (files: FileObject[], inputID: string) => {
-            const updatedFiles = [...uploadedFiles[inputID], ...files];
-            setUploadedFiles((prev) => ({...prev, [inputID]: updatedFiles}));
-            setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: updatedFiles});
-        },
-        [uploadedFiles],
-    );
+    const handleSelectFile = (files: FileObject[], inputID: string) => {
+        const updatedFiles = [...uploadedFiles[inputID], ...files];
+        setUploadedFiles((prev) => ({...prev, [inputID]: updatedFiles}));
+        setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: updatedFiles});
+    };
 
-    const handleRemoveFile = useCallback(
-        (fileName: string, inputID: string) => {
-            const updatedFiles = uploadedFiles[inputID].filter((file) => file.name !== fileName);
-            setUploadedFiles((prev) => ({...prev, [inputID]: updatedFiles}));
-            setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: updatedFiles});
-        },
-        [uploadedFiles],
-    );
+    const handleRemoveFile = (fileName: string, inputID: string) => {
+        const updatedFiles = uploadedFiles[inputID].filter((file) => file.name !== fileName);
+        setUploadedFiles((prev) => ({...prev, [inputID]: updatedFiles}));
+        setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: updatedFiles});
+    };
 
-    const setUploadError = useCallback((error: string, inputID: string) => {
+    const setUploadError = (error: string, inputID: string) => {
         if (!error) {
             clearErrorFields(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM);
             return;
         }
         setErrorFields(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: {onUpload: error}});
-    }, []);
+    };
 
-    const submit = useCallback(() => {
+    const submit = () => {
         uploadUserKYBDocs({
             inputs: JSON.stringify(uploadedFiles),
             bankAccountID,
         });
-    }, [bankAccountID, uploadedFiles]);
+    };
 
     const requiredDocuments = DOCUMENTS_CONFIG.filter((document) => document.required);
     const footer = (

From 840da4ff537f64db8d8dc27b2288b150cf83d86d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Tue, 30 Dec 2025 12:10:27 +0100
Subject: [PATCH 09/27] fix: add kyb param

---
 src/libs/API/parameters/OpenReimbursementAccountPageParams.ts | 1 +
 src/libs/actions/BankAccounts.ts                              | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts b/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts
index 8e4ae5208a2e..b578da492bb3 100644
--- a/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts
+++ b/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts
@@ -8,6 +8,7 @@ type OpenReimbursementAccountPageParams = {
     subStep: ReimbursementAccountSubStep;
     localCurrentStep: ReimbursementAccountStep;
     policyID: string;
+    includeKYBStep: boolean;
 };
 
 export default OpenReimbursementAccountPageParams;
diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts
index 45a625c24528..0f417c70c627 100644
--- a/src/libs/actions/BankAccounts.ts
+++ b/src/libs/actions/BankAccounts.ts
@@ -1038,6 +1038,7 @@ function openReimbursementAccountPage(stepToOpen: ReimbursementAccountStep, subS
         subStep,
         localCurrentStep,
         policyID,
+        includeKYBStep: true,
     };
 
     return API.read(READ_COMMANDS.OPEN_REIMBURSEMENT_ACCOUNT_PAGE, parameters, onyxData);

From 3a4d54d4c755f300b70cc54a78ff99615aa9de8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Mon, 16 Feb 2026 13:32:00 +0100
Subject: [PATCH 10/27] feat: param name

---
 src/libs/API/parameters/AcceptACHContractForBankAccount.ts   | 2 +-
 .../API/parameters/OpenReimbursementAccountPageParams.ts     | 2 +-
 src/libs/actions/BankAccounts.ts                             | 5 +++--
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/libs/API/parameters/AcceptACHContractForBankAccount.ts b/src/libs/API/parameters/AcceptACHContractForBankAccount.ts
index 52e5d2cec62e..baafd70d0246 100644
--- a/src/libs/API/parameters/AcceptACHContractForBankAccount.ts
+++ b/src/libs/API/parameters/AcceptACHContractForBankAccount.ts
@@ -1,5 +1,5 @@
 import type {ACHContractStepProps} from '@src/types/form/ReimbursementAccountForm';
 
-type AcceptACHContractForBankAccount = ACHContractStepProps & {bankAccountID: number; policyID: string | undefined};
+type AcceptACHContractForBankAccount = ACHContractStepProps & {bankAccountID: number; policyID: string | undefined; includeUploadKYBSetupStep: boolean};
 
 export default AcceptACHContractForBankAccount;
diff --git a/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts b/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts
index 5f05d98db0a2..4b99ec08891d 100644
--- a/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts
+++ b/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts
@@ -9,7 +9,7 @@ type OpenReimbursementAccountPageParams = {
     localCurrentStep: ReimbursementAccountStep;
     policyID: string;
     shouldPreserveDraft?: boolean;
-    includeKYBStep: boolean;
+    includeUploadKYBSetupStep: boolean;
 };
 
 export default OpenReimbursementAccountPageParams;
diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts
index 82f27e03088f..dd7e44948243 100644
--- a/src/libs/actions/BankAccounts.ts
+++ b/src/libs/actions/BankAccounts.ts
@@ -1061,7 +1061,7 @@ function openReimbursementAccountPage(
         localCurrentStep,
         policyID,
         shouldPreserveDraft,
-        includeKYBStep: true,
+        includeUploadKYBSetupStep: true,
     };
 
     return API.read(READ_COMMANDS.OPEN_REIMBURSEMENT_ACCOUNT_PAGE, parameters, onyxData);
@@ -1118,6 +1118,7 @@ function acceptACHContractForBankAccount(bankAccountID: number, params: ACHContr
             ...params,
             bankAccountID,
             policyID,
+            includeUploadKYBSetupStep: true,
         },
         onyxData,
     );
@@ -1156,7 +1157,7 @@ function verifyIdentityForBankAccount(bankAccountID: number, onfidoData: OnfidoD
 }
 
 function uploadUserKYBDocs(parameters: UploadUserKYBDocsParams) {
-    const onyxData: OnyxData = {
+    const onyxData: OnyxData<typeof ONYXKEYS.REIMBURSEMENT_ACCOUNT> = {
         optimisticData: [
             {
                 onyxMethod: Onyx.METHOD.MERGE,

From 5b0aaa79c4d1128ecb865e5c9c384f37b2fd0785 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Wed, 11 Mar 2026 14:49:47 +0100
Subject: [PATCH 11/27] fix: can be missing

---
 src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index 26b71477a235..ee6cdc195701 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -27,8 +27,8 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
-    const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: false});
-    const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT, {canBeMissing: true});
+    const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
+    const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT);
     const reimbursementAccountData = reimbursementAccount?.achData?.verifications?.externalApiResponse;
     const bankAccountID = reimbursementAccount?.achData?.bankAccountID ?? CONST.DEFAULT_NUMBER_ID;
 

From 1a3656881b4070c3ba471eb1ec1efb798061112c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Fri, 10 Apr 2026 14:56:38 +0200
Subject: [PATCH 12/27] feat: after rebase

---
 src/CONST/index.ts                                |  1 +
 .../Address.tsx                                   | 15 +--------------
 .../ReimbursementAccountPage.tsx                  |  1 +
 .../USD/KYBDocuments/index.tsx                    |  6 +++---
 .../USD/USDVerifiedBankAccountFlowPage.tsx        |  2 ++
 5 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index 9165b0abe5ff..20fe8af0d3c5 100644
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -619,6 +619,7 @@ const CONST = {
             ACH_CONTRACT: 'ach-contract',
             VALIDATION: 'validation',
             ENABLE: 'enable',
+            KYB_DOCS: 'upload-kyb-documents',
         },
         STEP_NAMES: ['1', '2', '3', '4', '5', '6'],
         BANK_INFO_STEP: {
diff --git a/src/pages/ReimbursementAccount/NonUSD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormSubSteps/Address.tsx b/src/pages/ReimbursementAccount/NonUSD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormSubSteps/Address.tsx
index a75fbaf04eb5..25b1c6b2153f 100644
--- a/src/pages/ReimbursementAccount/NonUSD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormSubSteps/Address.tsx
+++ b/src/pages/ReimbursementAccount/NonUSD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormSubSteps/Address.tsx
@@ -60,22 +60,9 @@ function Address({onNext, isEditing, onMove, isUserEnteringHisOwnData, ownerBein
         setShouldDisplayStateSelector(country === CONST.COUNTRY.US || country === CONST.COUNTRY.CA);
     };
 
-    const handleNextStep = () => {
-        // owner is US citizen so we need to gather last four digits of his SSN
-        if (nationality === CONST.COUNTRY.US) {
-            onNext();
-            // currency is set to GBP and owner is UK citizen, so we skip SSN and KYBDocuments step
-        } else if (countryStepCountryValue === CONST.COUNTRY.GB && nationality === CONST.COUNTRY.GB) {
-            onMove(7, false);
-            // owner is not US citizen so we skip SSN step
-        } else {
-            onMove(6, false);
-        }
-    };
-
     const handleSubmit = useReimbursementAccountStepFormSubmit({
         fieldIds: stepFields,
-        onNext: handleNextStep,
+        onNext,
         shouldSaveDraft: isEditing,
     });
 
diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx b/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx
index d174637aa8f8..4de7bfc73c7c 100644
--- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx
+++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx
@@ -358,6 +358,7 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy}: Reimbursemen
                 [CONST.BANK_ACCOUNT.STEP.COMPANY]: CONST.BANK_ACCOUNT.PAGE_NAMES.COMPANY,
                 [CONST.BANK_ACCOUNT.STEP.BENEFICIAL_OWNERS]: CONST.BANK_ACCOUNT.PAGE_NAMES.BENEFICIAL_OWNERS,
                 [CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT]: CONST.BANK_ACCOUNT.PAGE_NAMES.ACH_CONTRACT,
+                [CONST.BANK_ACCOUNT.STEP.KYB_DOCS]: CONST.BANK_ACCOUNT.PAGE_NAMES.KYB_DOCS,
                 [CONST.BANK_ACCOUNT.STEP.VALIDATION]: CONST.BANK_ACCOUNT.PAGE_NAMES.VALIDATION,
             };
             const page = stepToPageName[currentStep] ?? CONST.BANK_ACCOUNT.PAGE_NAMES.COUNTRY;
diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index ee6cdc195701..5a05ed70820e 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -45,19 +45,19 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
             inputID: 'companyTaxID',
             title: 'documentsStep.taxIDVerification',
             description: 'documentsStep.taxIDVerificationDescription',
-            required: reimbursementAccountData?.companyTaxID?.status !== 'pass',
+            required: reimbursementAccountData?.companyTaxID?.status !== undefined && reimbursementAccountData?.companyTaxID?.status !== 'pass',
         },
         {
             inputID: 'nameChangeDocument',
             title: 'documentsStep.nameChangeDocument',
             description: 'documentsStep.nameChangeDocumentDescription',
-            required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
+            required: (reimbursementAccountData?.lexisNexisInstantIDResult?.status !== undefined && reimbursementAccountData?.lexisNexisInstantIDResult?.status) !== 'pass',
         },
         {
             inputID: 'companyAddressVerification',
             title: 'documentsStep.companyAddressVerification',
             description: 'documentsStep.companyAddressVerificationDescription',
-            required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
+            required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== undefined && reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
         },
         {
             inputID: 'userAddressVerification',
diff --git a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx
index 1d6e95290437..e030b73c5ad6 100644
--- a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx
+++ b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx
@@ -15,6 +15,7 @@ import BusinessInfo from './BusinessInfo/BusinessInfo';
 import CompleteVerification from './CompleteVerification/CompleteVerification';
 import ConnectBankAccount from './ConnectBankAccount/ConnectBankAccount';
 import Country from './Country';
+import KYBDocuments from './KYBDocuments';
 import RequestorStep from './Requestor/RequestorStep';
 import VerifyIdentity from './Requestor/VerifyIdentity/VerifyIdentity';
 import type USDPageProps from './types';
@@ -61,6 +62,7 @@ const pages: PageEntry[] = [
         firstSubPage: COMPLETE_VERIFICATION_SUB_PAGES.CONFIRM_AGREEMENTS,
         lastSubPage: COMPLETE_VERIFICATION_SUB_PAGES.CONFIRM_AGREEMENTS,
     },
+    {pageName: PAGE_NAMES.KYB_DOCS, component: KYBDocuments as React.ComponentType<USDPageProps>},
     {pageName: PAGE_NAMES.VALIDATION, component: ConnectBankAccount as React.ComponentType<USDPageProps>},
 ];
 

From caf6acf5ad5fad477b1261936ef1a2d421f617f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Fri, 10 Apr 2026 16:12:46 +0200
Subject: [PATCH 13/27] fix: pass params differently

---
 src/libs/API/parameters/UploadUserKYBDocsParams.ts     |  8 +++++++-
 .../ReimbursementAccount/USD/KYBDocuments/index.tsx    | 10 +++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/libs/API/parameters/UploadUserKYBDocsParams.ts b/src/libs/API/parameters/UploadUserKYBDocsParams.ts
index 4006596933bd..b89605cb8fea 100644
--- a/src/libs/API/parameters/UploadUserKYBDocsParams.ts
+++ b/src/libs/API/parameters/UploadUserKYBDocsParams.ts
@@ -1,6 +1,12 @@
+import type {FileObject} from '@src/types/utils/Attachment';
+
 type UploadUserKYBDocsParams = {
     bankAccountID: number;
-    inputs: string;
+    companyTaxID?: FileObject;
+    nameChangeDocument?: FileObject;
+    companyAddressVerification?: FileObject;
+    userAddressVerification?: FileObject;
+    userDOBVerification?: FileObject;
 };
 
 export default UploadUserKYBDocsParams;
diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index 5a05ed70820e..036d66d89720 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -112,8 +112,15 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
     };
 
     const submit = () => {
+        const params: Record<string, FileObject> = {};
+        for (const [key, files] of Object.entries(uploadedFiles)) {
+            const file = files.at(0);
+            if (file) {
+                params[key] = file;
+            }
+        }
         uploadUserKYBDocs({
-            inputs: JSON.stringify(uploadedFiles),
+            ...params,
             bankAccountID,
         });
     };
@@ -161,6 +168,7 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
                 enabledWhenOffline={false}
                 shouldRenderFooterAboveSubmit
                 footerContent={footer}
+                isLoading={reimbursementAccount?.isUploadingKYBDocuments}
             >
                 <Text style={[styles.textHeadlineLineHeightXXL, styles.mb5]}>{translate('documentsStep.beforeYouGo')}</Text>
                 <Text style={[styles.textSupporting, styles.mb5]}>{translate('documentsStep.verificationFailed')}</Text>

From 3c9e92119f5000c43a22fa7a089963915d3585f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Wed, 6 May 2026 13:06:59 +0200
Subject: [PATCH 14/27] plug in finish via chat button and update the submit
 logic

---
 src/libs/actions/BankAccounts.ts              | 41 +------------
 .../USD/KYBDocuments/index.tsx                | 59 ++++++++++++-------
 src/types/onyx/ReimbursementAccount.ts        |  3 -
 3 files changed, 38 insertions(+), 65 deletions(-)

diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts
index 8451b3de55e8..073cb9dc8ed9 100644
--- a/src/libs/actions/BankAccounts.ts
+++ b/src/libs/actions/BankAccounts.ts
@@ -1068,10 +1068,6 @@ type OpenReimbursementAccountPageActionParams = {
     shouldPreserveDraft?: boolean;
 };
 
-function clearReimbursementAccountUploadKYBDocuments() {
-    Onyx.merge(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {isSuccess: null, isUploadingKYBDocuments: null});
-}
-
 /**
  * Function to display and fetch data for Reimbursement Account step
  * @param stepToOpen - current step to open
@@ -1215,41 +1211,7 @@ function verifyIdentityForBankAccount(bankAccountID: number, onfidoData: OnfidoD
 }
 
 function uploadUserKYBDocs(parameters: UploadUserKYBDocsParams) {
-    const onyxData: OnyxData<typeof ONYXKEYS.REIMBURSEMENT_ACCOUNT> = {
-        optimisticData: [
-            {
-                onyxMethod: Onyx.METHOD.MERGE,
-                key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
-                value: {
-                    isUploadingKYBDocuments: true,
-                    errors: null,
-                },
-            },
-        ],
-        successData: [
-            {
-                onyxMethod: Onyx.METHOD.MERGE,
-                key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
-                value: {
-                    isUploadingKYBDocuments: false,
-                    isSuccess: true,
-                },
-            },
-        ],
-        failureData: [
-            {
-                onyxMethod: Onyx.METHOD.MERGE,
-                key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
-                value: {
-                    isUploadingKYBDocuments: false,
-                    isSuccess: false,
-                    errors: getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
-                },
-            },
-        ],
-    };
-
-    API.write(WRITE_COMMANDS.UPLOAD_USER_KYB_DOCS, parameters, onyxData);
+    API.write(WRITE_COMMANDS.UPLOAD_USER_KYB_DOCS, parameters, getVBBADataForOnyx());
 }
 
 function openWorkspaceView(policyID: string | undefined) {
@@ -1762,5 +1724,4 @@ export {
     initiateBankAccountUnlock,
     pressLockedBankAccount,
     uploadUserKYBDocs,
-    clearReimbursementAccountUploadKYBDocuments,
 };
diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index 036d66d89720..fd4ec40f08a1 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -1,4 +1,5 @@
-import React, {useEffect, useState} from 'react';
+import {hasSeenTourSelector} from '@selectors/Onboarding';
+import React, {useCallback, useState} from 'react';
 import {View} from 'react-native';
 import Button from '@components/Button';
 import FormProvider from '@components/Form/FormProvider';
@@ -7,13 +8,16 @@ import type {FormInputErrors, FormOnyxValues} from '@components/Form/types';
 import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
 import Text from '@components/Text';
 import UploadFile from '@components/UploadFile';
+import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
+import useReimbursementAccountSubmitCallback from '@hooks/useReimbursementAccountSubmitCallback';
 import useThemeStyles from '@hooks/useThemeStyles';
 import isUserAddressVerificationRequired from '@pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired';
 import isUserDOBVerificationRequired from '@pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired';
-import {clearReimbursementAccountUploadKYBDocuments, uploadUserKYBDocs} from '@userActions/BankAccounts';
+import {uploadUserKYBDocs} from '@userActions/BankAccounts';
 import {clearErrorFields, setDraftValues, setErrorFields} from '@userActions/FormActions';
+import {navigateToConciergeChat} from '@userActions/Report';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import type {FileObject} from '@src/types/utils/Attachment';
@@ -21,16 +25,38 @@ import type {FileObject} from '@src/types/utils/Attachment';
 type KYBDocumentsProps = {
     /** Goes to the previous step */
     onBackButtonPress: () => void;
+
+    /** Handles submit button press (URL-based navigation) */
+    onSubmit?: () => void;
 };
 
-function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
+function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT);
+    const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
+    const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
+    const [betas] = useOnyx(ONYXKEYS.BETAS);
+    const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
+    const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails();
     const reimbursementAccountData = reimbursementAccount?.achData?.verifications?.externalApiResponse;
     const bankAccountID = reimbursementAccount?.achData?.bankAccountID ?? CONST.DEFAULT_NUMBER_ID;
+    const isLoading = reimbursementAccount?.isLoading;
+
+    const handleNavigateToConciergeChat = () =>
+        navigateToConciergeChat(
+            conciergeReportID,
+            introSelected,
+            currentUserAccountID,
+            isSelfTourViewed,
+            betas,
+            true,
+            undefined,
+            undefined,
+            reimbursementAccount?.achData?.ACHRequestReportActionID,
+        );
 
     const defaultValues = {
         companyTaxID: reimbursementAccountDraft?.companyTaxID ?? [],
@@ -111,7 +137,9 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
         setErrorFields(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {[inputID]: {onUpload: error}});
     };
 
-    const submit = () => {
+    const markSubmitting = useReimbursementAccountSubmitCallback(onSubmit);
+
+    const submit = useCallback(() => {
         const params: Record<string, FileObject> = {};
         for (const [key, files] of Object.entries(uploadedFiles)) {
             const file = files.at(0);
@@ -123,7 +151,8 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
             ...params,
             bankAccountID,
         });
-    };
+        markSubmitting();
+    }, [uploadedFiles, bankAccountID, markSubmitting]);
 
     const requiredDocuments = DOCUMENTS_CONFIG.filter((document) => document.required);
     const footer = (
@@ -131,25 +160,11 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
             large
             style={[styles.mv3]}
             text={translate('documentsStep.finishViaChat')}
-            onPress={() => {}}
+            onPress={handleNavigateToConciergeChat}
+            isDisabled={isLoading}
         />
     );
 
-    useEffect(() => {
-        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
-        if (reimbursementAccount?.errors || reimbursementAccount?.isUploadingKYBDocuments || !reimbursementAccount?.isSuccess) {
-            return;
-        }
-
-        if (reimbursementAccount?.isSuccess) {
-            clearReimbursementAccountUploadKYBDocuments();
-        }
-
-        return () => {
-            clearReimbursementAccountUploadKYBDocuments();
-        };
-    }, [reimbursementAccount?.errors, reimbursementAccount?.isUploadingKYBDocuments, reimbursementAccount?.isSuccess]);
-
     return (
         <InteractiveStepWrapper
             wrapperID={KYBDocuments.displayName}
@@ -168,7 +183,7 @@ function KYBDocuments({onBackButtonPress}: KYBDocumentsProps) {
                 enabledWhenOffline={false}
                 shouldRenderFooterAboveSubmit
                 footerContent={footer}
-                isLoading={reimbursementAccount?.isUploadingKYBDocuments}
+                isLoading={isLoading}
             >
                 <Text style={[styles.textHeadlineLineHeightXXL, styles.mb5]}>{translate('documentsStep.beforeYouGo')}</Text>
                 <Text style={[styles.textSupporting, styles.mb5]}>{translate('documentsStep.verificationFailed')}</Text>
diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts
index 120a941961d3..b2635c26e0f2 100644
--- a/src/types/onyx/ReimbursementAccount.ts
+++ b/src/types/onyx/ReimbursementAccount.ts
@@ -307,9 +307,6 @@ type ReimbursementAccount = OnyxCommon.OnyxValueWithOfflineFeedback<{
     /** Whether we are sending a reminder about filling signer information via the API */
     isSendingReminderForCorpaySignerInformation?: boolean;
 
-    /** Whether we are uploading KYB documents via the API */
-    isUploadingKYBDocuments?: boolean;
-
     /** Where the request is successful */
     isSuccess?: boolean;
 

From ec512c795572216ce1c424cda9da2f7a5abaa203 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Fri, 8 May 2026 13:12:34 +0200
Subject: [PATCH 15/27] fix: const renaming

---
 src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index fd4ec40f08a1..eeba59431a1d 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -197,8 +197,8 @@ function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
                             onUpload={(files) => handleSelectFile(files, document.inputID)}
                             onRemove={(fileName) => handleRemoveFile(fileName, document.inputID)}
                             setError={(error) => setUploadError(error, document.inputID)}
-                            fileLimit={CONST.NON_USD_BANK_ACCOUNT.FILE_LIMIT}
-                            acceptedFileTypes={[...CONST.NON_USD_BANK_ACCOUNT.ALLOWED_FILE_TYPES]}
+                            fileLimit={CONST.CORPAY_DOCUMENT.FILE_LIMIT}
+                            acceptedFileTypes={[...CONST.CORPAY_DOCUMENT.ALLOWED_FILE_TYPES]}
                             value={uploadedFiles[document.inputID]}
                             inputID={document.inputID}
                         />

From 8c9d9f0d20db3b977ad42130dc9b26b2d211d424 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Fri, 8 May 2026 14:22:38 +0200
Subject: [PATCH 16/27] fix: false positive

---
 src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index eeba59431a1d..c3c2a6506349 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -77,7 +77,7 @@ function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
             inputID: 'nameChangeDocument',
             title: 'documentsStep.nameChangeDocument',
             description: 'documentsStep.nameChangeDocumentDescription',
-            required: (reimbursementAccountData?.lexisNexisInstantIDResult?.status !== undefined && reimbursementAccountData?.lexisNexisInstantIDResult?.status) !== 'pass',
+            required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== undefined && reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
         },
         {
             inputID: 'companyAddressVerification',

From 5c1bbf7ee28edbe0fa68c8784e78b1071dbbfa4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Tue, 12 May 2026 08:43:08 +0200
Subject: [PATCH 17/27] Reapply "feat: 79048 restore reverted usd flow"

This reverts commit 2a6276e99740955c761f50b9ab8163b0b2314568.
---
 src/CONST/index.ts                            |  58 +++++
 src/ROUTES.ts                                 |  37 ++-
 src/SCREENS.ts                                |   1 +
 src/components/Navigation/DebugTabView.tsx    |   6 +-
 .../useReimbursementAccountSubmitCallback.ts  |  28 +++
 .../ModalStackNavigators/index.tsx            |  14 ++
 src/libs/Navigation/linkingConfig/config.ts   |   4 +
 src/libs/Navigation/types.ts                  |   8 +
 src/libs/ReimbursementAccountUtils.ts         |  25 +-
 .../ConnectedVerifiedBankAccount.tsx          |   4 +-
 .../NonUSDVerifiedBankAccountFlowPage.tsx     |   2 +-
 .../ReimbursementAccountPage.tsx              |  40 ++-
 .../ReimbursementAccountVerifyAccountPage.tsx |   3 +-
 .../USD/BankInfo/BankInfo.tsx                 |  37 +--
 .../USD/BankInfo/subSteps/Manual.tsx          |   6 +-
 .../USD/BankInfo/subSteps/Plaid.tsx           |  12 +-
 .../USD/BankInfo/types.ts                     |   6 +
 .../BeneficialOwnerDetailsFormPages.tsx       | 123 ++++++++++
 .../BeneficialOwnersStep.tsx                  | 232 +++++++++---------
 .../AddressUBO.tsx                            |   4 +-
 .../ConfirmationUBO.tsx                       |   4 +-
 .../DateOfBirthUBO.tsx                        |   4 +-
 .../LegalNameUBO.tsx                          |   4 +-
 .../SocialSecurityNumberUBO.tsx               |   5 +-
 .../USD/BusinessInfo/BusinessInfo.tsx         |  80 +++---
 .../BusinessInfo/subSteps/AddressBusiness.tsx |   4 +-
 .../subSteps/ConfirmationBusiness.tsx         |  12 +-
 .../subSteps/IncorporationCode.tsx            |   4 +-
 .../subSteps/IncorporationDateBusiness.tsx    |   4 +-
 .../subSteps/IncorporationStateBusiness.tsx   |   4 +-
 .../IndustryCode/IndustryCodeSelector.tsx     |  23 +-
 .../BusinessInfo/subSteps/NameBusiness.tsx    |   5 +-
 .../subSteps/PhoneNumberBusiness.tsx          |   5 +-
 .../BusinessInfo/subSteps/TaxIdBusiness.tsx   |   5 +-
 .../subSteps/TypeBusiness/TypeBusiness.tsx    |   4 +-
 .../BusinessInfo/subSteps/WebsiteBusiness.tsx |   5 +-
 .../CompleteVerification.tsx                  |  37 +--
 .../subSteps/ConfirmAgreements.tsx            |   8 +-
 .../ConnectBankAccount/ConnectBankAccount.tsx |  30 ++-
 .../components/FinishChatCard.tsx             |   4 +-
 .../USD/Country/index.tsx                     |  14 +-
 .../Requestor/PersonalInfo/PersonalInfo.tsx   |  73 ++++--
 .../PersonalInfo/subSteps/Address.tsx         |   4 +-
 .../PersonalInfo/subSteps/Confirmation.tsx    |   4 +-
 .../PersonalInfo/subSteps/DateOfBirth.tsx     |   4 +-
 .../PersonalInfo/subSteps/FullName.tsx        |   4 +-
 .../subSteps/SocialSecurityNumber.tsx         |   5 +-
 .../USD/Requestor/RequestorStep.tsx           |  16 +-
 .../VerifyIdentity/VerifyIdentity.tsx         |  27 +-
 .../USD/USDVerifiedBankAccountFlow.tsx        |  97 --------
 .../USD/USDVerifiedBankAccountFlowPage.tsx    | 135 ++++++++++
 src/pages/ReimbursementAccount/USD/types.ts   |  28 +++
 .../VerifiedBankAccountFlowEntryPoint.tsx     |   4 +-
 .../WorkspaceExpensifyCardBankAccounts.tsx    |   2 -
 .../WorkspaceExpensifyCardPageEmptyState.tsx  |   3 +-
 .../WorkspaceTravelInvoicingSection.tsx       |   3 +-
 ...ceTravelInvoicingSettlementAccountPage.tsx |   2 -
 tests/unit/ReimbursementAccountUtilsTest.ts   |   9 +-
 58 files changed, 837 insertions(+), 498 deletions(-)
 create mode 100644 src/hooks/useReimbursementAccountSubmitCallback.ts
 create mode 100644 src/pages/ReimbursementAccount/USD/BankInfo/types.ts
 create mode 100644 src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormPages.tsx
 delete mode 100644 src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
 create mode 100644 src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx
 create mode 100644 src/pages/ReimbursementAccount/USD/types.ts

diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index f41294669029..c0aa10c9cc77 100644
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -629,7 +629,65 @@ const CONST = {
             VALIDATION: 'ValidationStep',
             ENABLE: 'EnableStep',
         },
+        PAGE_NAMES: {
+            COUNTRY: 'currency-and-country',
+            BANK_ACCOUNT: 'bank-info',
+            REQUESTOR: 'personal-info',
+            VERIFY_IDENTITY: 'verify-identity',
+            COMPANY: 'company',
+            BENEFICIAL_OWNERS: 'business-owner',
+            ACH_CONTRACT: 'ach-contract',
+            VALIDATION: 'validation',
+            ENABLE: 'enable',
+        },
         STEP_NAMES: ['1', '2', '3', '4', '5', '6'],
+        BANK_INFO_STEP: {
+            SUB_PAGE_NAMES: {
+                MANUAL: 'manual',
+                PLAID: 'plaid',
+            },
+        },
+        PERSONAL_INFO_STEP: {
+            SUB_PAGE_NAMES: {
+                FULL_NAME: 'full-name',
+                DATE_OF_BIRTH: 'date-of-birth',
+                SSN: 'ssn',
+                ADDRESS: 'address',
+                CONFIRMATION: 'confirmation',
+            },
+        },
+        BUSINESS_INFO_STEP: {
+            SUB_PAGE_NAMES: {
+                NAME: 'name',
+                TAX_ID: 'tax-id',
+                WEBSITE: 'website',
+                PHONE: 'phone',
+                ADDRESS: 'address',
+                TYPE: 'type',
+                INCORPORATION_DATE: 'start-date',
+                INCORPORATION_STATE: 'state',
+                INCORPORATION_CODE: 'code',
+                CONFIRMATION: 'confirmation',
+            },
+        },
+        BENEFICIAL_OWNERS_STEP: {
+            SUB_PAGE_NAMES: {
+                IS_USER_UBO: 'is-user-ubo',
+                IS_ANYONE_ELSE_UBO: 'is-anyone-else-ubo',
+                ARE_THERE_MORE_UBOS: 'are-there-more-ubos',
+                UBOS_LIST: 'ubos-list',
+                LEGAL_NAME: 'legal-name',
+                DATE_OF_BIRTH: 'date-of-birth',
+                SSN: 'ssn',
+                ADDRESS: 'address',
+                CONFIRMATION: 'confirmation',
+            },
+        },
+        COMPLETE_VERIFICATION_STEP: {
+            SUB_PAGE_NAMES: {
+                CONFIRM_AGREEMENTS: 'confirm-agreements',
+            },
+        },
         SUBSTEP: {
             MANUAL: 'manual',
             PLAID: 'plaid',
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index a474bbc6a5e9..fe9687e1c4fa 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -14,7 +14,6 @@ import type {ReplacementReason} from './libs/actions/Card';
 import type {IOURequestType} from './libs/actions/IOU';
 import Log from './libs/Log';
 import type {RootNavigatorParamList} from './libs/Navigation/types';
-import type {ReimbursementAccountStepToOpen} from './libs/ReimbursementAccountUtils';
 import StringUtils from './libs/StringUtils';
 import {getUrlWithParams} from './libs/Url';
 import SCREENS from './SCREENS';
@@ -624,36 +623,24 @@ const ROUTES = {
         // eslint-disable-next-line no-restricted-syntax -- Legacy route generation
         getRoute: (policyID?: string, backTo?: string) => getUrlWithBackToParam(`bank-account/${VERIFY_ACCOUNT}?policyID=${policyID}`, backTo),
     },
-    BANK_ACCOUNT_NEW: 'bank-account/new',
     BANK_ACCOUNT_PERSONAL: 'bank-account/personal',
+    // TODO: rename the route as no longer accepts step
     BANK_ACCOUNT_WITH_STEP_TO_OPEN: {
-        route: 'bank-account/:stepToOpen?',
-        getRoute: ({
-            policyID,
-            stepToOpen = '',
-            bankAccountID,
-            backTo,
-            subStepToOpen,
-        }: {
-            policyID: string | undefined;
-            stepToOpen?: ReimbursementAccountStepToOpen;
-            bankAccountID?: number;
-            backTo?: string;
-            subStepToOpen?: typeof CONST.BANK_ACCOUNT.STEP.COUNTRY;
-        }) => {
+        route: 'bank-account/new',
+        getRoute: ({policyID, bankAccountID, backTo}: {policyID: string | undefined; bankAccountID?: number; backTo?: string}) => {
             if (!policyID && !bankAccountID) {
                 // eslint-disable-next-line no-restricted-syntax -- Legacy route generation
-                return getUrlWithBackToParam(`bank-account/${stepToOpen}`, backTo);
+                return getUrlWithBackToParam(`bank-account/new`, backTo);
             }
 
             if (bankAccountID) {
                 // eslint-disable-next-line no-restricted-syntax -- Legacy route generation
-                return getUrlWithBackToParam(`bank-account/${stepToOpen}?bankAccountID=${bankAccountID}`, backTo);
+                return getUrlWithBackToParam(`bank-account/new?bankAccountID=${bankAccountID}`, backTo);
             }
             // TODO this backTo comes from drilling it through bank account form screens
             // should be removed once https://github.com/Expensify/App/pull/72219 is resolved
             // eslint-disable-next-line no-restricted-syntax -- Legacy route generation
-            return getUrlWithBackToParam(`bank-account/${stepToOpen}?policyID=${policyID}${subStepToOpen ? `&subStep=${subStepToOpen}` : ''}`, backTo);
+            return getUrlWithBackToParam(`bank-account/new?policyID=${policyID}`, backTo);
         },
     },
     BANK_ACCOUNT_ENTER_SIGNER_INFO: {
@@ -685,6 +672,18 @@ const ROUTES = {
             return getUrlWithBackToParam(`${base}${pagePart}${subPagePart}${actionPart}${queryString}`, backTo);
         },
     },
+    BANK_ACCOUNT_USD_SETUP: {
+        route: 'bank-account/new/us/:page?/:subPage?/:action?',
+        getRoute: ({policyID, page, subPage, action, backTo}: {policyID?: string; page?: string; subPage?: string; action?: 'edit'; backTo?: string}) => {
+            const base = 'bank-account/new/us';
+            const pagePart = page ? `/${page}` : '';
+            const subPagePart = subPage ? `/${subPage}` : '';
+            const actionPart = action ? `/${action}` : '';
+            const queryString = policyID ? `?policyID=${policyID}` : '';
+            // eslint-disable-next-line no-restricted-syntax -- Legacy route generation
+            return getUrlWithBackToParam(`${base}${pagePart}${subPagePart}${actionPart}${queryString}`, backTo);
+        },
+    },
     SETTINGS: 'settings',
     SETTINGS_PROFILE: {
         route: 'settings/profile',
diff --git a/src/SCREENS.ts b/src/SCREENS.ts
index e9450573c282..566dc62b8dd9 100644
--- a/src/SCREENS.ts
+++ b/src/SCREENS.ts
@@ -970,6 +970,7 @@ const SCREENS = {
     },
     DYNAMIC_FLAG_COMMENT: 'Dynamic_Flag_Comment',
     REIMBURSEMENT_ACCOUNT: 'ReimbursementAccount',
+    REIMBURSEMENT_ACCOUNT_USD: 'Reimbursement_Account_USD',
     REIMBURSEMENT_ACCOUNT_NON_USD: 'Reimbursement_Account_Non_USD',
     REIMBURSEMENT_ACCOUNT_ENTER_SIGNER_INFO: 'Reimbursement_Account_Signer_Info',
     REFERRAL_DETAILS: 'Referral_Details',
diff --git a/src/components/Navigation/DebugTabView.tsx b/src/components/Navigation/DebugTabView.tsx
index 536998617597..b0778412dafd 100644
--- a/src/components/Navigation/DebugTabView.tsx
+++ b/src/components/Navigation/DebugTabView.tsx
@@ -15,7 +15,6 @@ import useStyleUtils from '@hooks/useStyleUtils';
 import useTheme from '@hooks/useTheme';
 import useThemeStyles from '@hooks/useThemeStyles';
 import Navigation from '@libs/Navigation/Navigation';
-import {getRouteForCurrentStep as getReimbursementAccountRouteForCurrentStep} from '@libs/ReimbursementAccountUtils';
 import type {BrickRoad} from '@libs/WorkspacesSettingsUtils';
 import {getChatTabBrickRoadReportID} from '@libs/WorkspacesSettingsUtils';
 import CONST from '@src/CONST';
@@ -82,10 +81,7 @@ function getSettingsRoute(status: IndicatorStatus | undefined, reimbursementAcco
         case CONST.INDICATOR_STATUS.HAS_POLICY_ERRORS:
             return ROUTES.WORKSPACE_INITIAL.getRoute(policyIDWithErrors);
         case CONST.INDICATOR_STATUS.HAS_REIMBURSEMENT_ACCOUNT_ERRORS:
-            return ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({
-                policyID: reimbursementAccount?.achData?.policyID,
-                stepToOpen: getReimbursementAccountRouteForCurrentStep(reimbursementAccount?.achData?.currentStep ?? CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT),
-            });
+            return ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({policyID: reimbursementAccount?.achData?.policyID});
         case CONST.INDICATOR_STATUS.HAS_SUBSCRIPTION_ERRORS:
             return ROUTES.SETTINGS_SUBSCRIPTION.route;
         case CONST.INDICATOR_STATUS.HAS_SUBSCRIPTION_INFO:
diff --git a/src/hooks/useReimbursementAccountSubmitCallback.ts b/src/hooks/useReimbursementAccountSubmitCallback.ts
new file mode 100644
index 000000000000..90fdc0026166
--- /dev/null
+++ b/src/hooks/useReimbursementAccountSubmitCallback.ts
@@ -0,0 +1,28 @@
+import {useCallback, useEffect, useRef} from 'react';
+import ONYXKEYS from '@src/ONYXKEYS';
+import useOnyx from './useOnyx';
+
+/**
+ * Defers navigation (onSubmit) until the reimbursement account API call completes.
+ * Instead of navigating to the next step immediately after firing the API call,
+ * this hook waits for `isLoading` to go back to `false` and checks for errors.
+ *
+ * @param onSubmit - callback that navigates to the next step
+ * @returns markSubmitting - call this right after firing the API action
+ */
+export default function useReimbursementAccountSubmitCallback(onSubmit?: () => void) {
+    const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
+    const isSubmittingRef = useRef(false);
+
+    useEffect(() => {
+        if (!isSubmittingRef.current || reimbursementAccount?.isLoading || reimbursementAccount?.errors) {
+            return;
+        }
+        isSubmittingRef.current = false;
+        onSubmit?.();
+    }, [reimbursementAccount?.isLoading, reimbursementAccount?.errors, onSubmit]);
+
+    return useCallback(() => {
+        isSubmittingRef.current = true;
+    }, []);
+}
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
index 5f02416ae24a..e8c8aaea6eaa 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
@@ -3,6 +3,7 @@ import React, {useCallback} from 'react';
 import {View} from 'react-native';
 import useResponsiveLayout from '@hooks/useResponsiveLayout';
 import useThemeStyles from '@hooks/useThemeStyles';
+import {isMobileChrome} from '@libs/Browser';
 import createPlatformStackNavigator from '@libs/Navigation/PlatformStackNavigation/createPlatformStackNavigator';
 import Animations from '@libs/Navigation/PlatformStackNavigation/navigationOptions/animation';
 import type {PlatformStackNavigationOptions} from '@libs/Navigation/PlatformStackNavigation/types';
@@ -62,6 +63,17 @@ const loadAttachmentModalScreen = () => require<ReactComponentModule>('../../../
 
 type Screens = Partial<Record<Screen, () => React.ComponentType>>;
 
+// Reimbursement Account flow animations glitch on low-end Android devices in Chrome mWeb https://github.com/Expensify/App/issues/87658 so we intentionally disable them
+const IS_MOBILE_CHROME = isMobileChrome();
+
+const REIMBURSEMENT_ACCOUNT_FLOW_SCREENS: Screen[] = [
+    SCREENS.REIMBURSEMENT_ACCOUNT,
+    SCREENS.REIMBURSEMENT_ACCOUNT_USD,
+    SCREENS.REIMBURSEMENT_ACCOUNT_NON_USD,
+    SCREENS.REIMBURSEMENT_ACCOUNT_VERIFY_ACCOUNT,
+    SCREENS.REIMBURSEMENT_ACCOUNT_ENTER_SIGNER_INFO,
+];
+
 const OPTIONS_PER_SCREEN: Partial<Record<Screen, PlatformStackNavigationOptions>> = {
     [SCREENS.SETTINGS.MERGE_ACCOUNTS.MERGE_RESULT]: {
         animationTypeForReplace: 'push',
@@ -114,6 +126,7 @@ const OPTIONS_PER_SCREEN: Partial<Record<Screen, PlatformStackNavigationOptions>
     [SCREENS.WORKSPACE.DYNAMIC_CATEGORIES_IMPORTED]: {
         animationTypeForReplace: 'push',
     },
+    ...(IS_MOBILE_CHROME ? Object.fromEntries(REIMBURSEMENT_ACCOUNT_FLOW_SCREENS.map((screen) => [screen, {animation: Animations.NONE}])) : {}),
 };
 
 /**
@@ -671,6 +684,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
     [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_DESKTOP_ITEMS]: () => require<ReactComponentModule>('../../../../pages/workspace/accounting/qbd/import/QuickbooksDesktopItemsPage').default,
     [SCREENS.CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT_ROOT]: () => require<ReactComponentModule>('@pages/workspace/ConnectExistingBusinessBankAccountPage').default,
     [SCREENS.REIMBURSEMENT_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/ReimbursementAccount/ReimbursementAccountPage').default,
+    [SCREENS.REIMBURSEMENT_ACCOUNT_USD]: () => require<ReactComponentModule>('../../../../pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage').default,
     [SCREENS.REIMBURSEMENT_ACCOUNT_NON_USD]: () => require<ReactComponentModule>('../../../../pages/ReimbursementAccount/NonUSD/NonUSDVerifiedBankAccountFlowPage').default,
     [SCREENS.REIMBURSEMENT_ACCOUNT_VERIFY_ACCOUNT]: () => require<ReactComponentModule>('../../../../pages/ReimbursementAccount/ReimbursementAccountVerifyAccountPage').default,
     [SCREENS.REIMBURSEMENT_ACCOUNT_ENTER_SIGNER_INFO]: () => require<ReactComponentModule>('../../../../pages/ReimbursementAccount/EnterSignerInfo').default,
diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts
index 26cacff5c40a..d26b86691ff7 100644
--- a/src/libs/Navigation/linkingConfig/config.ts
+++ b/src/libs/Navigation/linkingConfig/config.ts
@@ -1174,6 +1174,10 @@ const config: LinkingOptions<RootNavigatorParamList>['config'] = {
                             path: ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.route,
                             exact: true,
                         },
+                        [SCREENS.REIMBURSEMENT_ACCOUNT_USD]: {
+                            path: ROUTES.BANK_ACCOUNT_USD_SETUP.route,
+                            exact: true,
+                        },
                         [SCREENS.REIMBURSEMENT_ACCOUNT_NON_USD]: {
                             path: ROUTES.BANK_ACCOUNT_NON_USD_SETUP.route,
                             exact: true,
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index e8212b24c2d3..938706f634b7 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -2329,6 +2329,14 @@ type ReimbursementAccountNavigatorParamList = {
         bankAccountID?: string;
         subStep?: typeof CONST.BANK_ACCOUNT.STEP.COUNTRY;
     };
+    [SCREENS.REIMBURSEMENT_ACCOUNT_USD]: {
+        page?: string;
+        subPage?: string;
+        action?: 'edit';
+        policyID?: string;
+        // eslint-disable-next-line no-restricted-syntax -- backTo is a temporary param will be removed after https://github.com/Expensify/App/issues/73825 is done
+        backTo?: Routes;
+    };
     [SCREENS.REIMBURSEMENT_ACCOUNT_NON_USD]: {
         page?: string;
         subPage?: string;
diff --git a/src/libs/ReimbursementAccountUtils.ts b/src/libs/ReimbursementAccountUtils.ts
index e0f1dd03be60..4bce69e731c0 100644
--- a/src/libs/ReimbursementAccountUtils.ts
+++ b/src/libs/ReimbursementAccountUtils.ts
@@ -1,6 +1,6 @@
 import type {ValueOf} from 'type-fest';
 import CONST from '@src/CONST';
-import type {ACHDataReimbursementAccount, ReimbursementAccountStep} from '@src/types/onyx/ReimbursementAccount';
+import type {ACHDataReimbursementAccount} from '@src/types/onyx/ReimbursementAccount';
 
 type ReimbursementAccountStepToOpen = ValueOf<typeof REIMBURSEMENT_ACCOUNT_ROUTE_NAMES> | '';
 
@@ -14,27 +14,6 @@ const REIMBURSEMENT_ACCOUNT_ROUTE_NAMES = {
     NEW: 'new',
 } as const;
 
-function getRouteForCurrentStep(currentStep: ReimbursementAccountStep): ReimbursementAccountStepToOpen {
-    switch (currentStep) {
-        case CONST.BANK_ACCOUNT.STEP.COMPANY:
-            return REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.COMPANY;
-        case CONST.BANK_ACCOUNT.STEP.REQUESTOR:
-            return REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.PERSONAL_INFORMATION;
-        case CONST.BANK_ACCOUNT.STEP.BENEFICIAL_OWNERS:
-            return REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.BENEFICIAL_OWNERS;
-        case CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT:
-            return REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.CONTRACT;
-        case CONST.BANK_ACCOUNT.STEP.VALIDATION:
-            return REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.VALIDATE;
-        case CONST.BANK_ACCOUNT.STEP.ENABLE:
-            return REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.ENABLE;
-        case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:
-        case CONST.BANK_ACCOUNT.STEP.COUNTRY:
-        default:
-            return REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.NEW;
-    }
-}
-
 /**
  * Returns true if a VBBA exists in any state other than OPEN or LOCKED
  */
@@ -67,5 +46,5 @@ const hasInProgressVBBA = (achData?: ACHDataReimbursementAccount, isNonUSDWorksp
     return hasInProgressUSDVBBA(achData);
 };
 
-export {getBankAccountIDAsNumber, getRouteForCurrentStep, hasInProgressUSDVBBA, hasInProgressVBBA, REIMBURSEMENT_ACCOUNT_ROUTE_NAMES};
+export {getBankAccountIDAsNumber, hasInProgressUSDVBBA, hasInProgressVBBA, REIMBURSEMENT_ACCOUNT_ROUTE_NAMES};
 export type {ReimbursementAccountStepToOpen};
diff --git a/src/pages/ReimbursementAccount/ConnectedVerifiedBankAccount.tsx b/src/pages/ReimbursementAccount/ConnectedVerifiedBankAccount.tsx
index a426ad5ffa4f..50f622603918 100644
--- a/src/pages/ReimbursementAccount/ConnectedVerifiedBankAccount.tsx
+++ b/src/pages/ReimbursementAccount/ConnectedVerifiedBankAccount.tsx
@@ -27,10 +27,10 @@ type ConnectedVerifiedBankAccountProps = {
     onBackButtonPress: () => void;
 
     /** Method to set the state of shouldShowConnectedVerifiedBankAccount */
-    setShouldShowConnectedVerifiedBankAccount: (shouldShowConnectedVerifiedBankAccount: boolean) => void;
+    setShouldShowConnectedVerifiedBankAccount?: (shouldShowConnectedVerifiedBankAccount: boolean) => void;
 
     /** Method to set the state of USD bank account step */
-    setUSDBankAccountStep: (step: string | null) => void;
+    setUSDBankAccountStep?: (step: string | null) => void;
 
     /** Whether the workspace currency is set to non USD currency */
     isNonUSDWorkspace: boolean;
diff --git a/src/pages/ReimbursementAccount/NonUSD/NonUSDVerifiedBankAccountFlowPage.tsx b/src/pages/ReimbursementAccount/NonUSD/NonUSDVerifiedBankAccountFlowPage.tsx
index 8d675eac39e9..f8b065860289 100644
--- a/src/pages/ReimbursementAccount/NonUSD/NonUSDVerifiedBankAccountFlowPage.tsx
+++ b/src/pages/ReimbursementAccount/NonUSD/NonUSDVerifiedBankAccountFlowPage.tsx
@@ -121,7 +121,7 @@ function NonUSDVerifiedBankAccountFlowPage({route}: NonUSDVerifiedBankAccountFlo
     }, [backTo, currentPageIndex, pages, policyID]);
 
     return (
-        <View style={styles.flex1}>
+        <View style={[styles.flex1, styles.appBG]}>
             <CurrentPage
                 onSubmit={onSubmit}
                 onBackButtonPress={onBackButtonPress}
diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx b/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx
index d5fa72a4d1fc..e70826be0f45 100644
--- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx
+++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.tsx
@@ -28,7 +28,7 @@ import Navigation from '@libs/Navigation/Navigation';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
 import type {ReimbursementAccountNavigatorParamList} from '@libs/Navigation/types';
 import {goBackFromInvalidPolicy, isPendingDeletePolicy, isPolicyAdmin} from '@libs/PolicyUtils';
-import {getRouteForCurrentStep, hasInProgressUSDVBBA, hasInProgressVBBA} from '@libs/ReimbursementAccountUtils';
+import {hasInProgressUSDVBBA, hasInProgressVBBA} from '@libs/ReimbursementAccountUtils';
 import shouldReopenOnfido from '@libs/shouldReopenOnfido';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import {isFullScreenName} from '@navigation/helpers/isNavigatorName';
@@ -60,7 +60,6 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject';
 import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
 import ConnectedVerifiedBankAccount from './ConnectedVerifiedBankAccount';
 import getStartPageForContinueSetup from './NonUSD/utils/getStartPageForContinueSetup';
-import USDVerifiedBankAccountFlow from './USD/USDVerifiedBankAccountFlow';
 import getFieldsForStep from './USD/utils/getFieldsForStep';
 import getStepToOpenFromRouteParams from './USD/utils/getStepToOpenFromRouteParams';
 import VerifiedBankAccountFlowEntryPoint from './VerifiedBankAccountFlowEntryPoint';
@@ -77,7 +76,7 @@ const OFFLINE_ACCESSIBLE_STEPS = [
     CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT,
 ] as const;
 
-function ReimbursementAccountPage({route, policy, isLoadingPolicy, navigation}: ReimbursementAccountPageProps) {
+function ReimbursementAccountPage({route, policy, isLoadingPolicy}: ReimbursementAccountPageProps) {
     const {environmentURL} = useEnvironment();
     const session = useSession();
     const [reimbursementAccount, reimbursementAccountMetadata] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
@@ -332,12 +331,6 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy, navigation}:
                 // so we don't clear it. We only want to clear the errors if we are moving between steps.
                 hideBankAccountErrors();
             }
-
-            // Use the current page navigation object to set the param to the correct route in the stack
-            const stepToOpen = getRouteForCurrentStep(currentStep);
-            if (stepToOpen && !isNonUSDSetup) {
-                navigation.setParams({stepToOpen});
-            }
         },
         // eslint-disable-next-line react-hooks/exhaustive-deps
         [
@@ -356,10 +349,19 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy, navigation}:
         // If user comes back to the flow we never want to allow him to go through plaid again
         // so we're always showing manual setup with locked numbers he can not change
         setBankAccountSubStep(CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL).then(() => {
-            setShouldShowContinueSetupButton(false);
-            setUSDBankAccountStep(currentStep);
+            const stepToPageName: Record<string, string> = {
+                [CONST.BANK_ACCOUNT.STEP.COUNTRY]: CONST.BANK_ACCOUNT.PAGE_NAMES.COUNTRY,
+                [CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT]: CONST.BANK_ACCOUNT.PAGE_NAMES.BANK_ACCOUNT,
+                [CONST.BANK_ACCOUNT.STEP.REQUESTOR]: CONST.BANK_ACCOUNT.PAGE_NAMES.REQUESTOR,
+                [CONST.BANK_ACCOUNT.STEP.COMPANY]: CONST.BANK_ACCOUNT.PAGE_NAMES.COMPANY,
+                [CONST.BANK_ACCOUNT.STEP.BENEFICIAL_OWNERS]: CONST.BANK_ACCOUNT.PAGE_NAMES.BENEFICIAL_OWNERS,
+                [CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT]: CONST.BANK_ACCOUNT.PAGE_NAMES.ACH_CONTRACT,
+                [CONST.BANK_ACCOUNT.STEP.VALIDATION]: CONST.BANK_ACCOUNT.PAGE_NAMES.VALIDATION,
+            };
+            const page = stepToPageName[currentStep] ?? CONST.BANK_ACCOUNT.PAGE_NAMES.COUNTRY;
+            Navigation.navigate(ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID: policyIDParam, page, backTo}));
         });
-    }, [currentStep]);
+    }, [currentStep, policyIDParam, backTo]);
 
     const continueNonUSDVBBASetup = () => {
         const {page: startPage, subPage: startSubPage} = getStartPageForContinueSetup(achData, nonUSDCountryDraftValue, policyCurrency, reimbursementAccountDraft);
@@ -529,20 +531,6 @@ function ReimbursementAccountPage({route, policy, isLoadingPolicy, navigation}:
         );
     }
 
-    if (!isNonUSDSetup && USDBankAccountStep !== null) {
-        return (
-            <USDVerifiedBankAccountFlow
-                USDBankAccountStep={USDBankAccountStep}
-                policyID={policyIDParam}
-                onBackButtonPress={goBack}
-                requestorStepRef={requestorStepRef}
-                onfidoToken={onfidoToken}
-                setUSDBankAccountStep={setUSDBankAccountStep}
-                setShouldShowConnectedVerifiedBankAccount={setShouldShowConnectedVerifiedBankAccount}
-            />
-        );
-    }
-
     return (
         <VerifiedBankAccountFlowEntryPoint
             setShouldShowContinueSetupButton={setShouldShowContinueSetupButton}
diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountVerifyAccountPage.tsx b/src/pages/ReimbursementAccount/ReimbursementAccountVerifyAccountPage.tsx
index 819f5c75c041..f7f5e8be32b7 100644
--- a/src/pages/ReimbursementAccount/ReimbursementAccountVerifyAccountPage.tsx
+++ b/src/pages/ReimbursementAccount/ReimbursementAccountVerifyAccountPage.tsx
@@ -3,7 +3,6 @@ import Navigation from '@libs/Navigation/Navigation';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
 import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
 import VerifyAccountPageBase from '@pages/settings/VerifyAccountPageBase';
-import CONST from '@src/CONST';
 import ROUTES from '@src/ROUTES';
 import type SCREENS from '@src/SCREENS';
 
@@ -15,7 +14,7 @@ function ReimbursementAccountVerifyAccountPage({route}: ReimbursementAccountVeri
         <VerifyAccountPageBase
             navigateBackTo={ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({policyID, backTo})}
             handleClose={() => {
-                Navigation.goBack(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({policyID, backTo, subStepToOpen: CONST.BANK_ACCOUNT.STEP.COUNTRY}), {compareParams: false});
+                Navigation.goBack(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({policyID, backTo}), {compareParams: false});
             }}
         />
     );
diff --git a/src/pages/ReimbursementAccount/USD/BankInfo/BankInfo.tsx b/src/pages/ReimbursementAccount/USD/BankInfo/BankInfo.tsx
index 8ff529ef084d..a5b3dc71988f 100644
--- a/src/pages/ReimbursementAccount/USD/BankInfo/BankInfo.tsx
+++ b/src/pages/ReimbursementAccount/USD/BankInfo/BankInfo.tsx
@@ -2,8 +2,7 @@ import React, {useEffect, useRef} from 'react';
 import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
-import useSubStep from '@hooks/useSubStep';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import useReimbursementAccountSubmitCallback from '@hooks/useReimbursementAccountSubmitCallback';
 import getPlaidOAuthReceivedRedirectURI from '@libs/getPlaidOAuthReceivedRedirectURI';
 import {getBankAccountIDAsNumber} from '@libs/ReimbursementAccountUtils';
 import getSubStepValues from '@pages/ReimbursementAccount/utils/getSubStepValues';
@@ -20,27 +19,22 @@ type BankInfoProps = {
     /** Goes to the previous step */
     onBackButtonPress: () => void;
 
+    /** Handles submit button press (URL-based navigation) */
+    onSubmit?: () => void;
+
     /** Current Policy ID */
     policyID: string;
-
-    /** Set the step of the USD verified bank account flow */
-    setUSDBankAccountStep: (step: string | null) => void;
-};
-
-type BankInfoSubStepProps = SubStepProps & {
-    setUSDBankAccountStep: (step: string | null) => void;
 };
 
 const BANK_INFO_STEP_KEYS = INPUT_IDS.BANK_INFO_STEP;
-const manualSubSteps: Array<React.ComponentType<BankInfoSubStepProps>> = [Manual];
-const plaidSubSteps: Array<React.ComponentType<BankInfoSubStepProps>> = [Plaid];
 const receivedRedirectURI = getPlaidOAuthReceivedRedirectURI();
 
-function BankInfo({onBackButtonPress, policyID, setUSDBankAccountStep}: BankInfoProps) {
+function BankInfo({onBackButtonPress, onSubmit, policyID}: BankInfoProps) {
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT);
     const [plaidLinkToken] = useOnyx(ONYXKEYS.RAM_ONLY_PLAID_LINK_TOKEN);
     const {translate} = useLocalize();
+    const markSubmitting = useReimbursementAccountSubmitCallback(onSubmit);
 
     const redirectedFromPlaidToManualRef = useRef(false);
     const values = getSubStepValues(BANK_INFO_STEP_KEYS, reimbursementAccountDraft, reimbursementAccount ?? {});
@@ -90,10 +84,10 @@ function BankInfo({onBackButtonPress, policyID, setUSDBankAccountStep}: BankInfo
                 policyID,
             );
         }
+        markSubmitting();
     };
 
-    const bodyContent = setupType === CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID ? plaidSubSteps : manualSubSteps;
-    const {componentToRender: SubStep, isEditing, screenIndex, nextScreen, prevScreen, moveTo} = useSubStep<BankInfoSubStepProps>({bodyContent, startFrom: 0, onFinished: submit});
+    const BankInfoPage = setupType === CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID ? Plaid : Manual;
 
     // Some services user connects to via Plaid return dummy account numbers and routing numbers e.g. Chase
     // In this case we need to redirect user to manual flow to enter real account number and routing number
@@ -108,12 +102,8 @@ function BankInfo({onBackButtonPress, policyID, setUSDBankAccountStep}: BankInfo
     }, [setupType, values.bankName]);
 
     const handleBackButtonPress = () => {
-        if (screenIndex === 0) {
-            onBackButtonPress();
-            hideBankAccountErrors();
-        } else {
-            prevScreen();
-        }
+        onBackButtonPress();
+        hideBankAccountErrors();
     };
 
     return (
@@ -125,12 +115,7 @@ function BankInfo({onBackButtonPress, policyID, setUSDBankAccountStep}: BankInfo
             startStepIndex={1}
             stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
         >
-            <SubStep
-                isEditing={isEditing}
-                onNext={nextScreen}
-                onMove={moveTo}
-                setUSDBankAccountStep={setUSDBankAccountStep}
-            />
+            <BankInfoPage onNext={submit} />
         </InteractiveStepWrapper>
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Manual.tsx b/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Manual.tsx
index 6e89550cb6d8..53a090418c49 100644
--- a/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Manual.tsx
+++ b/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Manual.tsx
@@ -8,21 +8,19 @@ import useAutoFocusInput from '@hooks/useAutoFocusInput';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {getFieldRequiredErrors, isValidRoutingNumber} from '@libs/ValidationUtils';
 import ExampleCheckImage from '@pages/ReimbursementAccount/USD/BankInfo/ExampleCheck';
+import type BankInfoSubStepProps from '@pages/ReimbursementAccount/USD/BankInfo/types';
 import getSubStepValues from '@pages/ReimbursementAccount/utils/getSubStepValues';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 
-type ManualProps = SubStepProps;
-
 const BANK_INFO_STEP_KEYS = INPUT_IDS.BANK_INFO_STEP;
 const STEP_FIELDS = [BANK_INFO_STEP_KEYS.ROUTING_NUMBER, BANK_INFO_STEP_KEYS.ACCOUNT_NUMBER];
 
-function Manual({onNext}: ManualProps) {
+function Manual({onNext}: BankInfoSubStepProps) {
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT);
 
diff --git a/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Plaid.tsx b/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Plaid.tsx
index d1719b8047fa..b64b07e70a45 100644
--- a/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Plaid.tsx
+++ b/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Plaid.tsx
@@ -6,21 +6,17 @@ import InputWrapper from '@components/Form/InputWrapper';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import usePrevious from '@hooks/usePrevious';
-import type {SubStepProps} from '@hooks/useSubStep/types';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {getBankAccountIDAsNumber} from '@libs/ReimbursementAccountUtils';
+import type BankInfoSubStepProps from '@pages/ReimbursementAccount/USD/BankInfo/types';
 import {setBankAccountSubStep, validatePlaidSelection} from '@userActions/BankAccounts';
 import {updateReimbursementAccountDraft} from '@userActions/ReimbursementAccount';
 import ONYXKEYS from '@src/ONYXKEYS';
 import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 
-type PlaidProps = SubStepProps & {
-    setUSDBankAccountStep: (step: string | null) => void;
-};
-
 const BANK_INFO_STEP_KEYS = INPUT_IDS.BANK_INFO_STEP;
 
-function Plaid({onNext, setUSDBankAccountStep}: PlaidProps) {
+function Plaid({onNext}: BankInfoSubStepProps) {
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT);
     const [plaidData] = useOnyx(ONYXKEYS.PLAID_DATA);
@@ -61,12 +57,10 @@ function Plaid({onNext, setUSDBankAccountStep}: PlaidProps) {
             return;
         }
         setBankAccountSubStep(null);
-        setUSDBankAccountStep(null);
-    }, [isFocused, prevIsFocused, plaidData?.bankAccounts, setUSDBankAccountStep]);
+    }, [isFocused, prevIsFocused, plaidData?.bankAccounts]);
 
     const handlePlaidExit = () => {
         setBankAccountSubStep(null);
-        setUSDBankAccountStep(null);
     };
 
     return (
diff --git a/src/pages/ReimbursementAccount/USD/BankInfo/types.ts b/src/pages/ReimbursementAccount/USD/BankInfo/types.ts
new file mode 100644
index 000000000000..e79203da7611
--- /dev/null
+++ b/src/pages/ReimbursementAccount/USD/BankInfo/types.ts
@@ -0,0 +1,6 @@
+type BankInfoSubStepProps = {
+    /** Continues to the next step */
+    onNext: (data?: unknown) => void;
+};
+
+export default BankInfoSubStepProps;
diff --git a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormPages.tsx b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormPages.tsx
new file mode 100644
index 000000000000..5ea2a967a3ae
--- /dev/null
+++ b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/BeneficialOwnerDetailsFormPages.tsx
@@ -0,0 +1,123 @@
+import React, {useCallback} from 'react';
+import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
+import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
+import useLocalize from '@hooks/useLocalize';
+import useOnyx from '@hooks/useOnyx';
+import useSubPage from '@hooks/useSubPage';
+import type {SubPageProps} from '@hooks/useSubPage/types';
+import Navigation from '@libs/Navigation/Navigation';
+import CONST from '@src/CONST';
+import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
+import AddressUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/AddressUBO';
+import ConfirmationUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/ConfirmationUBO';
+import DateOfBirthUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/DateOfBirthUBO';
+import LegalNameUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/LegalNameUBO';
+import SocialSecurityNumberUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/SocialSecurityNumberUBO';
+
+const PAGE_NAMES = CONST.BANK_ACCOUNT.PAGE_NAMES;
+const SUB_PAGE_NAMES = CONST.BANK_ACCOUNT.BENEFICIAL_OWNERS_STEP.SUB_PAGE_NAMES;
+
+type BeneficialOwnerSubPageProps = SubPageProps & {
+    beneficialOwnerBeingModifiedID: string;
+    setBeneficialOwnerBeingModifiedID?: (id: string) => void;
+};
+
+const pages = [
+    {pageName: SUB_PAGE_NAMES.LEGAL_NAME, component: LegalNameUBO},
+    {pageName: SUB_PAGE_NAMES.DATE_OF_BIRTH, component: DateOfBirthUBO},
+    {pageName: SUB_PAGE_NAMES.SSN, component: SocialSecurityNumberUBO},
+    {pageName: SUB_PAGE_NAMES.ADDRESS, component: AddressUBO},
+    {pageName: SUB_PAGE_NAMES.CONFIRMATION, component: ConfirmationUBO},
+];
+
+type BeneficialOwnerDetailsFormPagesProps = {
+    /** ID of current policy */
+    policyID?: string;
+
+    /** ID of the beneficial owner being modified */
+    beneficialOwnerBeingModifiedID: string;
+
+    /** Setter for the beneficial owner being modified */
+    setBeneficialOwnerBeingModifiedID: (id: string) => void;
+
+    /** Whether user is editing an already-created beneficial owner */
+    isEditingCreatedBeneficialOwner: boolean;
+
+    /** Callback triggered after the last form page is completed */
+    onFinished: () => void;
+
+    /** Back to URL for preserving navigation context */
+    backTo?: string;
+};
+
+function BeneficialOwnerDetailsFormPages({
+    policyID,
+    beneficialOwnerBeingModifiedID,
+    setBeneficialOwnerBeingModifiedID,
+    isEditingCreatedBeneficialOwner,
+    onFinished,
+    backTo,
+}: BeneficialOwnerDetailsFormPagesProps) {
+    const {translate} = useLocalize();
+    const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT);
+    const hasExistingBeneficialOwners = (reimbursementAccountDraft?.beneficialOwnerKeys ?? []).length > 0;
+
+    const buildRoute = useCallback(
+        (pageName: string, action?: 'edit') => ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: PAGE_NAMES.BENEFICIAL_OWNERS, subPage: pageName, action, backTo}),
+        [policyID, backTo],
+    );
+
+    const {CurrentPage, isEditing, currentPageName, pageIndex, prevPage, nextPage, moveTo, isRedirecting} = useSubPage<BeneficialOwnerSubPageProps>({
+        pages,
+        startFrom: 0,
+        onFinished,
+        buildRoute,
+    });
+
+    const handleBackButtonPress = useCallback(() => {
+        if (isEditing) {
+            Navigation.goBack(buildRoute(SUB_PAGE_NAMES.CONFIRMATION));
+            return;
+        }
+
+        if (pageIndex === 0) {
+            if (isEditingCreatedBeneficialOwner) {
+                Navigation.goBack(buildRoute(SUB_PAGE_NAMES.UBOS_LIST));
+            } else if (hasExistingBeneficialOwners) {
+                Navigation.goBack(buildRoute(SUB_PAGE_NAMES.ARE_THERE_MORE_UBOS));
+            } else {
+                Navigation.goBack(buildRoute(SUB_PAGE_NAMES.IS_ANYONE_ELSE_UBO));
+            }
+        } else {
+            prevPage();
+        }
+    }, [buildRoute, isEditing, isEditingCreatedBeneficialOwner, pageIndex, prevPage, hasExistingBeneficialOwners]);
+
+    if (isRedirecting) {
+        return <FullScreenLoadingIndicator reasonAttributes={{context: 'BeneficialOwnerDetailsFormPages', isRedirecting}} />;
+    }
+
+    return (
+        <InteractiveStepWrapper
+            wrapperID="BeneficialOwnersStep"
+            shouldEnablePickerAvoiding={false}
+            shouldEnableMaxHeight
+            headerTitle={translate('beneficialOwnerInfoStep.companyOwner')}
+            handleBackButtonPress={handleBackButtonPress}
+            startStepIndex={5}
+            stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
+        >
+            <CurrentPage
+                isEditing={isEditing}
+                onNext={nextPage}
+                onMove={moveTo}
+                currentPageName={currentPageName}
+                beneficialOwnerBeingModifiedID={beneficialOwnerBeingModifiedID}
+                setBeneficialOwnerBeingModifiedID={setBeneficialOwnerBeingModifiedID}
+            />
+        </InteractiveStepWrapper>
+    );
+}
+
+export default BeneficialOwnerDetailsFormPages;
diff --git a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/BeneficialOwnersStep.tsx b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/BeneficialOwnersStep.tsx
index 83e6e31c1616..ee0f5404c74b 100644
--- a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/BeneficialOwnersStep.tsx
+++ b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/BeneficialOwnersStep.tsx
@@ -1,37 +1,46 @@
 import {Str} from 'expensify-common';
-import React, {useState} from 'react';
+import React, {useCallback, useEffect} from 'react';
 import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
 import YesNoStep from '@components/SubStepForms/YesNoStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
-import useSubStep from '@hooks/useSubStep';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import useReimbursementAccountSubmitCallback from '@hooks/useReimbursementAccountSubmitCallback';
 import useThemeStyles from '@hooks/useThemeStyles';
+import Navigation from '@libs/Navigation/Navigation';
 import {getBankAccountIDAsNumber} from '@libs/ReimbursementAccountUtils';
 import {updateBeneficialOwnersForBankAccount} from '@userActions/BankAccounts';
 import {setDraftValues} from '@userActions/FormActions';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
 import SafeString from '@src/utils/SafeString';
-import AddressUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/AddressUBO';
-import ConfirmationUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/ConfirmationUBO';
-import DateOfBirthUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/DateOfBirthUBO';
-import LegalNameUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/LegalNameUBO';
-import SocialSecurityNumberUBO from './subSteps/BeneficialOwnerDetailsFormSubSteps/SocialSecurityNumberUBO';
+import BeneficialOwnerDetailsFormPages from './BeneficialOwnerDetailsFormPages';
 import CompanyOwnersListUBO from './subSteps/CompanyOwnersListUBO';
 
 type BeneficialOwnersStepProps = {
     /** Goes to the previous step */
     onBackButtonPress: () => void;
-};
 
-type BeneficialOwnerSubStepProps = SubStepProps & {beneficialOwnerBeingModifiedID: string; setBeneficialOwnerBeingModifiedID?: (id: string) => void};
+    /** Handles submit button press (URL-based navigation) */
+    onSubmit?: () => void;
+
+    /** Name of the current sub page */
+    currentSubPage?: string;
+
+    /** ID of current policy */
+    policyID?: string;
+
+    /** Back to URL for preserving navigation context */
+    backTo?: string;
+};
 
-const SUBSTEP = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.SUBSTEP;
+const PAGE_NAMES = CONST.BANK_ACCOUNT.PAGE_NAMES;
+const SUB_PAGE_NAMES = CONST.BANK_ACCOUNT.BENEFICIAL_OWNERS_STEP.SUB_PAGE_NAMES;
 const MAX_NUMBER_OF_UBOS = 4;
-const bodyContent: Array<React.ComponentType<BeneficialOwnerSubStepProps>> = [LegalNameUBO, DateOfBirthUBO, SocialSecurityNumberUBO, AddressUBO, ConfirmationUBO];
 
-function BeneficialOwnersStep({onBackButtonPress}: BeneficialOwnersStepProps) {
+const OUTER_SUB_PAGES = new Set<string>([SUB_PAGE_NAMES.IS_USER_UBO, SUB_PAGE_NAMES.IS_ANYONE_ELSE_UBO, SUB_PAGE_NAMES.ARE_THERE_MORE_UBOS, SUB_PAGE_NAMES.UBOS_LIST]);
+
+function BeneficialOwnersStep({onBackButtonPress, onSubmit, currentSubPage, policyID, backTo}: BeneficialOwnersStepProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
@@ -39,27 +48,53 @@ function BeneficialOwnersStep({onBackButtonPress}: BeneficialOwnersStepProps) {
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT);
 
     const companyName = reimbursementAccount?.achData?.companyName ?? '';
-    const policyID = reimbursementAccount?.achData?.policyID;
-    const defaultValues = {
-        ownsMoreThan25Percent: reimbursementAccount?.achData?.ownsMoreThan25Percent ?? reimbursementAccountDraft?.ownsMoreThan25Percent ?? false,
-        hasOtherBeneficialOwners: reimbursementAccount?.achData?.hasOtherBeneficialOwners ?? reimbursementAccountDraft?.hasOtherBeneficialOwners ?? false,
-        beneficialOwnerKeys: reimbursementAccount?.achData?.beneficialOwnerKeys ?? reimbursementAccountDraft?.beneficialOwnerKeys ?? [],
-    };
-
-    // We're only reading beneficialOwnerKeys from draft values because there is not option to remove UBO
-    // if we were to set them based on values saved in BE then there would be no option to enter different UBOs
-    // user would always see the same UBOs that was saved in BE when returning to this step and trying to change something
-    const [beneficialOwnerKeys, setBeneficialOwnerKeys] = useState<string[]>(defaultValues.beneficialOwnerKeys);
-    const [beneficialOwnerBeingModifiedID, setBeneficialOwnerBeingModifiedID] = useState('');
-    const [isEditingCreatedBeneficialOwner, setIsEditingCreatedBeneficialOwner] = useState(false);
-    const [isUserUBO, setIsUserUBO] = useState(defaultValues.ownsMoreThan25Percent);
-    const [isAnyoneElseUBO, setIsAnyoneElseUBO] = useState(defaultValues.hasOtherBeneficialOwners);
-    const [currentUBOSubStep, setCurrentUBOSubStep] = useState(1);
+    const markSubmitting = useReimbursementAccountSubmitCallback(onSubmit);
+
+    // Read state from Onyx draft so it survives URL-based navigation (component remounts)
+    const isUserUBO = reimbursementAccountDraft?.ownsMoreThan25Percent ?? reimbursementAccount?.achData?.ownsMoreThan25Percent ?? false;
+    const beneficialOwners = reimbursementAccount?.achData?.beneficialOwners;
+    const isAnyoneElseUBO = beneficialOwners?.length ? true : (reimbursementAccountDraft?.hasOtherBeneficialOwners ?? false);
+    const beneficialOwnerKeys: string[] = reimbursementAccountDraft?.beneficialOwnerKeys ?? reimbursementAccount?.achData?.beneficialOwnerKeys ?? [];
+    // eslint-disable-next-line rulesdir/no-default-id-values
+    const beneficialOwnerBeingModifiedID = reimbursementAccountDraft?.ownerBeingModifiedID ?? '';
+    const isEditingCreatedBeneficialOwner = reimbursementAccountDraft?.isEditingCreatedOwner ?? false;
     const canAddMoreUBOS = beneficialOwnerKeys.length < (isUserUBO ? MAX_NUMBER_OF_UBOS - 1 : MAX_NUMBER_OF_UBOS);
 
+    const hasCompletedBeneficialOwnersStep = reimbursementAccount?.achData?.ownsMoreThan25Percent !== undefined;
+
+    // Redirect to the correct sub-page if no subPage is in the URL
+    useEffect(() => {
+        if (currentSubPage) {
+            return;
+        }
+
+        let subPage: string = SUB_PAGE_NAMES.IS_USER_UBO;
+        if (isUserUBO || (isAnyoneElseUBO && beneficialOwnerKeys.length > 0)) {
+            subPage = SUB_PAGE_NAMES.UBOS_LIST;
+        } else if (hasCompletedBeneficialOwnersStep) {
+            subPage = SUB_PAGE_NAMES.IS_ANYONE_ELSE_UBO;
+        }
+
+        Navigation.setParams({subPage} as Record<string, unknown>);
+    }, [currentSubPage, policyID, backTo, isAnyoneElseUBO, beneficialOwnerKeys.length, isUserUBO, hasCompletedBeneficialOwnersStep]);
+
+    const navigateToSubPage = useCallback(
+        (subPage: string) => {
+            Navigation.navigate(ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: PAGE_NAMES.BENEFICIAL_OWNERS, subPage, backTo}));
+        },
+        [policyID, backTo],
+    );
+
+    const navigateBackToSubPage = useCallback(
+        (subPage: string) => {
+            Navigation.goBack(ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: PAGE_NAMES.BENEFICIAL_OWNERS, subPage, backTo}));
+        },
+        [policyID, backTo],
+    );
+
     const submit = () => {
         const beneficialOwnerFields = ['firstName', 'lastName', 'dob', 'ssnLast4', 'street', 'city', 'state', 'zipCode'];
-        const beneficialOwners = beneficialOwnerKeys.map((ownerKey) =>
+        const beneficialOwnersData = beneficialOwnerKeys.map((ownerKey) =>
             beneficialOwnerFields.reduce(
                 (acc, fieldName) => {
                     acc[fieldName] = reimbursementAccountDraft ? SafeString(reimbursementAccountDraft[`beneficialOwner_${ownerKey}_${fieldName}`]) : undefined;
@@ -73,75 +108,56 @@ function BeneficialOwnersStep({onBackButtonPress}: BeneficialOwnersStepProps) {
             getBankAccountIDAsNumber(reimbursementAccount?.achData),
             {
                 ownsMoreThan25Percent: isUserUBO,
-                beneficialOwners: JSON.stringify(beneficialOwners),
+                beneficialOwners: JSON.stringify(beneficialOwnersData),
                 beneficialOwnerKeys,
             },
             policyID,
         );
+        markSubmitting();
     };
 
     const addBeneficialOwner = (beneficialOwnerID: string) => {
-        // Each beneficial owner is assigned a unique key that will connect it to values in saved ONYX.
-        // That way we can dynamically render each Identity Form based on which keys are present in the beneficial owners array.
         const newBeneficialOwners = [...beneficialOwnerKeys, beneficialOwnerID];
-
-        setBeneficialOwnerKeys(newBeneficialOwners);
-        setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {beneficialOwners: JSON.stringify(newBeneficialOwners)});
+        setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {beneficialOwnerKeys: newBeneficialOwners, beneficialOwners: JSON.stringify(newBeneficialOwners)});
     };
+
     const handleBeneficialOwnerDetailsFormSubmit = () => {
         const shouldAddBeneficialOwner = !beneficialOwnerKeys.find((beneficialOwnerID) => beneficialOwnerID === beneficialOwnerBeingModifiedID) && canAddMoreUBOS;
 
-        if (shouldAddBeneficialOwner) {
+        if (shouldAddBeneficialOwner && beneficialOwnerBeingModifiedID) {
             addBeneficialOwner(beneficialOwnerBeingModifiedID);
         }
 
-        // Because beneficialOwnerKeys array is not yet updated at this point we need to check against lower MAX_NUMBER_OF_UBOS (account for the one that is being added)
         const isLastUBOThatCanBeAdded = beneficialOwnerKeys.length === (isUserUBO ? MAX_NUMBER_OF_UBOS - 2 : MAX_NUMBER_OF_UBOS - 1);
-        setCurrentUBOSubStep(isEditingCreatedBeneficialOwner || isLastUBOThatCanBeAdded ? SUBSTEP.UBOS_LIST : SUBSTEP.ARE_THERE_MORE_UBOS);
-        setIsEditingCreatedBeneficialOwner(false);
+        const nextSubPage = isEditingCreatedBeneficialOwner || isLastUBOThatCanBeAdded ? SUB_PAGE_NAMES.UBOS_LIST : SUB_PAGE_NAMES.ARE_THERE_MORE_UBOS;
+        setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {isEditingCreatedOwner: false});
+        navigateToSubPage(nextSubPage);
     };
 
-    const {
-        componentToRender: BeneficialOwnerDetailsForm,
-        isEditing,
-        screenIndex,
-        nextScreen,
-        prevScreen,
-        moveTo,
-        resetScreenIndex,
-        goToTheLastStep,
-    } = useSubStep<BeneficialOwnerSubStepProps>({
-        bodyContent,
-        startFrom: 0,
-        onFinished: handleBeneficialOwnerDetailsFormSubmit,
-    });
-
     const prepareBeneficialOwnerDetailsForm = () => {
         const beneficialOwnerID = Str.guid();
-        setBeneficialOwnerBeingModifiedID(beneficialOwnerID);
-        // Reset Beneficial Owner Details Form to first subStep
-        resetScreenIndex();
-        setCurrentUBOSubStep(SUBSTEP.UBO_DETAILS_FORM);
+        setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {ownerBeingModifiedID: beneficialOwnerID});
+        navigateToSubPage(SUB_PAGE_NAMES.LEGAL_NAME);
     };
 
     const handleNextUBOSubstep = (value: boolean) => {
-        if (currentUBOSubStep === SUBSTEP.IS_USER_UBO) {
-            setIsUserUBO(value);
+        if (currentSubPage === SUB_PAGE_NAMES.IS_USER_UBO) {
+            setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {ownsMoreThan25Percent: value});
 
             // User is an owner but there are 4 other owners already added, so we remove last one
             if (value && beneficialOwnerKeys.length === 4) {
-                setBeneficialOwnerKeys((previousBeneficialOwners) => previousBeneficialOwners.slice(0, 3));
+                setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {beneficialOwnerKeys: beneficialOwnerKeys.slice(0, 3)});
             }
 
-            setCurrentUBOSubStep(SUBSTEP.IS_ANYONE_ELSE_UBO);
+            navigateToSubPage(SUB_PAGE_NAMES.IS_ANYONE_ELSE_UBO);
             return;
         }
 
-        if (currentUBOSubStep === SUBSTEP.IS_ANYONE_ELSE_UBO) {
-            setIsAnyoneElseUBO(value);
+        if (currentSubPage === SUB_PAGE_NAMES.IS_ANYONE_ELSE_UBO) {
+            setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {hasOtherBeneficialOwners: value});
 
             if (!canAddMoreUBOS && value) {
-                setCurrentUBOSubStep(SUBSTEP.UBOS_LIST);
+                navigateToSubPage(SUB_PAGE_NAMES.UBOS_LIST);
                 return;
             }
 
@@ -150,66 +166,62 @@ function BeneficialOwnersStep({onBackButtonPress}: BeneficialOwnersStepProps) {
                 return;
             }
 
-            // User is not an owner and no one else is an owner
             if (!isUserUBO && !value) {
                 submit();
                 return;
             }
 
-            // User is an owner and no one else is an owner
             if (isUserUBO && !value) {
-                setCurrentUBOSubStep(SUBSTEP.UBOS_LIST);
+                navigateToSubPage(SUB_PAGE_NAMES.UBOS_LIST);
                 return;
             }
         }
 
-        // Are there more UBOs
-        if (currentUBOSubStep === SUBSTEP.ARE_THERE_MORE_UBOS) {
+        if (currentSubPage === SUB_PAGE_NAMES.ARE_THERE_MORE_UBOS) {
             if (value) {
                 prepareBeneficialOwnerDetailsForm();
                 return;
             }
-            setCurrentUBOSubStep(SUBSTEP.UBOS_LIST);
-            return;
-        }
-
-        // User reached the limit of UBOs
-        if (currentUBOSubStep === SUBSTEP.UBO_DETAILS_FORM && !canAddMoreUBOS) {
-            setCurrentUBOSubStep(SUBSTEP.UBOS_LIST);
+            navigateToSubPage(SUB_PAGE_NAMES.UBOS_LIST);
         }
     };
 
     const handleBackButtonPress = () => {
-        if (isEditing) {
-            goToTheLastStep();
-            return;
-        }
-
-        // User goes back to previous step
-        if (currentUBOSubStep === SUBSTEP.IS_USER_UBO) {
+        if (currentSubPage === SUB_PAGE_NAMES.IS_USER_UBO) {
             onBackButtonPress();
-            // User reached limit of UBOs and goes back to initial question about additional UBOs
-        } else if (currentUBOSubStep === SUBSTEP.UBOS_LIST && !canAddMoreUBOS) {
-            setCurrentUBOSubStep(SUBSTEP.IS_ANYONE_ELSE_UBO);
-            // User goes back to last radio button
-        } else if (currentUBOSubStep === SUBSTEP.UBOS_LIST && isAnyoneElseUBO) {
-            setCurrentUBOSubStep(SUBSTEP.ARE_THERE_MORE_UBOS);
-        } else if (currentUBOSubStep === SUBSTEP.UBOS_LIST && isUserUBO && !isAnyoneElseUBO) {
-            setCurrentUBOSubStep(SUBSTEP.IS_ANYONE_ELSE_UBO);
-            // User moves between subSteps of beneficial owner details form
-        } else if (currentUBOSubStep === SUBSTEP.UBO_DETAILS_FORM && screenIndex > 0) {
-            prevScreen();
+        } else if (currentSubPage === SUB_PAGE_NAMES.IS_ANYONE_ELSE_UBO) {
+            navigateBackToSubPage(SUB_PAGE_NAMES.IS_USER_UBO);
+        } else if (currentSubPage === SUB_PAGE_NAMES.UBOS_LIST && !canAddMoreUBOS) {
+            navigateBackToSubPage(SUB_PAGE_NAMES.IS_ANYONE_ELSE_UBO);
+        } else if (currentSubPage === SUB_PAGE_NAMES.UBOS_LIST && isAnyoneElseUBO) {
+            navigateBackToSubPage(SUB_PAGE_NAMES.ARE_THERE_MORE_UBOS);
+        } else if (currentSubPage === SUB_PAGE_NAMES.UBOS_LIST && isUserUBO && !isAnyoneElseUBO) {
+            navigateBackToSubPage(SUB_PAGE_NAMES.IS_ANYONE_ELSE_UBO);
         } else {
-            setCurrentUBOSubStep((currentSubstep) => currentSubstep - 1);
+            Navigation.goBack();
         }
     };
 
     const handleUBOEdit = (beneficialOwnerID: string) => {
-        setBeneficialOwnerBeingModifiedID(beneficialOwnerID);
-        setIsEditingCreatedBeneficialOwner(true);
-        setCurrentUBOSubStep(SUBSTEP.UBO_DETAILS_FORM);
+        setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {ownerBeingModifiedID: beneficialOwnerID, isEditingCreatedOwner: true});
+        navigateToSubPage(SUB_PAGE_NAMES.LEGAL_NAME);
     };
 
+    // If the current sub page is not an outer page, render the details form
+    if (currentSubPage && !OUTER_SUB_PAGES.has(currentSubPage)) {
+        return (
+            <BeneficialOwnerDetailsFormPages
+                policyID={policyID}
+                beneficialOwnerBeingModifiedID={beneficialOwnerBeingModifiedID}
+                // eslint-disable-next-line @typescript-eslint/no-misused-promises
+                setBeneficialOwnerBeingModifiedID={(id: string) => setDraftValues(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM, {ownerBeingModifiedID: id})}
+                isEditingCreatedBeneficialOwner={isEditingCreatedBeneficialOwner}
+                onFinished={handleBeneficialOwnerDetailsFormSubmit}
+                backTo={backTo}
+            />
+        );
+    }
+
     return (
         <InteractiveStepWrapper
             wrapperID="BeneficialOwnersStep"
@@ -217,11 +229,11 @@ function BeneficialOwnersStep({onBackButtonPress}: BeneficialOwnersStepProps) {
             shouldEnableMaxHeight
             headerTitle={translate('beneficialOwnerInfoStep.companyOwner')}
             handleBackButtonPress={handleBackButtonPress}
-            shouldShowOfflineIndicatorInWideScreen={currentUBOSubStep === SUBSTEP.UBOS_LIST}
+            shouldShowOfflineIndicatorInWideScreen={currentSubPage === SUB_PAGE_NAMES.UBOS_LIST}
             startStepIndex={5}
             stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
         >
-            {currentUBOSubStep === SUBSTEP.IS_USER_UBO && (
+            {currentSubPage === SUB_PAGE_NAMES.IS_USER_UBO && (
                 <YesNoStep
                     title={translate('beneficialOwnerInfoStep.doYouOwn25percent', companyName)}
                     description={translate('beneficialOwnerInfoStep.regulationRequiresUsToVerifyTheIdentity')}
@@ -231,7 +243,7 @@ function BeneficialOwnersStep({onBackButtonPress}: BeneficialOwnersStepProps) {
                 />
             )}
 
-            {currentUBOSubStep === SUBSTEP.IS_ANYONE_ELSE_UBO && (
+            {currentSubPage === SUB_PAGE_NAMES.IS_ANYONE_ELSE_UBO && (
                 <YesNoStep
                     title={translate('beneficialOwnerInfoStep.doAnyIndividualOwn25percent', companyName)}
                     description={translate('beneficialOwnerInfoStep.regulationRequiresUsToVerifyTheIdentity')}
@@ -241,17 +253,7 @@ function BeneficialOwnersStep({onBackButtonPress}: BeneficialOwnersStepProps) {
                 />
             )}
 
-            {currentUBOSubStep === SUBSTEP.UBO_DETAILS_FORM && (
-                <BeneficialOwnerDetailsForm
-                    isEditing={isEditing}
-                    beneficialOwnerBeingModifiedID={beneficialOwnerBeingModifiedID}
-                    setBeneficialOwnerBeingModifiedID={setBeneficialOwnerBeingModifiedID}
-                    onNext={nextScreen}
-                    onMove={moveTo}
-                />
-            )}
-
-            {currentUBOSubStep === SUBSTEP.ARE_THERE_MORE_UBOS && (
+            {currentSubPage === SUB_PAGE_NAMES.ARE_THERE_MORE_UBOS && (
                 <YesNoStep
                     title={translate('beneficialOwnerInfoStep.areThereMoreIndividualsWhoOwn25percent', companyName)}
                     description={translate('beneficialOwnerInfoStep.regulationRequiresUsToVerifyTheIdentity')}
@@ -261,7 +263,7 @@ function BeneficialOwnersStep({onBackButtonPress}: BeneficialOwnersStepProps) {
                 />
             )}
 
-            {currentUBOSubStep === SUBSTEP.UBOS_LIST && (
+            {currentSubPage === SUB_PAGE_NAMES.UBOS_LIST && (
                 <CompanyOwnersListUBO
                     beneficialOwnerKeys={beneficialOwnerKeys}
                     handleUBOsConfirmation={submit}
diff --git a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/AddressUBO.tsx b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/AddressUBO.tsx
index 1f3507f8357a..03e1ad8a2494 100644
--- a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/AddressUBO.tsx
+++ b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/AddressUBO.tsx
@@ -3,7 +3,7 @@ import AddressStep from '@components/SubStepForms/AddressStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import SafeString from '@src/utils/SafeString';
@@ -11,7 +11,7 @@ import SafeString from '@src/utils/SafeString';
 const BENEFICIAL_OWNER_INFO_KEY = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA;
 const BENEFICIAL_OWNER_PREFIX = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.PREFIX;
 
-type AddressUBOProps = SubStepProps & {beneficialOwnerBeingModifiedID: string};
+type AddressUBOProps = SubPageProps & {beneficialOwnerBeingModifiedID: string};
 
 function AddressUBO({onNext, onMove, isEditing, beneficialOwnerBeingModifiedID}: AddressUBOProps) {
     const {translate} = useLocalize();
diff --git a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/ConfirmationUBO.tsx b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/ConfirmationUBO.tsx
index 5534c513c721..db3260ed398c 100644
--- a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/ConfirmationUBO.tsx
+++ b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/ConfirmationUBO.tsx
@@ -2,13 +2,13 @@ import React from 'react';
 import ConfirmationStep from '@components/SubStepForms/ConfirmationStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import {getLatestErrorMessage} from '@libs/ErrorUtils';
 import getValuesForBeneficialOwner from '@pages/ReimbursementAccount/USD/utils/getValuesForBeneficialOwner';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 
-type ConfirmationUBOProps = SubStepProps & {beneficialOwnerBeingModifiedID: string};
+type ConfirmationUBOProps = SubPageProps & {beneficialOwnerBeingModifiedID: string};
 
 const UBO_STEP_INDEXES = CONST.REIMBURSEMENT_ACCOUNT.SUBSTEP_INDEX.UBO;
 
diff --git a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/DateOfBirthUBO.tsx b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/DateOfBirthUBO.tsx
index 8f824cf54334..9eb85e749b36 100644
--- a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/DateOfBirthUBO.tsx
+++ b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/DateOfBirthUBO.tsx
@@ -3,7 +3,7 @@ import DateOfBirthStep from '@components/SubStepForms/DateOfBirthStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import SafeString from '@src/utils/SafeString';
@@ -11,7 +11,7 @@ import SafeString from '@src/utils/SafeString';
 const DOB = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.DOB;
 const BENEFICIAL_OWNER_PREFIX = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.PREFIX;
 
-type DateOfBirthUBOProps = SubStepProps & {beneficialOwnerBeingModifiedID: string};
+type DateOfBirthUBOProps = SubPageProps & {beneficialOwnerBeingModifiedID: string};
 
 function DateOfBirthUBO({onNext, onMove, isEditing, beneficialOwnerBeingModifiedID}: DateOfBirthUBOProps) {
     const {translate} = useLocalize();
diff --git a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/LegalNameUBO.tsx b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/LegalNameUBO.tsx
index ac34d4e4132f..dcd23543abbd 100644
--- a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/LegalNameUBO.tsx
+++ b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/LegalNameUBO.tsx
@@ -4,7 +4,7 @@ import FullNameStep from '@components/SubStepForms/FullNameStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import SafeString from '@src/utils/SafeString';
@@ -12,7 +12,7 @@ import SafeString from '@src/utils/SafeString';
 const {FIRST_NAME, LAST_NAME} = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA;
 const BENEFICIAL_OWNER_PREFIX = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.PREFIX;
 
-type LegalNameUBOProps = SubStepProps & {beneficialOwnerBeingModifiedID: string};
+type LegalNameUBOProps = SubPageProps & {beneficialOwnerBeingModifiedID: string};
 
 function LegalNameUBO({onNext, onMove, isEditing, beneficialOwnerBeingModifiedID}: LegalNameUBOProps) {
     const {translate} = useLocalize();
diff --git a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/SocialSecurityNumberUBO.tsx b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/SocialSecurityNumberUBO.tsx
index 84c8723cf296..2df5a39d837d 100644
--- a/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/SocialSecurityNumberUBO.tsx
+++ b/src/pages/ReimbursementAccount/USD/BeneficialOwnerInfo/subSteps/BeneficialOwnerDetailsFormSubSteps/SocialSecurityNumberUBO.tsx
@@ -4,7 +4,7 @@ import SingleFieldStep from '@components/SubStepForms/SingleFieldStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import {getFieldRequiredErrors, isValidSSNLastFour} from '@libs/ValidationUtils';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -13,7 +13,7 @@ import SafeString from '@src/utils/SafeString';
 const SSN_LAST_4 = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.SSN_LAST_4;
 const BENEFICIAL_OWNER_PREFIX = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.PREFIX;
 
-type SocialSecurityNumberUBOProps = SubStepProps & {beneficialOwnerBeingModifiedID: string};
+type SocialSecurityNumberUBOProps = SubPageProps & {beneficialOwnerBeingModifiedID: string};
 
 function SocialSecurityNumberUBO({onNext, onMove, isEditing, beneficialOwnerBeingModifiedID}: SocialSecurityNumberUBOProps) {
     const {translate} = useLocalize();
@@ -54,6 +54,7 @@ function SocialSecurityNumberUBO({onNext, onMove, isEditing, beneficialOwnerBein
             defaultValue={defaultSsnLast4}
             shouldShowHelpLinks={false}
             maxLength={CONST.BANK_ACCOUNT.MAX_LENGTH.SSN}
+            shouldDelayAutoFocus
         />
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx
index be7ff00b0080..60e87e064fcf 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx
@@ -1,11 +1,14 @@
 import {Str} from 'expensify-common';
 import lodashPick from 'lodash/pick';
 import React, {useCallback, useMemo} from 'react';
+import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
 import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
-import useSubStep from '@hooks/useSubStep';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import useReimbursementAccountSubmitCallback from '@hooks/useReimbursementAccountSubmitCallback';
+import useSubPage from '@hooks/useSubPage';
+import type {SubPageProps} from '@hooks/useSubPage/types';
+import Navigation from '@libs/Navigation/Navigation';
 import {parsePhoneNumber} from '@libs/PhoneNumber';
 import {getBankAccountIDAsNumber} from '@libs/ReimbursementAccountUtils';
 import {isValidWebsite} from '@libs/ValidationUtils';
@@ -14,6 +17,7 @@ import getSubStepValues from '@pages/ReimbursementAccount/utils/getSubStepValues
 import {updateCompanyInformationForBankAccount} from '@userActions/BankAccounts';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
 import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 import AddressBusiness from './subSteps/AddressBusiness';
 import ConfirmationBusiness from './subSteps/ConfirmationBusiness';
@@ -29,24 +33,32 @@ import WebsiteBusiness from './subSteps/WebsiteBusiness';
 type BusinessInfoProps = {
     /** Goes to the previous step */
     onBackButtonPress: () => void;
+
+    /** Handles submit button press (URL-based navigation) */
+    onSubmit?: () => void;
+
+    /** Back to URL for preserving navigation context */
+    backTo?: string;
 };
 
 const BUSINESS_INFO_STEP_KEYS = INPUT_IDS.BUSINESS_INFO_STEP;
+const PAGE_NAMES = CONST.BANK_ACCOUNT.PAGE_NAMES;
+const SUB_PAGE_NAMES = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.SUB_PAGE_NAMES;
 
-const bodyContent: Array<React.ComponentType<SubStepProps>> = [
-    NameBusiness,
-    TaxIdBusiness,
-    WebsiteBusiness,
-    PhoneNumberBusiness,
-    AddressBusiness,
-    TypeBusiness,
-    IncorporationDateBusiness,
-    IncorporationStateBusiness,
-    IncorporationCode,
-    ConfirmationBusiness,
+const pages = [
+    {pageName: SUB_PAGE_NAMES.NAME, component: NameBusiness},
+    {pageName: SUB_PAGE_NAMES.TAX_ID, component: TaxIdBusiness},
+    {pageName: SUB_PAGE_NAMES.WEBSITE, component: WebsiteBusiness},
+    {pageName: SUB_PAGE_NAMES.PHONE, component: PhoneNumberBusiness},
+    {pageName: SUB_PAGE_NAMES.ADDRESS, component: AddressBusiness},
+    {pageName: SUB_PAGE_NAMES.TYPE, component: TypeBusiness},
+    {pageName: SUB_PAGE_NAMES.INCORPORATION_DATE, component: IncorporationDateBusiness},
+    {pageName: SUB_PAGE_NAMES.INCORPORATION_STATE, component: IncorporationStateBusiness},
+    {pageName: SUB_PAGE_NAMES.INCORPORATION_CODE, component: IncorporationCode},
+    {pageName: SUB_PAGE_NAMES.CONFIRMATION, component: ConfirmationBusiness},
 ];
 
-function BusinessInfo({onBackButtonPress}: BusinessInfoProps) {
+function BusinessInfo({onBackButtonPress, onSubmit, backTo}: BusinessInfoProps) {
     const {translate} = useLocalize();
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT);
@@ -61,6 +73,7 @@ function BusinessInfo({onBackButtonPress}: BusinessInfoProps) {
 
     const policyID = reimbursementAccount?.achData?.policyID;
     const bankAccountID = getBankAccountIDAsNumber(reimbursementAccount?.achData);
+    const markSubmitting = useReimbursementAccountSubmitCallback(onSubmit);
     const values = useMemo(() => getSubStepValues(BUSINESS_INFO_STEP_KEYS, reimbursementAccountDraft, reimbursementAccount), [reimbursementAccount, reimbursementAccountDraft]);
 
     const submit = useCallback(
@@ -85,29 +98,39 @@ function BusinessInfo({onBackButtonPress}: BusinessInfoProps) {
     const isBankAccountVerifying = reimbursementAccount?.achData?.state === CONST.BANK_ACCOUNT.STATE.VERIFYING;
     const startFrom = useMemo(() => (isBankAccountVerifying ? 0 : getInitialSubStepForBusinessInfo(values)), [values, isBankAccountVerifying]);
 
-    const {
-        componentToRender: SubStep,
-        isEditing,
-        screenIndex,
-        nextScreen,
-        prevScreen,
-        moveTo,
-        goToTheLastStep,
-    } = useSubStep({bodyContent, startFrom, onFinished: () => submit(true), onNextSubStep: () => submit(false)});
+    const buildRoute = useCallback(
+        (pageName: string, action?: 'edit') => ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: PAGE_NAMES.COMPANY, subPage: pageName, action, backTo}),
+        [policyID, backTo],
+    );
+
+    const {CurrentPage, isEditing, currentPageName, pageIndex, nextPage, prevPage, moveTo, isRedirecting} = useSubPage<SubPageProps>({
+        pages,
+        startFrom,
+        onFinished: () => {
+            submit(true);
+            markSubmitting();
+        },
+        onPageChange: () => submit(false),
+        buildRoute,
+    });
 
     const handleBackButtonPress = () => {
         if (isEditing) {
-            goToTheLastStep();
+            Navigation.goBack(buildRoute(SUB_PAGE_NAMES.CONFIRMATION));
             return;
         }
 
-        if (screenIndex === 0) {
+        if (pageIndex === 0) {
             onBackButtonPress();
         } else {
-            prevScreen();
+            prevPage();
         }
     };
 
+    if (isRedirecting) {
+        return <FullScreenLoadingIndicator reasonAttributes={{context: 'BusinessInfo', isRedirecting}} />;
+    }
+
     return (
         <InteractiveStepWrapper
             wrapperID="BusinessInfo"
@@ -118,10 +141,11 @@ function BusinessInfo({onBackButtonPress}: BusinessInfoProps) {
             startStepIndex={4}
             stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
         >
-            <SubStep
+            <CurrentPage
                 isEditing={isEditing}
-                onNext={nextScreen}
+                onNext={nextPage}
                 onMove={moveTo}
+                currentPageName={currentPageName}
             />
         </InteractiveStepWrapper>
     );
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/AddressBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/AddressBusiness.tsx
index 9d68d1da372f..69fc14e84caa 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/AddressBusiness.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/AddressBusiness.tsx
@@ -4,7 +4,7 @@ import AddressStep from '@components/SubStepForms/AddressStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import ONYXKEYS from '@src/ONYXKEYS';
 import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
@@ -21,7 +21,7 @@ const INPUT_KEYS = {
 
 const STEP_FIELDS = [COMPANY_BUSINESS_INFO_KEY.STREET, COMPANY_BUSINESS_INFO_KEY.CITY, COMPANY_BUSINESS_INFO_KEY.STATE, COMPANY_BUSINESS_INFO_KEY.ZIP_CODE];
 
-function AddressBusiness({onNext, onMove, isEditing}: SubStepProps) {
+function AddressBusiness({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount, reimbursementAccountResult] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/ConfirmationBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/ConfirmationBusiness.tsx
index 4bdeebd55e21..2ce528bc2118 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/ConfirmationBusiness.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/ConfirmationBusiness.tsx
@@ -10,7 +10,7 @@ import Text from '@components/Text';
 import TextLink from '@components/TextLink';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {getFieldRequiredErrors} from '@libs/ValidationUtils';
 import getSubStepValues from '@pages/ReimbursementAccount/utils/getSubStepValues';
@@ -35,7 +35,7 @@ function ConfirmCompanyLabel() {
     );
 }
 
-function ConfirmationBusiness({onNext, onMove}: SubStepProps) {
+function ConfirmationBusiness({onNext, onMove}: SubPageProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
@@ -106,7 +106,11 @@ function ConfirmationBusiness({onNext, onMove}: SubStepProps) {
             />
             <MenuItemWithTopDescription
                 description={translate('businessInfoStep.companyType')}
-                title={translate(`businessInfoStep.incorporationType.${values[BUSINESS_INFO_STEP_KEYS.INCORPORATION_TYPE]}` as TranslationPaths)}
+                title={
+                    values[BUSINESS_INFO_STEP_KEYS.INCORPORATION_TYPE]
+                        ? translate(`businessInfoStep.incorporationType.${values[BUSINESS_INFO_STEP_KEYS.INCORPORATION_TYPE]}` as TranslationPaths)
+                        : ''
+                }
                 shouldShowRightIcon
                 onPress={() => {
                     onMove(BUSINESS_INFO_STEP_INDEXES.COMPANY_TYPE);
@@ -122,7 +126,7 @@ function ConfirmationBusiness({onNext, onMove}: SubStepProps) {
             />
             <MenuItemWithTopDescription
                 description={translate('businessInfoStep.incorporationState')}
-                title={translate(`allStates.${values[BUSINESS_INFO_STEP_KEYS.INCORPORATION_STATE] as States}.stateName`)}
+                title={values[BUSINESS_INFO_STEP_KEYS.INCORPORATION_STATE] ? translate(`allStates.${values[BUSINESS_INFO_STEP_KEYS.INCORPORATION_STATE] as States}.stateName`) : ''}
                 shouldShowRightIcon
                 onPress={() => {
                     onMove(BUSINESS_INFO_STEP_INDEXES.INCORPORATION_STATE);
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationCode.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationCode.tsx
index 579ac48913fe..8cca170661eb 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationCode.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationCode.tsx
@@ -6,7 +6,7 @@ import Text from '@components/Text';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {isValidIndustryCode} from '@libs/ValidationUtils';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -16,7 +16,7 @@ import IndustryCodeSelector from './IndustryCode/IndustryCodeSelector';
 const COMPANY_INCORPORATION_CODE_KEY = INPUT_IDS.BUSINESS_INFO_STEP.INCORPORATION_CODE;
 const STEP_FIELDS = [COMPANY_INCORPORATION_CODE_KEY];
 
-function IncorporationCode({onNext, isEditing}: SubStepProps) {
+function IncorporationCode({onNext, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationDateBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationDateBusiness.tsx
index 2febf55e42b5..7674f9b770d6 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationDateBusiness.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationDateBusiness.tsx
@@ -8,7 +8,7 @@ import Text from '@components/Text';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import useThemeStyles from '@hooks/useThemeStyles';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import {getFieldRequiredErrors, isValidDate, isValidPastDate} from '@libs/ValidationUtils';
@@ -19,7 +19,7 @@ import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
 const COMPANY_INCORPORATION_DATE_KEY = INPUT_IDS.BUSINESS_INFO_STEP.INCORPORATION_DATE;
 const STEP_FIELDS = [COMPANY_INCORPORATION_DATE_KEY];
 
-function IncorporationDateBusiness({onNext, isEditing}: SubStepProps) {
+function IncorporationDateBusiness({onNext, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationStateBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationStateBusiness.tsx
index 5d10d77469b0..24d899552ea9 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationStateBusiness.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IncorporationStateBusiness.tsx
@@ -9,7 +9,7 @@ import Text from '@components/Text';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import useThemeStyles from '@hooks/useThemeStyles';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import {getFieldRequiredErrors} from '@libs/ValidationUtils';
@@ -25,7 +25,7 @@ const validate = (
     translate: LocalizedTranslate,
 ): FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> => getFieldRequiredErrors(values, STEP_FIELDS, translate);
 
-function IncorporationStateBusiness({onNext, isEditing}: SubStepProps) {
+function IncorporationStateBusiness({onNext, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IndustryCode/IndustryCodeSelector.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IndustryCode/IndustryCodeSelector.tsx
index 1584b9e5b93f..b5ced220b5bd 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IndustryCode/IndustryCodeSelector.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IndustryCode/IndustryCodeSelector.tsx
@@ -1,9 +1,12 @@
-import React, {useEffect, useMemo, useState} from 'react';
+import {useFocusEffect} from '@react-navigation/native';
+import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
 import {View} from 'react-native';
 import SelectionList from '@components/SelectionList';
 import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import type {ListItem, SelectionListHandle} from '@components/SelectionList/types';
 import useLocalize from '@hooks/useLocalize';
 import useThemeStyles from '@hooks/useThemeStyles';
+import CONST from '@src/CONST';
 import {ALL_NAICS, NAICS, NAICS_MAPPING_WITH_ID} from '@src/NAICS';
 
 type IndustryCodeSelectorProps = {
@@ -14,11 +17,25 @@ type IndustryCodeSelectorProps = {
 
 function IndustryCodeSelector({onInputChange, value, errorText}: IndustryCodeSelectorProps) {
     const styles = useThemeStyles();
+    const selectionListRef = useRef<SelectionListHandle<ListItem>>(null);
     const [searchValue, setSearchValue] = useState<string | undefined>(value);
+    const [isReady, setIsReady] = useState(false);
 
     const [shouldDisplayChildItems, setShouldDisplayChildItems] = useState(false);
     const {translate} = useLocalize();
 
+    // Delay rendering the list and focusing the input until the screen transition animation completes.
+    useFocusEffect(
+        useCallback(() => {
+            const timeout = setTimeout(() => {
+                setIsReady(true);
+                selectionListRef.current?.focusTextInput();
+            }, CONST.ANIMATED_TRANSITION);
+
+            return () => clearTimeout(timeout);
+        }, []),
+    );
+
     const codeOptions = useMemo(() => {
         if (!searchValue) {
             return NAICS.map((item) => {
@@ -65,6 +82,7 @@ function IndustryCodeSelector({onInputChange, value, errorText}: IndustryCodeSel
                 onInputChange?.(val);
             },
             value: searchValue,
+            disableAutoFocus: true,
             errorText,
         }),
         [errorText, onInputChange, searchValue, translate],
@@ -73,7 +91,8 @@ function IndustryCodeSelector({onInputChange, value, errorText}: IndustryCodeSel
     return (
         <View style={styles.flexGrow1}>
             <SelectionList
-                data={codeOptions}
+                ref={selectionListRef}
+                data={isReady ? codeOptions : []}
                 ListItem={SingleSelectListItem}
                 onSelectRow={(item) => {
                     setSearchValue(item.value);
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx
index 6e18b09b2923..fd819f39875d 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/NameBusiness.tsx
@@ -4,7 +4,7 @@ import SingleFieldStep from '@components/SubStepForms/SingleFieldStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import {getFieldRequiredErrors, isValidCompanyName} from '@libs/ValidationUtils';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -13,7 +13,7 @@ import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 const COMPANY_NAME_KEY = INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_NAME;
 const STEP_FIELDS = [COMPANY_NAME_KEY];
 
-function NameBusiness({onNext, onMove, isEditing}: SubStepProps) {
+function NameBusiness({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
@@ -63,6 +63,7 @@ function NameBusiness({onNext, onMove, isEditing}: SubStepProps) {
             shouldUseDefaultValue={shouldDisableCompanyName}
             disabled={shouldDisableCompanyName}
             shouldShowHelpLinks={false}
+            shouldDelayAutoFocus
         />
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/PhoneNumberBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/PhoneNumberBusiness.tsx
index 4437c83e6228..85dec7f7c1f0 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/PhoneNumberBusiness.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/PhoneNumberBusiness.tsx
@@ -5,7 +5,7 @@ import SingleFieldStep from '@components/SubStepForms/SingleFieldStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import {getFieldRequiredErrors, isValidUSPhone} from '@libs/ValidationUtils';
 import CONST from '@src/CONST';
@@ -16,7 +16,7 @@ import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
 const COMPANY_PHONE_NUMBER_KEY = INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_PHONE;
 const STEP_FIELDS = [COMPANY_PHONE_NUMBER_KEY];
 
-function PhoneNumberBusiness({onNext, onMove, isEditing}: SubStepProps) {
+function PhoneNumberBusiness({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount, reimbursementAccountResult] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
@@ -67,6 +67,7 @@ function PhoneNumberBusiness({onNext, onMove, isEditing}: SubStepProps) {
             defaultValue={defaultCompanyPhoneNumber}
             shouldShowHelpLinks={false}
             placeholder={translate('common.phoneNumberPlaceholder')}
+            shouldDelayAutoFocus
         />
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx
index 94a85398e8fb..5e3e9b13f73e 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TaxIdBusiness.tsx
@@ -5,7 +5,7 @@ import SingleFieldStep from '@components/SubStepForms/SingleFieldStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import {getFieldRequiredErrors, isValidTaxID} from '@libs/ValidationUtils';
 import CONST from '@src/CONST';
@@ -15,7 +15,7 @@ import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
 
 const COMPANY_TAX_ID_KEY = INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_TAX_ID;
 const STEP_FIELDS = [COMPANY_TAX_ID_KEY];
-function TaxIdBusiness({onNext, onMove, isEditing}: SubStepProps) {
+function TaxIdBusiness({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount, reimbursementAccountResult] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
@@ -77,6 +77,7 @@ function TaxIdBusiness({onNext, onMove, isEditing}: SubStepProps) {
             shouldShowHelpLinks={false}
             placeholder={translate('businessInfoStep.taxIDNumberPlaceholder')}
             inputMode={CONST.INPUT_MODE.NUMERIC}
+            shouldDelayAutoFocus
         />
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TypeBusiness/TypeBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TypeBusiness/TypeBusiness.tsx
index f8a296965496..0154ec35c188 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TypeBusiness/TypeBusiness.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TypeBusiness/TypeBusiness.tsx
@@ -7,7 +7,7 @@ import Text from '@components/Text';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import useThemeStyles from '@hooks/useThemeStyles';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import {getFieldRequiredErrors} from '@libs/ValidationUtils';
@@ -19,7 +19,7 @@ import BusinessTypePicker from './BusinessTypePicker';
 const COMPANY_INCORPORATION_TYPE_KEY = INPUT_IDS.BUSINESS_INFO_STEP.INCORPORATION_TYPE;
 const STEP_FIELDS = [COMPANY_INCORPORATION_TYPE_KEY];
 
-function TypeBusiness({onNext, isEditing}: SubStepProps) {
+function TypeBusiness({onNext, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/WebsiteBusiness.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/WebsiteBusiness.tsx
index 8a15cbcf8908..7214ee4aa687 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/WebsiteBusiness.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/WebsiteBusiness.tsx
@@ -6,7 +6,7 @@ import SingleFieldStep from '@components/SubStepForms/SingleFieldStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import {getDefaultCompanyWebsite} from '@libs/BankAccountUtils';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import {getFieldRequiredErrors, isValidWebsite} from '@libs/ValidationUtils';
@@ -19,7 +19,7 @@ import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
 const COMPANY_WEBSITE_KEY = INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_WEBSITE;
 const STEP_FIELDS = [COMPANY_WEBSITE_KEY];
 
-function WebsiteBusiness({onNext, onMove, isEditing}: SubStepProps) {
+function WebsiteBusiness({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
     const [reimbursementAccount, reimbursementAccountResult] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
     const isLoadingReimbursementAccount = isLoadingOnyxValue(reimbursementAccountResult);
@@ -74,6 +74,7 @@ function WebsiteBusiness({onNext, onMove, isEditing}: SubStepProps) {
             defaultValue={defaultCompanyWebsite}
             inputMode={CONST.INPUT_MODE.URL}
             shouldShowHelpLinks={false}
+            shouldDelayAutoFocus
         />
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/CompleteVerification/CompleteVerification.tsx b/src/pages/ReimbursementAccount/USD/CompleteVerification/CompleteVerification.tsx
index 8b99de40b19c..4110007599d6 100644
--- a/src/pages/ReimbursementAccount/USD/CompleteVerification/CompleteVerification.tsx
+++ b/src/pages/ReimbursementAccount/USD/CompleteVerification/CompleteVerification.tsx
@@ -1,10 +1,8 @@
 import React, {useCallback, useMemo} from 'react';
-import type {ComponentType} from 'react';
 import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
-import useSubStep from '@hooks/useSubStep';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import useReimbursementAccountSubmitCallback from '@hooks/useReimbursementAccountSubmitCallback';
 import {getBankAccountIDAsNumber} from '@libs/ReimbursementAccountUtils';
 import getSubStepValues from '@pages/ReimbursementAccount/utils/getSubStepValues';
 import {acceptACHContractForBankAccount} from '@userActions/BankAccounts';
@@ -16,12 +14,14 @@ import ConfirmAgreements from './subSteps/ConfirmAgreements';
 type CompleteVerificationProps = {
     /** Handles back button press */
     onBackButtonPress: () => void;
+
+    /** Handles submit button press (URL-based navigation) */
+    onSubmit?: () => void;
 };
 
 const COMPLETE_VERIFICATION_KEYS = INPUT_IDS.COMPLETE_VERIFICATION;
-const bodyContent: Array<ComponentType<SubStepProps>> = [ConfirmAgreements];
 
-function CompleteVerification({onBackButtonPress}: CompleteVerificationProps) {
+function CompleteVerification({onBackButtonPress, onSubmit}: CompleteVerificationProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
@@ -31,6 +31,7 @@ function CompleteVerification({onBackButtonPress}: CompleteVerificationProps) {
     const values = useMemo(() => getSubStepValues(COMPLETE_VERIFICATION_KEYS, reimbursementAccountDraft, reimbursementAccount), [reimbursementAccount, reimbursementAccountDraft]);
     const policyID = reimbursementAccount?.achData?.policyID;
     const bankAccountID = getBankAccountIDAsNumber(reimbursementAccount?.achData);
+    const markSubmitting = useReimbursementAccountSubmitCallback(onSubmit);
 
     const submit = useCallback(() => {
         acceptACHContractForBankAccount(
@@ -43,22 +44,8 @@ function CompleteVerification({onBackButtonPress}: CompleteVerificationProps) {
             policyID,
             policyID ? lastPaymentMethod?.[policyID] : undefined,
         );
-    }, [bankAccountID, values.isAuthorizedToUseBankAccount, values.certifyTrueInformation, values.acceptTermsAndConditions, policyID, lastPaymentMethod]);
-
-    const {componentToRender: SubStep, isEditing, screenIndex, nextScreen, prevScreen, moveTo, goToTheLastStep} = useSubStep({bodyContent, startFrom: 0, onFinished: submit});
-
-    const handleBackButtonPress = () => {
-        if (isEditing) {
-            goToTheLastStep();
-            return;
-        }
-
-        if (screenIndex === 0) {
-            onBackButtonPress();
-        } else {
-            prevScreen();
-        }
-    };
+        markSubmitting();
+    }, [bankAccountID, values.isAuthorizedToUseBankAccount, values.certifyTrueInformation, values.acceptTermsAndConditions, policyID, lastPaymentMethod, markSubmitting]);
 
     return (
         <InteractiveStepWrapper
@@ -66,15 +53,11 @@ function CompleteVerification({onBackButtonPress}: CompleteVerificationProps) {
             shouldEnablePickerAvoiding={false}
             shouldEnableMaxHeight
             headerTitle={translate('completeVerificationStep.completeVerification')}
-            handleBackButtonPress={handleBackButtonPress}
+            handleBackButtonPress={onBackButtonPress}
             startStepIndex={6}
             stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
         >
-            <SubStep
-                isEditing={isEditing}
-                onNext={nextScreen}
-                onMove={moveTo}
-            />
+            <ConfirmAgreements onNext={submit} />
         </InteractiveStepWrapper>
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx b/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx
index 0799cece1418..ad825930e2f1 100644
--- a/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx
+++ b/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx
@@ -7,15 +7,12 @@ import RenderHTML from '@components/RenderHTML';
 import Text from '@components/Text';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
-import type {SubStepProps} from '@hooks/useSubStep/types';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {getFieldRequiredErrors, isRequiredFulfilled} from '@libs/ValidationUtils';
 import getSubStepValues from '@pages/ReimbursementAccount/utils/getSubStepValues';
 import ONYXKEYS from '@src/ONYXKEYS';
 import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 
-type ConfirmAgreementsProps = SubStepProps;
-
 const COMPLETE_VERIFICATION_KEYS = INPUT_IDS.COMPLETE_VERIFICATION;
 const STEP_FIELDS = [
     INPUT_IDS.COMPLETE_VERIFICATION.IS_AUTHORIZED_TO_USE_BANK_ACCOUNT,
@@ -38,6 +35,11 @@ function TermsAndConditionsLabel() {
     return <RenderHTML html={translate('common.acceptTermsAndConditions')} />;
 }
 
+type ConfirmAgreementsProps = {
+    /** Continues to the next step */
+    onNext: () => void;
+};
+
 function ConfirmAgreements({onNext}: ConfirmAgreementsProps) {
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
     const [reimbursementAccountDraft] = useOnyx(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT);
diff --git a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx
index 5d44b1b79949..640215e572f3 100644
--- a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx
+++ b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx
@@ -1,6 +1,7 @@
 import {hasSeenTourSelector} from '@selectors/Onboarding';
 import React from 'react';
 import {View} from 'react-native';
+import ConfirmationPage from '@components/ConfirmationPage';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
 import ScreenWrapper from '@components/ScreenWrapper';
 import Text from '@components/Text';
@@ -8,10 +9,14 @@ import TextLink from '@components/TextLink';
 import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
+import useRootNavigationState from '@hooks/useRootNavigationState';
 import useThemeStyles from '@hooks/useThemeStyles';
+import {isFullScreenName} from '@navigation/helpers/isNavigatorName';
+import Navigation from '@navigation/Navigation';
 import ConnectedVerifiedBankAccount from '@pages/ReimbursementAccount/ConnectedVerifiedBankAccount';
 import {navigateToConciergeChat} from '@userActions/Report';
 import CONST from '@src/CONST';
+import NAVIGATORS from '@src/NAVIGATORS';
 import ONYXKEYS from '@src/ONYXKEYS';
 import BankAccountValidationForm from './components/BankAccountValidationForm';
 import FinishChatCard from './components/FinishChatCard';
@@ -21,15 +26,16 @@ type ConnectBankAccountProps = {
     onBackButtonPress: () => void;
 
     /** Method to set the state of shouldShowConnectedVerifiedBankAccount */
-    setShouldShowConnectedVerifiedBankAccount: (shouldShowConnectedVerifiedBankAccount: boolean) => void;
+    setShouldShowConnectedVerifiedBankAccount?: (shouldShowConnectedVerifiedBankAccount: boolean) => void;
 
     /** Method to set the state of shouldShowConnectedVerifiedBankAccount */
-    setUSDBankAccountStep: (step: string | null) => void;
+    setUSDBankAccountStep?: (step: string | null) => void;
 };
 
 function ConnectBankAccount({onBackButtonPress, setShouldShowConnectedVerifiedBankAccount, setUSDBankAccountStep}: ConnectBankAccountProps) {
     const styles = useThemeStyles();
     const {translate} = useLocalize();
+    const topmostFullScreenRoute = useRootNavigationState((state) => state?.routes.findLast((lastRoute) => isFullScreenName(lastRoute.name)));
 
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
     const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${reimbursementAccount?.achData?.policyID}`);
@@ -45,10 +51,28 @@ function ConnectBankAccount({onBackButtonPress, setShouldShowConnectedVerifiedBa
 
     // If a user tries to navigate directly to the validate page we'll show them the EnableStep
     if (bankAccountState === CONST.BANK_ACCOUNT.STATE.OPEN) {
+        if (topmostFullScreenRoute?.name === NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR) {
+            return (
+                <ScreenWrapper testID="ReimbursementAccountPage">
+                    <HeaderWithBackButton
+                        title={translate('bankAccount.addBankAccount')}
+                        onBackButtonPress={() => Navigation.dismissModal()}
+                    />
+                    <ConfirmationPage
+                        heading={translate('bankAccount.bbaAdded')}
+                        description={translate('bankAccount.bbaAddedDescription')}
+                        shouldShowButton
+                        headingStyle={styles.mh5}
+                        buttonText={translate('common.confirm')}
+                        onButtonPress={() => Navigation.dismissModal()}
+                    />
+                </ScreenWrapper>
+            );
+        }
         return (
             <ConnectedVerifiedBankAccount
                 reimbursementAccount={reimbursementAccount}
-                onBackButtonPress={onBackButtonPress}
+                onBackButtonPress={() => Navigation.dismissModal()}
                 setShouldShowConnectedVerifiedBankAccount={setShouldShowConnectedVerifiedBankAccount}
                 setUSDBankAccountStep={setUSDBankAccountStep}
                 isNonUSDWorkspace={false}
diff --git a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx
index d1add2f1e6bd..9493fad76a0d 100644
--- a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx
+++ b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx
@@ -26,7 +26,7 @@ type FinishChatCardProps = {
     requiresTwoFactorAuth: boolean;
 
     /** Method to set the state of USD bank account step */
-    setUSDBankAccountStep: (step: string | null) => void;
+    setUSDBankAccountStep?: (step: string | null) => void;
 };
 
 function FinishChatCard({requiresTwoFactorAuth, reimbursementAccount, setUSDBankAccountStep}: FinishChatCardProps) {
@@ -78,7 +78,7 @@ function FinishChatCard({requiresTwoFactorAuth, reimbursementAccount, setUSDBank
                     title={translate('workspace.bankAccount.updateDetails')}
                     onPress={() => {
                         setBankAccountSubStep(CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL).then(() => {
-                            setUSDBankAccountStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR);
+                            setUSDBankAccountStep?.(CONST.BANK_ACCOUNT.STEP.REQUESTOR);
                             goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR);
                         });
                     }}
diff --git a/src/pages/ReimbursementAccount/USD/Country/index.tsx b/src/pages/ReimbursementAccount/USD/Country/index.tsx
index b4a28c913745..ded09899c388 100644
--- a/src/pages/ReimbursementAccount/USD/Country/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/Country/index.tsx
@@ -7,24 +7,20 @@ type CountryProps = {
     /** Handles back button press */
     onBackButtonPress: () => void;
 
+    /** Handles submit button press (URL-based navigation) */
+    onSubmit?: () => void;
+
     /** Array of step names */
     stepNames: readonly string[];
 
-    /** Method to set the state of setUSDBankAccountStep */
-    setUSDBankAccountStep?: (step: string | null) => void;
-
     /** ID of current policy */
     policyID: string | undefined;
 };
 
-function Country({onBackButtonPress, stepNames, setUSDBankAccountStep, policyID}: CountryProps) {
+function Country({onBackButtonPress, onSubmit, stepNames, policyID}: CountryProps) {
     const submit = () => {
-        if (!setUSDBankAccountStep) {
-            return;
-        }
-
-        setUSDBankAccountStep(CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT);
         goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT);
+        onSubmit?.();
     };
 
     return (
diff --git a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/PersonalInfo.tsx b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/PersonalInfo.tsx
index bd548f912ff0..a0c39597cf35 100644
--- a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/PersonalInfo.tsx
+++ b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/PersonalInfo.tsx
@@ -1,17 +1,21 @@
 import type {ForwardedRef} from 'react';
 import React, {useCallback, useMemo} from 'react';
 import type {View} from 'react-native';
+import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
 import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
-import useSubStep from '@hooks/useSubStep';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import useReimbursementAccountSubmitCallback from '@hooks/useReimbursementAccountSubmitCallback';
+import useSubPage from '@hooks/useSubPage';
+import type {SubPageProps} from '@hooks/useSubPage/types';
+import Navigation from '@libs/Navigation/Navigation';
 import {getBankAccountIDAsNumber} from '@libs/ReimbursementAccountUtils';
 import getInitialSubStepForPersonalInfo from '@pages/ReimbursementAccount/USD/utils/getInitialSubStepForPersonalInfo';
 import getSubStepValues from '@pages/ReimbursementAccount/utils/getSubStepValues';
 import {updatePersonalInformationForBankAccount} from '@userActions/BankAccounts';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
 import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 import Address from './subSteps/Address';
 import Confirmation from './subSteps/Confirmation';
@@ -23,14 +27,29 @@ type PersonalInfoProps = {
     /** Goes to the previous step */
     onBackButtonPress: () => void;
 
+    /** Handles submit button press (URL-based navigation) */
+    onSubmit?: () => void;
+
     /** Reference to the outer element */
     ref?: ForwardedRef<View>;
+
+    /** Back to URL for preserving navigation context */
+    backTo?: string;
 };
 
 const PERSONAL_INFO_STEP_KEYS = INPUT_IDS.PERSONAL_INFO_STEP;
-const bodyContent: Array<React.ComponentType<SubStepProps>> = [FullName, DateOfBirth, SocialSecurityNumber, Address, Confirmation];
+const PAGE_NAMES = CONST.BANK_ACCOUNT.PAGE_NAMES;
+const SUB_PAGE_NAMES = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.SUB_PAGE_NAMES;
+
+const pages = [
+    {pageName: SUB_PAGE_NAMES.FULL_NAME, component: FullName},
+    {pageName: SUB_PAGE_NAMES.DATE_OF_BIRTH, component: DateOfBirth},
+    {pageName: SUB_PAGE_NAMES.SSN, component: SocialSecurityNumber},
+    {pageName: SUB_PAGE_NAMES.ADDRESS, component: Address},
+    {pageName: SUB_PAGE_NAMES.CONFIRMATION, component: Confirmation},
+];
 
-function PersonalInfo({onBackButtonPress, ref}: PersonalInfoProps) {
+function PersonalInfo({onBackButtonPress, onSubmit, ref, backTo}: PersonalInfoProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
@@ -39,6 +58,7 @@ function PersonalInfo({onBackButtonPress, ref}: PersonalInfoProps) {
     const policyID = reimbursementAccount?.achData?.policyID;
     const values = useMemo(() => getSubStepValues(PERSONAL_INFO_STEP_KEYS, reimbursementAccountDraft, reimbursementAccount), [reimbursementAccount, reimbursementAccountDraft]);
     const bankAccountID = getBankAccountIDAsNumber(reimbursementAccount?.achData);
+    const markSubmitting = useReimbursementAccountSubmitCallback(onSubmit);
     const submit = useCallback(
         (isConfirmPage: boolean) => {
             updatePersonalInformationForBankAccount(bankAccountID, {...values}, policyID, isConfirmPage);
@@ -48,26 +68,32 @@ function PersonalInfo({onBackButtonPress, ref}: PersonalInfoProps) {
     const isBankAccountVerifying = reimbursementAccount?.achData?.state === CONST.BANK_ACCOUNT.STATE.VERIFYING;
     const startFrom = useMemo(() => (isBankAccountVerifying ? 0 : getInitialSubStepForPersonalInfo(values)), [values, isBankAccountVerifying]);
 
-    const {
-        componentToRender: SubStep,
-        isEditing,
-        screenIndex,
-        nextScreen,
-        prevScreen,
-        moveTo,
-        goToTheLastStep,
-    } = useSubStep({bodyContent, startFrom, onFinished: () => submit(true), onNextSubStep: () => submit(false)});
+    const buildRoute = useCallback(
+        (pageName: string, action?: 'edit') => ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: PAGE_NAMES.REQUESTOR, subPage: pageName, action, backTo}),
+        [policyID, backTo],
+    );
+
+    const {CurrentPage, isEditing, currentPageName, pageIndex, nextPage, prevPage, moveTo, isRedirecting} = useSubPage<SubPageProps>({
+        pages,
+        startFrom,
+        onFinished: () => {
+            submit(true);
+            markSubmitting();
+        },
+        onPageChange: () => submit(false),
+        buildRoute,
+    });
 
     const handleBackButtonPress = () => {
         if (isEditing) {
-            goToTheLastStep();
+            Navigation.goBack(buildRoute(SUB_PAGE_NAMES.CONFIRMATION));
             return;
         }
 
-        if (screenIndex === 0) {
+        if (pageIndex === 0) {
             onBackButtonPress();
         } else {
-            prevScreen();
+            prevPage();
         }
     };
 
@@ -82,11 +108,16 @@ function PersonalInfo({onBackButtonPress, ref}: PersonalInfoProps) {
             startStepIndex={2}
             stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
         >
-            <SubStep
-                isEditing={isEditing}
-                onNext={nextScreen}
-                onMove={moveTo}
-            />
+            {isRedirecting ? (
+                <FullScreenLoadingIndicator reasonAttributes={{context: 'PersonalInfo', isRedirecting}} />
+            ) : (
+                <CurrentPage
+                    isEditing={isEditing}
+                    onNext={nextPage}
+                    onMove={moveTo}
+                    currentPageName={currentPageName}
+                />
+            )}
         </InteractiveStepWrapper>
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/Address.tsx b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/Address.tsx
index cc63886621ce..39c912e0ce38 100644
--- a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/Address.tsx
+++ b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/Address.tsx
@@ -4,7 +4,7 @@ import AddressStep from '@components/SubStepForms/AddressStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -22,7 +22,7 @@ const INPUT_KEYS = {
 
 const STEP_FIELDS = [PERSONAL_INFO_STEP_KEY.STREET, PERSONAL_INFO_STEP_KEY.CITY, PERSONAL_INFO_STEP_KEY.STATE, PERSONAL_INFO_STEP_KEY.ZIP_CODE];
 
-function Address({onNext, onMove, isEditing}: SubStepProps) {
+function Address({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount, reimbursementAccountResult] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
diff --git a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/Confirmation.tsx b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/Confirmation.tsx
index 17c29db3ce12..e9c1a8749b9c 100644
--- a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/Confirmation.tsx
+++ b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/Confirmation.tsx
@@ -2,7 +2,7 @@ import React, {useMemo} from 'react';
 import ConfirmationStep from '@components/SubStepForms/ConfirmationStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import {getLatestErrorMessage} from '@libs/ErrorUtils';
 import getSubStepValues from '@pages/ReimbursementAccount/utils/getSubStepValues';
 import CONST from '@src/CONST';
@@ -12,7 +12,7 @@ import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 const PERSONAL_INFO_STEP_KEYS = INPUT_IDS.PERSONAL_INFO_STEP;
 const PERSONAL_INFO_STEP_INDEXES = CONST.REIMBURSEMENT_ACCOUNT.SUBSTEP_INDEX.PERSONAL_INFO;
 
-function Confirmation({onNext, onMove, isEditing}: SubStepProps) {
+function Confirmation({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
diff --git a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/DateOfBirth.tsx b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/DateOfBirth.tsx
index cde22e01ed97..54adf2a4be87 100644
--- a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/DateOfBirth.tsx
+++ b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/DateOfBirth.tsx
@@ -4,7 +4,7 @@ import DateOfBirthStep from '@components/SubStepForms/DateOfBirthStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import useThemeStyles from '@hooks/useThemeStyles';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import HelpLinks from '@pages/ReimbursementAccount/USD/Requestor/PersonalInfo/HelpLinks';
@@ -16,7 +16,7 @@ import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
 const PERSONAL_INFO_DOB_KEY = INPUT_IDS.PERSONAL_INFO_STEP.DOB;
 const STEP_FIELDS = [PERSONAL_INFO_DOB_KEY];
 
-function DateOfBirth({onNext, onMove, isEditing}: SubStepProps) {
+function DateOfBirth({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
diff --git a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/FullName.tsx b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/FullName.tsx
index a1f841963792..6093b3c2a77a 100644
--- a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/FullName.tsx
+++ b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/FullName.tsx
@@ -3,7 +3,7 @@ import FullNameStep from '@components/SubStepForms/FullNameStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
@@ -11,7 +11,7 @@ import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 const PERSONAL_INFO_STEP_KEY = INPUT_IDS.PERSONAL_INFO_STEP;
 const STEP_FIELDS = [PERSONAL_INFO_STEP_KEY.FIRST_NAME, PERSONAL_INFO_STEP_KEY.LAST_NAME];
 
-function FullName({onNext, onMove, isEditing}: SubStepProps) {
+function FullName({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
diff --git a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/SocialSecurityNumber.tsx b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/SocialSecurityNumber.tsx
index ff9d07476a6a..6e7384be05ab 100644
--- a/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/SocialSecurityNumber.tsx
+++ b/src/pages/ReimbursementAccount/USD/Requestor/PersonalInfo/subSteps/SocialSecurityNumber.tsx
@@ -5,7 +5,7 @@ import SingleFieldStep from '@components/SubStepForms/SingleFieldStep';
 import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit';
-import type {SubStepProps} from '@hooks/useSubStep/types';
+import type {SubPageProps} from '@hooks/useSubPage/types';
 import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
 import {getFieldRequiredErrors, isValidSSNLastFour} from '@libs/ValidationUtils';
 import CONST from '@src/CONST';
@@ -16,7 +16,7 @@ import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
 const PERSONAL_INFO_STEP_KEY = INPUT_IDS.PERSONAL_INFO_STEP;
 const STEP_FIELDS = [PERSONAL_INFO_STEP_KEY.SSN_LAST_4];
 
-function SocialSecurityNumber({onNext, onMove, isEditing}: SubStepProps) {
+function SocialSecurityNumber({onNext, onMove, isEditing}: SubPageProps) {
     const {translate} = useLocalize();
 
     const [reimbursementAccount, reimbursementAccountResult] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
@@ -68,6 +68,7 @@ function SocialSecurityNumber({onNext, onMove, isEditing}: SubStepProps) {
             maxLength={CONST.BANK_ACCOUNT.MAX_LENGTH.SSN}
             enabledWhenOffline
             forwardedFSClass={CONST.FULLSTORY.CLASS.MASK}
+            shouldDelayAutoFocus
         />
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/Requestor/RequestorStep.tsx b/src/pages/ReimbursementAccount/USD/Requestor/RequestorStep.tsx
index 4a9de8d65704..f02b5186081d 100644
--- a/src/pages/ReimbursementAccount/USD/Requestor/RequestorStep.tsx
+++ b/src/pages/ReimbursementAccount/USD/Requestor/RequestorStep.tsx
@@ -2,28 +2,28 @@ import React from 'react';
 import type {ForwardedRef} from 'react';
 import type {View} from 'react-native';
 import PersonalInfo from './PersonalInfo/PersonalInfo';
-import VerifyIdentity from './VerifyIdentity/VerifyIdentity';
 
 type RequestorStepProps = {
     /** Goes to the previous step */
     onBackButtonPress: () => void;
 
-    /** If we should show Onfido flow */
-    shouldShowOnfido: boolean;
+    /** Handles submit button press (URL-based navigation) */
+    onSubmit?: () => void;
 
     /** Reference to the outer element */
     ref?: ForwardedRef<View>;
-};
 
-function RequestorStep({shouldShowOnfido, onBackButtonPress, ref}: RequestorStepProps) {
-    if (shouldShowOnfido) {
-        return <VerifyIdentity onBackButtonPress={onBackButtonPress} />;
-    }
+    /** Back to URL for preserving navigation context */
+    backTo?: string;
+};
 
+function RequestorStep({onBackButtonPress, onSubmit, ref, backTo}: RequestorStepProps) {
     return (
         <PersonalInfo
             ref={ref}
             onBackButtonPress={onBackButtonPress}
+            onSubmit={onSubmit}
+            backTo={backTo}
         />
     );
 }
diff --git a/src/pages/ReimbursementAccount/USD/Requestor/VerifyIdentity/VerifyIdentity.tsx b/src/pages/ReimbursementAccount/USD/Requestor/VerifyIdentity/VerifyIdentity.tsx
index 5947ef3f01f8..c739dd63a433 100644
--- a/src/pages/ReimbursementAccount/USD/Requestor/VerifyIdentity/VerifyIdentity.tsx
+++ b/src/pages/ReimbursementAccount/USD/Requestor/VerifyIdentity/VerifyIdentity.tsx
@@ -1,4 +1,4 @@
-import React, {useCallback, useState} from 'react';
+import React, {useCallback, useEffect, useRef, useState} from 'react';
 import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView';
 import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
 import Onfido from '@components/Onfido';
@@ -8,18 +8,21 @@ import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
 import Growl from '@libs/Growl';
-import {clearOnfidoToken, goToWithdrawalAccountSetupStep, updateReimbursementAccountDraft, verifyIdentityForBankAccount} from '@userActions/BankAccounts';
+import {clearOnfidoToken, updateReimbursementAccountDraft, verifyIdentityForBankAccount} from '@userActions/BankAccounts';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 
 type VerifyIdentityProps = {
     /** Goes to the previous step */
     onBackButtonPress: () => void;
+
+    /** Navigates to the next step */
+    onSubmit?: () => void;
 };
 
 const ONFIDO_ERROR_DISPLAY_DURATION = 10000;
 
-function VerifyIdentity({onBackButtonPress}: VerifyIdentityProps) {
+function VerifyIdentity({onBackButtonPress, onSubmit}: VerifyIdentityProps) {
     const styles = useThemeStyles();
     const {translate} = useLocalize();
 
@@ -31,25 +34,37 @@ function VerifyIdentity({onBackButtonPress}: VerifyIdentityProps) {
     const policyID = reimbursementAccount?.achData?.policyID;
     const bankAccountID = reimbursementAccount?.achData?.bankAccountID;
 
+    const isOnfidoAlreadyComplete = useRef(reimbursementAccount?.achData?.isOnfidoSetupComplete);
+    const onSubmitRef = useRef(onSubmit);
+
+    // If Onfido is already complete (e.g. direct URL navigation), skip to next step
+    useEffect(() => {
+        if (!isOnfidoAlreadyComplete.current) {
+            return;
+        }
+        onSubmitRef.current?.();
+    }, []);
+
     const handleOnfidoSuccess = useCallback(
         (onfidoData: OnfidoData) => {
             verifyIdentityForBankAccount(Number(bankAccountID), {...onfidoData, applicantID: onfidoApplicantID}, policyID);
             updateReimbursementAccountDraft({isOnfidoSetupComplete: true});
+            onSubmit?.();
         },
-        [bankAccountID, onfidoApplicantID, policyID],
+        [bankAccountID, onfidoApplicantID, policyID, onSubmit],
     );
 
     const handleOnfidoError = () => {
         // In case of any unexpected error we log it to the server, show a growl, and return the user back to the requestor step so they can try again.
         Growl.error(translate('onfidoStep.genericError'), ONFIDO_ERROR_DISPLAY_DURATION);
         clearOnfidoToken();
-        goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR);
+        onBackButtonPress();
     };
 
     const handleOnfidoUserExit = (isUserInitiated?: boolean) => {
         if (isUserInitiated) {
             clearOnfidoToken();
-            goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR);
+            onBackButtonPress();
         } else {
             setOnfidoKey(Math.floor(Math.random() * 1000000));
         }
diff --git a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
deleted file mode 100644
index c13784998b2a..000000000000
--- a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlow.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-import React from 'react';
-import {View} from 'react-native';
-import useOnyx from '@hooks/useOnyx';
-import useThemeStyles from '@hooks/useThemeStyles';
-import CONST from '@src/CONST';
-import ONYXKEYS from '@src/ONYXKEYS';
-import BankInfo from './BankInfo/BankInfo';
-import BeneficialOwnersStep from './BeneficialOwnerInfo/BeneficialOwnersStep';
-import BusinessInfo from './BusinessInfo/BusinessInfo';
-import CompleteVerification from './CompleteVerification/CompleteVerification';
-import ConnectBankAccount from './ConnectBankAccount/ConnectBankAccount';
-import Country from './Country';
-import RequestorStep from './Requestor/RequestorStep';
-
-type USDVerifiedBankAccountFlowProps = {
-    USDBankAccountStep: string;
-    policyID: string | undefined;
-    onBackButtonPress: () => void;
-    requestorStepRef: React.RefObject<View | null>;
-    onfidoToken: string;
-    setUSDBankAccountStep: (step: string | null) => void;
-    setShouldShowConnectedVerifiedBankAccount: (shouldShowConnectedVerifiedBankAccount: boolean) => void;
-};
-
-function USDVerifiedBankAccountFlow({
-    USDBankAccountStep,
-    policyID = '',
-    onBackButtonPress,
-    requestorStepRef,
-    onfidoToken,
-    setUSDBankAccountStep,
-    setShouldShowConnectedVerifiedBankAccount,
-}: USDVerifiedBankAccountFlowProps) {
-    const styles = useThemeStyles();
-    const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
-
-    let CurrentStep: React.JSX.Element | null;
-    switch (USDBankAccountStep) {
-        case CONST.BANK_ACCOUNT.STEP.COUNTRY:
-            CurrentStep = (
-                <Country
-                    onBackButtonPress={onBackButtonPress}
-                    policyID={policyID}
-                    setUSDBankAccountStep={setUSDBankAccountStep}
-                    stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
-                />
-            );
-            break;
-        case CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT:
-            CurrentStep = (
-                <BankInfo
-                    onBackButtonPress={onBackButtonPress}
-                    policyID={policyID}
-                    setUSDBankAccountStep={setUSDBankAccountStep}
-                />
-            );
-            break;
-        case CONST.BANK_ACCOUNT.STEP.REQUESTOR:
-            CurrentStep = (
-                <RequestorStep
-                    ref={requestorStepRef}
-                    shouldShowOnfido={!!(onfidoToken && !reimbursementAccount?.achData?.isOnfidoSetupComplete)}
-                    onBackButtonPress={onBackButtonPress}
-                />
-            );
-            break;
-        case CONST.BANK_ACCOUNT.STEP.COMPANY:
-            CurrentStep = <BusinessInfo onBackButtonPress={onBackButtonPress} />;
-            break;
-        case CONST.BANK_ACCOUNT.STEP.BENEFICIAL_OWNERS:
-            CurrentStep = <BeneficialOwnersStep onBackButtonPress={onBackButtonPress} />;
-            break;
-        case CONST.BANK_ACCOUNT.STEP.ACH_CONTRACT:
-            CurrentStep = <CompleteVerification onBackButtonPress={onBackButtonPress} />;
-            break;
-        case CONST.BANK_ACCOUNT.STEP.VALIDATION:
-            CurrentStep = (
-                <ConnectBankAccount
-                    onBackButtonPress={onBackButtonPress}
-                    setUSDBankAccountStep={setUSDBankAccountStep}
-                    setShouldShowConnectedVerifiedBankAccount={setShouldShowConnectedVerifiedBankAccount}
-                />
-            );
-            break;
-        default:
-            CurrentStep = null;
-            break;
-    }
-
-    if (CurrentStep) {
-        return <View style={styles.flex1}>{CurrentStep}</View>;
-    }
-
-    return null;
-}
-
-export default USDVerifiedBankAccountFlow;
diff --git a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx
new file mode 100644
index 000000000000..d721d8155e1c
--- /dev/null
+++ b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx
@@ -0,0 +1,135 @@
+import React, {useCallback, useMemo, useRef} from 'react';
+import {View} from 'react-native';
+import useOnyx from '@hooks/useOnyx';
+import useThemeStyles from '@hooks/useThemeStyles';
+import Navigation from '@libs/Navigation/Navigation';
+import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
+import type {ReimbursementAccountNavigatorParamList} from '@libs/Navigation/types';
+import CONST from '@src/CONST';
+import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
+import type SCREENS from '@src/SCREENS';
+import BankInfo from './BankInfo/BankInfo';
+import BeneficialOwnersStep from './BeneficialOwnerInfo/BeneficialOwnersStep';
+import BusinessInfo from './BusinessInfo/BusinessInfo';
+import CompleteVerification from './CompleteVerification/CompleteVerification';
+import ConnectBankAccount from './ConnectBankAccount/ConnectBankAccount';
+import Country from './Country';
+import RequestorStep from './Requestor/RequestorStep';
+import VerifyIdentity from './Requestor/VerifyIdentity/VerifyIdentity';
+import type USDPageProps from './types';
+
+const PAGE_NAMES = CONST.BANK_ACCOUNT.PAGE_NAMES;
+const BANK_INFO_SUB_PAGES = CONST.BANK_ACCOUNT.BANK_INFO_STEP.SUB_PAGE_NAMES;
+const PERSONAL_INFO_SUB_PAGES = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.SUB_PAGE_NAMES;
+const BUSINESS_INFO_SUB_PAGES = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.SUB_PAGE_NAMES;
+const BENEFICIAL_OWNERS_SUB_PAGES = CONST.BANK_ACCOUNT.BENEFICIAL_OWNERS_STEP.SUB_PAGE_NAMES;
+const COMPLETE_VERIFICATION_SUB_PAGES = CONST.BANK_ACCOUNT.COMPLETE_VERIFICATION_STEP.SUB_PAGE_NAMES;
+
+type PageEntry = {
+    pageName: string;
+    component: React.ComponentType<USDPageProps>;
+    firstSubPage?: string;
+    lastSubPage?: string;
+};
+
+const pages: PageEntry[] = [
+    {pageName: PAGE_NAMES.COUNTRY, component: Country as React.ComponentType<USDPageProps>},
+    {pageName: PAGE_NAMES.BANK_ACCOUNT, component: BankInfo as React.ComponentType<USDPageProps>, firstSubPage: BANK_INFO_SUB_PAGES.PLAID, lastSubPage: BANK_INFO_SUB_PAGES.PLAID},
+    {
+        pageName: PAGE_NAMES.REQUESTOR,
+        component: RequestorStep as React.ComponentType<USDPageProps>,
+        firstSubPage: PERSONAL_INFO_SUB_PAGES.FULL_NAME,
+        lastSubPage: PERSONAL_INFO_SUB_PAGES.CONFIRMATION,
+    },
+    {pageName: PAGE_NAMES.VERIFY_IDENTITY, component: VerifyIdentity as React.ComponentType<USDPageProps>},
+    {
+        pageName: PAGE_NAMES.COMPANY,
+        component: BusinessInfo as React.ComponentType<USDPageProps>,
+        firstSubPage: BUSINESS_INFO_SUB_PAGES.NAME,
+        lastSubPage: BUSINESS_INFO_SUB_PAGES.CONFIRMATION,
+    },
+    {
+        pageName: PAGE_NAMES.BENEFICIAL_OWNERS,
+        component: BeneficialOwnersStep as React.ComponentType<USDPageProps>,
+        firstSubPage: BENEFICIAL_OWNERS_SUB_PAGES.IS_USER_UBO,
+        lastSubPage: undefined,
+    },
+    {
+        pageName: PAGE_NAMES.ACH_CONTRACT,
+        component: CompleteVerification as React.ComponentType<USDPageProps>,
+        firstSubPage: COMPLETE_VERIFICATION_SUB_PAGES.CONFIRM_AGREEMENTS,
+        lastSubPage: COMPLETE_VERIFICATION_SUB_PAGES.CONFIRM_AGREEMENTS,
+    },
+    {pageName: PAGE_NAMES.VALIDATION, component: ConnectBankAccount as React.ComponentType<USDPageProps>},
+];
+
+type USDVerifiedBankAccountFlowPageProps = PlatformStackScreenProps<ReimbursementAccountNavigatorParamList, typeof SCREENS.REIMBURSEMENT_ACCOUNT_USD>;
+
+function USDVerifiedBankAccountFlowPage({route}: USDVerifiedBankAccountFlowPageProps) {
+    const styles = useThemeStyles();
+    const policyID = route.params?.policyID;
+    const currentPage = route.params?.page;
+    const currentSubPage = route.params?.subPage;
+    const backTo = route.params?.backTo;
+
+    const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
+
+    const requestorStepRef = useRef<View>(null);
+    const isOnfidoSetupComplete = reimbursementAccount?.achData?.isOnfidoSetupComplete;
+
+    const currentPageIndex = useMemo(() => {
+        const index = pages.findIndex((p) => p.pageName === currentPage);
+        return index >= 0 ? index : 0;
+    }, [currentPage]);
+
+    const currentEntry = pages.at(currentPageIndex);
+    const CurrentPage = currentEntry?.component ?? (Country as React.ComponentType<USDPageProps>);
+    const isRequestorStep = currentEntry?.pageName === PAGE_NAMES.REQUESTOR;
+
+    const shouldSkipVerifyIdentity = useCallback((pageName?: string) => pageName === PAGE_NAMES.VERIFY_IDENTITY && isOnfidoSetupComplete, [isOnfidoSetupComplete]);
+
+    const onSubmit = useCallback(() => {
+        let nextIndex = currentPageIndex + 1;
+        if (shouldSkipVerifyIdentity(pages.at(nextIndex)?.pageName)) {
+            nextIndex += 1;
+        }
+        if (nextIndex >= pages.length) {
+            Navigation.goBack();
+            return;
+        }
+        const nextPage = pages.at(nextIndex);
+        Navigation.navigate(ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: nextPage?.pageName, subPage: nextPage?.firstSubPage, backTo}));
+    }, [backTo, currentPageIndex, policyID, shouldSkipVerifyIdentity]);
+
+    const onBackButtonPress = useCallback(() => {
+        let prevIndex = currentPageIndex - 1;
+        if (shouldSkipVerifyIdentity(pages.at(prevIndex)?.pageName)) {
+            prevIndex -= 1;
+        }
+        if (prevIndex < 0) {
+            Navigation.goBack();
+            return;
+        }
+        const prevPage = pages.at(prevIndex);
+        Navigation.goBack(ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: prevPage?.pageName, subPage: prevPage?.lastSubPage, backTo}));
+    }, [backTo, currentPageIndex, policyID, shouldSkipVerifyIdentity]);
+
+    return (
+        <View style={[styles.flex1, styles.appBG]}>
+            <CurrentPage
+                onSubmit={onSubmit}
+                onBackButtonPress={onBackButtonPress}
+                policyID={policyID}
+                currentSubPage={currentSubPage}
+                stepNames={CONST.BANK_ACCOUNT.STEP_NAMES}
+                ref={isRequestorStep ? requestorStepRef : undefined}
+                backTo={backTo}
+            />
+        </View>
+    );
+}
+
+USDVerifiedBankAccountFlowPage.displayName = 'USDVerifiedBankAccountFlowPage';
+
+export default USDVerifiedBankAccountFlowPage;
diff --git a/src/pages/ReimbursementAccount/USD/types.ts b/src/pages/ReimbursementAccount/USD/types.ts
new file mode 100644
index 000000000000..c808a68bff8f
--- /dev/null
+++ b/src/pages/ReimbursementAccount/USD/types.ts
@@ -0,0 +1,28 @@
+import type {ForwardedRef} from 'react';
+import type {View} from 'react-native';
+import type {Route} from '@src/ROUTES';
+
+type USDPageProps = {
+    /** Handles submit button press */
+    onSubmit: () => void;
+
+    /** Handles back button press */
+    onBackButtonPress: () => void;
+
+    /** ID of current policy */
+    policyID?: string;
+
+    /** Name of the current sub page */
+    currentSubPage?: string;
+
+    /** Array of step names for the progress indicator */
+    stepNames?: readonly string[];
+
+    /** Reference to the outer element (used by RequestorStep) */
+    ref?: ForwardedRef<View>;
+
+    /** Back to URL for preserving navigation context */
+    backTo?: Route;
+};
+
+export default USDPageProps;
diff --git a/src/pages/ReimbursementAccount/VerifiedBankAccountFlowEntryPoint.tsx b/src/pages/ReimbursementAccount/VerifiedBankAccountFlowEntryPoint.tsx
index 4da763c2981f..8e6a747efcc5 100644
--- a/src/pages/ReimbursementAccount/VerifiedBankAccountFlowEntryPoint.tsx
+++ b/src/pages/ReimbursementAccount/VerifiedBankAccountFlowEntryPoint.tsx
@@ -123,10 +123,10 @@ function VerifiedBankAccountFlowEntryPoint({
     const prepareNextStep = useCallback(
         (setupType: ValueOf<typeof CONST.BANK_ACCOUNT.SETUP_TYPE>) => {
             setBankAccountSubStep(setupType);
-            setUSDBankAccountStep(CONST.BANK_ACCOUNT.STEP.COUNTRY);
             goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.COUNTRY);
+            Navigation.navigate(ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: CONST.BANK_ACCOUNT.PAGE_NAMES.COUNTRY, backTo}));
         },
-        [setUSDBankAccountStep],
+        [policyID, backTo],
     );
 
     /**
diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx
index dc08a6534505..24dd5d84896f 100644
--- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx
+++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx
@@ -19,7 +19,6 @@ import {getLastFourDigits} from '@libs/BankAccountUtils';
 import {getEligibleBankAccountsForCard, getEligibleBankAccountsForUkEuCard} from '@libs/CardUtils';
 import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
-import {REIMBURSEMENT_ACCOUNT_ROUTE_NAMES} from '@libs/ReimbursementAccountUtils';
 import Navigation from '@navigation/Navigation';
 import type {SettingsNavigatorParamList} from '@navigation/types';
 import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
@@ -67,7 +66,6 @@ function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankA
         Navigation.navigate(
             ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({
                 policyID,
-                stepToOpen: REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.NEW,
                 backTo: ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policyID),
             }),
         );
diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx
index 2c694a0253c8..063813a70834 100644
--- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx
+++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx
@@ -20,7 +20,7 @@ import {getEligibleBankAccountsForCard, getEligibleBankAccountsForUkEuCard} from
 import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
 import type {WorkspaceSplitNavigatorParamList} from '@libs/Navigation/types';
-import {hasInProgressUSDVBBA, REIMBURSEMENT_ACCOUNT_ROUTE_NAMES} from '@libs/ReimbursementAccountUtils';
+import {hasInProgressUSDVBBA} from '@libs/ReimbursementAccountUtils';
 import Navigation from '@navigation/Navigation';
 import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading';
 import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading';
@@ -71,7 +71,6 @@ function WorkspaceExpensifyCardPageEmptyState({route, policy}: WorkspaceExpensif
             Navigation.navigate(
                 ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({
                     policyID: policy?.id,
-                    stepToOpen: REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.NEW,
                     backTo: ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policy?.id),
                 }),
             );
diff --git a/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx b/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx
index 1b2f0312a243..a2f57f08248d 100644
--- a/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx
+++ b/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx
@@ -29,7 +29,7 @@ import {getLastFourDigits} from '@libs/BankAccountUtils';
 import {getCardSettings, getEligibleBankAccountsForCard} from '@libs/CardUtils';
 import Navigation from '@libs/Navigation/Navigation';
 import {areTravelPersonalDetailsMissing} from '@libs/PersonalDetailsUtils';
-import {hasInProgressUSDVBBA, REIMBURSEMENT_ACCOUNT_ROUTE_NAMES} from '@libs/ReimbursementAccountUtils';
+import {hasInProgressUSDVBBA} from '@libs/ReimbursementAccountUtils';
 import {
     getIsTravelInvoicingEnabled,
     getTravelInvoicingCardSettingsKey,
@@ -173,7 +173,6 @@ function WorkspaceTravelInvoicingSection({policyID}: WorkspaceTravelInvoicingSec
             Navigation.navigate(
                 ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({
                     policyID,
-                    stepToOpen: REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.NEW,
                     backTo: ROUTES.WORKSPACE_TRAVEL.getRoute(policyID),
                 }),
             );
diff --git a/src/pages/workspace/travel/WorkspaceTravelInvoicingSettlementAccountPage.tsx b/src/pages/workspace/travel/WorkspaceTravelInvoicingSettlementAccountPage.tsx
index 1203dfce00b2..981ab69e16ff 100644
--- a/src/pages/workspace/travel/WorkspaceTravelInvoicingSettlementAccountPage.tsx
+++ b/src/pages/workspace/travel/WorkspaceTravelInvoicingSettlementAccountPage.tsx
@@ -15,7 +15,6 @@ import {configureTravelInvoicingForPolicy, setTravelInvoicingSettlementAccount}
 import {getLastFourDigits} from '@libs/BankAccountUtils';
 import {getCardSettings, getEligibleBankAccountsForCard} from '@libs/CardUtils';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
-import {REIMBURSEMENT_ACCOUNT_ROUTE_NAMES} from '@libs/ReimbursementAccountUtils';
 import {getIsTravelInvoicingEnabled, getTravelInvoicingCardSettingsKey} from '@libs/TravelInvoicingUtils';
 import Navigation from '@navigation/Navigation';
 import type {SettingsNavigatorParamList} from '@navigation/types';
@@ -97,7 +96,6 @@ function WorkspaceTravelInvoicingSettlementAccountPage({route}: WorkspaceTravelI
         Navigation.navigate(
             ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({
                 policyID,
-                stepToOpen: REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.NEW,
                 backTo: ROUTES.WORKSPACE_TRAVEL_SETTINGS_ACCOUNT.getRoute(policyID),
             }),
         );
diff --git a/tests/unit/ReimbursementAccountUtilsTest.ts b/tests/unit/ReimbursementAccountUtilsTest.ts
index b531357e9865..e2f3be2e8703 100644
--- a/tests/unit/ReimbursementAccountUtilsTest.ts
+++ b/tests/unit/ReimbursementAccountUtilsTest.ts
@@ -1,19 +1,12 @@
 import Onyx from 'react-native-onyx';
 import CONST from '../../src/CONST';
-import {getBankAccountIDAsNumber, getRouteForCurrentStep, REIMBURSEMENT_ACCOUNT_ROUTE_NAMES} from '../../src/libs/ReimbursementAccountUtils';
+import {getBankAccountIDAsNumber} from '../../src/libs/ReimbursementAccountUtils';
 import ONYXKEYS from '../../src/ONYXKEYS';
 import type {ACHDataReimbursementAccount} from '../../src/types/onyx/ReimbursementAccount';
 
 Onyx.init({keys: ONYXKEYS});
 
 describe('ReimbursementAccountUtils', () => {
-    describe('getRouteForCurrentStep', () => {
-        it("should return 'new' step if 'BankAccountStep' or '' is provided", () => {
-            expect(getRouteForCurrentStep(CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT)).toEqual(REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.NEW);
-            expect(getRouteForCurrentStep('')).toEqual(REIMBURSEMENT_ACCOUNT_ROUTE_NAMES.NEW);
-        });
-    });
-
     describe('getBankAccountIDAsNumber', () => {
         it('should return DEFAULT_NUMBER_ID when achData is undefined', () => {
             // Given no ACH data

From 9b1d68fa95637a3aec73fd43157c9a720484e121 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Tue, 12 May 2026 10:29:09 +0200
Subject: [PATCH 18/27] fix: update details

---
 .../ConnectBankAccount/ConnectBankAccount.tsx   |  7 ++++++-
 .../components/FinishChatCard.tsx               | 17 +++++++++++++++--
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx
index 640215e572f3..3b67b12cecca 100644
--- a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx
+++ b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx
@@ -18,6 +18,7 @@ import {navigateToConciergeChat} from '@userActions/Report';
 import CONST from '@src/CONST';
 import NAVIGATORS from '@src/NAVIGATORS';
 import ONYXKEYS from '@src/ONYXKEYS';
+import type {Route} from '@src/ROUTES';
 import BankAccountValidationForm from './components/BankAccountValidationForm';
 import FinishChatCard from './components/FinishChatCard';
 
@@ -30,9 +31,12 @@ type ConnectBankAccountProps = {
 
     /** Method to set the state of shouldShowConnectedVerifiedBankAccount */
     setUSDBankAccountStep?: (step: string | null) => void;
+
+    /** Route to return to when navigating back out of the flow */
+    backTo?: Route;
 };
 
-function ConnectBankAccount({onBackButtonPress, setShouldShowConnectedVerifiedBankAccount, setUSDBankAccountStep}: ConnectBankAccountProps) {
+function ConnectBankAccount({onBackButtonPress, setShouldShowConnectedVerifiedBankAccount, setUSDBankAccountStep, backTo}: ConnectBankAccountProps) {
     const styles = useThemeStyles();
     const {translate} = useLocalize();
     const topmostFullScreenRoute = useRootNavigationState((state) => state?.routes.findLast((lastRoute) => isFullScreenName(lastRoute.name)));
@@ -116,6 +120,7 @@ function ConnectBankAccount({onBackButtonPress, setShouldShowConnectedVerifiedBa
                     requiresTwoFactorAuth={requiresTwoFactorAuth}
                     reimbursementAccount={reimbursementAccount}
                     setUSDBankAccountStep={setUSDBankAccountStep}
+                    backTo={backTo}
                 />
             )}
         </ScreenWrapper>
diff --git a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx
index 9493fad76a0d..3ff2ac160020 100644
--- a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx
+++ b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/components/FinishChatCard.tsx
@@ -10,11 +10,14 @@ import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useResponsiveLayout from '@hooks/useResponsiveLayout';
 import useThemeStyles from '@hooks/useThemeStyles';
+import Navigation from '@libs/Navigation/Navigation';
 import WorkspaceResetBankAccountModal from '@pages/workspace/WorkspaceResetBankAccountModal';
 import {goToWithdrawalAccountSetupStep, requestResetBankAccount, setBankAccountSubStep} from '@userActions/BankAccounts';
 import {navigateToConciergeChat} from '@userActions/Report';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
+import type {Route} from '@src/ROUTES';
 import type {ReimbursementAccount} from '@src/types/onyx';
 import Enable2FACard from './Enable2FACard';
 
@@ -27,9 +30,12 @@ type FinishChatCardProps = {
 
     /** Method to set the state of USD bank account step */
     setUSDBankAccountStep?: (step: string | null) => void;
+
+    /** Route to return to when navigating back out of the flow */
+    backTo?: Route;
 };
 
-function FinishChatCard({requiresTwoFactorAuth, reimbursementAccount, setUSDBankAccountStep}: FinishChatCardProps) {
+function FinishChatCard({requiresTwoFactorAuth, reimbursementAccount, setUSDBankAccountStep, backTo}: FinishChatCardProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
     const {shouldUseNarrowLayout} = useResponsiveLayout();
@@ -78,8 +84,15 @@ function FinishChatCard({requiresTwoFactorAuth, reimbursementAccount, setUSDBank
                     title={translate('workspace.bankAccount.updateDetails')}
                     onPress={() => {
                         setBankAccountSubStep(CONST.BANK_ACCOUNT.SETUP_TYPE.MANUAL).then(() => {
-                            setUSDBankAccountStep?.(CONST.BANK_ACCOUNT.STEP.REQUESTOR);
                             goToWithdrawalAccountSetupStep(CONST.BANK_ACCOUNT.STEP.REQUESTOR);
+                            Navigation.navigate(
+                                ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({
+                                    policyID,
+                                    page: CONST.BANK_ACCOUNT.PAGE_NAMES.REQUESTOR,
+                                    subPage: CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.SUB_PAGE_NAMES.FULL_NAME,
+                                    backTo,
+                                }),
+                            );
                         });
                     }}
                     outerWrapperStyle={shouldUseNarrowLayout ? styles.mhn5 : styles.mhn8}

From f7fecec6dfb28f94198bb9258b622a81b62c8f7f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Tue, 12 May 2026 12:29:46 +0200
Subject: [PATCH 19/27] fix: hide date picker on navigating forward via
 hardware button

---
 src/components/DatePicker/index.tsx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/DatePicker/index.tsx b/src/components/DatePicker/index.tsx
index 39dd7e675d80..da41eddc66d9 100644
--- a/src/components/DatePicker/index.tsx
+++ b/src/components/DatePicker/index.tsx
@@ -172,6 +172,7 @@ function DatePicker({
                 anchorPosition={popoverPosition}
                 shouldPositionFromTop={!isInverted}
                 forwardedFSClass={forwardedFSClass}
+                shouldCloseWhenBrowserNavigationChanged
             />
         </>
     );

From 6428b30e94d203bef0ecd9c999e16b942734934f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Thu, 14 May 2026 11:18:39 +0200
Subject: [PATCH 20/27] fix: allow resubmitting after going back

---
 .../CompleteVerification/CompleteVerification.tsx   | 13 +++++++++++--
 .../subSteps/ConfirmAgreements.tsx                  |  2 +-
 src/types/onyx/ReimbursementAccount.ts              |  3 +++
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/pages/ReimbursementAccount/USD/CompleteVerification/CompleteVerification.tsx b/src/pages/ReimbursementAccount/USD/CompleteVerification/CompleteVerification.tsx
index 4110007599d6..a428397b24b1 100644
--- a/src/pages/ReimbursementAccount/USD/CompleteVerification/CompleteVerification.tsx
+++ b/src/pages/ReimbursementAccount/USD/CompleteVerification/CompleteVerification.tsx
@@ -39,13 +39,22 @@ function CompleteVerification({onBackButtonPress, onSubmit}: CompleteVerificatio
             {
                 isAuthorizedToUseBankAccount: values.isAuthorizedToUseBankAccount,
                 certifyTrueInformation: values.certifyTrueInformation,
-                acceptTermsAndConditions: values.acceptTermsAndConditions,
+                acceptTermsAndConditions: (values.acceptTermsAndConditions || reimbursementAccount?.achData?.acceptTerms) ?? false,
             },
             policyID,
             policyID ? lastPaymentMethod?.[policyID] : undefined,
         );
         markSubmitting();
-    }, [bankAccountID, values.isAuthorizedToUseBankAccount, values.certifyTrueInformation, values.acceptTermsAndConditions, policyID, lastPaymentMethod, markSubmitting]);
+    }, [
+        bankAccountID,
+        values.isAuthorizedToUseBankAccount,
+        values.certifyTrueInformation,
+        values.acceptTermsAndConditions,
+        reimbursementAccount?.achData?.acceptTerms,
+        policyID,
+        lastPaymentMethod,
+        markSubmitting,
+    ]);
 
     return (
         <InteractiveStepWrapper
diff --git a/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx b/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx
index ad825930e2f1..34b648cea0dc 100644
--- a/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx
+++ b/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx
@@ -52,7 +52,7 @@ function ConfirmAgreements({onNext}: ConfirmAgreementsProps) {
     const defaultValues = {
         isAuthorizedToUseBankAccount: confirmAgreementsValues.isAuthorizedToUseBankAccount ?? false,
         certifyTrueInformation: confirmAgreementsValues.certifyTrueInformation ?? false,
-        acceptTermsAndConditions: confirmAgreementsValues.acceptTermsAndConditions ?? false,
+        acceptTermsAndConditions: (confirmAgreementsValues.acceptTermsAndConditions || reimbursementAccount?.achData?.acceptTerms) ?? false,
     };
     const validate = useCallback(
         (values: FormOnyxValues<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> => {
diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts
index 2d7e6da3f90b..2d8d909b884d 100644
--- a/src/types/onyx/ReimbursementAccount.ts
+++ b/src/types/onyx/ReimbursementAccount.ts
@@ -175,6 +175,9 @@ type ACHData = Partial<BeneficialOwnersStepProps & CompanyStepProps & RequestorS
     /** Weather Onfido setup is complete */
     isOnfidoSetupComplete?: boolean;
 
+    /** Confirmation that the user accepted the ACH terms. The form input key is `acceptTermsAndConditions`; the achData field uses the shorter `acceptTerms`. */
+    acceptTerms?: boolean;
+
     /** Last 4 digits of the account number */
     mask?: string;
 

From b6d3e94ddbf3dccb3b34051afb727efcc220f06b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Fri, 15 May 2026 12:58:04 +0200
Subject: [PATCH 21/27] fix: reseting freshly connected acc

---
 .../resetUSDBankAccount.ts                    |  8 +++++-
 .../ConnectBankAccount/ConnectBankAccount.tsx | 25 +++++++++++++++++--
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/libs/actions/ReimbursementAccount/resetUSDBankAccount.ts b/src/libs/actions/ReimbursementAccount/resetUSDBankAccount.ts
index ce33a5b144cc..cc4c99c88e69 100644
--- a/src/libs/actions/ReimbursementAccount/resetUSDBankAccount.ts
+++ b/src/libs/actions/ReimbursementAccount/resetUSDBankAccount.ts
@@ -82,7 +82,13 @@ function resetUSDBankAccount(
             {
                 onyxMethod: Onyx.METHOD.SET,
                 key: ONYXKEYS.REIMBURSEMENT_ACCOUNT,
-                value: CONST.REIMBURSEMENT_ACCOUNT.DEFAULT_DATA,
+                value: {
+                    ...CONST.REIMBURSEMENT_ACCOUNT.DEFAULT_DATA,
+                    achData: {
+                        ...CONST.REIMBURSEMENT_ACCOUNT.DEFAULT_DATA.achData,
+                        policyID,
+                    },
+                },
             },
             {
                 onyxMethod: Onyx.METHOD.SET,
diff --git a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx
index 3b67b12cecca..060901a2ad92 100644
--- a/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx
+++ b/src/pages/ReimbursementAccount/USD/ConnectBankAccount/ConnectBankAccount.tsx
@@ -1,8 +1,9 @@
 import {hasSeenTourSelector} from '@selectors/Onboarding';
-import React from 'react';
+import React, {useEffect, useRef} from 'react';
 import {View} from 'react-native';
 import ConfirmationPage from '@components/ConfirmationPage';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import ReimbursementAccountLoadingIndicator from '@components/ReimbursementAccountLoadingIndicator';
 import ScreenWrapper from '@components/ScreenWrapper';
 import Text from '@components/Text';
 import TextLink from '@components/TextLink';
@@ -18,6 +19,7 @@ import {navigateToConciergeChat} from '@userActions/Report';
 import CONST from '@src/CONST';
 import NAVIGATORS from '@src/NAVIGATORS';
 import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
 import type {Route} from '@src/ROUTES';
 import BankAccountValidationForm from './components/BankAccountValidationForm';
 import FinishChatCard from './components/FinishChatCard';
@@ -32,11 +34,14 @@ type ConnectBankAccountProps = {
     /** Method to set the state of shouldShowConnectedVerifiedBankAccount */
     setUSDBankAccountStep?: (step: string | null) => void;
 
+    /** ID of current policy */
+    policyID?: string;
+
     /** Route to return to when navigating back out of the flow */
     backTo?: Route;
 };
 
-function ConnectBankAccount({onBackButtonPress, setShouldShowConnectedVerifiedBankAccount, setUSDBankAccountStep, backTo}: ConnectBankAccountProps) {
+function ConnectBankAccount({onBackButtonPress, setShouldShowConnectedVerifiedBankAccount, setUSDBankAccountStep, policyID, backTo}: ConnectBankAccountProps) {
     const styles = useThemeStyles();
     const {translate} = useLocalize();
     const topmostFullScreenRoute = useRootNavigationState((state) => state?.routes.findLast((lastRoute) => isFullScreenName(lastRoute.name)));
@@ -52,6 +57,22 @@ function ConnectBankAccount({onBackButtonPress, setShouldShowConnectedVerifiedBa
 
     const handleNavigateToConciergeChat = () => navigateToConciergeChat(conciergeReportID, introSelected, currentUserAccountID, isSelfTourViewed, betas, true);
     const bankAccountState = reimbursementAccount?.achData?.state ?? '';
+    const pendingAction = reimbursementAccount?.pendingAction;
+
+    // After a disconnect, wait for the reset API to finish before navigating to the entry point.
+    const prevPendingActionRef = useRef(pendingAction);
+    useEffect(() => {
+        const prev = prevPendingActionRef.current;
+        prevPendingActionRef.current = pendingAction;
+        if (prev === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) {
+            Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute({policyID, backTo}));
+        }
+    }, [pendingAction, policyID, backTo]);
+
+    // While the disconnect is in flight, show the existing flow loader so the success screen doesn't re-render with cleared bank data
+    if (pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) {
+        return <ReimbursementAccountLoadingIndicator onBackButtonPress={onBackButtonPress} />;
+    }
 
     // If a user tries to navigate directly to the validate page we'll show them the EnableStep
     if (bankAccountState === CONST.BANK_ACCOUNT.STATE.OPEN) {

From 7a2356fc739992c2fda2a183c0ab5c71b207d635 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Mon, 18 May 2026 12:04:09 +0200
Subject: [PATCH 22/27] fix: code review improvements

---
 src/CONST/index.ts                            |  3 +
 src/languages/en.ts                           |  2 +-
 src/libs/BankAccountUtils.ts                  | 41 ++++++++++
 .../USD/KYBDocuments/index.tsx                | 29 +++++---
 .../isUserAddressVerificationRequired.ts      | 20 -----
 .../utils/isUserDOBVerificationRequired.ts    | 20 -----
 src/types/onyx/ReimbursementAccount.ts        |  2 +-
 tests/unit/BankAccountUtilsTest.ts            | 74 +++++++++++++++++++
 8 files changed, 138 insertions(+), 53 deletions(-)
 delete mode 100644 src/pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired.ts
 delete mode 100644 src/pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired.ts

diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index 52713e0cc127..221e2fc39d7f 100644
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -741,6 +741,9 @@ const CONST = {
             BUSINESS: 'BUSINESS',
             PERSONAL: 'PERSONAL',
         },
+        KYB_STATUS: {
+            PASS: 'pass',
+        },
         KYB_REQUESTOR_IDENTITY_ERROR: {
             ADDRESS: [
                 'resultcode.address.does.not.match',
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 320e4d5f7f8d..8c572426c2ba 100644
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -4122,7 +4122,7 @@ const translations = {
         userAddressVerificationDescription: dedent(`
             Please upload one of the following files:
             • Voter Registration Card
-            • Drivers License
+            • Driver's License
             • Bank Statement
             • Utility Bill`),
         userDOBVerification: 'Date of birth verification',
diff --git a/src/libs/BankAccountUtils.ts b/src/libs/BankAccountUtils.ts
index bd0ede3b430e..30c4e5d00687 100644
--- a/src/libs/BankAccountUtils.ts
+++ b/src/libs/BankAccountUtils.ts
@@ -98,12 +98,53 @@ function hasPersonalBankAccountMissingInfo(bankAccountList: OnyxEntry<OnyxTypes.
     return Object.values(bankAccountList ?? {}).some((bankAccount) => isPersonalBankAccountMissingInfo(bankAccount?.accountData));
 }
 
+/** Compares error keys and searches for overlap. Based on the result we decide whether to gather extra file
+ * @param status - status of the check
+ * @param qualifiers - errors returned after the check
+ * @returns boolean - whether to gather additional address verification file
+ */
+function isUserAddressVerificationRequired(
+    status: string | undefined,
+    qualifiers:
+        | Array<{
+              key: string;
+              message: string;
+          }>
+        | undefined,
+): boolean {
+    return (
+        status !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS &&
+        !!CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.ADDRESS.find((error) => qualifiers?.map((qualifier) => qualifier.key).includes(error))
+    );
+}
+
+/** Compares error keys and searches for overlap. Based on the result we decide whether to gather extra file
+ * @param status - status of the check
+ * @param qualifiers - errors returned after the check
+ * @returns boolean - whether to gather additional DOB verification file
+ */
+function isUserDOBVerificationRequired(
+    status: string | undefined,
+    qualifiers:
+        | Array<{
+              key: string;
+              message: string;
+          }>
+        | undefined,
+): boolean {
+    return (
+        status !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS && !!CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.DOB.find((error) => qualifiers?.map((qualifier) => qualifier.key).includes(error))
+    );
+}
+
 export {
     getDefaultCompanyWebsite,
     getLastFourDigits,
     hasPartiallySetupBankAccount,
     hasPersonalBankAccountMissingInfo,
     isBankAccountPartiallySetup,
+    isUserAddressVerificationRequired,
+    isUserDOBVerificationRequired,
     doesPolicyHavePartiallySetupBankAccount,
     isPersonalBankAccountMissingInfo,
     getCompletedStepsForBankAccount,
diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index c3c2a6506349..121e86e65d51 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -13,8 +13,7 @@ import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountSubmitCallback from '@hooks/useReimbursementAccountSubmitCallback';
 import useThemeStyles from '@hooks/useThemeStyles';
-import isUserAddressVerificationRequired from '@pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired';
-import isUserDOBVerificationRequired from '@pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired';
+import {isUserAddressVerificationRequired, isUserDOBVerificationRequired} from '@libs/BankAccountUtils';
 import {uploadUserKYBDocs} from '@userActions/BankAccounts';
 import {clearErrorFields, setDraftValues, setErrorFields} from '@userActions/FormActions';
 import {navigateToConciergeChat} from '@userActions/Report';
@@ -41,7 +40,7 @@ function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
     const [betas] = useOnyx(ONYXKEYS.BETAS);
     const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
     const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails();
-    const reimbursementAccountData = reimbursementAccount?.achData?.verifications?.externalApiResponse;
+    const reimbursementAccountVerificationData = reimbursementAccount?.achData?.verifications?.externalApiResponses;
     const bankAccountID = reimbursementAccount?.achData?.bankAccountID ?? CONST.DEFAULT_NUMBER_ID;
     const isLoading = reimbursementAccount?.isLoading;
 
@@ -71,43 +70,52 @@ function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
             inputID: 'companyTaxID',
             title: 'documentsStep.taxIDVerification',
             description: 'documentsStep.taxIDVerificationDescription',
-            required: reimbursementAccountData?.companyTaxID?.status !== undefined && reimbursementAccountData?.companyTaxID?.status !== 'pass',
+            required:
+                reimbursementAccountVerificationData?.companyTaxID?.status !== undefined && reimbursementAccountVerificationData?.companyTaxID?.status !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS,
         },
         {
             inputID: 'nameChangeDocument',
             title: 'documentsStep.nameChangeDocument',
             description: 'documentsStep.nameChangeDocumentDescription',
-            required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== undefined && reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
+            required:
+                reimbursementAccountVerificationData?.lexisNexisInstantIDResult?.status !== undefined &&
+                reimbursementAccountVerificationData?.lexisNexisInstantIDResult?.status !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS,
         },
         {
             inputID: 'companyAddressVerification',
             title: 'documentsStep.companyAddressVerification',
             description: 'documentsStep.companyAddressVerificationDescription',
-            required: reimbursementAccountData?.lexisNexisInstantIDResult?.status !== undefined && reimbursementAccountData?.lexisNexisInstantIDResult?.status !== 'pass',
+            required:
+                reimbursementAccountVerificationData?.lexisNexisInstantIDResult?.status !== undefined &&
+                reimbursementAccountVerificationData?.lexisNexisInstantIDResult?.status !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS,
         },
         {
             inputID: 'userAddressVerification',
             title: 'documentsStep.userAddressVerification',
             description: 'documentsStep.userAddressVerificationDescription',
             required: isUserAddressVerificationRequired(
-                reimbursementAccountData?.requestorIdentityID?.status,
-                reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
+                reimbursementAccountVerificationData?.requestorIdentityID?.status,
+                reimbursementAccountVerificationData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
             ),
         },
         {
             inputID: 'userDOBVerification',
             title: 'documentsStep.userDOBVerification',
             description: 'documentsStep.userDOBVerificationDescription',
-            required: isUserDOBVerificationRequired(reimbursementAccountData?.requestorIdentityID?.status, reimbursementAccountData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier),
+            required: isUserDOBVerificationRequired(
+                reimbursementAccountVerificationData?.requestorIdentityID?.status,
+                reimbursementAccountVerificationData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
+            ),
         },
     ] as const;
+    const requiredDocuments = DOCUMENTS_CONFIG.filter((document) => document.required);
 
     const [uploadedFiles, setUploadedFiles] = useState<Record<string, FileObject[]>>(defaultValues);
 
     const validate = (values: FormOnyxValues<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM>): FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> => {
         const errors: FormInputErrors<typeof ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM> = {};
 
-        for (const document of DOCUMENTS_CONFIG.filter((documentItem) => documentItem.required)) {
+        for (const document of requiredDocuments) {
             const files = values[document.inputID] as FileObject[] | undefined;
             if (!files || files.length === 0) {
                 errors[document.inputID] = translate('common.error.fieldRequired');
@@ -154,7 +162,6 @@ function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
         markSubmitting();
     }, [uploadedFiles, bankAccountID, markSubmitting]);
 
-    const requiredDocuments = DOCUMENTS_CONFIG.filter((document) => document.required);
     const footer = (
         <Button
             large
diff --git a/src/pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired.ts b/src/pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired.ts
deleted file mode 100644
index 2968a5e618f9..000000000000
--- a/src/pages/ReimbursementAccount/USD/utils/isUserAddressVerificationRequired.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import CONST from '@src/CONST';
-
-/** Compares error keys and searches for overlap. Based on the result we decide whether to gather extra file
- * @param status - status of the check
- * @param qualifiers - errors returned after the check
- * @returns boolean - whether to gather additional address verification file
- */
-function isUserAddressVerificationRequired(
-    status: string | undefined,
-    qualifiers:
-        | Array<{
-              key: string;
-              message: string;
-          }>
-        | undefined,
-): boolean {
-    return status !== 'pass' && !!CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.ADDRESS.find((error) => qualifiers?.map((qualifier) => qualifier.key).includes(error));
-}
-
-export default isUserAddressVerificationRequired;
diff --git a/src/pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired.ts b/src/pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired.ts
deleted file mode 100644
index 1b5da4d14934..000000000000
--- a/src/pages/ReimbursementAccount/USD/utils/isUserDOBVerificationRequired.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import CONST from '@src/CONST';
-
-/** Compares error keys and searches for overlap. Based on the result we decide whether to gather extra file
- * @param status - status of the check
- * @param qualifiers - errors returned after the check
- * @returns boolean - whether to gather additional DOB verification file
- */
-function isUserDOBVerificationRequired(
-    status: string | undefined,
-    qualifiers:
-        | Array<{
-              key: string;
-              message: string;
-          }>
-        | undefined,
-): boolean {
-    return status !== 'pass' && !!CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.DOB.find((error) => qualifiers?.map((qualifier) => qualifier.key).includes(error));
-}
-
-export default isUserDOBVerificationRequired;
diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts
index 1cd0ca28b742..3ddcf11ad34f 100644
--- a/src/types/onyx/ReimbursementAccount.ts
+++ b/src/types/onyx/ReimbursementAccount.ts
@@ -227,7 +227,7 @@ type ACHData = Partial<BeneficialOwnersStepProps & CompanyStepProps & RequestorS
     /** Statuses of additional checks hinting at missing documents user still needs to upload */
     verifications?: {
         /** points towards one of external providers */
-        externalApiResponse?: {
+        externalApiResponses?: {
             /** provider name */
             companyTaxID?: {
                 /** status of check */
diff --git a/tests/unit/BankAccountUtilsTest.ts b/tests/unit/BankAccountUtilsTest.ts
index 4b405ce7f21f..a7e8b70c349a 100644
--- a/tests/unit/BankAccountUtilsTest.ts
+++ b/tests/unit/BankAccountUtilsTest.ts
@@ -6,6 +6,8 @@ import {
     hasPersonalBankAccountMissingInfo,
     isBankAccountPartiallySetup,
     isPersonalBankAccountMissingInfo,
+    isUserAddressVerificationRequired,
+    isUserDOBVerificationRequired,
     PERSONAL_INFO_STEP,
 } from '@libs/BankAccountUtils';
 import CONST from '@src/CONST';
@@ -483,4 +485,76 @@ describe('BankAccountUtils', () => {
             expect(getCompletedStepsForBankAccount(bankAccountList, bankAccountID)).toEqual([]);
         });
     });
+
+    describe('isUserAddressVerificationRequired', () => {
+        const qualifier = (key: string) => ({key, message: 'irrelevant'});
+        const PASS = CONST.BANK_ACCOUNT.KYB_STATUS.PASS;
+        const ADDRESS_KEYS = CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.ADDRESS;
+        const DOB_KEYS = CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.DOB;
+        const SOME_ADDRESS_KEY = ADDRESS_KEYS.at(0) ?? '';
+
+        it('returns false when status is PASS, even with a matching address qualifier', () => {
+            expect(isUserAddressVerificationRequired(PASS, [qualifier(SOME_ADDRESS_KEY)])).toBe(false);
+        });
+
+        it.each(ADDRESS_KEYS)('returns true for non-pass status when qualifiers contain address key "%s"', (key) => {
+            expect(isUserAddressVerificationRequired('fail', [qualifier(key)])).toBe(true);
+        });
+
+        it('returns false when status is non-pass but qualifiers only contain an unrelated key', () => {
+            expect(isUserAddressVerificationRequired('fail', [qualifier('resultcode.some.unrelated.code')])).toBe(false);
+        });
+
+        it('returns false when status is non-pass and qualifiers is undefined', () => {
+            expect(isUserAddressVerificationRequired('fail', undefined)).toBe(false);
+        });
+
+        it('returns false when status is non-pass and qualifiers is empty', () => {
+            expect(isUserAddressVerificationRequired('fail', [])).toBe(false);
+        });
+
+        it('returns true when status is undefined and qualifiers contain a matching address key', () => {
+            expect(isUserAddressVerificationRequired(undefined, [qualifier(SOME_ADDRESS_KEY)])).toBe(true);
+        });
+
+        it.each(DOB_KEYS)('returns false when qualifiers contain only DOB key "%s" (cross-category)', (key) => {
+            expect(isUserAddressVerificationRequired('fail', [qualifier(key)])).toBe(false);
+        });
+    });
+
+    describe('isUserDOBVerificationRequired', () => {
+        const qualifier = (key: string) => ({key, message: 'irrelevant'});
+        const PASS = CONST.BANK_ACCOUNT.KYB_STATUS.PASS;
+        const ADDRESS_KEYS = CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.ADDRESS;
+        const DOB_KEYS = CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.DOB;
+        const SOME_DOB_KEY = DOB_KEYS.at(0) ?? '';
+
+        it('returns false when status is PASS, even with a matching DOB qualifier', () => {
+            expect(isUserDOBVerificationRequired(PASS, [qualifier(SOME_DOB_KEY)])).toBe(false);
+        });
+
+        it.each(DOB_KEYS)('returns true for non-pass status when qualifiers contain DOB key "%s"', (key) => {
+            expect(isUserDOBVerificationRequired('fail', [qualifier(key)])).toBe(true);
+        });
+
+        it('returns false when status is non-pass but qualifiers only contain an unrelated key', () => {
+            expect(isUserDOBVerificationRequired('fail', [qualifier('resultcode.some.unrelated.code')])).toBe(false);
+        });
+
+        it('returns false when status is non-pass and qualifiers is undefined', () => {
+            expect(isUserDOBVerificationRequired('fail', undefined)).toBe(false);
+        });
+
+        it('returns false when status is non-pass and qualifiers is empty', () => {
+            expect(isUserDOBVerificationRequired('fail', [])).toBe(false);
+        });
+
+        it('returns true when status is undefined and qualifiers contain a matching DOB key', () => {
+            expect(isUserDOBVerificationRequired(undefined, [qualifier(SOME_DOB_KEY)])).toBe(true);
+        });
+
+        it.each(ADDRESS_KEYS)('returns false when qualifiers contain only address key "%s" (cross-category)', (key) => {
+            expect(isUserDOBVerificationRequired('fail', [qualifier(key)])).toBe(false);
+        });
+    });
 });

From c9687c7d8ee9c631d9cd5f4ff3dd7a0272c6e4ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muzyk?= <mimuzyk@gmail.com>
Date: Fri, 29 May 2026 09:29:33 +0200
Subject: [PATCH 23/27] fix: after rebase

---
 cspell.json        |  3 ++-
 src/CONST/index.ts | 11 -----------
 src/ROUTES.ts      | 12 ------------
 3 files changed, 2 insertions(+), 24 deletions(-)

diff --git a/cspell.json b/cspell.json
index 3cea543f3069..c1adee69df8c 100644
--- a/cspell.json
+++ b/cspell.json
@@ -1026,7 +1026,8 @@
         "src/libs/SearchParser/*",
         "modules/group-ib-fp",
         "web/snippets/gib.js",
-        "tests/unit/hooks/useLetterAvatars.test.tsx"
+        "tests/unit/hooks/useLetterAvatars.test.tsx",
+        "tests/unit/BankAccountUtilsTest.ts"
     ],
     "ignoreRegExpList": ["@assets/.*"],
     "useGitignore": true
diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index 0a67a13db844..a680be150046 100644
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -680,17 +680,6 @@ const CONST = {
             ENABLE: 'enable',
             KYB_DOCS: 'upload-kyb-documents',
         },
-        PAGE_NAMES: {
-            COUNTRY: 'currency-and-country',
-            BANK_ACCOUNT: 'bank-info',
-            REQUESTOR: 'personal-info',
-            VERIFY_IDENTITY: 'verify-identity',
-            COMPANY: 'company',
-            BENEFICIAL_OWNERS: 'business-owner',
-            ACH_CONTRACT: 'ach-contract',
-            VALIDATION: 'validation',
-            ENABLE: 'enable',
-        },
         STEP_NAMES: ['1', '2', '3', '4', '5', '6'],
         BANK_INFO_STEP: {
             SUB_PAGE_NAMES: {
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 97567ec231b8..cf6f8f95f7a5 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -980,18 +980,6 @@ const ROUTES = {
             return getUrlWithBackToParam(`${base}${pagePart}${subPagePart}${actionPart}${queryString}`, backTo);
         },
     },
-    BANK_ACCOUNT_USD_SETUP: {
-        route: 'bank-account/new/us/:page?/:subPage?/:action?',
-        getRoute: ({policyID, page, subPage, action, backTo}: {policyID?: string; page?: string; subPage?: string; action?: 'edit'; backTo?: string}) => {
-            const base = 'bank-account/new/us';
-            const pagePart = page ? `/${page}` : '';
-            const subPagePart = subPage ? `/${subPage}` : '';
-            const actionPart = action ? `/${action}` : '';
-            const queryString = policyID ? `?policyID=${policyID}` : '';
-            // eslint-disable-next-line no-restricted-syntax -- Legacy route generation
-            return getUrlWithBackToParam(`${base}${pagePart}${subPagePart}${actionPart}${queryString}`, backTo);
-        },
-    },
     SETTINGS: 'settings',
     SETTINGS_PROFILE: {
         route: 'settings/profile',

From 5bf282626edc5f757ea09e014aa44d168c1469ff Mon Sep 17 00:00:00 2001
From: VickyStash <vikstash@gmail.com>
Date: Mon, 1 Jun 2026 16:46:27 +0200
Subject: [PATCH 24/27] Update descriptions

---
 src/languages/en.ts | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/languages/en.ts b/src/languages/en.ts
index e766baa4eaa7..afb4a4f07dd2 100644
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -4183,7 +4183,7 @@ const translations = {
     documentsStep: {
         beforeYouGo: 'Before you go, we need some documents to verify some things',
         subheader: 'Verification',
-        verificationFailed: "The verification failed, so we'll need some extra documents to verify you and your business",
+        verificationFailed: "The verification failed, so we'll need some extra documents to verify you and your business.",
         taxIDVerification: 'Tax ID Verification',
         taxIDVerificationDescription: dedent(`
             Please upload one of the following files:
@@ -4199,7 +4199,8 @@ const translations = {
             • Bank Statement showing company name and address
             • Current Lease/Rental Agreement including the signature page showing your company name and current address
             • Insurance Statement showing company name and address
-            • TIN assignment doc showing company name and address`),
+            • TIN assignment doc showing company name and address
+            • Business tax return (most current) showing company name and address`),
         userAddressVerification: 'Address verification',
         userAddressVerificationDescription: dedent(`
             Please upload one of the following files:

From 46bfc03f2ae8766614fdc9b9b02da93502e1e480 Mon Sep 17 00:00:00 2001
From: VickyStash <vikstash@gmail.com>
Date: Mon, 1 Jun 2026 17:10:58 +0200
Subject: [PATCH 25/27] Skip KYB documents step when no documents are required

---
 src/libs/BankAccountUtils.ts                  | 36 +++++++++++++++++++
 .../USD/KYBDocuments/index.tsx                | 21 ++---------
 .../USD/USDVerifiedBankAccountFlowPage.tsx    | 15 ++++++--
 3 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/src/libs/BankAccountUtils.ts b/src/libs/BankAccountUtils.ts
index 30c4e5d00687..f9f6274d7e06 100644
--- a/src/libs/BankAccountUtils.ts
+++ b/src/libs/BankAccountUtils.ts
@@ -3,6 +3,10 @@ import type {OnyxEntry} from 'react-native-onyx';
 import CONST from '@src/CONST';
 import type * as OnyxTypes from '@src/types/onyx';
 import type AccountData from '@src/types/onyx/AccountData';
+import type {ACHData} from '@src/types/onyx/ReimbursementAccount';
+
+/** Responses of the additional KYB verification checks, hinting at which documents the user still needs to upload */
+type KYBVerificationResponses = NonNullable<ACHData['verifications']>['externalApiResponses'];
 
 function getDefaultCompanyWebsite(session: OnyxEntry<OnyxTypes.Session>, account: OnyxEntry<OnyxTypes.Account>, shouldShowPublicDomain = false): string {
     return account?.isFromPublicDomain && !shouldShowPublicDomain ? '' : `https://www.${Str.extractEmailDomain(session?.email ?? '')}`;
@@ -137,8 +141,40 @@ function isUserDOBVerificationRequired(
     );
 }
 
+/** Builds the list of KYB document inputIDs the user must upload, based on which verification checks did not pass.
+ * Returns an empty array when no documents are required (e.g. automated verification passed), in which case the
+ * KYB documents step should be skipped entirely.
+ * @param externalApiResponses - statuses of the external verification checks from the reimbursement account
+ * @returns inputIDs of the documents that still need to be uploaded
+ */
+function getRequiredKYBDocuments(externalApiResponses: KYBVerificationResponses): string[] {
+    const requiredDocuments: string[] = [];
+
+    const companyTaxIDStatus = externalApiResponses?.companyTaxID?.status;
+    if (companyTaxIDStatus !== undefined && companyTaxIDStatus !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS) {
+        requiredDocuments.push('companyTaxID');
+    }
+
+    const lexisNexisStatus = externalApiResponses?.lexisNexisInstantIDResult?.status;
+    if (lexisNexisStatus !== undefined && lexisNexisStatus !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS) {
+        requiredDocuments.push('nameChangeDocument', 'companyAddressVerification');
+    }
+
+    const requestorIdentityStatus = externalApiResponses?.requestorIdentityID?.status;
+    const requestorIdentityQualifiers = externalApiResponses?.requestorIdentityID?.apiResult?.qualifiers?.qualifier;
+    if (isUserAddressVerificationRequired(requestorIdentityStatus, requestorIdentityQualifiers)) {
+        requiredDocuments.push('userAddressVerification');
+    }
+    if (isUserDOBVerificationRequired(requestorIdentityStatus, requestorIdentityQualifiers)) {
+        requiredDocuments.push('userDOBVerification');
+    }
+
+    return requiredDocuments;
+}
+
 export {
     getDefaultCompanyWebsite,
+    getRequiredKYBDocuments,
     getLastFourDigits,
     hasPartiallySetupBankAccount,
     hasPersonalBankAccountMissingInfo,
diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index 121e86e65d51..275803327fb4 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -13,7 +13,7 @@ import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useReimbursementAccountSubmitCallback from '@hooks/useReimbursementAccountSubmitCallback';
 import useThemeStyles from '@hooks/useThemeStyles';
-import {isUserAddressVerificationRequired, isUserDOBVerificationRequired} from '@libs/BankAccountUtils';
+import {getRequiredKYBDocuments} from '@libs/BankAccountUtils';
 import {uploadUserKYBDocs} from '@userActions/BankAccounts';
 import {clearErrorFields, setDraftValues, setErrorFields} from '@userActions/FormActions';
 import {navigateToConciergeChat} from '@userActions/Report';
@@ -70,45 +70,30 @@ function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
             inputID: 'companyTaxID',
             title: 'documentsStep.taxIDVerification',
             description: 'documentsStep.taxIDVerificationDescription',
-            required:
-                reimbursementAccountVerificationData?.companyTaxID?.status !== undefined && reimbursementAccountVerificationData?.companyTaxID?.status !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS,
         },
         {
             inputID: 'nameChangeDocument',
             title: 'documentsStep.nameChangeDocument',
             description: 'documentsStep.nameChangeDocumentDescription',
-            required:
-                reimbursementAccountVerificationData?.lexisNexisInstantIDResult?.status !== undefined &&
-                reimbursementAccountVerificationData?.lexisNexisInstantIDResult?.status !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS,
         },
         {
             inputID: 'companyAddressVerification',
             title: 'documentsStep.companyAddressVerification',
             description: 'documentsStep.companyAddressVerificationDescription',
-            required:
-                reimbursementAccountVerificationData?.lexisNexisInstantIDResult?.status !== undefined &&
-                reimbursementAccountVerificationData?.lexisNexisInstantIDResult?.status !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS,
         },
         {
             inputID: 'userAddressVerification',
             title: 'documentsStep.userAddressVerification',
             description: 'documentsStep.userAddressVerificationDescription',
-            required: isUserAddressVerificationRequired(
-                reimbursementAccountVerificationData?.requestorIdentityID?.status,
-                reimbursementAccountVerificationData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
-            ),
         },
         {
             inputID: 'userDOBVerification',
             title: 'documentsStep.userDOBVerification',
             description: 'documentsStep.userDOBVerificationDescription',
-            required: isUserDOBVerificationRequired(
-                reimbursementAccountVerificationData?.requestorIdentityID?.status,
-                reimbursementAccountVerificationData?.requestorIdentityID?.apiResult?.qualifiers?.qualifier,
-            ),
         },
     ] as const;
-    const requiredDocuments = DOCUMENTS_CONFIG.filter((document) => document.required);
+    const requiredDocumentInputIDs = getRequiredKYBDocuments(reimbursementAccountVerificationData);
+    const requiredDocuments = DOCUMENTS_CONFIG.filter((document) => requiredDocumentInputIDs.includes(document.inputID));
 
     const [uploadedFiles, setUploadedFiles] = useState<Record<string, FileObject[]>>(defaultValues);
 
diff --git a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx
index c7d140c8afc8..f3932e59a5ae 100644
--- a/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx
+++ b/src/pages/ReimbursementAccount/USD/USDVerifiedBankAccountFlowPage.tsx
@@ -2,6 +2,7 @@ import React, {useCallback, useMemo, useRef} from 'react';
 import {View} from 'react-native';
 import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
+import {getRequiredKYBDocuments} from '@libs/BankAccountUtils';
 import Navigation from '@libs/Navigation/Navigation';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
 import type {ReimbursementAccountNavigatorParamList} from '@libs/Navigation/types';
@@ -79,6 +80,7 @@ function USDVerifiedBankAccountFlowPage({route}: USDVerifiedBankAccountFlowPageP
 
     const requestorStepRef = useRef<View>(null);
     const isOnfidoSetupComplete = reimbursementAccount?.achData?.isOnfidoSetupComplete;
+    const isKYBDocumentsRequired = getRequiredKYBDocuments(reimbursementAccount?.achData?.verifications?.externalApiResponses).length > 0;
 
     const currentPageIndex = useMemo(() => {
         const index = pages.findIndex((p) => p.pageName === currentPage);
@@ -91,31 +93,40 @@ function USDVerifiedBankAccountFlowPage({route}: USDVerifiedBankAccountFlowPageP
 
     const shouldSkipVerifyIdentity = useCallback((pageName?: string) => pageName === PAGE_NAMES.VERIFY_IDENTITY && isOnfidoSetupComplete, [isOnfidoSetupComplete]);
 
+    // Skip the KYB documents page unless the backend's verification checks flagged documents that still need to be uploaded.
+    const shouldSkipKYBDocs = useCallback((pageName?: string) => pageName === PAGE_NAMES.KYB_DOCS && !isKYBDocumentsRequired, [isKYBDocumentsRequired]);
+
     const onSubmit = useCallback(() => {
         let nextIndex = currentPageIndex + 1;
         if (shouldSkipVerifyIdentity(pages.at(nextIndex)?.pageName)) {
             nextIndex += 1;
         }
+        if (shouldSkipKYBDocs(pages.at(nextIndex)?.pageName)) {
+            nextIndex += 1;
+        }
         if (nextIndex >= pages.length) {
             Navigation.goBack();
             return;
         }
         const nextPage = pages.at(nextIndex);
         Navigation.navigate(ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: nextPage?.pageName, subPage: nextPage?.firstSubPage, backTo}));
-    }, [backTo, currentPageIndex, policyID, shouldSkipVerifyIdentity]);
+    }, [backTo, currentPageIndex, policyID, shouldSkipVerifyIdentity, shouldSkipKYBDocs]);
 
     const onBackButtonPress = useCallback(() => {
         let prevIndex = currentPageIndex - 1;
         if (shouldSkipVerifyIdentity(pages.at(prevIndex)?.pageName)) {
             prevIndex -= 1;
         }
+        if (shouldSkipKYBDocs(pages.at(prevIndex)?.pageName)) {
+            prevIndex -= 1;
+        }
         if (prevIndex < 0) {
             Navigation.goBack();
             return;
         }
         const prevPage = pages.at(prevIndex);
         Navigation.goBack(ROUTES.BANK_ACCOUNT_USD_SETUP.getRoute({policyID, page: prevPage?.pageName, subPage: prevPage?.lastSubPage, backTo}));
-    }, [backTo, currentPageIndex, policyID, shouldSkipVerifyIdentity]);
+    }, [backTo, currentPageIndex, policyID, shouldSkipVerifyIdentity, shouldSkipKYBDocs]);
 
     return (
         <View style={[styles.flex1, styles.appBG]}>

From f9e4c2db2472cacb9edecc6978c7cf2fe821a966 Mon Sep 17 00:00:00 2001
From: VickyStash <vikstash@gmail.com>
Date: Mon, 1 Jun 2026 17:27:19 +0200
Subject: [PATCH 26/27] Fix KYB tax ID upload crash from draft key collision

---
 src/libs/BankAccountUtils.ts                  |  9 +++--
 .../USD/KYBDocuments/index.tsx                | 39 +++++++++++++------
 2 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/src/libs/BankAccountUtils.ts b/src/libs/BankAccountUtils.ts
index f9f6274d7e06..a99b74a7e23e 100644
--- a/src/libs/BankAccountUtils.ts
+++ b/src/libs/BankAccountUtils.ts
@@ -1,6 +1,7 @@
 import {Str} from 'expensify-common';
 import type {OnyxEntry} from 'react-native-onyx';
 import CONST from '@src/CONST';
+import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 import type * as OnyxTypes from '@src/types/onyx';
 import type AccountData from '@src/types/onyx/AccountData';
 import type {ACHData} from '@src/types/onyx/ReimbursementAccount';
@@ -152,21 +153,21 @@ function getRequiredKYBDocuments(externalApiResponses: KYBVerificationResponses)
 
     const companyTaxIDStatus = externalApiResponses?.companyTaxID?.status;
     if (companyTaxIDStatus !== undefined && companyTaxIDStatus !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS) {
-        requiredDocuments.push('companyTaxID');
+        requiredDocuments.push(INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID);
     }
 
     const lexisNexisStatus = externalApiResponses?.lexisNexisInstantIDResult?.status;
     if (lexisNexisStatus !== undefined && lexisNexisStatus !== CONST.BANK_ACCOUNT.KYB_STATUS.PASS) {
-        requiredDocuments.push('nameChangeDocument', 'companyAddressVerification');
+        requiredDocuments.push(INPUT_IDS.KYB_DOCUMENTS.NAME_CHANGE_DOCUMENT, INPUT_IDS.KYB_DOCUMENTS.COMPANY_ADDRESS_VERIFICATION);
     }
 
     const requestorIdentityStatus = externalApiResponses?.requestorIdentityID?.status;
     const requestorIdentityQualifiers = externalApiResponses?.requestorIdentityID?.apiResult?.qualifiers?.qualifier;
     if (isUserAddressVerificationRequired(requestorIdentityStatus, requestorIdentityQualifiers)) {
-        requiredDocuments.push('userAddressVerification');
+        requiredDocuments.push(INPUT_IDS.KYB_DOCUMENTS.USER_ADDRESS_VERIFICATION);
     }
     if (isUserDOBVerificationRequired(requestorIdentityStatus, requestorIdentityQualifiers)) {
-        requiredDocuments.push('userDOBVerification');
+        requiredDocuments.push(INPUT_IDS.KYB_DOCUMENTS.USER_DOB_VERIFICATION);
     }
 
     return requiredDocuments;
diff --git a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
index 275803327fb4..9e243ba8c4b4 100644
--- a/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
+++ b/src/pages/ReimbursementAccount/USD/KYBDocuments/index.tsx
@@ -19,6 +19,7 @@ import {clearErrorFields, setDraftValues, setErrorFields} from '@userActions/For
 import {navigateToConciergeChat} from '@userActions/Report';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
+import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 import type {FileObject} from '@src/types/utils/Attachment';
 
 type KYBDocumentsProps = {
@@ -29,6 +30,19 @@ type KYBDocumentsProps = {
     onSubmit?: () => void;
 };
 
+/**
+ * Maps the KYB document form input IDs to the param names expected by the UploadUserKYBDocs command.
+ * The tax ID document uses a form key (`companyTaxId`) distinct from the API param (`companyTaxID`) so it
+ * does not collide with the business-info step's string EIN/SSN draft field.
+ */
+const KYB_DOCUMENT_API_PARAM: Record<string, string> = {
+    [INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID]: 'companyTaxID',
+    [INPUT_IDS.KYB_DOCUMENTS.NAME_CHANGE_DOCUMENT]: 'nameChangeDocument',
+    [INPUT_IDS.KYB_DOCUMENTS.COMPANY_ADDRESS_VERIFICATION]: 'companyAddressVerification',
+    [INPUT_IDS.KYB_DOCUMENTS.USER_ADDRESS_VERIFICATION]: 'userAddressVerification',
+    [INPUT_IDS.KYB_DOCUMENTS.USER_DOB_VERIFICATION]: 'userDOBVerification',
+};
+
 function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
     const {translate} = useLocalize();
     const styles = useThemeStyles();
@@ -58,36 +72,36 @@ function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
         );
 
     const defaultValues = {
-        companyTaxID: reimbursementAccountDraft?.companyTaxID ?? [],
-        nameChangeDocument: reimbursementAccountDraft?.nameChangeDocument ?? [],
-        companyAddressVerification: reimbursementAccountDraft?.companyAddressVerification ?? [],
-        userAddressVerification: reimbursementAccountDraft?.userAddressVerification ?? [],
-        userDOBVerification: reimbursementAccountDraft?.userDOBVerification ?? [],
+        [INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID]: reimbursementAccountDraft?.[INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID] ?? [],
+        [INPUT_IDS.KYB_DOCUMENTS.NAME_CHANGE_DOCUMENT]: reimbursementAccountDraft?.[INPUT_IDS.KYB_DOCUMENTS.NAME_CHANGE_DOCUMENT] ?? [],
+        [INPUT_IDS.KYB_DOCUMENTS.COMPANY_ADDRESS_VERIFICATION]: reimbursementAccountDraft?.[INPUT_IDS.KYB_DOCUMENTS.COMPANY_ADDRESS_VERIFICATION] ?? [],
+        [INPUT_IDS.KYB_DOCUMENTS.USER_ADDRESS_VERIFICATION]: reimbursementAccountDraft?.[INPUT_IDS.KYB_DOCUMENTS.USER_ADDRESS_VERIFICATION] ?? [],
+        [INPUT_IDS.KYB_DOCUMENTS.USER_DOB_VERIFICATION]: reimbursementAccountDraft?.[INPUT_IDS.KYB_DOCUMENTS.USER_DOB_VERIFICATION] ?? [],
     } as Record<string, FileObject[]>;
 
     const DOCUMENTS_CONFIG = [
         {
-            inputID: 'companyTaxID',
+            inputID: INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID,
             title: 'documentsStep.taxIDVerification',
             description: 'documentsStep.taxIDVerificationDescription',
         },
         {
-            inputID: 'nameChangeDocument',
+            inputID: INPUT_IDS.KYB_DOCUMENTS.NAME_CHANGE_DOCUMENT,
             title: 'documentsStep.nameChangeDocument',
             description: 'documentsStep.nameChangeDocumentDescription',
         },
         {
-            inputID: 'companyAddressVerification',
+            inputID: INPUT_IDS.KYB_DOCUMENTS.COMPANY_ADDRESS_VERIFICATION,
             title: 'documentsStep.companyAddressVerification',
             description: 'documentsStep.companyAddressVerificationDescription',
         },
         {
-            inputID: 'userAddressVerification',
+            inputID: INPUT_IDS.KYB_DOCUMENTS.USER_ADDRESS_VERIFICATION,
             title: 'documentsStep.userAddressVerification',
             description: 'documentsStep.userAddressVerificationDescription',
         },
         {
-            inputID: 'userDOBVerification',
+            inputID: INPUT_IDS.KYB_DOCUMENTS.USER_DOB_VERIFICATION,
             title: 'documentsStep.userDOBVerification',
             description: 'documentsStep.userDOBVerificationDescription',
         },
@@ -136,8 +150,9 @@ function KYBDocuments({onBackButtonPress, onSubmit}: KYBDocumentsProps) {
         const params: Record<string, FileObject> = {};
         for (const [key, files] of Object.entries(uploadedFiles)) {
             const file = files.at(0);
-            if (file) {
-                params[key] = file;
+            const apiParamKey = KYB_DOCUMENT_API_PARAM[key];
+            if (file && apiParamKey) {
+                params[apiParamKey] = file;
             }
         }
         uploadUserKYBDocs({

From d338a683ffec8dd8480b44dae33433edddecc955 Mon Sep 17 00:00:00 2001
From: VickyStash <vikstash@gmail.com>
Date: Fri, 5 Jun 2026 10:20:48 +0200
Subject: [PATCH 27/27] Add getRequiredKYBDocuments tests

---
 src/libs/BankAccountUtils.ts       |  1 +
 tests/unit/BankAccountUtilsTest.ts | 88 ++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+)

diff --git a/src/libs/BankAccountUtils.ts b/src/libs/BankAccountUtils.ts
index a99b74a7e23e..15c284aca46d 100644
--- a/src/libs/BankAccountUtils.ts
+++ b/src/libs/BankAccountUtils.ts
@@ -187,3 +187,4 @@ export {
     getCompletedStepsForBankAccount,
     PERSONAL_INFO_STEP,
 };
+export type {KYBVerificationResponses};
diff --git a/tests/unit/BankAccountUtilsTest.ts b/tests/unit/BankAccountUtilsTest.ts
index a7e8b70c349a..b50e6513797a 100644
--- a/tests/unit/BankAccountUtilsTest.ts
+++ b/tests/unit/BankAccountUtilsTest.ts
@@ -2,6 +2,7 @@ import {
     getCompletedStepsForBankAccount,
     getDefaultCompanyWebsite,
     getLastFourDigits,
+    getRequiredKYBDocuments,
     hasPartiallySetupBankAccount,
     hasPersonalBankAccountMissingInfo,
     isBankAccountPartiallySetup,
@@ -10,7 +11,9 @@ import {
     isUserDOBVerificationRequired,
     PERSONAL_INFO_STEP,
 } from '@libs/BankAccountUtils';
+import type {KYBVerificationResponses} from '@libs/BankAccountUtils';
 import CONST from '@src/CONST';
+import INPUT_IDS from '@src/types/form/ReimbursementAccountForm';
 import type {Account, BankAccountList, Session} from '@src/types/onyx';
 import type AccountData from '@src/types/onyx/AccountData';
 
@@ -557,4 +560,89 @@ describe('BankAccountUtils', () => {
             expect(isUserDOBVerificationRequired('fail', [qualifier(key)])).toBe(false);
         });
     });
+
+    describe('getRequiredKYBDocuments', () => {
+        const PASS = CONST.BANK_ACCOUNT.KYB_STATUS.PASS;
+        const ADDRESS_KEY = CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.ADDRESS.at(0);
+        const DOB_KEY = CONST.BANK_ACCOUNT.KYB_REQUESTOR_IDENTITY_ERROR.DOB.at(0);
+
+        const requestorIdentity = (status: string, ...keys: Array<string | undefined>): NonNullable<KYBVerificationResponses>['requestorIdentityID'] => ({
+            status,
+            apiResult: {
+                qualifiers: {
+                    qualifier: keys.filter((key): key is string => key !== undefined).map((key) => ({key, message: 'irrelevant'})),
+                },
+            },
+        });
+
+        it('returns an empty array when externalApiResponses is undefined', () => {
+            expect(getRequiredKYBDocuments(undefined)).toEqual([]);
+        });
+
+        it('returns an empty array when externalApiResponses is empty', () => {
+            expect(getRequiredKYBDocuments({})).toEqual([]);
+        });
+
+        it('returns an empty array when every check passes', () => {
+            const externalApiResponses: KYBVerificationResponses = {
+                companyTaxID: {status: PASS},
+                lexisNexisInstantIDResult: {status: PASS},
+                requestorIdentityID: requestorIdentity(PASS, ADDRESS_KEY, DOB_KEY),
+            };
+            expect(getRequiredKYBDocuments(externalApiResponses)).toEqual([]);
+        });
+
+        it('requires the company tax ID document when the companyTaxID check does not pass', () => {
+            expect(getRequiredKYBDocuments({companyTaxID: {status: 'fail'}})).toEqual([INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID]);
+        });
+
+        it('does not require the company tax ID document when the companyTaxID check passes', () => {
+            expect(getRequiredKYBDocuments({companyTaxID: {status: PASS}})).toEqual([]);
+        });
+
+        it('requires the name change and company address documents when the lexisNexis check does not pass', () => {
+            expect(getRequiredKYBDocuments({lexisNexisInstantIDResult: {status: 'fail'}})).toEqual([
+                INPUT_IDS.KYB_DOCUMENTS.NAME_CHANGE_DOCUMENT,
+                INPUT_IDS.KYB_DOCUMENTS.COMPANY_ADDRESS_VERIFICATION,
+            ]);
+        });
+
+        it('does not require the lexisNexis documents when the check passes', () => {
+            expect(getRequiredKYBDocuments({lexisNexisInstantIDResult: {status: PASS}})).toEqual([]);
+        });
+
+        it('requires the user address verification document when a non-passing identity check flags an address error', () => {
+            expect(getRequiredKYBDocuments({requestorIdentityID: requestorIdentity('fail', ADDRESS_KEY)})).toEqual([INPUT_IDS.KYB_DOCUMENTS.USER_ADDRESS_VERIFICATION]);
+        });
+
+        it('requires the user DOB verification document when a non-passing identity check flags a DOB error', () => {
+            expect(getRequiredKYBDocuments({requestorIdentityID: requestorIdentity('fail', DOB_KEY)})).toEqual([INPUT_IDS.KYB_DOCUMENTS.USER_DOB_VERIFICATION]);
+        });
+
+        it('requires both user verification documents when the identity check flags address and DOB errors', () => {
+            expect(getRequiredKYBDocuments({requestorIdentityID: requestorIdentity('fail', ADDRESS_KEY, DOB_KEY)})).toEqual([
+                INPUT_IDS.KYB_DOCUMENTS.USER_ADDRESS_VERIFICATION,
+                INPUT_IDS.KYB_DOCUMENTS.USER_DOB_VERIFICATION,
+            ]);
+        });
+
+        it('does not require user verification documents when a non-passing identity check has only unrelated qualifiers', () => {
+            expect(getRequiredKYBDocuments({requestorIdentityID: requestorIdentity('fail', 'resultcode.some.unrelated.code')})).toEqual([]);
+        });
+
+        it('aggregates the documents from all failing checks in a stable order', () => {
+            const externalApiResponses: KYBVerificationResponses = {
+                companyTaxID: {status: 'fail'},
+                lexisNexisInstantIDResult: {status: 'fail'},
+                requestorIdentityID: requestorIdentity('fail', ADDRESS_KEY, DOB_KEY),
+            };
+            expect(getRequiredKYBDocuments(externalApiResponses)).toEqual([
+                INPUT_IDS.KYB_DOCUMENTS.COMPANY_TAX_ID,
+                INPUT_IDS.KYB_DOCUMENTS.NAME_CHANGE_DOCUMENT,
+                INPUT_IDS.KYB_DOCUMENTS.COMPANY_ADDRESS_VERIFICATION,
+                INPUT_IDS.KYB_DOCUMENTS.USER_ADDRESS_VERIFICATION,
+                INPUT_IDS.KYB_DOCUMENTS.USER_DOB_VERIFICATION,
+            ]);
+        });
+    });
 });
