Features
Why a Static Site Cannot Take Payments
Where the secret has to live, and what a webhook is actually proving.
11 October 2026

The secret has to live somewhere
A static site cannot take payments because it has no persistent state to store the private cryptographic keys required to verify transactions. When you try to perform a static site payment integration, you are hitting a fundamental wall: the browser sends a request to a file on a disk, not a process that can hold a secret.
On our infrastructure, this distinction is physical. GamingCap and Invoiceful are static builds served straight from disk by Caddy. They have no server process and no database. If a user tries to pay for a GamingCap subscription, the request goes to Caddy, which serves the HTML and JavaScript. There is no backend to receive the payment intent, no place to store the merchant ID, and no logic to sign the transaction. The file system is read-only for the application code, meaning the "secret" has nowhere to live.
What a webhook is actually proving
Many developers misunderstand webhooks as the moment payment happens. It is not. A webhook is a callback that proves a payment was already processed by a third-party processor. The processor holds the card data, not you. Your job is to verify that the webhook came from the processor and then update your own state.
For Instalaz, which runs as its own separate Node process on port 3050, this is manageable. It can listen for webhooks, verify the signature, and update the user’s status in the shared PostgreSQL 16 database. But for a static site, there is no listener. You cannot have a static file listen for an HTTP POST request. You would need to proxy the webhook to a serverless function or a backend API, which effectively means you are no longer running a pure static site for that specific interaction.

Why we keep static sites static
We maintain the separation because processes on one box compete for memory. Our single VPS has 12GB of RAM. The Next.js process serves four sites, including the admin panel and PracandyFlix. Instalaz runs separately to isolate its event loop. If we tried to bolt a payment backend onto the static assets of GamingCap, we would introduce a new failure mode without gaining any architectural benefit.
Static sites are fast and resilient because they have no moving parts to crash. They do not need to restart when a dependency updates. They do not need to scale out during a traffic spike because they are just files. Adding a payment flow requires a stateful component. That component needs to be managed, monitored, and secured. It is not worth the complexity for a product like Invoiceful, which is free and requires no account. For paid products, we use a dedicated backend or a managed service, not a hack on the static hosting layer.
Where the logic must sit
The logic must sit in a process that can hold state. For us, that is either the Next.js application or the Instalaz Node process. Both connect to the shared PostgreSQL database. The database is the source of truth for user subscriptions. The static site is merely the interface.
If you are building a product, decide early where the money flow happens. Do not try to make a static site do the job of a server. Use a payment processor that handles the heavy lifting, and send webhooks to a backend that you control. Keep your static assets static. They are your most reliable asset. For more on how we structure our content and tools, see PracandyFlix. The architecture is boring, but it works.


