Skip to content

Runbook: Integrace aplikace na BillIt API

⚠️ ZASTARALÉ (auth sekce) od CR-021 (RS256/JWKS), zjištěno 2026-07-04. Krok 1 (HS256 JWT se SENTINEL_JWT_SECRET) NEFUNGUJE — billit .env.prod už tento secret nemá, tokeny validuje přes S60Auth JWKS (RS256). Sentinel ops cesta pro správu API klíčů/webhooků je v řešení s billit agentem (T-20260704-003). ApiKey auth header je Authorization: ApiKey blt_... (ne X-Api-Key). Po zavedení ops cesty runbook přepsat.

Přehled

BillIt používá tenant-based model. Aplikace (Pulse, budoucí další) se integrují pod existující tenant (typicky studio-60), NETVOŘÍ vlastní tenant.

Prerekvizity

  • Přístup na prod-alfa (SSH)
  • SENTINEL_JWT_SECRET z /root/secrets/billit/.env.prod
  • Python3 s PyJWT (pip3 install pyjwt)

Krok 1: Vygenerovat JWT token

BillIt API akceptuje JWT signed s SENTINEL_JWT_SECRET. Potřebuješ user ID ownera cílového tenantu.

# Najdi owner user ID pro tenant
# (DB: s60_billit_prod, tabulka tenant_users)
psql "$DB_CONN" -t -c "SELECT tu.user_id, tu.role FROM tenants t JOIN tenant_users tu ON t.id = tu.tenant_id WHERE t.slug = 'studio-60' AND tu.role = 'owner';"

# Vygeneruj JWT
TOKEN=$(python3 -c "
import jwt, time
token = jwt.encode(
    {'sub': '<USER_ID>', 'email': '<EMAIL>', 'roles': ['admin'],
     'iat': int(time.time()), 'exp': int(time.time()) + 3600,
     'iss': 'https://auth.studio60.cz'},
    '<SENTINEL_JWT_SECRET>',
    algorithm='HS256'
)
print(token)
")

Krok 2: Vytvořit API key

# Na prod-alfa přes SSH (token přes soubor kvůli quoting)
ssh root@100.78.87.88 "echo '$TOKEN' > /tmp/billit-jwt.txt && \
  curl -s -X POST http://127.0.0.1:3200/v1/accounts/studio-60/api-keys \
  -H 'Content-Type: application/json' \
  -H \"Authorization: Bearer \$(cat /tmp/billit-jwt.txt)\" \
  -d '{\"name\": \"<APP> Production\", \"scopes\": [\"write:orders\", \"read:orders\", \"read:invoices\"]}' && \
  rm /tmp/billit-jwt.txt"

Odpověď obsahuje rawKey (blt_...) — uložit do /root/secrets/<app>/billit-api-key-prod.txt.

Dostupné scopes

Scope Popis
read:invoices Čtení faktur
write:invoices Vytváření/editace faktur
read:orders Čtení objednávek
write:orders Vytváření/editace objednávek
read:subjects Čtení kontaktů
write:subjects Vytváření/editace kontaktů
read:expenses Čtení nákladů
write:expenses Vytváření/editace nákladů
read:accounting Čtení účetnictví
write:accounting Zápis předkontace
export:accounting Export do ABRA/Pohoda/Money
read:webhooks Správa webhooků

Krok 3: Vytvořit webhook (volitelné)

ssh root@100.78.87.88 "echo '$TOKEN' > /tmp/billit-jwt.txt && \
  curl -s -X POST http://127.0.0.1:3200/v1/accounts/studio-60/webhooks \
  -H 'Content-Type: application/json' \
  -H \"Authorization: Bearer \$(cat /tmp/billit-jwt.txt)\" \
  -d '{\"url\": \"https://<APP_DOMAIN>/webhooks/billit\", \"events\": [\"order.paid\", \"order.cancelled\"]}' && \
  rm /tmp/billit-jwt.txt"

Odpověď obsahuje secret (whsec_...) — uložit jako BILLIT_WEBHOOK_SECRET.

Krok 4: Nastavit env vars v cílové aplikaci

# Na prod-alfa v /opt/<app>/.env:
BILLIT_API_URL=https://billit.cz/api
BILLIT_API_KEY=blt_<key>
BILLIT_WEBHOOK_SECRET=whsec_<secret>

Restart kontejneru + ověřit health.

Krok 5: Uložit credentials

# Na sentinelu
cat > /root/secrets/<app>/billit-integration-prod.env << EOF
BILLIT_API_URL=https://billit.cz/api
BILLIT_API_KEY=blt_<key>
BILLIT_WEBHOOK_SECRET=whsec_<secret>
BILLIT_WEBHOOK_URL=https://<APP_DOMAIN>/webhooks/billit
EOF
chmod 600 /root/secrets/<app>/billit-integration-prod.env

Důležité poznámky

  • NIKDY nevytvářet vlastní tenant pro aplikaci — vše pod studio-60
  • ForwardAuth headers (x-user-id, x-user-email) už NEFUNGUJÍ — použít JWT
  • BillIt API base na prod: https://billit.cz/api (nginx /api/127.0.0.1:3200/)
  • Interní cesta: http://127.0.0.1:3200/v1/accounts/:slug/...
  • JWT token předávat přes dočasný soubor (quoting problém přes SSH)
  • Hub URL: https://billit.s60hub.cz/api

Aktuální integrace

Aplikace Tenant API Key prefix Webhook Stav
Pulse studio-60 blt_6859 pulselab.cz/webhooks/billit ✅ prod (2026-03-30)