You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a /shop route to the Gnars site to sell three kinds of things, with $0 fixed cost (only revenue-share payment fees, which the customer's payment covers):
Affiliate / external products — curated cards linking out to other stores (with ref params).
Native products / print-on-demand (dropshipping) — Gnars merch fulfilled by Printful, zero inventory, customer-funded per order.
Worldwide shipping — shipping cost baked into product price so the customer sees "free worldwide shipping" and the DAO is never out of pocket (no paid real-time-rate engine).
Build strategy
Many small phases, enabled one at a time, ordered by setup effort (easiest first). Each phase is independently shippable as its own PR and gated behind a feature flag / nav visibility so it can be turned on only when ready. Pure-code phases (no external accounts, no secrets) come first; phases needing third-party accounts come later.
Cost stance (hard requirement: $0 fixed cost)
Catalog + route: free, on existing Vercel deploy.
Printful: no monthly fee, pay-per-order (customer covers it).
Payments: Coinbase Commerce first (~1%, USDC → treasury) — cheapest per sale, no chargebacks, lands in the DAO treasury, fits Base/thirdweb. Stripe Payment Links (~2.9% + $0.30) added later to capture non-crypto buyers.
No processor takes 0% — that cut comes out of margin, priced into products.
Payment decision (locked for v1): crypto-first with Coinbase Commerce; Stripe as a fast-follow.
Any DB work mirrors src/services/rounds.ts: lazy pg Pool, isXConfigured() guard, env precedence, server-only, auto-create tables. Reuse the existing Postgres — no new infra/cost.
New data access lives in src/services/shop.ts (canonical layer).
Server Components for load/SEO; Client Components only for cart/checkout interaction.
i18n: all UI strings via next-intl, EN + PT-BR in the same change.
Address/profile links → internal /members/[address], never Basescan.
Each phase ships behind a flag so it can be enabled independently.
Phase 1 — Affiliate catalog (easiest: pure code, no accounts, no DB)
Goal: a live /shop showing curated external products that link out. Nothing to buy on-site.
P5: test payment → Printful test order placed via webhook; worldwide shipping confirmed.
P6: card payment routes to same fulfillment; order shape consistent.
P7: order persists idempotently; member purchase view renders.
Notes
Living plan. Each phase is re-planned and this issue updated with concrete details (file lists, decisions, supplier choices) as we go. Phases ship one at a time, each flag-gated.
Summary
Add a
/shoproute to the Gnars site to sell three kinds of things, with $0 fixed cost (only revenue-share payment fees, which the customer's payment covers):Build strategy
Many small phases, enabled one at a time, ordered by setup effort (easiest first). Each phase is independently shippable as its own PR and gated behind a feature flag / nav visibility so it can be turned on only when ready. Pure-code phases (no external accounts, no secrets) come first; phases needing third-party accounts come later.
Cost stance (hard requirement: $0 fixed cost)
Payment decision (locked for v1): crypto-first with Coinbase Commerce; Stripe as a fast-follow.
Conventions to follow (this repo)
src/data/installations.jsonshape (id,slug, ...).src/services/rounds.ts: lazypgPool,isXConfigured()guard, env precedence,server-only, auto-create tables. Reuse the existing Postgres — no new infra/cost.src/services/shop.ts(canonical layer)./members/[address], never Basescan.Phase 1 — Affiliate catalog (easiest: pure code, no accounts, no DB)
Goal: a live
/shopshowing curated external products that link out. Nothing to buy on-site.src/data/shop.json— schema:id,slug,title,description,images[],priceUSD,type: "affiliate",externalUrl,tags[],status.src/services/shop.ts(server-only) — read + filter catalog./shoproute (server component) — product grid, mirrors existing feature-page layout + skeletons.src/components/shop/product card — affiliate cards link out with ref param.Setup needed: none. Deliverable: PR.
Phase 2 — Native product showcase (pure code, no checkout)
Goal: show Gnars merch as a static catalog +
/shop/[slug]detail pages. No cart yet; CTA can be "coming soon" or a temporary external link.shop.jsonwithtype: "native"items + detail fields./shop/[slug]product detail (server component).Setup needed: none. Deliverable: PR.
Phase 3 — Client-side cart (pure code, no backend)
Goal: add-to-cart and cart drawer for native products. State in localStorage/React only.
Setup needed: none. Deliverable: PR.
Phase 4 — Crypto checkout via Coinbase Commerce (first external account)
Goal: customers can actually pay in USDC; revenue lands in the treasury. Fulfillment is manual at this stage.
env.example).Setup needed: 1 account (Coinbase Commerce). Deliverable: PR. Fulfillment handled manually until Phase 5.
Phase 5 — Printful POD auto-fulfillment (second external account + webhook)
Goal: paid orders are placed with Printful automatically and shipped worldwide.
Setup needed: 1 account (Printful) + webhook secret. Deliverable: PR.
Phase 6 — Card checkout via Stripe Payment Links (capture non-crypto buyers)
Goal: add a card payment option alongside crypto.
Setup needed: 1 account (Stripe). Deliverable: PR.
Phase 7 — DAO-native order tracking (reuses existing Postgres)
Goal: own order data and tie purchases to member identity. Still $0 (DB already exists for rounds).
shop_orderstable via therounds.tspattern (lazy pool,isShopDatabaseConfigured()guard, auto-create).order ↔ wallet address; surface purchases in/members/[address].Setup needed: none beyond existing DB. Deliverable: PR. On-brand DAO feature; defer until earlier phases are validated.
Test plan (per phase)
/shoprenders via Server Components, affiliate out-links work, mobile verified, EN + PT-BR present,pnpm lint+pnpm format:checkclean./shop/[slug]detail renders for native + affiliate items.Notes
Living plan. Each phase is re-planned and this issue updated with concrete details (file lists, decisions, supplier choices) as we go. Phases ship one at a time, each flag-gated.
Generated with Claude Code