first commit
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# webhook
|
||||
|
||||
## Purpose
|
||||
|
||||
Response schema for `POST /payments/webhook`. The webhook receiver MUST read the raw request body and verify the provider HMAC BEFORE deserialising — there's no body schema because the route does not parse JSON at the Zod boundary; instead the receiver hands the raw bytes to `WebhookVerifier.verify` from `@suaveplan/payment`.
|
||||
|
||||
The response is intentionally minimal: an `accepted: boolean` flag the provider's webhook delivery infrastructure can use to decide whether to retry. A `true` response means "we received and authenticated the payload"; a `false` response (returned from the rejection path) indicates the request was rejected for a non-retryable reason (signature mismatch) and the provider should not retry.
|
||||
|
||||
## Features
|
||||
|
||||
- `WebhookResponseSchema` carries one field: `accepted: boolean`.
|
||||
- Schema is small by design — the wire surface for webhooks is the request body (provider-defined), not the response.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { WebhookResponseSchema } from "@suaveplan/api-plugin-payment/schemas/routes";
|
||||
|
||||
const wire = WebhookResponseSchema.parse({ accepted: true });
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
// Provider-side delivery loop:
|
||||
const res = await fetch(`${endpoint}/payments/webhook`, {
|
||||
method: "POST",
|
||||
headers: { "X-Signature": sig, "X-Timestamp": String(ts) },
|
||||
body,
|
||||
});
|
||||
const { accepted } = WebhookResponseSchema.parse(await res.json());
|
||||
if (!accepted) {
|
||||
// signature failure — do NOT retry, alert on dashboard instead
|
||||
alertOps({ event: "webhook_rejected" });
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `WebhookResponseSchema` — `z.object({ accepted: z.boolean() })`.
|
||||
- `WebhookResponse` — inferred TS type.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The receiver does not surface the verified payload back to the provider in the response — payment providers neither inspect nor care about the response body beyond the status code. Returning a minimal `{ accepted }` shape lets operators distinguish authenticated-rejected (`200 { accepted: false }`) from total-failure (`5xx`) in their delivery logs without leaking sensitive internal state.
|
||||
Reference in New Issue
Block a user