Skip to content

Start typing to search the documentation.

Stripe Channel API

AI-generated, awaiting review View as Markdown

Import from @flue/stripe.

createStripeChannel()

function createStripeChannel<E extends Env = Env>(
  options: StripeSnapshotChannelOptions<E>,
): StripeChannel<E>;

function createStripeChannel<E extends Env = Env>(
  options: StripeThinChannelOptions<E>,
): StripeChannel<E>;

Creates one stateless Stripe webhook channel. The callback is stored during construction and runs only after Stripe’s SDK verifies the exact request bytes, signature timestamp, and configured payload mode.

StripeChannelOptions

interface StripeSnapshotChannelOptions<E extends Env = Env> {
  client: Stripe;
  webhookSecret: string;
  bodyLimit?: number;
  signatureToleranceSeconds?: number;
  eventPayload?: 'snapshot';
  webhook(input: StripeSnapshotWebhookHandlerInput<E>): StripeHandlerResult;
}

interface StripeThinChannelOptions<E extends Env = Env> {
  client: Stripe;
  webhookSecret: string;
  bodyLimit?: number;
  signatureToleranceSeconds?: number;
  eventPayload: 'thin';
  webhook(input: StripeThinWebhookHandlerInput<E>): StripeHandlerResult;
}

Snapshot mode is the default. Set eventPayload: 'thin' only when the Stripe event destination sends thin event notifications.

interface StripeSnapshotWebhookHandlerInput<E extends Env = Env> {
  c: Context<E>;
  event: Stripe.Event;
}

interface StripeThinWebhookHandlerInput<E extends Env = Env> {
  c: Context<E>;
  event: Stripe.V2.Core.EventNotification;
}
FieldDescription
clientProject-owned official Stripe SDK client.
webhookSecretSigning secret for this Stripe event destination.
signatureToleranceSecondsAllowed signature timestamp age. Defaults to 300 seconds.
bodyLimitMaximum request-body size in bytes. Defaults to 1 MiB.
eventPayloadSigned payload mode. Defaults to snapshot.
webhookReceives every event verified for the configured payload mode.

The package calls client.webhooks.constructEventAsync() for snapshot events and client.parseEventNotificationAsync() for thin notifications. The raw request is not parsed or reserialized before verification.

Handler result

type StripeHandlerResult = void | JsonValue | Response | Promise<void | JsonValue | Response>;

Returning nothing produces an empty 200. A JSON-compatible value becomes a JSON response. An ordinary Hono or Fetch Response passes through unchanged. Thrown callbacks and unsupported return values produce a server error.

The package does not impose a general handler deadline because Stripe does not publish one timeout for every event family. Applications should acknowledge ordinary asynchronous events quickly. Specialized synchronous event workflows may have stricter provider-specific response requirements.

StripeChannel

interface StripeChannel<E extends Env = Env> {
  readonly routes: readonly ChannelRoute<E>[];
}

routes contains one POST /webhook declaration. A file named channels/stripe.ts is served at /channels/stripe/webhook relative to the flue() mount.

Stripe does not supply one canonical conversation identity across its event families, so this package does not expose conversation-key helpers.

Snapshot events

The snapshot callback receives the provider-native Stripe.Event. The event’s type discriminates its data.object for the API version represented by the installed Stripe SDK.

Verified event types newer than the installed SDK are still forwarded at runtime. Until Stripe’s declarations include one, inspect event.type as string and validate its resource fields in application code. The callback keeps Stripe’s closed native union so known cases retain their provider-supplied payload narrowing.

Useful identity fields include:

  • event.id for event-level idempotency;
  • event.account for Connect deliveries;
  • event.context for organization destinations;
  • event.request?.id for an originating API request;
  • resource ids within event.data.object.

The package does not deduplicate deliveries or guarantee ordering. Header and payload metadata identify the delivery context but do not grant authorization for outbound API calls.

Thin event notifications

Thin mode receives the provider-native Stripe.V2.Core.EventNotification. Notifications expose their own id, type, context, and provider-supplied related-object metadata. Some event types have no related object. Stripe’s SDK adds fetchEvent() and fetchRelatedObject() methods that use the supplied project-owned client and propagate the notification context; fetchRelatedObject() returns null when no related object exists.

Snapshot events and thin notifications are separate modes. A snapshot payload sent to a thin channel, or a thin notification sent to a snapshot channel, is rejected before the application callback.

Thin notification types are also generated with the installed SDK. A verified future type is forwarded at runtime and may be inspected through event.type as string until the SDK is upgraded.

Verification

The route requires application/json and Stripe-Signature. Stripe’s SDK verifies HMAC-SHA256 over the exact request bytes and checks the signed timestamp against signatureToleranceSeconds. Multiple v1 signatures are accepted according to the SDK’s signing-secret rotation behavior.

Invalid, missing, stale, malformed, oversized, or mode-mismatched requests fail before webhook runs.

Invalid constructor options such as a missing client or signing secret, unsupported payload mode, non-positive body limit, or non-positive signature tolerance throw a TypeError.

See Stripe setup for event-destination setup, the project-owned SDK client, and application-owned tools.