Payezz under the hood
How the system is built, what the API contract looks like, and which parts of it work today.
How to read these pages
Payezz is in early access. These docs describe the system as it is designed, and every piece is labeled with its real status so nobody builds on something that doesn't exist yet.
- In production
- Built, tested and in use. You can integrate against it.
- Partial
- The structure exists and compiles, but one part is still missing for it to work end to end.
- Designed, not built
- Specified in detail, with no code written yet. The contract may change before it ships.
REST API
The payments contract between your instance and the control plane: HMAC signatures, intents, charges, refunds, manual fees and idempotency.
Webhooks
The events the control plane forwards, signed, to your instance, with their retry policy and the one idempotency rule that isn't up for debate.
MCP server
Connecting your billing to an AI assistant. It's the least mature part of the product, and the page says so plainly.
Provisioning modules
The interface that connects a service you sold to the system that delivers it: manual, Pterodactyl, and whatever comes next.
The two planes
Payezz is not one app with lots of tenants sharing a single database. It's two separate things:
- The control plane provisions instances, holds the platform's Stripe key, receives Stripe Connect events, calculates fees and keeps the fee ledger. It's the only part that ever sees data from more than one customer.
- The instance is the product: the storefront, the provider's admin panel, the client area, the billing engine and the provisioning modules. Every customer gets their own, with its own container, database and domain.
What an instance never has, by design:
- The platform's Stripe secret key.
- Access to the control plane's database.
- Access to another instance's database.
- Any way to set its own fee.
The three channels
The two planes talk over three channels. All of them are authenticated, and each one is only ever initiated from one side:
(A) Signed API instance ──▶ control plane
HMAC-SHA256 + Idempotency-Key + API version
charges, intents, manual fees, heartbeat
(B) Signed webhooks control plane ──▶ instance
payment_intent.succeeded charge.refunded
payment_intent.failed account.updated
charge.dispute.created plan.changed
(C) Control channel orchestrator ══▶ container
deployment, migrations, backups, suspension,
secret rotation. Never goes through the app.The instance has no Stripe endpoint. The control plane receives every event at a single endpoint, works out the connected account from the event's account field, translates it into a Payezz domain event and forwards it, signed. That means there's one webhook secret in the whole system, instances don't need to be reachable from the outside, and the retry policy is ours.
The control channel never goes through the application: it talks to the container engine and to DNS. An instance has no way to call it, and that's what stops a bug in storefront code from ever touching the infrastructure.
Conventions that apply everywhere
- Money is an integer in the smallest currency unit.
1499means €14.99. Never decimals, never floating point. A field that holds an amount is calledamount_minor, notamount, so nobody misreads it. - Currencies are lowercase ISO 4217 codes:
eur,usd. - Dates are ISO 8601 with a time zone, in UTC.
- Fee percentages travel as whole basis points:
190is 1.9%. No rounding halfway through. - Every request carries an API version. An instance that hasn't been updated has to keep working.
What works today
Spelled out, so nobody plans on vapor. The fee engine, authentication between the instance and the control plane, and both database schemas are built and tested. The payment gateway is wired up but still missing its database queries, so today it returns an error. The storefront editor, the SEO panel, the MCP server and the provisioning modules are specified but not built.
If you're planning an integration and need to know when something specific will land, email us at hola@payezz.app and we'll give you the date we're working with, no padding.