# AetherDesk payments and entitlements

AetherDesk should sell through multiple channels, but every channel must feed one entitlement shape.
The product unlock should not care whether the customer paid through the website, Google Play, or a manual founder deal.

## Payment lanes

- Website checkout: Stripe Checkout and Billing.
- Website wallets: Google Pay through Stripe.
- Website Cash App: Cash App Pay through Stripe.
- Google Play Store: Google Play Billing for in-app digital unlocks and subscriptions.
- Manual Cash App: founder/pilot fallback only, converted into a signed entitlement receipt before unlock.

## Boundary rules

- Do not put Stripe secret keys in browser, mobile, npm, PyPI, or desktop client code.
- Do not process Stripe webhook events unless the webhook signature has been verified server-side.
- Do not treat Google Pay as a replacement for Google Play Billing inside a Play-distributed digital product.
- Do not unlock paid features from a manual Cash App payment until an operator creates a signed entitlement receipt.
- Do not let npm or PyPI become payment processors; packages install the client, the entitlement provider unlocks paid capability.

## Public self-serve action cards

Generate UI/API-ready setup cards for Google Play, website Stripe checkout, entitlement/license provider, code signing, legal review, npm, PyPI, and manual Cash App pilot fallback:

```powershell
npm run aetherdesk:public-self-serve:actions
```

```text
GET /api/agent/public-self-serve-action-cards
POST /api/agent/workflows/public_self_serve_action_cards/run
```

These cards are secret-safe: they stage env templates and official account boundaries, but do not store Stripe keys, license secrets, signing keys, provider tokens, or legal claims in artifacts.

The desktop shell also exposes these cards visually as **Public Launch** from This PC, the launcher nav, the mission cards, and the command finder. It reuses the same secret-safe `/api/agent/public-self-serve-action-cards` artifact, so the visual surface and headless surface stay aligned.

Each generated action also writes a local public-launch receipt row:

- `artifacts/aetherdesk_public_self_serve_action_cards/latest.receipts.json`
- `artifacts/aetherdesk_public_self_serve_action_cards/latest.state.json`

Receipt rows include card id, action id, action label, access tier, allowed/denied posture, timestamp, reason, blockers, and boundary. External sign-in, money movement, legal attestation, signing material, and secret entry actions are marked denied until the operator completes them outside AetherDesk artifacts.

## Public-sale environment gates

```dotenv
AETHERDESK_PAYMENT_PROVIDER=stripe
AETHERDESK_STRIPE_CHECKOUT_READY=false
AETHERDESK_STRIPE_CUSTOMER_PORTAL_READY=false
AETHERDESK_STRIPE_WEBHOOK_SIGNING_READY=false
AETHERDESK_STRIPE_DYNAMIC_PAYMENT_METHODS_READY=false
AETHERDESK_STRIPE_GOOGLE_PAY_READY=false
AETHERDESK_STRIPE_CASH_APP_PAY_READY=false
AETHERDESK_GOOGLE_PLAY_BILLING_READY=false
AETHERDESK_MANUAL_CASH_APP_PILOT_READY=false
AETHERDESK_ENTITLEMENT_PROVIDER_URL=https://example.com/aetherdesk/entitlements
AETHERDESK_LICENSE_SECRET=<load-from-secret-manager-minimum-32-chars>
```

Set the booleans to `true` only after the live configuration exists and has been checked outside the repo.
These flags are receipts of operational readiness, not placeholders for secrets.

## Shared entitlement shape

```json
{
  "schema": "aetherdesk_entitlement_v1",
  "license_id": "aetherdesk-pro-...",
  "customer_id_hash": "sha256...",
  "edition": "pro",
  "status": "active",
  "source": "stripe_checkout",
  "source_event_id": "evt_...",
  "issued_at": "2026-07-03T00:00:00.000Z",
  "expires_at": "2026-08-03T00:00:00.000Z",
  "features": ["local AI PC desktop", "workflow receipts", "agent workflows"],
  "signature": {
    "mode": "hmac-sha256",
    "present": true
  }
}
```

Allowed `source` values:

- `stripe_checkout`
- `stripe_subscription`
- `stripe_cash_app_pay`
- `stripe_google_pay`
- `google_play_billing`
- `manual_founder_cash_app`
- `local_pilot`

## Headless commands

```powershell
npm run aetherdesk:license:proof
npm run aetherdesk:payments:map
npm run aetherdesk:public-sale:config
npm run aetherdesk:public-sale:readiness
npm run aetherdesk:public-sale:launch-kit
```

## UI/API surfaces

- `/api/agent/license-entitlement` exposes the latest local entitlement proof.
- `/api/agent/payment-entitlement-map` exposes the latest payment/channel readiness map.
- `/api/agent/public-sale-config` exposes the latest payment/config preflight.
- `/api/agent/public-sale-readiness` exposes the paid-pilot and public-sale readiness receipt.
- `/api/agent/public-sale-launch-kit` exposes the launch-kit artifact and channel checklist.

The UI should show these as a control-panel status lane, not as a secret-entry form.
Secrets belong in the production entitlement provider or secret manager, not in AetherDesk's static desktop shell.
