Skip to content

Integrations Guide

This guide summarizes how Kilavuz talks to external services and the contracts an integration developer needs to know about.

Stripe for payments

Kilavuz uses Stripe for one-time credit-pack purchases. Credit packs are purchased once at a time; there are no recurring renewals, project activation fees, or plan upgrades.

  • Credit packs are sold as one-time purchases: the standard pack includes 1,000 credits for €100, tax included, and the launch pack includes 10,000 credits for €500, tax included (the launch pack is shown only to eligible accounts during its configured 30-day campaign window). The server selects the Stripe price ID on behalf of the customer; client-supplied price information is presentation only and the Stripe-side amount is the source of truth.
  • Checkout is completed on Stripe’s hosted Checkout page with mode=payment and quantity=1 for a single pack. Kilavuz never stores card numbers or CVVs; the payment return page (app/src/payment/CheckoutResultPage.tsx) does not increase the balance by itself and keeps the purchase pending until payment confirmation is verified on the server.
  • Webhooks arrive from Stripe at the /stripe-webhook endpoint on api.kilavuz.app; the endpoint rejects the request before verifying the signed raw body. Each successful payment is fulfilled once: a new credit lot is granted, unused credits expire six calendar months after purchase, and the lot is recorded in billing history where authorized users can access payment receipts. The same endpoint applies refund and dispute adjustments against verified payment records; there are no recurring renewal events.

Email provider (Resend)

Wasp 0.25 ships a native Resend provider (emailSender.provider: "Resend" in app/main.wasp). In production, Kilavuz calls Resend’s HTTPS API and the server reads a single environment variable:

  • RESEND_API_KEY=<injected via platform secret store>

All sender identities share the address noreply@kilavuz.app. Both auth.methods.email.fromField and emailSender.defaultFrom are set to the same value, so authentication and operational emails both go out through a single verified sender.

The RESEND_API_KEY value is not committed as a real API key; the value is injected at runtime from the platform’s secret store. The rationale for that limitation is documented in detail in docs/deploy/kilavuz-readiness.md.

Admin panel

The admin panel running at admin.kilavuz.app shares the same client code base but is deployed as a separate build.

  • User management lists every signed-up user; it grants or revokes the isAdmin role.
  • Billing view mirrors each organization’s credit balance, credit lots, and usage history.
  • Audit records display the server-side event log of sensitive operations as read-only tables in the admin UI.

The admin side is open only to users with isAdmin === true; the language choice does not influence authorization decisions.

Static blog and documentation service

The Starlight site running at blog.kilavuz.app does not depend on any API. Plain HTML produced at build time is served by nginx. Content updates are reflected in the next deployment; no image rebuild is required.

Third-party client libraries

LibraryPurposeWhere
Stripe.jsPayment form, SCA flowapp/src/payment/
React QueryServer state caching on the clientapp/src/client/
Wasp SDKAuthentication, actions, and queriesapp/src/client/

Versions of third-party libraries are pinned in app/package.json and blog/package.json; any upgrade must be tested separately against each of the three independent images (api, web, admin).