Browser signup and signed webhooks
A self-contained application using the real Stripe SDK and an exact released twin. No platform account, pack checkout, database or production credential is needed. Node 22.6 or newer and npm are required. The automatic browser suite additionally needs Playwright's Chromium installation.
Use the example files below in an empty directory, then follow test an app in the browser. Individual files: package.json, server, configuration helper, browser assertions, Playwright configuration, environment names, ignore file.
Prepare and run
$ npm install
$ npx volter world init --name browser-signup --twins stripe
$ node configure-app.mjs
$ npx volter world up
$ npx volter world clock set 2026-01-15T12:00:00Z
$ npx volter-world app-url browser-signup --root .Review the detected vendor and init-generated source before booting. The helper appends one process service to the generated config; run it once. The World owns its environment, readiness, app endpoint and teardown. Open the app URL; create an account with an email at example.com and a fresh random password for this run. Signup creates a customer through the unchanged SDK. The account page reads it back and reports its signed customer.created callback. Reload verifies the session persists; sign out and revisit /account to see access refused.
Automatic assertions
The protected-account assertion uses the browser session's own request client after sign-out and requires the server to redirect to sign-in. A separate request session would not prove logout. The returning-user step uses the sign-in form already shown in the browser.
Install Chromium during environment preparation, outside the runtime World, then run the suite:
$ npx playwright install chromium
$ npx volter world run -- npm run test:browser
$ npx volter world log
$ npx volter world downThe score is eight named application assertions passed out of eight: signup, email read-back, customer ID, verified callback, session persistence, rejection of an invalid signature, logout, and signing back in. It is not coverage of Stripe's API, source code, DOM or state transitions. The test has one worker, no retries and no arbitrary sleeps. Use a fresh World/app for each run; restarting clears this example's in-memory users and sessions. World reset alone does not clear app memory. The test generates a random password and disables captures so the password is not retained in a trace.
Scope and limits
This is a teaching application, with in-memory account/session storage and local HTTP cookies. It is not a production authentication implementation. Customer state belongs to the twin; application sessions and delivered-event deduplication belong to the app. The callback verifies Stripe's signature using the secret returned when the SDK registers that exact endpoint. Frozen World time differs from wall time, so this example disables only the SDK's signature-age check. Production handlers should retain their age tolerance. See signed webhooks.
The example verifies signup and a customer callback, not payments, subscriptions, OAuth, email delivery or arbitrary Stripe operations. Exact dependencies live in the complete manifest. Commit the generated lockfile and reviewed config in your own application.