# Demo 5: Licensing and royalties

**Port:** 3005 · **Postgres schema:** `licensing` (migration slot `2026102405xxxx`) · **Services:** Stripe Connect (test mode)

## Demo moment

A catalogue card: "Floor plan · commissioned by Spin Mitte · built by Lea (Verified) · €50 license + €9/month". The builder's name, badge and stats come from `seed/builders/builder-lea.json`, the profile the onboarding demo produces. Padel Ost clicks "License". After Checkout, two transfers appear in Stripe (builder 40%, commissioner 30%), the platform keeps the rest, and the royalty ledger shows Spin Mitte's earnings with progress towards its cap (1× its €500 commission).

## Inputs

- `catalogue.json`: entry `floor-plan` (`owner_business`, `builder`, fees)
- `price-buckets.json`: `royalty_split_of_license`
- `padel-ost.json` as the buyer

## Flow

1. Stripe objects: a Product "Floor plan" with a recurring price (€9/month) and a one-off price (€50); an Entitlements feature `plugin.floor-plan` attached to the product.
2. Checkout in subscription mode with the one-off license price added to the first invoice; `transfer_group` = license id.
3. Webhook `invoice.paid` (first invoice) → transfers from the charge with `source_transaction`: builder 40% of the license, commissioner 30% (until the cap), platform keeps the rest.
4. Write `licensing.license_sales` and `licensing.royalty_ledger` (party, amount, source invoice, running total vs cap).
5. Webhook `entitlements.active_entitlement_summary.updated` → `licensing.entitlements_cache`; show "Floor plan active for Padel Ost".

## Setup

Connected accounts for the builder (`BUILDER_CONNECTED_ACCOUNT_ID`) and the commissioner (`COMMISSIONER_CONNECTED_ACCOUNT_ID`).

## Env

`STRIPE_SECRET_KEY`, `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY`, `STRIPE_WEBHOOK_SECRET`, `BUILDER_CONNECTED_ACCOUNT_ID`, `COMMISSIONER_CONNECTED_ACCOUNT_ID`, Supabase variables

## Fallback

If subscription mode slows you down, a one-off €50 Checkout payment with the same split. Seeded ledger rows for earlier licenses so the cap progress looks real.

## Done when

- One license purchase produces two transfers visible in Stripe and ledger rows.
- The cap progress updates.
- The entitlement shows as active (or is simulated, stated in the README).

## Out of scope

Crediting royalties to the commissioner's customer balance (mention in the pitch), Accounts v2, refunds and transfer reversals.
