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=paymentandquantity=1for 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-webhookendpoint onapi.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
isAdminrole. - 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
| Library | Purpose | Where |
|---|---|---|
| Stripe.js | Payment form, SCA flow | app/src/payment/ |
| React Query | Server state caching on the client | app/src/client/ |
| Wasp SDK | Authentication, actions, and queries | app/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).