2.0 KiB
capture-intent
Purpose
Body schema for POST /payments/intents/:id/capture. Supports both full capture (empty body) and partial capture (body carries amount: MoneySchema). The partial-capture path is essential for two-phase authorise+capture flows such as hotel reservations where the final amount differs from the original authorisation, and for split-shipment e-commerce orders that bill at fulfilment.
The provider is the authoritative source of capture eligibility — the schema only enforces that the optional amount is a well-formed Money value if present, and lets the PaymentService reject business-rule violations (capturing more than authorised, capturing after refund, currency mismatch).
Features
CaptureBodySchemaaccepts an optionalamount: MoneySchema.- Empty body → full-amount capture (request
{}). - Inferred
CaptureBodytype plugs into Hono's typed body parser.
Usage: Basic
import { CaptureBodySchema } from "@suaveplan/api-plugin-payment/schemas/routes";
const body = CaptureBodySchema.parse({}); // full capture
const partial = CaptureBodySchema.parse({
amount: { amount: 1500n, currency: "USD" },
});
Usage: Advanced
// Two-phase capture flow — authorise full, capture partial after fulfilment
await fetch("/payments/intents/pi_abc/capture", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
amount: { amount: shippedItemsTotal, currency: "USD" },
}),
});
API Reference
CaptureBodySchema—z.object({ amount?: MoneySchema }).CaptureBody— inferred TS type.
Implementation Notes
The schema allows an empty body for the full-capture path because forcing callers to send { amount: { amount: <originalAmount>, currency: <originalCurrency> } } would require them to re-fetch the intent first — that's two round-trips for a happy-path full capture. Letting amount be optional shortens the common case to one request.