← Back to experiment
BUILD & LAUNCH GUIDE

One small ask.
A clear setup.

Nearby discovery & sharing

Share is available in the sticky navigation, the mobile bottom bar, the landing prompt and the final results panel. Sharing links contain no participant details. Nearby public responses are visible on the landing and results pages before voting is required.

The hosting network’s approximate city estimate is used where available; visitors can correct it with Change city. It does not request GPS or save the inferred area to a participant response. A chosen browsing city is remembered for 30 days and does not alter a vote. Participants still choose whether to supply a city with their response, and can withdraw their public listing. Network-location availability and accuracy depend on the hosting request metadata; the manual fallback always remains available.

What works now

Persistent anonymous voting; changes of mind update the same browser’s response; optional name, city, country and income; automatic city-based listings with upfront disclosure and withdrawal; aggregate results; nearby city distances; share links and downloadable aggregate PNG; protected administration. Every displayed count is drawn from stored test responses. There are no seeded participants.

Stripe checkout, signature-verified webhooks, event deduplication, payment verification and refund accounting are implemented. They need your Stripe test credentials for an end-to-end provider test. No payment is simulated as verified in this preview. Live keys are deliberately rejected by the application.

Screen flow

Question → optional details (or skip) → No: results / Yes: checkout → complete, cancel or Not now → results → optional sharing. A returning browser resumes its saved response. Saying yes after no updates that response. Payment remains exactly 100 US cents, with no quantity selector, tips, promotion codes, subscription or fee added.

Payment recommendation

Start with a US Stripe merchant account and hosted Checkout. Cards and eligible Apple Pay / Google Pay use one integration. Activate Cash App Pay if Stripe approves the account for it. Keep Venmo as a later optional second integration: a bare payment link cannot supply reliable participant-level verification.

MethodAvailability for this approachMinimum / standard fee / remainder on $1
CardsUS merchant; supported cardholders globally, subject to restrictionsUSD $0.50 minimum; 2.9% + $0.30 domestic; approximately $0.67 remains
Apple PayEligible bank, supported country and device/browser; Stripe-hosted Checkout handles wallet setupSame USD minimum and card pricing; approximately $0.67 domestic
Google PayEligible wallet, card and browser; enable in Stripe payment settings. Wallet availability differs by country; Stripe excludes India for these wallet flowsSame USD minimum and card pricing; approximately $0.67 domestic
Cash App PayUS merchants and US customers; USD only; US territories excluded$0.50 minimum; 2.9% + $0.30; approximately $0.67
Venmo via PayPalEligible US business and US buyer, USD; separate integration not builtStandard online rate 3.49% + $0.49; approximately $0.48. A Venmo-specific minimum was not confirmed in the reviewed documentation; validate $1 with PayPal before adding it.

Reviewed September 17, 2026. Standard US pricing, excluding account-specific add-ons. International cards and conversion may cost more. Stripe generally retains original processing fees on refunds.

Sources: Stripe pricing · USD minimum · Apple Pay · Google Pay · Cash App Pay availability · Cash App pricing · Venmo pricing · Venmo integration

