All files / src/hooks/merchant-api/BankAccounts usePlaidService.ts

42.85% Statements 15/35
10% Branches 1/10
12.5% Functions 1/8
45.45% Lines 15/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                                              15x 15x               15x           15x           15x 15x 15x   15x   15x   15x       15x                                     15x       15x   15x                                     15x                              
import {
  useAccessPlaidLinkToken,
  useCreateBankAccountWithPlaid,
  useGenerateNewPlaidToken,
  useRequestPlaidToken,
} from "@services/api/products/manage-money";
import { useRef } from "react";
import { PlaidHandler } from "react-plaid-link";
import {
  composePermission,
  useAccessControl,
} from "features/Permissions/AccessControl";
import RESOURCE_BASE, { OPERATIONS } from "@constants/permissions";
import { checkPortals } from "utils/routing";
import { showMessage } from "@common/Toast";
 
/*
  1. get link token
  2.the iframe Plaid starts
  3. Onsuccess public token plus account it to post bank-accounts
  4. Onfail, if token is expired, regenerate it and launch iframe again with new token
*/
export function usePlaidService() {
  const { isEnterprisePortal } = checkPortals();
  const canCreateBA = useAccessControl({
    resource: composePermission(
      isEnterprisePortal ? RESOURCE_BASE.ENTERPRISE : RESOURCE_BASE.MERCHANT,
      RESOURCE_BASE.BANK_ACCOUNT,
    ),
    operation: OPERATIONS.CREATE,
  });
 
  const isEnabledPlaid = useAccessControl({
    resource: RESOURCE_BASE.PLAID,
    operation: OPERATIONS.READ,
    withPortal: true,
  });
 
  const isEnableLinkPlaid = useAccessControl({
    resource: RESOURCE_BASE.PLAID,
    operation: OPERATIONS.LINK,
    withPortal: true,
  });
 
  const isRequestPlaidTokenEnabled = false;
  const { refetch } = useRequestPlaidToken(isRequestPlaidTokenEnabled);
  const { mutateAsync: generateNewToken } = useGenerateNewPlaidToken();
 
  useAccessPlaidLinkToken();
 
  const Plaid = useRef<PlaidHandler | undefined>();
 
  const showErrorMessage = () => {
    showMessage("Error", "Unable to add Plaid account. Please try again later");
  };
 
  const onRegenerateLinkToken = async (error: any) => {
    const errorMessage = error?.response?.data?.message as string;
    const isRegenerateError =
      error?.status === 400 && errorMessage?.startsWith("Plaid login required");
 
    if (!isRegenerateError) return showErrorMessage();
 
    const tokenIndex = errorMessage.indexOf("access-sandbox");
    const token = errorMessage.slice(tokenIndex);
 
    try {
      const result = await generateNewToken(token);
      if (!result?.link_token) return;
      openPlaidModal(result?.link_token);
    } catch (e) {
      showErrorMessage();
    }
  };
 
  const mutation = useCreateBankAccountWithPlaid({
    onError: onRegenerateLinkToken,
  });
 
  const { mutate: mutateBakAccountsList, data } = mutation;
 
  const openPlaidModal = (token: any) => {
    Plaid.current = window.Plaid.create({
      token,
      onSuccess: async (publicToken, metadata) => {
        mutateBakAccountsList({
          plaid: {
            publicToken: publicToken,
            accountID: metadata.accounts[0].id,
          },
        });
      },
      // onEvent: (eventName, metadata) => {},
      // onExit: (error, metadata) => {},
    });
    if (Plaid.current) {
      Plaid.current?.open();
    }
  };
 
  return {
    isCreatingAccount: mutation.isLoading,
    isEnableLinkPlaid,
    open: () => {
      refetch()
        .then((res) => {
          openPlaidModal((res.data as any).link_token);
        })
        .catch((err) => {
          console.log(err);
        });
    },
    data,
  };
}