Proposed MVP · October 1, 2026
Your inventory is already here.
Now give dealers the keys.
A branded, passwordless entry into ONLYEV. Connect each dealer to the inventory we already imported, then show leads and the right billing status.
Specification + visual example only. This page is public and needs no login to read. It does not send codes, take payments, or connect to live dealer data. Routes below are proposed, not confirmed live. Share this page in Slack. The full handoff and short brief are available below.
The entire dealer journey
Open their branded linkONLYEV + their dealership name. One reusable page.
Verify an approved contactEmail OR mobile. A code, not a password.
See what is already theirsExisting inventory, leads, and billing.
Activate advertising, only if unpaidAlready paying? No extra charge. Not subscribed? Explicit $199/month Checkout.
Do not rebuild the marketplace.
Do not make dealers upload their vehicles again.
Welcome,
Motorpoint.
Your EV inventory is already here. Sign in to view your listings, leads, and billing.
Visual example · Reuse actual ONLYEV brand assets
1. Copy/paste kickoff
Build a mobile-first ONLYEV dealer activation and login flow on www.onlyev.com for our approximately 10 existing advertising dealers. We already have their EV inventory. Do not ask them to sign up from scratch, enter their website again, or re-upload vehicles.
Give each dealer a branded login link. They verify an approved email OR mobile number using a one-time code, then land in a simple dashboard with their existing inventory, leads, and billing.
Reuse our current dealer records, authentication, inventory imports, and Stripe setup. Dealers already paying go straight in without another charge. Dealers not subscribed can review their inventory and explicitly activate advertising at $199/month. Keep dashboard access separate from paid advertising status. Pilot with Motorpoint before inviting the rest.
2. Routes and branding
Create one reusable page, not 10 separate builds:
- General login:
https://www.onlyev.com/dealers/login - Branded example:
https://www.onlyev.com/dealers/login?dealer=motorpoint - Authenticated dashboard:
https://www.onlyev.com/dealers/dashboard
Use the existing ONLYEV logo, fonts, and colors. Resolve the dealership display name and optional logo from its existing record; “Motorpoint” is an example, not a request to rename any record. A dealer slug changes branding only. It must never grant account access.
The public homepage currently links Sign in to portal.onlyev.com [1]. Inspect and reuse the existing account/backend setup. Add a clearly labeled Dealer Login link in the Dealers navigation. Keep consumer sign-in working. The requested dealer experience should live on www.onlyev.com; do not create a second set of users or silently replace it with a different-domain flow.
3. What the dealer sees
Screen A — Branded login
ONLYEV | Dealer dashboard
Welcome, Motorpoint.
Your EV inventory is already here. Sign in to view your listings, leads, and billing.
[ Email | Phone ]
Email address OR mobile number
[ Send my code ]
No password needed. Use the email or mobile number connected to your dealership. Need access? Contact ONLYEV.
Default to Email and provide an equally clear Phone option. Ask for only one method at a time. Use large controls, the correct mobile keyboard, and accessible labels. Do not display a contact list or private account details before verification.
Screen B — Verify code
Enter your sign-in code.
One input that accepts the full code, supports paste and mobile code autofill, plus [ Open my dashboard ]. Include Change email/phone, resend with a cooldown, and clear expired/incorrect-code feedback. Do not make the dealer type a password or complete a profile wizard.
Screen C — Dashboard
Use three navigation items only:
| Area | MVP content |
|---|---|
| Inventory | Their existing EVs, accurate listing status, listing links, and last successful sync time. Reuse current import jobs. A simple Report an issue action is enough; no new price/photo editor. |
| Leads | Existing leads for this dealer, vehicle context, and mobile-friendly call/email/text actions where that contact information is available. Preserve current lead delivery; show where alerts are sent. |
| Billing | $199/month plan, actual status, renewal or paid-through date, and Activate advertising or Manage billing as appropriate. |
Show only real counts and dates. An empty state must say there are no leads yet, not display fake activity. Keep the dealer's inventory visible inside its dashboard even when paid advertising is inactive. Existing leads and billing remain accessible after cancellation.
Do not add cash-offer buying tools, AI-assistant upsells, a DMS, advanced analytics, a new feed, or a multi-step onboarding wizard to this release.
4. Account preparation — do this before sending invitations
Manually reconcile this small cohort rather than building a public “claim any dealership” flow.
- Locate each existing dealer/rooftop ID and confirm that the correct imported vehicles and leads already belong to it. Preserve record IDs and the current import source.
- Confirm the authorized owner/manager contact with Adam: email and, where supplied, an SMS-capable mobile number. A public dealership switchboard or website email alone is not proof of authority.
- Reuse an existing auth user or pre-provision an invited user server-side, then attach a dealer membership. An imported dealer record is not itself an authentication account. Pre-provisioning must not bypass the recipient's OTP verification.
- Support email and phone for the same authorized person without creating a second dealer or subscription. Verify each channel before enabling it. Handle existing identity conflicts through an authenticated/admin-reviewed linking flow, not an automatic merge based on name or domain.
- Reconcile existing Stripe customer/subscription IDs, prepaid invoices, agreed trials, and any special arrangement. Mark unresolved billing for manual review; do not suspend or double-charge these dealers during migration.
- Add a small view in the existing admin area: dealer, authorized contact, inventory count, invitation status, first login, billing status, paid-through date. Actions: Copy login link and Send/resend invitation. No new CRM required.
Use the current schema where it supports this. The required relationship is authenticated user → dealer membership → existing dealer ID → that dealer's inventory, leads, and billing. Users must not be able to edit their own membership, owner role, or Stripe mapping.
5. Login and access — developer implementation notes
Use the existing Supabase authentication project rather than writing an OTP system. Supabase supports email codes and phone codes [2,3]. Use its code verification/session handling and configure branded production email delivery through the current email provider/custom SMTP [4]. Phone login also requires a configured SMS provider [3].
For this invited cohort, pre-provision/link users before sending login invitations and use shouldCreateUser: false for the login requests [2]. Do not accidentally disable public consumer signup globally. An unknown contact must never automatically become a dealership member.
For email, include {{ .Token }} in the appropriate template to deliver a code [2]. Check existing consumer magic-link flows before changing shared templates. Use the configured code length and expiry consistently in the UI and message. Configure short-lived codes, resend/verification rate limits, abuse protection, and an SMS spending limit. Never log codes or place OTP/session secrets in URLs or analytics.
Use a neutral response for unknown contacts and provide a support route. Verify the code, then check the server-side membership. If a logged-in user opens a different dealer's branded link, never switch their permissions or expose that dealer's private data. Revoked memberships must fail even if an old session remains valid.
Protect dealer-owned data with server authorization and Supabase row-level security [5]. Test direct API/database requests, not just hidden buttons. Public listing data can remain public under existing policies; private leads, contacts, billing, and inventory mutations must be tenant-restricted. Keep service-role and Stripe secrets server-side. Only the authorized owner/admin can open billing management or create Checkout sessions.
6. $199/month billing
Use the existing Stripe account, a server-selected recurring USD $199 advertising price, Stripe Checkout for activation, and the customer portal for card updates, invoices, and cancellation [6,8]. One advertising subscription per dealer/rooftop. Keep AI and cash-offer fees separate.
| Dealer state | Show | Required behavior |
|---|---|---|
| Existing paid subscriber | Advertising active + Manage billing | Link existing subscription. No new Checkout, charge, or restarted billing period. |
| Prepaid / agreed trial / unresolved migration | Actual entitlement or Being reviewed | Preserve the agreed paid-through/trial date or current access while Adam reviews it. No automatic new trial or charge. |
| Confirmed not subscribed | Activate advertising — $199/month | Let the dealer inspect its own dashboard, then explicitly accept recurring payment in Checkout. Do not charge merely for logging in. |
| Payment requires action / past due | Update payment | Preserve account access. Use a configurable grace period; proposed new-policy default: 7 days, applied only after Adam approves the migration. |
| Canceled | Advertising ends [date] | Proposed default: cancel at period end. Then pause paid advertising, not the account, stored inventory, or historical leads. |
Before activation, display the monthly recurring price and cancellation terms clearly. Honor existing commercial agreements; do not silently introduce an inventory cap or alter a legacy plan. Do not promise a new free trial in this cohort invitation.
Create Checkout/portal sessions server-side from the authenticated dealer membership. Never trust a browser-supplied dealer ID, amount, or Stripe customer ID. Prevent duplicate subscriptions from repeat clicks, multiple tabs, or retries; reuse a pending session where appropriate and use a server-side lock/idempotency controls.
Confirm payment and subscription state using signature-verified Stripe webhooks, not the success-page redirect [7]. Handle paid invoices, payment failures, and subscription changes/deletions. Make handlers replay-safe, reconcile the latest Stripe state for out-of-order events, and keep advertising entitlement separate from login access. Test failed/abandoned Checkout, retries, renewal, and cancellation.
7. Launch order and definition of done
Prepare: Reconcile the approximately 10 dealer records, authorized contacts, inventory ownership, and existing billing before invitations.
Pilot: Test Motorpoint using its actual approved contact. Verify both login methods if both are enabled, confirm inventory and lead mapping, and test the appropriate paid/unpaid billing path. Use Stripe test mode for test charges; never create an extra live subscription for the pilot.
Roll out: Invite the remaining dealers only after the pilot passes. Adam can send the personalized links himself. Track invited → first successful login → subscription active; do not count a login as a paid conversion.
Release checklist:
- Branded page works on a narrow mobile screen; code paste/autofill and resend/error states work.
- Approved email and approved phone reach the same correct dealership.
- Expired/incorrect codes, unknown contacts, revoked users, and forwarded links cannot expose another dealer's account.
- Dealer A cannot read Dealer B's leads or billing, or edit Dealer B's inventory, via URL or direct API changes.
- Inventory counts and record IDs match before/after activation; no duplicate import or broken sync.
- Paid/prepaid dealers are not charged twice or unexpectedly suspended.
- A new subscription is $199/month with explicit acceptance; repeated Checkout/webhook requests do not create duplicate billing.
- Failed payments and cancellations affect advertising entitlement, not login or historical leads.
- Existing consumer login and lead-delivery flows still work.
- Production email/SMS delivery works, secrets stay server-side, and the admin view shows real activation and payment status.
At 10 paying dealers, gross monthly subscription revenue is 10 × $199 = $1,990, before expenses and payment fees. This is total cohort revenue, not necessarily incremental revenue from dealers who already pay.
8. Dealer invitation copy — send only after the page is live
Already paying
Hi [Name] — your ONLYEV dealer dashboard is ready. Your EV inventory is already connected. Use your email or mobile number to receive a sign-in code and view your listings, leads, and billing. No password and no need to upload your vehicles again.
[Personalized live dealer login link]
Not yet subscribed
Hi [Name] — your EV inventory is already loaded into ONLYEV. Open your dealer dashboard, review your listings, and activate advertising for $199/month when you are ready. Sign in with an email or text code. No password and no re-uploading inventory.
[Personalized live dealer login link]
Sources & implementation references
Public navigation and official vendor documentation reviewed October 1, 2026. Product requirements and commercial defaults are recommendations; private code and billing records have not been audited.
[1] OnlyEV public navigation — existing Sign in points to portal.onlyev.com
https://www.onlyev.com/
[2] Supabase — passwordless email codes
https://supabase.com/docs/guides/auth/auth-email-passwordless
[3] Supabase — phone codes and SMS-provider setup
https://supabase.com/docs/guides/auth/phone-login
[4] Supabase — production email / custom SMTP
https://supabase.com/docs/guides/auth/auth-smtp
[5] Supabase — row-level security
https://supabase.com/docs/guides/database/postgres/row-level-security
[6] Stripe — subscriptions with Checkout
https://docs.stripe.com/payments/checkout/build-subscriptions
[7] Stripe — subscription webhooks
https://docs.stripe.com/billing/subscriptions/webhooks
[8] Stripe — customer billing portal
https://docs.stripe.com/customer-management