Developer payments and auth
Developer notes on the payment provider boundary, NMI proof of concept, and Supabase auth integration.
Developer payments and auth
This page describes the implementation direction behind the client-facing payment and member pages.
Payment provider boundary
The API has a provider boundary for checkout.
Current provider modes:
pay-at-pickup: default mode for pickup hold requestsnmi: sandbox mode for NMI Payment Component checkout
The web app asks the API for checkout configuration before deciding how to proceed. This avoids hard-coding one processor as the only possible production path.
Server-side cart validation
The browser cart is convenient state, not trusted state.
Before checkout, the API rebuilds the cart from known product and variant records. It verifies:
- product exists
- variant exists
- quantity is valid
- stock limit is not exceeded
- subtotal comes from server-known prices
That pattern should remain when the demo catalog is replaced by Supabase tables or a point-of-sale source.
NMI proof of concept
The NMI sandbox integration proves the intended online payment shape:
- Shopper builds a cart.
- API creates a checkout session.
- Web app displays the NMI Payment Component.
- NMI tokenizes payment details in the browser.
- Web app sends the payment token and cart to the API.
- API validates the cart and attempts the sandbox sale.
- Shopper returns to the checkout status page.
The important security property is that raw card details do not flow through the React app or the Hono API.
Why not Stripe or Square as the only path
Stripe and Square are both strong products, but they are not safe to assume as the sole ecommerce processor for this storefront.
Stripe's public policy treats tobacco and e-cigarette products as restricted and cannabis products as prohibited. Square's payment terms restrict internet, mail, and telephone order sales of age-restricted products such as tobacco.
The current architecture keeps processor-specific work isolated so the project can adapt without rewriting the storefront.
Auth boundary
The web app uses the Supabase browser client for customer sessions.
The API does not trust the browser just because the browser says a user is signed in. Protected API routes require a bearer token. The Hono API verifies that token before returning member data.
Current member route:
GET /me: verifies the Supabase access token and returns the member profile shape
Current member UI:
/auth/login/auth/sign-up/auth/callback/locker
OAuth support exists in code, but the visible provider buttons are gated off in source config until the production provider setup is confirmed.
Future database tables
Likely Supabase tables:
profilessaved_productspickup_requestspickup_request_itemsreward_ledgermember_notes
The first production version should keep this narrow. Saved products and pickup requests are more valuable than a complicated rewards system on day one.