> ## Documentation Index
> Fetch the complete documentation index at: https://shinydapps-bd9fa40b.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Layer

> How l402-kit processes Bitcoin Lightning payments — BOLT11, L402 protocol, and cryptographic verification.

# Payment Layer

l402-kit is a **soberano middleware** that adds a Bitcoin Lightning paywall to any HTTP endpoint in 3 lines of code. You bring your own Lightning provider — funds go directly to your wallet, no intermediary required.

***

## Protocol: L402

L402 is an open standard that extends HTTP/1.1 with a native payment handshake:

```
Client → GET /api/data
Server ← 402 Payment Required
         WWW-Authenticate: L402 <macaroon>, invoice="<BOLT11>"

Client pays invoice via Lightning wallet
Client → GET /api/data
         Authorization: L402 <macaroon>:<preimage>
Server ← 200 OK + data
```

The **macaroon** is a capability token bound to the invoice's `paymentHash`. The **preimage** is the cryptographic secret released by the Lightning node when payment settles. The server verifies:

```
SHA256(preimage) == paymentHash ✓
```

No account, no session, no JWT — the preimage **is** the proof of payment.

***

## Invoice Creation Flow

```
Your API receives a request without valid Authorization
     │
     ▼
l402-kit middleware calls lightning.createInvoice(priceSats)
     │  (your provider: Blink, Alby, OpenNode, BTCPay, LNbits…)
     ▼
Provider returns BOLT11 invoice + paymentHash
     │
     ▼
Middleware builds macaroon: base64({ hash: paymentHash, exp: now+1h })
     │
     ▼
Your API returns 402 + invoice + macaroon to client
```

***

## Payment Verification Flow

```
Client pays BOLT11 invoice via any Lightning wallet
     │
     ▼
Lightning node releases preimage (32-byte secret)
     │
     ▼
Client sends Authorization: L402 <macaroon>:<preimage>
     │
     ▼
Middleware verifies locally — no network call:
  1. Decode macaroon (base64 → JSON { hash, exp })
  2. Check exp > now()
  3. SHA256(preimage) === hash ✓
     │
     ▼
Request passes through to your API handler → 200 OK
```

Verification is **O(1)** — pure cryptography, no database lookup on the hot path. Replay protection (Supabase `payment_hash` logging) runs asynchronously and does not block the request.

### Macaroon format

l402-kit uses a lightweight custom macaroon — not libmacaroon. The token is a `base64url`-encoded JSON object:

```json theme={null}
{ "hash": "<paymentHash hex>", "exp": <unix timestamp> }
```

This is simpler and auditable without any external library. The `Authorization` header format is:

```
Authorization: L402 <base64url-macaroon>:<preimage-hex>
```

***

## Fee Model

| Mode                            | Fee                    | Setup                                 |
| ------------------------------- | ---------------------- | ------------------------------------- |
| **Soberano** (any provider)     | **0%** — you keep 100% | Bring your own provider credentials   |
| **Managed** (`ManagedProvider`) | 0.3% to l402kit.com    | No Lightning node — works immediately |

Soberano mode is the default. Managed mode is an explicit opt-in:

```typescript theme={null}
// Soberano — 0% fee, you keep 100%
import { AlbyProvider } from 'l402-kit';
const lightning = new AlbyProvider(process.env.ALBY_TOKEN!);

// Managed — 0.3% fee, no Lightning node needed
import { ManagedProvider } from 'l402-kit';
const lightning = ManagedProvider.fromAddress('you@yourdomain.com');
```

***

## Data Storage (optional — Supabase)

Set `SUPABASE_URL` + `SUPABASE_ANON_KEY` to log payments automatically:

```sql theme={null}
create table payments (
  id            uuid primary key default gen_random_uuid(),
  payment_hash  text unique not null,  -- SHA256(preimage) — safe to store
  endpoint      text,
  amount_sats   integer,
  paid_at       timestamptz default now()
);
```

**Why `payment_hash` instead of `preimage`?** The `payment_hash` is already embedded in every BOLT11 invoice — it's public by design. Only the `preimage` is secret. Storing the hash gives replay protection with zero additional exposure.

***

## Lightning Providers

l402-kit is provider-agnostic. Any backend that implements `LightningProvider` works:

| Provider                                  | Notes                                    |
| ----------------------------------------- | ---------------------------------------- |
| [Alby Hub](https://hub.getalby.com)       | Self-custodial, 0% fee                   |
| [Blink](https://blink.sv)                 | Free custodial, no KYC for small amounts |
| [BTCPay Server](https://btcpayserver.org) | Self-hosted, full soberanoty             |
| [OpenNode](https://opennode.com)          | Custodial, no setup                      |
| [LNbits](https://lnbits.com)              | Self-hosted or cloud                     |

See the [TypeScript SDK](/sdk/typescript) or [Python SDK](/sdk/python) for provider setup.

***

## Security Guarantees

| Threat           | Mitigation                                                                 |
| ---------------- | -------------------------------------------------------------------------- |
| Replay attack    | Preimage marked used after first verification — in-memory or Redis adapter |
| Fake preimage    | `SHA256(preimage) === paymentHash` is cryptographically unforgeable        |
| Token expiry     | Macaroon embeds `exp` timestamp — verified on every request                |
| Webhook spoofing | `HMAC-SHA256(secret, body)` verified before processing                     |
