Merchant Onboarding
Step-by-step guide to onboard a new merchant store on the Prood platform.
This guide walks through onboarding a new merchant from registration to a live storefront with custom domain and payment processing.
Overview
Drag to pan · Scroll to zoom
Estimated time: 30–60 minutes (excluding DNS propagation).
Step 1 — Register
- Navigate to the dashboard:
https://dashboard.prood.com/register(or yourNEXT_PUBLIC_DASHBOARD_URLin dev) - Enter email, password, and store name
- Better Auth creates:
- A
userrecord - An
organizationrecord (the store — e.g. slugacme-store) - A
memberrecord (user asowner)
- A
The organization ID (e.g. org_abc123) becomes the tenant key for all commerce data.
Step 2 — Configure store settings
- Go to Settings (
/settings) - Set store name, default currency, and contact information
- These values appear on the storefront via
GET /v1/store
Step 3 — Add products
- Go to Products → New product (
/products/new) - Fill in:
- Name and description (localized if multi-language)
- Slug (URL path)
- At least one variant with SKU, price, and inventory
- Product images (uploaded via storage provider)
- Categories
- Set status to Published
- Repeat for additional products
Verify products appear in the API:
curl -H "Host: acme-store.prood.app" \
https://api.prood.com/v1/productsStep 4 — Configure payments
- Go to Integrations (
/integrations) - Select your payment provider (Stripe recommended for global, Easypay/Ifthenpay for Portugal)
- Enter provider credentials:
Stripe
| Field | Where to find |
|---|---|
| Secret key | Stripe Dashboard → Developers → API keys |
| Publishable key | Same page |
| Webhook secret | Stripe Dashboard → Webhooks → Signing secret |
Easypay
| Field | Where to find |
|---|---|
| Account ID | Easypay merchant panel |
| API key | Easypay merchant panel |
- Save — credentials are encrypted and stored per organization
Step 5 — Set up webhooks
Configure the payment provider to send webhooks to:
https://checkout.prood.com/api/webhooks/{provider}/{orgId}See Webhook setup for provider-specific instructions.
Step 6 — Add domain
Subdomain (automatic)
The store is immediately available on the platform subdomain — no dashboard action required:
Drag to pan · Scroll to zoom
Custom domain
- Go to Domains (
/domains) - Enter custom domain:
shop.acme.com - Add DNS records at your registrar:
| Type | Name | Value |
|---|---|---|
| CNAME | shop.acme.com | cname.vercel-dns.com |
- Wait for DNS propagation (up to 48 hours, usually minutes)
- Dashboard shows verification status
- Once verified, storefront serves at
https://shop.acme.com
Requires Vercel domain provisioning env vars (VERCEL_TOKEN, STOREFRONT_VERCEL_PROJECT_ID).
Step 7 — Invite team members
- Go to Team (
/team) - Invite colleagues by email with appropriate role:
- Admin — full store management
- Member — read-only (future fine-grained permissions)
Step 8 — Test the full flow
- Visit the storefront (subdomain or custom domain)
- Browse products — verify catalog loads
- Add item to cart
- Proceed to checkout
- Complete payment with test credentials
- Verify order appears in dashboard Orders
- Test refund flow (optional)
Test checklist
- Storefront loads with correct store name and products
- Cart add/update/remove works
- Checkout form collects address and contact info
- Payment completes (Stripe test card or Easypay sandbox)
- Order appears in dashboard with correct status
- Webhook updates order from
pendingtoconfirmed - Custom domain resolves (if configured)
- Team member can sign in and access dashboard
Step 9 — Go live
- Switch payment provider from test/sandbox to production keys
- Update webhook URLs to production endpoints
- Remove
DEFAULT_TENANT_ORG_IDif set (ensures strict host resolution) - Verify SSL certificates are active on all domains
- Monitor first real orders in dashboard
Data isolation verification
After onboarding, verify the new merchant's data is isolated:
-- Connect to Neon Postgres
SELECT set_config('app.current_org_id', 'org_new_merchant', false);
SELECT count(*) FROM products; -- only their products
SELECT set_config('app.current_org_id', 'org_demo', false);
SELECT count(*) FROM products; -- only demo products