# NORA — Sponsor Portal ## What I'm Working On - OTP login deployed, John testing ## Sponsor Features Status - Sponsor login: LIVE — OTP via SMS (no passwords), phone or email - Sponsor registration: LIVE — OTP verify → business profile form - Token purchases: LIVE (api/sponsor/buyTokens.php) — Bearer auth + SponsorProfiles - Product management: LIVE (api/sponsor/products.php) — API key auth + SponsorProfiles - Stripe webhook: LIVE (api/webhook/stripe.php) — credits SponsorProfiles - OTP send: LIVE (api/sponsor/sendOTP.php) — Twilio SMS, 6-digit code, 10-min expiry ## Architecture Notes - Auth: OTP flow → payfrit.OTPCodes table → payfrit.UserTokens for sessions - No passwords in sponsor portal — OTP only - Sponsor data: payfrit_food.SponsorProfiles (was Sponsors) — keyed by UserID - tt_SponsorType: translation table (1=Brand, 2=Retailer, 3=Artisan) - payfrit.Users.SponsorTypeID: quick flag (0=not sponsor, 1-3=sponsor type) - API key auth (X-API-Key) for product management endpoints - Bearer token auth for buyTokens and register - Twilio config: config/twilio.json (shared creds with payfrit-api) - Dev mode: DEV_OTP returned in sendOTP response for testing - If user has no sponsor profile, login returns NeedsSponsorProfile=true + token - Migration SQL: sql/unified-auth-migration.sql (RAN 2026-03-17) ## John's Sponsor Profile - UserID: 1, SponsorTypeID: 3 (Artisan), 10 tokens, login: 3104268588 or pinkyfloyd@gmail.com ## Notes From John - food.payfrit.com is the consumer-facing WordPress site - Sponsor portal at food.payfrit.com/portal or similar - John wants OTP login only, no passwords - John requested field labeled "Phone / Email" - John requested tt_SponsorType translation table