diff --git a/src/libs/API/parameters/ImportPlaidAccountsParams.ts b/src/libs/API/parameters/ImportPlaidAccountsParams.ts index 12a1c231bca1..17c722d5e5ab 100644 --- a/src/libs/API/parameters/ImportPlaidAccountsParams.ts +++ b/src/libs/API/parameters/ImportPlaidAccountsParams.ts @@ -6,6 +6,7 @@ type ImportPlaidAccountsParams = { domainName: string; plaidAccounts: string; plaidAccessToken?: string; + domainAccountID?: string; }; export default ImportPlaidAccountsParams; diff --git a/src/libs/actions/Plaid.ts b/src/libs/actions/Plaid.ts index d432f47e9362..71a8cc08623d 100644 --- a/src/libs/actions/Plaid.ts +++ b/src/libs/actions/Plaid.ts @@ -150,6 +150,7 @@ function importPlaidAccounts( domainName: string, plaidAccounts: string, plaidAccessToken: string | undefined, + domainAccountID?: number, ) { const parameters: ImportPlaidAccountsParams = { publicToken, @@ -159,6 +160,10 @@ function importPlaidAccounts( domainName, plaidAccounts, plaidAccessToken, + // When repairing a feed that originated from a Classic domain-level connection surfaced into a workspace, + // forward the originating domain's account ID so the server refreshes credentials on the feed the broken + // cards actually belong to instead of the synthetic workspace-policy domain. + ...(domainAccountID ? {domainAccountID: String(domainAccountID)} : {}), }; const onyxData = { diff --git a/src/pages/workspace/companyCards/BankConnection/index.native.tsx b/src/pages/workspace/companyCards/BankConnection/index.native.tsx index 2ffa45766fea..22fc2ccfbb21 100644 --- a/src/pages/workspace/companyCards/BankConnection/index.native.tsx +++ b/src/pages/workspace/companyCards/BankConnection/index.native.tsx @@ -120,17 +120,26 @@ function BankConnection({policyID, feed, title}: BankConnectionProps) { } // Handle assign card flow - if (feed && !isFeedExpired) { - if (isFeedConnectionBroken) { - updateBrokenConnection(); - Navigation.goBack(ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(policyID)); + if (feed) { + if (!isFeedExpired) { + if (isFeedConnectionBroken) { + updateBrokenConnection(); + Navigation.goBack(ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(policyID)); + return; + } + setAssignCardStepAndData({ + currentStep: assignCard?.cardToAssign?.dateOption ? CONST.COMPANY_CARD.STEP.CONFIRMATION : CONST.COMPANY_CARD.STEP.ASSIGNEE, + isEditing: false, + }); + return; + } + // Repairing an existing Plaid feed: PlaidConnectionStep already fired importPlaidAccounts with the + // prefixed feed + domainAccountID. Don't queue a second import from the bare institutionId here (it would + // miss the `plaid.` prefix and take the server's create-new-feed branch, duplicating the feed). This + // mirrors the web effect, which returns for a still-expired Plaid feed. + if (isPlaid) { return; } - setAssignCardStepAndData({ - currentStep: assignCard?.cardToAssign?.dateOption ? CONST.COMPANY_CARD.STEP.CONFIRMATION : CONST.COMPANY_CARD.STEP.ASSIGNEE, - isEditing: false, - }); - return; } // Handle add new card flow diff --git a/src/pages/workspace/companyCards/addNew/PlaidConnectionStep.tsx b/src/pages/workspace/companyCards/addNew/PlaidConnectionStep.tsx index 316f9f49532d..d80d849b443b 100644 --- a/src/pages/workspace/companyCards/addNew/PlaidConnectionStep.tsx +++ b/src/pages/workspace/companyCards/addNew/PlaidConnectionStep.tsx @@ -11,6 +11,7 @@ import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; import {setAddNewCompanyCardStepAndData, setAssignCardStepAndData} from '@libs/actions/CompanyCards'; +import {splitCardFeedWithDomainID} from '@libs/CardUtils'; import getPlaidOAuthReceivedRedirectURI from '@libs/getPlaidOAuthReceivedRedirectURI'; import KeyboardShortcut from '@libs/KeyboardShortcut'; import Log from '@libs/Log'; @@ -141,14 +142,18 @@ function PlaidConnectionStep({feed, policyID, onExit, title}: PlaidConnectionSte if (feed) { if (plaidConnectedFeed && addNewCard?.data?.selectedCountry && plaidConnectedFeedName) { + // Repairing an existing feed: send the existing `feed` (which keeps its `plaid.` prefix and + // originating `#domainID`) rather than the freshly-derived bare institution ID, so the server + // takes its repair branch and refreshes the existing feed instead of minting a duplicate. importPlaidAccounts( publicToken, - plaidConnectedFeed, + feed, plaidConnectedFeedName, addNewCard.data.selectedCountry, getDomainNameForPolicy(policyID), JSON.stringify(metadata?.accounts), '', + splitCardFeedWithDomainID(feed)?.domainID, ); } setAssignCardStepAndData({