Detective checkout — revised proposal

A pared-back version of the v1 mockup, focused only on changes we can ship now with high confidence. Mockups emulate the actual 529 UI (Baloo 2, yellow primary, rounded pill buttons, white cards on grey) so the team can see what the live screens will look like, not a hypothetical redesign.

Sequenced as v1 — ship now (three copy/template wins, no Stripe or auth changes) and v2 — next (enable Apple Pay and Google Pay once Brett has confirmed the prerequisites). Anything that still needs an answer before we can scope it sits in the verify-later list at the bottom.

v1 · Ship now v2 · Next iteration Verify before committing
Win 1 of 3 Ship now · copy + content only

Confirm & Checkout: tell people what they're buying

No structural changes to the form. Two surgical edits in app/views/memberships/new.html.haml: replace the bare pricing line with a content block that names the marketplaces and frequency, and change the submit button label so it stops calling a one-time purchase a subscription.

Live today
9:415G
Back to Plans

Confirm & Checkout

529 Detective
529 Detective
Bike stolen? Smart detection. Faster recovery.
$25$50
Email Address
you@email.com
Postal code
Enter your postal code…
Phone number
Enter your phone number…
529 Detective (One-time purchase, 6 months unlimited access) $50.00
Discount−$25.00
Total$25.00
[ Stripe Payment Element ]
Subscribe
Secure payment powered by Stripe
Proposed
9:415G
Back to Plans

Confirm & Checkout

529 Detective
529 Detective
Bike stolen? Smart detection. Faster recovery.
$25$50
Email Address
you@email.com
Postal code
Enter your postal code…
Phone number
Enter your phone number…
529 Detective
One-time purchase. 6 months. Does not auto-renew.
$50.00
Discount−$25.00
Total$25.00
  • Scans Craigslist, Facebook Marketplace, eBay, OfferUp, Kijiji, Pinkbike
  • Twice-daily checks for 6 months — covers the months thieves wait to resell
Multiple bikes stolen? One purchase. Detective searches for all of them.
[ Stripe Payment Element ]
Pay $25 — Activate Detective
Secure payment powered by Stripe
Why this slice: the two highest-leverage problems on this screen are (a) "Subscribe" on a one-time purchase and (b) the user not knowing concretely what they get. Both are pure content edits — no JS, no Stripe config, no schema changes — so they're safe to ship without a verify step.
  • Button label. The submit button's text comes from the subscribe i18n string in memberships.js's membershipTexts. We need a separate string for Detective rather than overloading the existing one (Protect is a real subscription and should keep "Subscribe"). The button render in new.html.haml:616 is plan-agnostic today — needs a small conditional.
  • Pricing block. Replace the inline parenthetical "(One-time purchase, 6 months unlimited access)" in new.html.haml:579 with a meta line + the three reason bullets. Cosmetic; no controller change.
  • Note also: the section heading on line 526 currently reads "Subscription Cost Summary" even when only Detective is on the page. Change to "Order Summary" for the Detective-only render.
Files: app/views/memberships/new.html.haml · app/assets/javascripts/memberships.js
Win 2 of 3 Ship now · single template rewrite

Activation: tell people what to do next

The biggest gap in the live flow. After paying, users land on a generic thank-you and then have to figure out for themselves that Detective can't actually do anything until they file a stolen-bike alert. This template is rewritten to give the user one clear next step, set realistic timing expectations, and offer side-by-side things to do while Detective scans.

Live today
9:425G
Back to Garage
Detective
529 Detective Activated
Thank you for being a part of the fight against bike theft.
You have not yet registered any missing bikes.
What would you like to do next?
Search using Detective
Add a bike
Proposed
9:425G
Back to Garage
Detective
Tell us which bike to search for
Detective scans Craigslist, Facebook Marketplace, eBay, OfferUp, Kijiji, and Pinkbike twice daily for 6 months. We email you when a listing matches.
Start a stolen bike alert
First scan results appear within 24 hours. Stolen bikes often surface weeks or months after theft — that's why Detective scans for 6 months.
While Detective scans, you can:
  • 1Report your bike to the police
  • 2Post in your local bike-recovery Facebook group
  • 3Add the serial number and photos to improve matching
Why this slice: the live template is doing two things badly — congratulating the user, and offering generic next-steps with no urgency. Without filing an alert, the $25 they just paid does nothing. Replacing the template is a one-file change.
  • Single file. app/views/memberships/success_detective.html.haml. The "Search using Detective" button (live) is a dead-end if the user has no missing bike — replace with the existing quick_panic_bikes_path, which is already used as the "Start an Alert" target on the empty Detective dashboard.
  • What I dropped from v1. The "set a password / skip for now" block was in the original mockup. Devise doesn't ship passwordless login, so the "skip" option needs a real auth design (see verify-later #3). Keeping it out of this slice — the existing post-checkout password flow stays as-is.
  • Stat caveat. The "police-reported bikes are 2–3× more likely to be returned" line from v1 is omitted here until we have a citation we're willing to publish.
File: app/views/memberships/success_detective.html.haml
Win 3 of 3 Ship now · header copy + status banner

Detective dashboard: be specific, show the expiry

The current dashboard tells the user Detective is "constantly on the lookout" across some marketplaces and that matches are "updated frequently". Both are vague, and neither tells the user when their access ends. Two changes: name the marketplaces and frequency in the header copy, and add a status banner with the expiry date.

Live today
9:435G
Back to Garage

529 Detective