Exact test setup checklist

  1. Create a Stripe account owned by the intended recipient. Confirm that Stripe accepts the disclosed social-experiment business model.
  2. Open a Stripe sandbox. Add its sk_test_ key as the secret STRIPE_SECRET_KEY in the Site’s environment settings. Never paste secrets into public code.
  3. Add an event destination pointing to this Site’s /api/webhook. Subscribe to checkout.session.completed, checkout.session.async_payment_succeeded, checkout.session.async_payment_failed, payment_intent.succeeded, payment_intent.payment_failed, payment_intent.processing, payment_intent.canceled, and charge.refunded. Save the signing secret as STRIPE_WEBHOOK_SECRET.
  4. The test Site is publicly accessible, so Stripe can reach /api/webhook without signing in. Configure the sandbox API key and webhook signing secret before testing. Real payments remain disabled. Use test details only and redeploy after changing environment settings.
  5. For Cash App, enable it in Stripe and set ENABLE_CASH_APP=true. Otherwise leave it false. Verify Apple Pay and Google Pay on eligible devices, including in-app social browsers.
  6. Set ADMIN_EMAILS to the organiser’s exact ChatGPT sign-in email (comma-separated for multiple admins). Admin requires both platform authentication and this allowlist. The preview owner has been allowlisted.
  7. Test a card success with 4242 4242 4242 4242, a future expiry and any CVC; test a decline with 4000 0000 0000 0002. Use sandbox only. Verify the webhook changes status; opening the success URL alone must not.
  8. Resend a successful webhook twice. Confirm one payment, one paid participant, and unchanged gross. Refund in the Stripe dashboard and resend that event; net must subtract the refund exactly once.

Before real payments

  1. The organiser has confirmed that a private individual will receive and hold the funds, with final discretion over their use. The public disclosure does not name that individual. App promotion is the initial intention, but other uses are possible. Confirm that this disclosure remains accurate before accepting payments; the merchant account must still contain the recipient’s accurate identity.
  2. Complete merchant identity and bank verification, business-model approval, statement descriptor, support contact, refund policy, privacy contact and retention schedule.
  3. Run the provider tests above successfully. Decide the launch country scope and ad audience. Do not advertise the test preview as a live experiment.
  4. Create a fresh live dataset so test votes never become live social proof. Implement and review a deliberate live-mode release, including matching live event checks and keys; this version intentionally cannot accept live keys.
  5. Approve public access and a production domain, configure the live webhook destination, deploy the live release and verify settlement, fee retrieval and refunds with the recipient.

Data integrity & privacy

A random HttpOnly SameSite browser cookie identifies a response; only its hash is stored. Payment records are separate from optional participant details. Server-side same-origin checks, prepared SQL, a honeypot and coarse IP/time-window rate limits reduce abuse. They do not guarantee one person per vote: clearing cookies, switching browsers or devices and shared browsers affect uniqueness. Further bot protection may be needed before a large advertising campaign.

Income is annual household income in USD, self-reported and optional. Only the distribution among verified paid participants is exposed, after at least 100 completed payments. Missing income is “Not provided.” Paid status measures historical completion, so later refunds do not erase completion; dollar totals subtract refunds. The income distribution uses this same historical paid cohort. Small bracket counts may still reveal information when combined with outside knowledge; group small cells if launching with a sensitive audience.

Providing a city automatically includes a participant in nearby results, as disclosed before submission. Missing names display as Anonymous. No city means no nearby listing. Income, cookie hashes and payment identifiers never appear in nearby lists or shared cards. Clearing the cookie loses the self-service control; publish an organiser contact before launch for withdrawal requests. No card details are stored by this app.

Promotion concepts

01 / THE DIRECT ASK

Would you give $1?

A bold yellow screen with the question, then two equal choices. Copy: “Exactly US$1. No more, no less. Answer a small question about human nature. Taking part is free.”

02 / INTENT & ACTION

Saying yes is only half the story.

A split screen: “I would” / “I did.” Copy: “What happens between an answer and an action? Join a voluntary experiment. No payment required.”

03 / OPEN CURIOSITY

No right answer. Just yours.

A simple animated question mark resolves into $1. Copy: “With everything costing more, would you give $1 just because someone asked? See how people answer.”

Deployment and maintenance

The app runs as a Sites-hosted Cloudflare Worker with D1 persistence. Source, schema and migrations are versioned together. After source edits, generate migrations only for schema changes, run the build, save the source revision and publish the saved version. Environment changes require redeployment. Keep test and live datasets separate. Monitor failed webhooks and unknown fees; replay failed events. Expired rate-limit buckets should be purged on a retention schedule before a high-volume launch.

The public launch requires a fresh production release and the owner decisions above. There is no hidden “turn on real payments” switch.