Skip to content

@paykernel/integration-hono

Thin Hono adapter that reads c.req.raw.text() and calls processWebhookHttp.

Updated View as Markdown

honoWebhook converts a Hono request into processWebhookHttp and returns webhookHttpResultToResponse. No payment logic, no store adapters. Depends only on @paykernel/integration-http among workspace packages.

Version 0.1.1 — published on npm. Portable (paymentsSdk.portable: true). Peer hono >= 4. Export map: "." only.

bun add @paykernel/integration-hono
# dependency: @paykernel/integration-http
# peer: hono >= 4

Usage

import { Hono } from "hono";
import { honoWebhook } from "@paykernel/integration-hono";

const app = new Hono();
app.post(
  "/webhooks/stripe",
  honoWebhook({
    gateway: "stripe",
    client, // PaymentClient with no onWebhookVerified fulfillment
    engine,
    handler,
  }),
);

honoWebhook accepts Omit<ProcessWebhookHttpInput, "rawBody" | "headers" | "query"> — you pass gateway, client, engine, handler, and optionally ackPolicy, correlationId, signatureProfile.

What it does:

  1. const request = c.req.raw
  2. rawBody = await request.text()never c.req.json()
  3. headers = request.headers
  4. query = c.req.query() (Paymob-style ?hmac= signatures)
  5. processWebhookHttp({ ...options, rawBody, headers, query })
  6. return webhookHttpResultToResponse(result)

Runnable host: Bun + Hono + SQLite (in-memory SQLite is single-host and process-local). Postgres variant: Bun + Hono + Postgres.

Failure paths

Same table as processWebhookHttp. Typical Stripe cases:

Request Status Body
Missing stripe-signature 400 { error: "invalid_webhook" } — client not called
Forgery (bad HMAC) 400 { error: "invalid_webhook" }
Parse / missing-config InvalidWebhookError 500 { outcome: "handler_failed", retryable: true }
already_processing 503 { outcome: "already_processing" }; Retry-After when retryAfterMs is set
payload_conflict 409 { outcome: "payload_conflict" }
Handler throws (no local paid order, store error) 500 { outcome: "handler_failed", retryable: true }

Default ackPolicy is provider_redelivery: scheduled_for_retry is 503. Pass ackPolicy: { kind: "durable_worker" } only when engine.mode === "durable_retry" and a processRetryable worker is guaranteed.

Status codes come from mapInboxOutcome in @paykernel/integration-http, not from @paykernel/webhooks.

Re-exports

Import HTTP helpers from this package if you want a single specifier:

import {
  honoWebhook,
  mapInboxOutcome,
  retryAfterSeconds,
  processWebhookHttp,
  webhookHttpResultToResponse,
  createWebhookOperationContext,
  getHeader,
  resolveCorrelationId,
  requireStringBindings,
  GATEWAY_WEBHOOK_SIGNATURE,
  extractWebhookSignature,
} from "@paykernel/integration-hono";

Also re-exported as types: InboxHttpAckPolicy, HeaderBag, GatewayWebhookSignatureProfile, WebhookClient, WebhookHttpResult, ProcessWebhookHttpInput.

OBJECT_HMAC_GATEWAYS is not re-exported here. Import it from @paykernel/integration-http.

Example POST /internal/* routes in the Hono checkout example are unauthenticated test hooks (enableTestHooks) and must not be deployed.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close