Files
kosmo-connect/backend/billing
Tomas Kracmar 0a4fb7b55e
Some checks failed
CI / lint-docs (push) Has been cancelled
CI / build-firmware (push) Has been cancelled
CI / test-backend (push) Has been cancelled
CI / test-web (push) Has been cancelled
feat: initial KosmoConnect platform v0.1
Includes:
- Backend services: ingestion (:8001), weather API (:8002),
  gateway (:8003), billing (:8004) with BTCPay integration
- Shared asyncpg pool, TimescaleDB hypertable, Redis, Mosquitto MQTT
- React frontend: Dashboard (MapLibre) and Messaging (chat UI)
- Bridge daemon for Pi + Meshtastic (Serial/TCP T-Deck support)
- Production Docker Compose, Nginx reverse proxy, ops scripts
- DEPLOY.md with step-by-step deployment guide
2026-04-12 17:30:15 +02:00
..

KosmoConnect Billing Service

Integrates with BTCPay Server (pay.cqre.net) for subscription payments.

What It Does

  • Invoice Creation: Generates BTCPay invoices for plan purchases (Wanderer, Guardian, Sanctuary)
  • Webhook Handling: Listens to BTCPay Server webhooks and updates subscription status on payment
  • Subscription Activation: On InvoiceSettled, extends the user's active subscription in PostgreSQL
  • Invoice History: Lets users view their past invoices and payment status

Why BTCPay Server?

The Church of Kosmo operates its own payment infrastructure at pay.cqre.net. BTCPay Server is a self-hosted, open-source Bitcoin payment processor. It enables sovereign, censorship-resistant payments without relying on third-party card processors.

Plan Pricing

Plan Monthly Price Messages Scope
Wanderer $5.00 50/month Any node on the mesh
Guardian $12.00 500/month Only whitelisted nodes
Sanctuary $50.00 Unlimited Any node + API/webhooks

Prices are denominated in USD and paid via BTCPay Server (settled in BTC or Lightning, depending on store configuration).

Running Locally

cd backend
export BTCPAY_URL=https://pay.cqre.net
export BTCPAY_API_KEY=your_api_key_here
export BTCPAY_STORE_ID=your_store_id_here
export WEBHOOK_SECRET=your_webhook_secret_here
./run-dev.sh billing

BTCPay Server Setup Checklist

  1. Create an API Key in your BTCPay Server instance with the following permissions:

    • Create invoice
    • View invoices
    • Modify store webhooks
  2. Create a Webhook in your BTCPay store pointing to:

    https://your-kosmoconnect-instance/api/v1/billing/webhooks/btcpay
    

    Enable events:

    • Invoice created
    • Invoice received payment
    • Invoice processing
    • Invoice expired
    • Invoice settled
    • Invoice invalid
  3. Set the Webhook Secret in the billing service (WEBHOOK_SECRET) to verify webhook signatures.

API Endpoints

Method Path Description
POST /api/v1/billing/invoices Create a new invoice for a plan
GET /api/v1/billing/invoices List user's invoices
GET /api/v1/billing/invoices/{invoice_id} Get invoice details + sync status
POST /api/v1/billing/webhooks/btcpay BTCPay webhook receiver

Example: Create an Invoice

curl -X POST http://localhost:8004/api/v1/billing/invoices \
  -H "Content-Type: application/json" \
  -H "X-User-ID: 11111111-1111-1111-1111-111111111111" \
  -d '{"plan_type": "wanderer", "redirect_url": "https://kosmoconnect.local/thank-you"}'

Response:

{
  "invoice_id": "...",
  "checkout_url": "https://pay.cqre.net/i/...",
  "amount": 5.0,
  "currency": "USD",
  "plan_type": "wanderer"
}

Webhook Payload

The billing service expects standard BTCPay Server webhook payloads. On InvoiceSettled, it:

  1. Looks up the invoice in btcpay_invoices
  2. Deactivates the user's previous subscription
  3. Inserts a new active subscription with valid_from = NOW() and valid_until = NOW() + 30 days
  4. Resets messages_used to 0

Testing Webhooks Locally

If you can't expose localhost to BTCPay, you can simulate a webhook:

curl -X POST http://localhost:8004/api/v1/billing/webhooks/btcpay \
  -H "Content-Type: application/json" \
  -d '{
    "type": "InvoiceSettled",
    "invoiceId": "your-test-invoice-id",
    "status": "Settled"
  }'

Note: Webhook signature verification is skipped if WEBHOOK_SECRET is not set.

Troubleshooting

  • "BTCPay not configured": Set BTCPAY_URL, BTCPAY_API_KEY, and BTCPAY_STORE_ID environment variables.
  • 403 on webhook: Check that WEBHOOK_SECRET matches the secret configured in BTCPay Server.
  • Invoice not found on webhook: Ensure the invoice was created through the billing service (so the btcpay_invoice_id exists in the database).