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
This commit is contained in:
116
backend/billing/README.md
Normal file
116
backend/billing/README.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user