Why ASD Tunnel makes real Mollie payment testing possible in CI

Why ASD Tunnel makes real Mollie payment testing possible in CI
If you've ever tried to write an end-to-end test for a payment provider like Mollie, you've hit the same wall we did: the webhook. Your test can create a payment, your test can click through the Mollie checkout in a headless browser, but then Mollie needs to phone home to tell your backend "the payment succeeded, activate the subscription." And Mollie's servers cannot reach http://localhost:54321.
This is not a Mollie-specific problem. Any payment provider requires a publicly reachable webhook endpoint. Without that, you can’t test the full payment lifecycle.
What most teams do
Most projects fall back to one of these approaches:
-
Mock the webhook by POSTing a synthetic payload to their handler
-
Use a shared staging environment with a public URL
-
Rely on external tunneling tools in development
Mocking is fast and useful, but it only verifies your handler logic. It does not verify that:
-
Mollie can actually reach your endpoint
-
Your routing, auth, and proxy layers are correct
-
The full payment → webhook → database pipeline works
In other words, you’re testing components and not the system.
The three-tier test strategy
We wanted both speed and realism. In our Playwright E2E suite (e2e/payment-webhook.spec.ts), we split the Mollie tests into three layers:
-
One-time payment (local) — pure API: call
create-payment, verify the DB row, then POST a synthetic webhook to our own edge function. No browser, no tunnel, runs on every PR in under a second. -
Subscription (local) — same idea for
create-subscription: verify customer creation, subscription row, linked order, and simulate the webhook. -
Full Mollie checkout (CI + tunnel) — the real flow. Playwright drives the actual Mollie checkout page, fills the PCI iframe with a test card, clicks "Paid" on Mollie’s status screen, and then waits for Mollie itself to deliver the webhook.
The key difference is that the third test runs inside a GitHub runner, not a staging environment.
The test polls the database until orders.status = 'paid' appears — meaning the entire pipeline completed successfully.
Why a tunnel is required in CI
GitHub runners are ephemeral and not publicly reachable:
-
No inbound traffic
-
No stable IP
-
No exposed ports
So without a public endpoint, Mollie cannot deliver webhooks to your test environment.
A tunnel solves this by creating a temporary, publicly accessible HTTPS endpoint that forwards traffic into the runner.
What ASD Tunnel actually does
The setup in CI is four lines:
asd init --yes
asd caddy start
asd net apply --seed --caddy --tunnel
API_TUNNEL_URL=$(grep '^API_TUNNEL_URL=' .env | cut -d= -f2- | tr -d '"')This provisions an ephemeral HTTPS endpoint — for example:
https://dev1-api-clientid.eu1.tn.asd.engineer
Requests to that URL are routed through:
-
Caddy (TLS + auth + reverse proxy)
-
into the GitHub runner
-
into local Supabase edge functions
We pass this URL as webhookUrl when creating a Mollie payment. From Mollie’s perspective, this is just a normal production endpoint.
The full payment flow
Playwright → Mollie checkout (real browser)
→ Mollie servers → ASD tunnel
→ Caddy → Supabase edge function
→ Postgres update → test assertion
Every hop is real:
-
Real browser
-
Real Mollie API
-
Real webhook delivery
-
Real database mutation
No mocks, no stubs, no staging environment.
Why this matters
Running this flow inside CI unlocks a few things:
-
End-to-end verification of the webhook path
You’re testing the actual network boundary, not a simulated call. -
Detection of integration drift
Changes in Mollie responses, redirect behavior, or iframe flows surface automatically. -
Visibility into test-mode quirks
Subscription and mandate behavior in Mollie test mode is not always deterministic. Running the real flow exposes this early. -
CI and local parity
The exact same setup runs locally and in CI. No dependency on shared staging infrastructure. -
No long-lived public environments
No staging servers to maintain, sync, or debug.
What’s actually different here
Tunnels themselves are not new. Tools like ngrok and Cloudflare Tunnel solve the same underlying problem.
The difference here is operational:
-
Runs inside a GitHub runner
-
Fully ephemeral (per run)
-
Requires no external setup or accounts
-
Integrated into the same CLI that runs the rest of the stack
This makes full webhook E2E testing something you can run on every PR — not something reserved for staging or manual QA.
Beyond Mollie
The Mollie use case is just one example. The same pattern applies to:
-
Stripe webhooks
-
OAuth callbacks
-
Third-party event systems
-
Any inbound HTTP integration
Boilerplate (Angular + Supabase)
Everything described in this setup is available out of the box in the ASD Angular + Supabase boilerplate:
https://github.com/asd-engineering/asd-angular-supabase
This boilerplate is designed specifically for Angular developers and includes:
-
Playwright E2E setup with webhook testing patterns
-
Supabase edge functions wired for real payment flows
-
ASD CLI integration (tunnel, Caddy, dev stack)
-
Secure defaults (auth, routing, environment handling)
The goal is not just to demonstrate the approach, but to make it directly usable without additional infrastructure work.
Support for additional frameworks is planned and will follow the same pattern.
Closing
The core problem isn’t "testing payments", it’s testing systems that depend on inbound webhooks in environments that are not publicly reachable.
ASD Tunnel doesn’t introduce a new concept. It removes the operational friction of using that concept in CI.
And that’s what makes full end-to-end webhook testing finally practical.
Kelvin Wuite
Kelvin Wuite is the founder of ASD B.V. With over eighteen years of development experience, he has witnessed the same patterns repeat across every software team - endless documentation, manual preparation, environment mismatches, and fragmented collaboration. His drive is to remove these barriers, enabling engineers to work together in unified environments with shorter feedback loops and hands-on collaboration. Since 2015 he has been refining these ideas, leading to ASD — a platform designed to create a faster, more integrated way for development teams to collaborate in an age where AI is thriving.