# 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 ```bash 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 ```bash 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: ```json { "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: ```bash 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).