Accepting zero-amount or sub-minimum transactions creates two concrete problems: payment processors (Stripe, Adyen) reject amounts below their floor and return errors that must be handled; and zero-amount transactions that do commit pollute the ledger with noise records that complicate reconciliation. OWASP A03 covers this as inadequate input validation. The error message matters too — WCAG 2.2 SC 3.3.1 and 3.3.3 require error messages to identify the constraint, not just report failure, so users know what to correct.
Medium because zero and sub-minimum amounts cause payment processor rejections that surface as user-visible errors and create invalid ledger records.
Enforce a minimum of 1 cent server-side and return a message that states the actual threshold, not a generic failure string.
// src/app/api/transfers/route.ts
const schema = z.object({
amountCents: z.number().int().min(1, 'Minimum transaction amount is $0.01'),
});
const parsed = schema.safeParse(await req.json());
if (!parsed.success) {
return Response.json(
{ error: parsed.error.issues[0]?.message },
{ status: 422 }
);
}
Mirror the constraint in src/components/TransferForm.tsx with min="0.01" on the amount input and a visible hint below the field.
ID: finserv-form-validation.account-routing.min-amount-enforcement
Severity: medium
What to look for: Count all financial amount submission endpoints. For each, check whether a minimum amount (at least 1 cent / $0.01) is enforced server-side. Quote the minimum value and the error message text returned when the minimum is violated. Report: "X of Y amount endpoints enforce a server-side minimum with a descriptive error message."
Pass criteria: At least 100% of amount endpoints enforce a minimum (at least 1 cent) server-side. The error message explicitly states the minimum value (e.g., "Minimum transaction is $0.01"), not a generic message like "Invalid amount". Report even on pass: "X endpoints enforce min of $Y with descriptive errors."
Fail criteria: Any endpoint accepts zero or sub-minimum amounts, or the error message is generic (fewer than 5 words describing the requirement).
Must not pass when: The minimum is enforced but the error message says only "Validation failed" or "Invalid input" — users need to know the actual threshold.
Skip (N/A) when: The project has no minimum transaction amount concept (0 financial submission endpoints found).
Detail on fail: Example: "Server accepts zero and negative amounts. No minimum validation or error message." or "Minimum enforced but error message is 'Validation failed' instead of 'Minimum transaction is $0.01'"
Cross-reference: The max-amount-limits check in this category covers the upper bound; together they define the valid amount range.
Remediation: Enforce minimums with clear messaging in src/app/api/ route handlers:
In src/app/api/transfers/route.ts:
const MIN_TRANSACTION_AMOUNT = 1; // 1 cent, i.e., $0.01
if (amountCents < MIN_TRANSACTION_AMOUNT) {
throw new ValidationError('Minimum transaction amount is $0.01');
}