import { type HeaderSource, type VerifyOptions } from '@m2c/core'; import type { ConversionEvent } from './types.js'; export interface HandleConversionWebhookOptions { /** Your webhook signing secret (dashboard -> Credentials -> Webhooks). */ secret: string; /** The RAW request body bytes - verification is over the EXACT bytes received. */ rawBody: string | Buffer; /** Request headers: Node's `IncomingHttpHeaders` or a WHATWG `Headers`. */ headers: HeaderSource; /** * Called with the verified event. Fulfill on `event.status === 'completed'` * and reverse on `'refunded'`/`'chargedback'`. Throw to signal a transient * failure: the throw propagates (the handler does NOT return a 2xx), so your * server returns 5xx and M2C retries, then dead-letters. */ onEvent: (event: ConversionEvent) => void | Promise; /** Forwarded to {@link verifyConversionWebhook} (e.g. a custom skew window). */ verifyOptions?: VerifyOptions; } /** What to write to the HTTP response. `body` is present only on the error path. */ export interface WebhookHandlerResult { status: number; body?: string; } /** * Run a conversion-webhook endpoint end to end in one call: verify M2C's * signature over the RAW body, then dispatch the verified event to `onEvent`, * returning the response to send - 204 on success, 400 on a bad/missing * signature. A throw from `onEvent` propagates so your server can return 5xx and * M2C retries. You keep the HTTP plumbing (capture the RAW body, write the * returned `status`/`body`); this owns the signature crypto and the status rules. * An empty webhook secret is local misconfiguration and still throws. * * A delivery whose signature verified but whose payload breaks the contract * throws (an authentic M2C contract issue, not tampering) - let it surface * rather than silently 204'ing. */ export declare function handleConversionWebhook(opts: HandleConversionWebhookOptions): Promise;