first commit
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# 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
|
||||
|
||||
- `CaptureBodySchema` accepts an optional `amount: MoneySchema`.
|
||||
- Empty body → full-amount capture (request `{}`).
|
||||
- Inferred `CaptureBody` type plugs into Hono's typed body parser.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
// 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.
|
||||
Reference in New Issue
Block a user