The $100,000 PageOne page, 1,000 brand spots, $100 each, once
The $100,000 Page sells exactly 1,000 permanent brand placements at $100 each, every one the same size, with no bidding and no premium positions. We designed and built it, and made the limit of 1,000 a database permission.

- Client
- The $100,000 Page
- Sector
- Advertising
- Year
- 2026
- Platforms
- Website, Mobile web
- Services
- Product and UX design, Web development
A single page holding a wall of 1,000 numbered spots. A brand claims an open spot, pays $100 once, and its logo, name and link stay on the wall permanently. Spot #0001 and spot #1000 are worth the same.
Built for
- Small brands, makers, studios and software products that want a permanent place on the wall.
- Visitors who browse the wall and click through to the brands on it.
- The operator, who corrects a placement or removes one that breaks the content policy.
The problem
The whole product is one promise: 1,000 spots, $100 each, all equal. If application code can add spot 1,001 or change the price, the promise lasts only until the next code change.
Selling a fixed number of things means two buyers reaching for the same spot in the same second, payment sessions that outlive the hold on a spot, and webhooks that never arrive. Each of those can sell a spot twice or take money for nothing.
The wall has to show all 1,000 spots on one page, on a phone as well as a laptop, and stay quick.
Goals
- 01Make the 1,000-spot limit and the $100 price impossible for application code to break.
- 02Never sell one spot twice, and refund anyone who pays for a spot that is already gone.
- 03Confirm payment only from a signed webhook.
- 04Keep every spot in the page, so find-in-page, deep links and crawlers see the whole wall.
- 05Let a buyer start a claim with one field: their website address.
Our role
We designed and built the product, from the database rules to the wall and the claim flow.
What we delivered
- Product rules and the public pages: about, questions, terms, content policy and privacy
- The wall of 1,000 spots, with live availability and a pager for moving through it
- Claim flow that reads the buyer’s site for a name, a logo and a description
- Checkout behind a payment-provider interface
- PostgreSQL schema, two database roles, migrations and seed data
- Refund outbox, payment recovery job and outbound click counting
- Admin screen to correct or remove a placement
- Vitest against a real database and a Playwright claim journey
How we worked
- 01
Put the promise in the database
The application connects as a role that cannot insert or delete a spot, and a check constraint fixes the price at 10,000 cents. A test asserts that the application role really is refused.
- 02
Guard each spot twice
Partial unique indexes stop two live orders for one spot, and the reservation is a conditional update that names the state it moves from. Both stay, because they fail in different ways.
- 03
Hold the spot as long as the payment can run
A spot is held for ten minutes while the buyer fills in the form. Once a payment session exists, nothing on our clock releases the spot; it waits until the provider confirms the session is dead.
- 04
Keep the wall in one document
All 1,000 cells are in the page. The grid is a cached server component with no client JavaScript, refreshed only when a placement publishes.
Screens and features
Every spot the same size
1,000 numbered placements at $100 each, with a live count of claimed spots. No bidding and no premium positions.

Claiming a spot takes one form
Pick a number, add a website, pay once. The placement stays on the page permanently.

A limit held by permissions
The application role has INSERT and DELETE revoked on the spots table, and is neither a superuser nor the table owner, so no bug in the application can add spot 1,001.
One field to start a claim
The buyer types a web address. The site is read for its name, description and best icon, old bitmap favicons included, and a logo can be uploaded instead. With no logo at all, the brand’s initial is drawn on a tile.
Refunds written with the failure
If a payment succeeds for a spot that is already gone, the order is marked orphaned and a refund is queued in the same transaction. A worker sends it with a stable idempotency key.
Lost webhooks recovered
Every five minutes a job asks the provider what happened to each hold that has outlived its session, recovers payments whose webhook never arrived and releases holds that are truly dead.
No stale open spots
A small poll every five seconds, paused while the tab is hidden, flips any spot reserved or sold since the page loaded, without touching the cached wall.
Paid means live
The webhook that records the sale also publishes the placement and refreshes the wall. The buyer’s confirmation waits until their spot has turned into their brand.
Uploads checked by their bytes
Logos are identified by their content, re-encoded to a fixed-size WebP and served as plain images. Brand addresses are stored in punycode, so a lookalike domain cannot pass as another brand.
Technical choices
What the product is built with, and why.
- Next.js 16 with a framework-free domain layer
- Pricing, reservations, state changes and webhook handling live in a folder that imports nothing from React or Next, so the tests reach them without a browser or a request.
- PostgreSQL and Drizzle, with two roles
- Migrations run as the owner and the application runs as a role that cannot change the number of spots. A superuser or the owner would bypass the revoke, so the application role is neither.
- One payment-provider interface
- Dodo Payments, a merchant of record, is the chosen provider, so sales tax is handled by them. The local adapter signs its own webhooks and posts them to the production endpoint, so development runs the same payment path.
- A cache tag on the wall
- The wall is cached until a placement publishes. Without the cache every request would run a 1,000-row query, and in Next 16 a request that claims to be a bot is enough to force a fresh render.
- Short class names at 1,000 cells
- Cells use short semantic classes and draw their arrows with CSS. Repeated a thousand times, utility-class strings alone would add about 200KB to the page.
- Vercel, with a five-minute cron
- A cron entry calls the recovery job every five minutes, and buyer logos are stored in Vercel Blob.
Selling something with a fixed supply?
Limited stock, racing payments and refunds that must happen are problems we enjoy. Tell us what you are selling.