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
117 lines
3.9 KiB
Markdown
117 lines
3.9 KiB
Markdown
# 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).
|