first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
# create-intent
## Purpose
Body and response schemas for `POST /payments/intents`. The request body carries the amount (typed `MoneySchema`), optional description, optional capture method (`automatic` | `manual`), and optional metadata map. The response envelope wraps a serialised `PaymentIntent` so the OpenAPI doc has a single canonical reference for the lifecycle's primary mutation.
This is the principal write endpoint for the plugin — every authenticated payment-creation flow calls it, and idempotency middleware (`Idempotency-Key`) wraps the route to replay identical second calls without re-charging the provider.
## Features
- `CreatePaymentIntentBodySchema` accepts `amount`, `description`, `captureMethod` (default `"automatic"`), and an optional string-to-string `metadata` map.
- `PaymentIntentResponseSchema` wraps a single `PaymentIntentSchema` for type-safe consumer parsing.
- All optional fields are strict — extra body keys are rejected via Zod's default-strict mode.
## Usage: Basic
```ts
import { CreatePaymentIntentBodySchema } from "@suaveplan/api-plugin-payment/schemas/routes";
const body = CreatePaymentIntentBodySchema.parse({
amount: { amount: 2500n, currency: "USD" },
});
```
## Usage: Advanced
```ts
import {
CreatePaymentIntentBodySchema,
PaymentIntentResponseSchema,
} from "@suaveplan/api-plugin-payment/schemas/routes";
const body = CreatePaymentIntentBodySchema.parse({
amount: { amount: "1999", currency: "EUR" },
captureMethod: "manual",
description: "Order #ORD-1234",
metadata: { orderId: "ORD-1234", source: "checkout-web" },
});
const res = await fetch("/payments/intents", {
method: "POST",
headers: { "content-type": "application/json", "Idempotency-Key": orderId },
body: JSON.stringify(body),
});
const parsed = PaymentIntentResponseSchema.parse(await res.json());
```
## API Reference
- `CreatePaymentIntentBodySchema` — `{ amount: MoneySchema, description?: string (1..500), captureMethod: "automatic" | "manual" (default "automatic"), metadata?: Record<string, string> }`.
- `CreatePaymentIntentBody` — inferred TS type.
- `PaymentIntentResponseSchema` — `{ intent: PaymentIntentSchema }`.
- `PaymentIntentResponse` — inferred TS type.
## Implementation Notes
`captureMethod` defaults to `"automatic"` because the dominant Stripe-style flow captures on confirm. `"manual"` exists for two-phase auth/capture flows (think hotel deposits / fuel pumps where the final amount differs from the authorisation). `description` is bounded to 500 chars to match Stripe's API limit and prevent unbounded metadata-driven storage costs downstream.