The 529 Detective is constantly on the lookout for bikes across 6 online marketplaces. New matches are updated frequently so we recommend checking back often.
No Missing Bikes Found
We could not find any bikes reported missing in your garage. Click on the button below to report a missing bike.
Start an Alert
Proposed
9:435G
Back to Garage
Detective

529 Detective

Detective scans Craigslist, Facebook Marketplace, eBay, OfferUp, Kijiji, and Pinkbike twice daily. We email you the moment a listing looks like your bike.
Ready to start scanning
File a stolen-bike alert and Detective begins searching the marketplaces for your bike.
Start an Alert
Why this slice: users currently have no in-product confirmation of what they have or when it expires. The empty-state title also reads like a result ("No Missing Bikes Found") rather than a prompt — a small word change with measurable confusion impact.
  • Header copy. Replace the two _( … ) strings at app/views/detectives/index.html.haml:24-25. The marketplace names should pull from the same source the count comes from (so they don't drift) — likely a model method on the marketplace scope already used to compute @active_marketplace_count. Worth checking with Brett.
  • Empty-state copy. Lines 42–46 of the same file. Pure string change.
  • Status banner with expiry. Needs a controller addition: surface the user's active Detective access end-date. The data exists (Stripe charge + 6-month TTL) but I don't think it's exposed to DetectivesController#index today. This is the only piece in the ship-now bucket that touches Ruby — flag for Brett to confirm scope. If it's a half-day or less, it goes in. If it surfaces anything ugly, this single banner moves to verify-later and the rest of Win 3 ships without it.
File: app/views/detectives/index.html.haml · controller: DetectivesController#index
v2 · next iteration Apple Pay / Google Pay

v2: enable Apple Pay and Google Pay

Once v1 ships, this is the next change worth making. 94% of paid traffic is mobile and the live checkout has wallets explicitly disabled (memberships.js:25-29). For users with a wallet set up, this collapses checkout from a full form to a single tap. The code change itself is tiny — the work is in the prerequisites (see verify-later #1).

v2 — wallets enabled
9:415G
Back to Plans

Confirm & Checkout

529 Detective
529 Detective
Bike stolen? Smart detection. Faster recovery.
$25$50
529 Detective
One-time purchase. 6 months. Does not auto-renew.
$25.00
  • Scans 6 marketplaces twice daily for 6 months
  • Covers every missing bike on your account
Or pay with card
Email Address
you@email.com
Postal code
Enter your postal code…
Multiple bikes stolen? One purchase. Detective searches for all of them.
[ Stripe Payment Element — card form ]
Pay $25 — Activate Detective
Secure payment powered by Stripe
What changes
  • Wallet buttons at top. Apple Pay and Google Pay render via the Stripe Payment Element when applePay: 'auto', googlePay: 'auto'. Stripe handles device detection and only shows the relevant button.
  • "Or pay with card" divider. Standard pattern — keeps the card form available for users without a wallet.
  • Email + postal still collected on the card path. For wallet users, contact details come from the wallet token (no need to type). For card users, the form behaves exactly as it does in v1.
  • Multi-bike callout stays. Same message, same position, both flows.
Cost note (correcting v1). Stripe processes wallet payments at the same fee as cards — there's no "up to 20%" wallet surcharge. v1 doc had this wrong.
Prereqs before this can ship — see verify-later #1:
· Stripe wallet enablement for US/CA
· Apple Pay domain verification
· Test that toggling wallets on Detective doesn't affect Protect (shared file)
Still open

Verify before committing

Items from the v1 mockup that need an answer from someone before we can scope them. Apple/Google Pay sits here too — the code change is small, but the prerequisites belong to Brett.

#
Item
What we need to confirm
Owner
1
Prerequisites for v2 (wallets)
v2 mockup above shows the destination. Code change itself is one line — flip applePay/googlePay from 'never' to 'auto' in memberships.js:25-29, gated to the Detective code path. Before we can do that, Brett to confirm: (a) Stripe account is wallet-enabled for US/CA, (b) Apple Pay domain verification is registered for our domain, (c) the Detective branch of memberships.js can be isolated from the Protect flow (which shares the file). Once those land, v2 ships in well under a day.
Brett
2
Phone-number field on Detective checkout
v1 stated "phone is required" — for Detective specifically it isn't required in the live form (new.html.haml:381). Question: do we want it removed entirely, kept optional, or repurposed? Removal is trivial but the "share with law enforcement" checkbox below it depends on the field existing.
Product
3
Optional / passwordless account creation
v1 proposed making the password field skippable with a magic-link login as the alternative. Devise (which we use) doesn't ship passwordless out of the box. Options: devise-passwordless gem, a custom signed-token flow, or keep mandatory and just improve the copy. Needs a 30-min Brett scope before we know which is realistic.
Brett
4
Abandoned-checkout email recovery
"Send me a link if I don't finish" checkbox needs server-side email persistence before payment, a queued reminder job, unsubscribe handling, and CAN-SPAM/CASL compliance. Several days of work for a $25 product. Worth doing eventually but not bundled here.
Defer
5
"Subscription Cost Summary" / "Cancel Membership" / "Update Plan" labels on adjacent pages
The membership management screens (memberships/show.html.haml, edit page) still use subscription language for Detective, which is one-time. Worth a separate sweep — touches more templates than the three in this slice and the end-state probably needs Detective to render a different management page entirely.
Product · separate ticket
6
"2–3× more likely to be returned" stat
Quoted in the v1 confirmation page mockup as "peer-reviewed and approved". Need the actual citation in our hands before we publish it on a payment page. Until then, the proposed Win 2 confirmation page omits the stat.
Marketing