@cfxlabsinc/b2b-services
    Preparing search index...

    Service responsible for handling withdrawal reconciliation operations.

    Only use this if the withdrawal method maps 1:1 with a bank transaction.

    Index
    • Create a pending ACH debit authorization for an inbound debit against a virtual account.

      Parameters

      • args: {
            accountNumber: string;
            achId: string;
            amount: string;
            originatorName: string | null;
        }

      Returns Promise<{ withdrawalId: string } | null>

    • Parameters

      • args: { bankTransactionId: string; withdrawalId: string }

      Returns Promise<
          | { ok: true; value: void }
          | {
              error:
                  | ServiceError<"REDEMPTION_NOT_FOUND", { redemptionId: string }>
                  | ServiceError<"REDEMPTION_NOT_PENDING", { redemptionId: string }>
                  | ServiceError<"INVALID_BANK_TX", { bankTransactionId: string }>
                  | ServiceError<
                      "AMOUNT_MISMATCH",
                      { bankTransactionAmount: string; redemptionAmount: string },
                  >
                  | ServiceError<"WITHDRAWAL_NOT_FOUND", { withdrawalId: string }>
                  | ServiceError<"INVALID_BANK_TX", { bankTransactionId: string }>
                  | ServiceError<
                      "WITHDRAWAL_ALREADY_RECONCILED",
                      { existingWithdrawalId: string; withdrawalId: string },
                  >
                  | ServiceError<
                      "AMOUNT_MISMATCH",
                      { bankTransactionAmount: string; withdrawalAmount: string },
                  >
                  | ServiceError<"REDEMPTION_NOT_FOUND", { withdrawalId: string }>;
              ok: false;
          },
      >

    • Find a pending ACH_PULL withdrawal by achId and reconcile it with the given bank transaction.

      When no authorization exists the debit has still settled, so this creates the same one the Pending webhook would have. That webhook is the only thing that normally opens the authorization, and a dropped delivery used to leave the bank transaction unreconciled and skip the FBO -> vacct sweep, which runs inside the withdrawal workflow and is keyed on the withdrawal. Callers must therefore only reach here for debits they have already established are real (see isAllZeroAchTrace on the webhook path).

      Parameters

      • args: {
            accountNumber: string;
            achId: string;
            amount: string;
            bankTransactionId: string;
            originatorName: string | null;
        }

      Returns Promise<
          | { ok: true; value: void }
          | {
              error:
                  | ServiceError<"REDEMPTION_NOT_FOUND", { redemptionId: string }>
                  | ServiceError<"REDEMPTION_NOT_PENDING", { redemptionId: string }>
                  | ServiceError<"INVALID_BANK_TX", { bankTransactionId: string }>
                  | ServiceError<
                      "AMOUNT_MISMATCH",
                      { bankTransactionAmount: string; redemptionAmount: string },
                  >
                  | ServiceError<"WITHDRAWAL_NOT_FOUND", { withdrawalId: string }>
                  | ServiceError<"INVALID_BANK_TX", { bankTransactionId: string }>
                  | ServiceError<
                      "WITHDRAWAL_ALREADY_RECONCILED",
                      { existingWithdrawalId: string; withdrawalId: string },
                  >
                  | ServiceError<
                      "AMOUNT_MISMATCH",
                      { bankTransactionAmount: string; withdrawalAmount: string },
                  >
                  | ServiceError<"REDEMPTION_NOT_FOUND", { withdrawalId: string }>
                  | ServiceError<
                      "WITHDRAWAL_STILL_CREATED",
                      { achId: string; withdrawalId: string },
                  >;
              ok: false;
          },
      >