Files
kashilo/docs/pow-server

PoW Captcha & Payment Server

PHP-basierter Server für kashilo.com mit Proof-of-Work Captcha und BTCPay Payment-Proxy.

Setup

  1. Subdomain pow.kashilo.com auf den Server zeigen

  2. Dateien in das Web-Root kopieren

  3. Secrets setzen:

    # In .env oder Apache/Nginx config:
    SetEnv POW_SECRET $(openssl rand -hex 32)
    SetEnv BTCPAY_API_KEY your_btcpay_api_key
    SetEnv BTCPAY_STORE_ID your_btcpay_store_id
    

    Oder direkt in config.php die Werte ändern.

  4. Testen:

    # PoW Challenge
    curl https://pow.kashilo.com/challenge
    
    # BTCPay Invoice erstellen
    curl -X POST https://pow.kashilo.com/btcpay/invoice \
      -H "Content-Type: application/json" \
      -d '{"listingId": "test-123", "currency": "EUR"}'
    

Endpoints

GET /challenge

Gibt eine signierte PoW-Challenge zurück.

POST /verify

Prüft die PoW-Lösung. Body (JSON):

{
  "challenge": "...",
  "difficulty": 4,
  "nonce": 12345,
  "signature": "...",
  "timestamp": 1700000000000
}

POST /btcpay/invoice

Erstellt eine BTCPay Server Invoice für eine Listing-Gebühr. Body (JSON):

{
  "listingId": "uuid-string",
  "currency": "EUR"
}

Response:

{
  "invoiceId": "...",
  "checkoutLink": "https://pay.xmr.rocks/i/...",
  "status": "New",
  "expirationTime": 1700000000
}

GET /btcpay/status?id={invoiceId}

Prüft den Zahlungsstatus einer Invoice. Response:

{
  "invoiceId": "...",
  "status": "New|Processing|Settled|Expired|Invalid",
  "additionalStatus": "None|PaidLate|PaidPartial|..."
}

POST /btcpay/webhook

Empfängt BTCPay Server Webhook-Events. Wird in BTCPay unter Store → Settings → Webhooks konfiguriert.

  • URL: https://pow.kashilo.com/btcpay/webhook
  • Event: InvoiceSettled (nach 1 Blockchain-Confirmation)
  • Aktion: Setzt das zugehörige Listing in Directus auf status: published, payment_status: paid, setzt paid_at und expires_at (30 Tage)
  • Sicherheit: Webhook-Secret wird serverseitig geprüft

Gebühren

Währung Betrag
EUR 1
USD 1
CHF 1
GBP 1
JPY 200

Sicherheit

  • HMAC-SHA256 signierte Challenges (nicht fälschbar)
  • TTL: 2 Minuten
  • CORS: nur https://kashilo.com
  • hash_equals() gegen Timing-Attacks
  • BTCPay API-Key bleibt serverseitig (nie im Frontend)
  • Gebühren serverseitig erzwungen (nicht manipulierbar)