Paid signups
Charge visitors to join your waitlist. Reserve-your-spot deposits, founding-member pricing, micro-donations — all settle direct to your USDC wallet on Base. Pro-only.
- Per-waitlist toggle — opt in one waitlist, leave the others free.
- USDC on Base — mainnet for real payments, Sepolia for testing. Owner-selectable per waitlist.
- 100% goes to you — no platform fee in v1. Funds settle direct to your wallet on the same on-chain transaction. WaitForge holds nothing.
- Idempotent — replays of the same payment are rejected at the database level. A failed network round-trip never charges twice.
- Same dashboard — paid signups appear in the Signups tab next to free ones, with a payment ledger row joinable by signup id.
Paid signups use a "pay before you proceed" flow, secured by LinkSell.co. A single round-trip swaps the empty signup form for a signed payment commitment plus a confirmed seat.
┌─ visitor's browser ───────┐ ┌─ waitforge worker ────────┐ ┌─ payment provider ────┐ │ │ │ │ │ │ │ POST /signup (no header) │ ────▶ │ paywall.challenge │ │ │ │ │ ◀──── │ 402 + payment terms │ │ │ │ │ │ │ │ │ │ USDC wallet signs │ │ │ │ │ │ │ │ │ │ │ │ POST /signup + X-PAYMENT │ ────▶ │ paywall.verify │ │ │ │ │ │ ledger row 'verified' │ │ │ │ │ │ │ │ │ │ │ │ paywall.settle │ ────▶ │ on-chain transfer │ │ │ │ │ ◀──── │ tx hash returned │ │ │ │ │ │ │ │ │ │ ledger row 'settled' │ │ │ │ │ │ insert signup row │ │ │ │ │ ◀──── │ 200 + position + tx │ │ │ └───────────────────────────┘ └───────────────────────────┘ └───────────────────────┘
Three paywall states are persisted to the waitlist_signup_payments ledger:
verified— signature accepted, on-chain settle in flightsettled— on-chain transfer confirmed; signup row inserted, signup_id back-filledrolled_back— settle failed cleanly; visitor's funds were not charged, payment header reusable on retry with a fresh signature
Hard failures (bad signature, expired nonce, network mismatch) land in the failed state — not retriable without a fresh signature.
- Open your dashboard and pick the waitlist you want to monetize.
- Open the Monetize tab (Pro-only).
- Set the amount in USD (atomic USDC = USD × 1,000,000 in the database row).
- Pick the network — Base mainnet for real payments, Sepolia for testing. The CTA on the hosted page picks up a
(testnet)suffix automatically when Sepolia is selected, so visitors never accidentally pay testnet USDC for a mainnet product. - Paste your wallet address (
0x+ 40 hex characters). Same address works on Sepolia and mainnet, but funds settle on the network you picked. Bad address loses funds with no recovery path — verify carefully. - (Optional) Write a one-line pitch shown on the hosted-page CTA, e.g. "Pay $5 to skip the line and reserve your beta seat".
- Toggle the Charge visitors to join switch. The hosted page CTA flips to "Pay to join · $X" within 60 seconds (edge cache).
| Network | CAIP-2 | Use for |
|---|---|---|
| Base Sepolia (testnet) | eip155:84532 |
Staging, end-to-end testing with fake USDC. Default. CTA shows (testnet) suffix so visitors know. |
| Base mainnet | eip155:8453 |
Real revenue. Real USDC. Real Basescan transactions. Test on Sepolia first. |
v1 is non-refundable. On-chain settles are final — once the visitor's USDC moves to your wallet, WaitForge cannot reverse it. Set the right pitch + price to manage expectations:
- "Pay $5 to skip the line and reserve your beta seat" — sets the right expectation for a deposit.
- "Pay $50 to lock in lifetime founding-member pricing" — sets the right expectation for a one-time commitment.
Disputes happen offline between you and the visitor. Your wallet has the funds; WaitForge is the matchmaker, not a custodian.
- Visitor's wallet rejects the signature — nothing settles. Visitor sees a payment-failed message and can retry with a fresh signature.
- Network mismatch — visitor's wallet is on mainnet but the waitlist accepts Sepolia (or vice-versa). Worker rejects with a clear error before the payment round-trip.
- Replay attack — same X-PAYMENT header sent twice. Worker's UNIQUE index on the payload hash returns 409 on the second attempt; only the first counts.
- Concurrent signups, duplicate email — two visitors with the same email submit at the same time. The dedup check before the paywall catches the second; if it slips through, the second visitor sees "you're already on this list" with their tx hash for reconciliation.
signup.paidIf the waitlist has webhooks subscribed to signup.paid, every settled paid signup fires a delivery with this body:
{
"event": "signup.paid",
"occurred_at": "2026-04-27T14:23:11.000Z",
"waitlist": { "id": "...", "slug": "your-slug", "title": "Your Waitlist" },
"signup": {
"id": "...",
"email": "alice@example.com",
"name": "Alice",
"position": 47,
"referred_by": null,
"referral_count": 0,
"metadata": {}
},
"payment": {
"amount_atomic": "5000000",
"currency": "USDC",
"network": "eip155:8453",
"tx_hash": "0xabc...",
"payer_address": null,
"platform_fee_atomic": "0",
"settled_at": "2026-04-27T14:23:10.500Z",
"ledger_id": "42"
}
}
Hooks subscribed only to signup.active still receive a notification on every paid signup — the event uses the active payload (no payment block) so existing handlers continue to work. Subscribe to signup.paid when you want the payment data.
Full webhook setup, signature verification, and retry semantics are covered in the webhooks guide.
Why USDC and not card payments?
USDC on Base settles in seconds, costs cents to send, and lands in your wallet without a payment processor in the middle. Card payments via Stripe Connect are queued for a follow-up release — same Monetize tab, just a second payment-method dropdown.
Can I take card payments today?
Not for paid signups, no. WaitForge Pro itself accepts card subscriptions via Creem at /dashboard/billing, but signups on your waitlist accept USDC only in v1.
Will WaitForge ever take a platform fee?
Maybe in a future release if there's volume to justify the engineering work to do an atomic on-chain split. v1 takes nothing — you keep 100%. We make money from Pro upgrades, not signup transactions.
What happens to my settings when I downgrade from Pro?
The Monetize tab toggle goes read-only and the gate stops firing on new signups. Your existing payment ledger rows stay intact for audit. Re-upgrade to resume.
How do I test this without spending real money?
Pick Base Sepolia (testnet) in the Monetize tab. Get free testnet USDC from a Sepolia faucet. The CTA on the hosted page automatically appends (testnet) so no visitor accidentally pays testnet USDC for a mainnet product.