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

    Operator-driven settlement and termination for cash deposits whose GDN AuthCommit never completed.

    A cash deposit's dp_ row is created at Auth, when the clerk takes the cash. AuthCommit is what re-quotes, accepts, consumes the barcode, and starts settlement. When AuthCommit declines, none of that runs and the row is stranded at PENDING with no workflow and no expiry timer — the expiry workflow was already cancelled at Auth. Green Dot resolves these by email and settles to us at end of week; these two methods are how an operator applies that resolution.

    Both methods replay the GDN handler rather than inventing a second state machine. Reference: GreendotBarcodeConsumptionEventProcessor.processAuthCommit (release) and processAuthVoid (fail).

    fail auto-recovers from a mint that lands after its pre-check: terminate does not abort an in-flight activity, so mintTokensForDeposit's sendAndConfirmTransaction can still confirm after the workflow is terminated. fail polls the mint signature after terminating (see CashDepositReconciliationService.pollForLateMint) and, if it appears, resumes settlement (restarts cashDepositWorkflow, which short-circuits the mint step and runs the remaining legs) instead of cancelling — a hand-written DEPOSITED would skip the swap and fee-sweep steps that only the workflow runs.

    Index
    • Terminate a cash deposit that will not settle, as AuthVoid would have, plus the workflow termination AuthVoid is missing.

      The success value reports which of the two outcomes actually happened, since an ok result does not always mean the deposit was cancelled: if a mint lands during workflow termination (see the late-signature race below), this method auto-recovers by resuming settlement instead, and that outcome — SETTLEMENT_RESUMED — is still an ok result. Callers must not assume CANCELLED from ok alone; read value.outcome.

      Parameters

      • args: { depositId: string; reason: string }

      Returns Promise<
          | { ok: true; value: { outcome: "CANCELLED"
          | "SETTLEMENT_RESUMED" } }
          | {
              error:
                  | ServiceError<"DEPOSIT_NOT_FOUND">
                  | ServiceError<"NOT_CASH">
                  | ServiceError<"DEPOSIT_NOT_ACTIONABLE", { status: string }>
                  | ServiceError<"ALREADY_MINTED">;
              ok: false;
          },
      >

    • Settle a cash deposit as a successful AuthCommit would have: refine and accept the product quote, consume the barcode, then start settlement.

      The amount comes from the deposit-quote's quote.sourceAmount — the register figure Auth stamped onto it (see CashDepositQuoteAdminService called from processAuth). Deliberately not the dp_ row's own sourceAmount: DepositAdminService.create is idempotency-keyed and short-circuits on a repeat Auth, so a second Auth at a different amount updates the quote but leaves the frozen dp_ row behind. There is no wire to re-read the amount from, and the operator does not supply it.

      Parameters

      • args: { depositId: string; reason: string }

      Returns Promise<
          | { ok: true; value: void }
          | {
              error:
                  | ServiceError<"DEPOSIT_NOT_FOUND">
                  | ServiceError<"NOT_CASH">
                  | ServiceError<"DEPOSIT_NOT_ACTIONABLE", { status: string }>
                  | ServiceError<"BARCODE_NOT_CONSUMABLE", { barcodeStatus: string }>;
              ok: false;
          },
      >