# @openreceive/http

Add Bitcoin Lightning checkout to your Node.js application while keeping
your orders, prices, and fulfillment in your own code. This package provides
the Web Request/Response handler and payment repository used by the Express,
Fastify, and Next.js adapters, with payment attempts stored in your existing
database.

OpenReceive supports optional swaps from **USDT, USDC, SOL, and ETH** through
a configured swap provider. The provider converts the payment to **BTC over
Lightning**, which settles into the merchant's connected wallet. Available
assets and networks depend on the provider; swaps are optional.

## Install

This package is ESM-only and requires Node >= 22.

```sh
npm install @openreceive/http
```

Start with the [integration quickstart](https://github.com/openreceive/openreceive/blob/master/docs/guides/quickstart-node.md)
and the [payment storage guide](https://github.com/openreceive/openreceive/blob/master/docs/guides/storage.md).

## Connect your application

For Express, Fastify, or Next.js, start with the matching adapter; each uses
this handler and repository. For a custom Node.js host, compose `service`,
`authorize`, and the `host` integration. Amounts come from your server, and
a payment attempt is committed before checkout instructions are returned.

`createHost({ db, amountFor, onPaid })` builds the
host integration on the library-owned payment repository inside the host
application's existing database (pg, mysql2, node:sqlite, better-sqlite3, or a custom
adapter). The library owns attempt selection, per-reference commit locking,
write-once settlement with first-attempt-only fulfillment, and the
`pending → settled | expired | failed | attention` reconciliation state
machine (`attention` reads as `pending` on the wire; operators see it only in
`openreceive_payments.status`). `onPaid` is the settlement hook in both modes: with `db` it receives
`PaymentSettlement` (`reference` plus a `query` that runs inside the
settlement transaction); with a custom repository it receives
`SettlementEvent<Transaction>` (`reference`, `paymentHash`, `paidAt`, `details`,
and `transaction`). The repository awaits fulfillment before commit; failure
rolls back both payment and host writes. On Cloudflare Workers, which cannot
open a Postgres connection to Supabase, `createHost({ supabase: { url, key },
amountFor })` keeps the same rows in Supabase over its HTTPS API, and the
host's SQL function `openreceive_on_paid` fulfills inside the settlement
transaction ([Supabase over HTTPS](https://github.com/openreceive/openreceive/blob/master/docs/guides/supabase.md#supabase-over-https)). Settlement
piggybacks on mounted routes by default through the durable `openreceive_meta`
gate (`opportunisticReconcile: false` disables, `{ minIntervalSeconds }`
tunes); `startNotificationWorker` is the optional
listen-plus-reconcile worker process. A custom `PaymentRepository`
via the `payments` option is the advanced escape hatch.

It reuses one live attempt per rail, permits new attempts after expiry, and
verifies the `payment_hash` selector belongs to the authorized order. Committed
retries use the stored safe checkout snapshot. `swapData` is never serialized
into an HTTP response. OpenReceive never requires a separate database or Redis.

This is the home of the full host-integration surface. The framework adapters
(`@openreceive/express`, `@openreceive/fastify`, `@openreceive/next`) re-export
only a curated slice — the handler/stack factories, error surface, notification
worker, and their options/context/hook types — so anything deeper imports from
here (`npm run check:public-api` pins both surfaces):

- Handler and stack: `createHttpHandler`, `createStack`,
  their options types, and `mapHostRouteError` / `HttpError` /
  `HostError`.
- Host integration: `createHost`, the SQL repository
  (`createSqlPayments`, `paymentsSchemaSql`), the
  `PaymentRepository` contract types, and the settlement hook
  contexts above.
- Reconciliation: `maybeReconcilePayments` (the durable gate pass),
  `reconcileHostPayments`, `startReconciler`, and the shared
  constants (`OPENRECEIVE_ATTEMPT_EXPIRY_GRACE_SECONDS`,
  `OPENRECEIVE_RECONCILE_BATCH_SIZE`, scan bounds).
- Rate limiting: `createIpRateLimit`, `resolveClientIp`, and
  `IpRateLimitConfig` behind the handler's `rateLimiting` /
  `rateLimitHook` options.
- Generated wire types: the snake_case `Wire*` request/response body
  types (`WireCheckout`, `WireCreateCheckoutRequest`,
  `WirePaymentCheck`, `WireError`, …), generated from the
  OpenAPI contract. The adapters re-export these too.

See the [API reference](https://github.com/openreceive/openreceive/blob/master/docs/guides/api-reference.md)
and [HTTP contract](https://github.com/openreceive/openreceive/blob/master/spec/openapi/openreceive-http.v1.yaml).

## Agent skills

Run `npx openreceive skills install` from your application after installing an
OpenReceive server adapter. The offline copy ships in `@openreceive/node`, a
server-adapter dependency. For a frontend-only project, use
`npx skills add OpenReceive/openreceive`.
See [agent setup](https://openreceive.org/agents). The bundled installers write
to `.agents/skills/`; use `--dir .claude/skills` for Claude Code. They replace
only `integrate-openreceive` and `debug-openreceive-payment`, preserving
unrelated skills.
