Dual Authentication & Seller Verification¶
SCOPE_ITEM: Authentication system that supports both buyer and seller roles, handles seller identity verification (KYC), and builds platform trust through verification levels and trust scores.
Decision Tree¶
IF: Marketplace allows anyone to become a seller. THEN: Implement self-service seller registration + KYC via PSP.
IF: Marketplace curates sellers (invite-only or application). THEN: Implement seller application flow + manual review + KYC via PSP.
IF: Marketplace is B2B only. THEN: Implement company verification (CoC/KVK lookup) + KYC via PSP.
IF: Users can be both buyer AND seller. THEN: Implement dual-role accounts with role switching.
Buyer Accounts¶
Registration¶
SCOPE_ITEM: Low-friction buyer account creation.
INCLUDES: - Email + password registration (minimum 12 characters, bcrypt cost 12). - Social login: Google OAuth 2.0, Apple Sign In. - Email verification (magic link, 24h expiry). - Basic profile: name, email (verified), optional shipping address. - Terms of service and privacy policy acceptance (timestamped).
OPTIONAL: - Phone number with SMS verification. - Profile photo upload. - Saved payment methods (stored at PSP, not in our DB).
CHECK: Social login must request minimal scopes (email, name only). CHECK: Password strength check against breached password list (HaveIBeenPwned API, k-anonymity model).
Buyer Profile Data Model¶
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT UNIQUE NOT NULL,
email_verified BOOLEAN DEFAULT false,
password_hash TEXT, -- null for social-only accounts
name TEXT NOT NULL,
avatar_url TEXT,
phone TEXT,
phone_verified BOOLEAN DEFAULT false,
roles TEXT[] DEFAULT '{buyer}', -- buyer, seller, admin
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
last_login_at TIMESTAMPTZ
);
Seller Accounts¶
Seller Registration Flow¶
SCOPE_ITEM: Seller onboarding with identity and business verification.
Buyer account exists
└── "Become a seller" action
└── Step 1: Business information
│ - Business name
│ - Business type (sole trader, BV, VOF, etc.)
│ - CoC/KVK number (NL) or equivalent
│ - VAT number (optional, validated format)
│ - Business address
└── Step 2: Identity verification (delegated to PSP)
│ - Stripe Connect onboarding flow, OR
│ - Mollie Connect OAuth onboarding flow
│ - PSP collects: ID document, selfie, proof of address
│ - PSP handles KYC compliance
└── Step 3: Payout details
│ - IBAN (validated format, EU banks)
│ - Account holder name
│ - Verified via micro-deposit or PSP verification
└── Step 4: Seller agreement acceptance
│ - Platform terms for sellers (timestamped)
│ - Commission structure acknowledgement
└── Status: Pending verification
└── PSP webhook: verification approved → seller active
└── PSP webhook: verification failed → notify, retry
CHECK: NEVER store identity documents (passport, ID card) in our database.
KYC documents are collected and stored by the PSP (Stripe/Mollie).
CHECK: IBAN validation: use iban npm package for format + checksum.
CHECK: KVK number validation: 8 digits, optionally verify via KVK API.
Seller Profile Data Model¶
CREATE TABLE seller_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID UNIQUE REFERENCES users(id),
business_name TEXT NOT NULL,
business_type TEXT NOT NULL, -- sole_trader, bv, vof, etc.
coc_number TEXT, -- KVK number (NL)
vat_number TEXT,
business_address JSONB NOT NULL, -- {street, city, postal, country}
psp_account_id TEXT, -- Stripe Connect account ID or Mollie org ID
verification_status TEXT DEFAULT 'pending', -- pending, verified, rejected, suspended
verification_completed_at TIMESTAMPTZ,
payout_enabled BOOLEAN DEFAULT false,
commission_rate NUMERIC(5,4) DEFAULT 0.10, -- 10% default
trust_score INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
KYC Verification (Delegated to PSP)¶
Stripe Connect KYC¶
SCOPE_ITEM: Seller verification via Stripe Connect onboarding.
INCLUDES:
- Stripe Connect Express or Custom account creation.
- Stripe-hosted onboarding flow (AccountLink).
- Webhook handling: account.updated for verification status.
- Capability checks: card_payments and transfers must be active.
- Ongoing verification (Stripe may request additional info over time).
Application Stripe
│ │
├── Create Connect account ────▶│
│◀── Account ID ───────────────│
├── Create AccountLink ────────▶│
│◀── Onboarding URL ──────────│
├── Redirect seller to URL ───▶│
│ (Stripe collects KYC) │
│◀── Webhook: account.updated ─│
├── Check capabilities │
├── Enable seller if verified │
CHECK: Use Express accounts for simplest onboarding (Stripe handles UI).
CHECK: Use Custom accounts only if full white-label onboarding is required.
CHECK: Handle requirements.currently_due — Stripe may require additional
documents after initial verification.
Mollie Connect KYC¶
SCOPE_ITEM: Seller verification via Mollie Connect onboarding.
INCLUDES: - Mollie OAuth flow for seller organisation creation. - Mollie-hosted onboarding (KYC data collection). - Webhook handling for onboarding status changes. - Payment method activation per seller organisation.
CHECK: Mollie Connect supports EUR and GBP split payments. CHECK: Mollie delayed payouts up to 90 days (not full escrow licence).
Trust Scores¶
OPTIONAL: SCOPE_ITEM: Computed trust score for sellers based on platform activity.
Score Components¶
| Signal | Weight | Description |
|---|---|---|
| Verification level | 20% | Basic (email) → Enhanced (ID + business) |
| Account age | 10% | Months active on platform |
| Transaction volume | 15% | Number of completed transactions |
| Review rating | 25% | Average rating across all reviews |
| Response time | 10% | Average message response time |
| Dispute rate | 15% | % of transactions with disputes (lower = better) |
| Refund rate | 5% | % of transactions refunded (lower = better) |
Score Calculation¶
INCLUDES: - Computed daily via background job (BullMQ scheduled). - Score range: 0-100. - Score displayed on seller profile (as badge or level, not raw number). - Score used for: search ranking boost, featured placement eligibility, commission tier qualification.
OPTIONAL: - Score history (trend over time). - Score breakdown visible to seller (transparency). - Score-based automated actions (suspend if score drops below threshold).
Trust Levels¶
| Level | Score Range | Badge | Benefits |
|---|---|---|---|
| New Seller | 0-20 | None | Standard commission, standard placement |
| Verified | 21-50 | Checkmark | Slightly higher search ranking |
| Trusted | 51-80 | Star | Lower commission, priority support |
| Top Seller | 81-100 | Gold star | Lowest commission, featured placement |
Account Security¶
Rate Limiting¶
SCOPE_ITEM: Prevent brute-force and credential stuffing attacks.
INCLUDES: - Login: 5 attempts per email per 15 minutes, then 30-minute lockout. - Registration: 3 accounts per IP per hour. - Password reset: 3 requests per email per hour. - API: 100 requests per minute per authenticated user.
Account Recovery¶
SCOPE_ITEM: Secure account recovery flows.
INCLUDES: - Password reset via email magic link (1-hour expiry, single use). - Account recovery invalidates all existing sessions. - Notification to user on password change (email to old + new if changed).
OPTIONAL: - Account recovery via support ticket with identity verification. - Recovery codes for MFA-enabled accounts.
Account Suspension¶
SCOPE_ITEM: Platform ability to suspend accounts.
INCLUDES: - Admin can suspend buyer or seller account with reason. - Suspended sellers: listings hidden, payouts paused, new orders blocked. - Suspended buyers: cannot purchase, can still view. - Suspension notification via email with reason and appeal instructions. - Appeal process: email to support, admin review, reinstate or confirm.
Data Privacy¶
COMPLIANCE: GDPR Article 6 — Lawful basis for processing. Buyer data: contractual necessity (purchase fulfilment). Seller data: contractual necessity (platform agreement) + legal obligation (KYC/AML via PSP).
COMPLIANCE: GDPR Article 13/14 — Information to data subjects. Privacy policy must explain: what data, why, how long, who receives it.
COMPLIANCE: GDPR Article 17 — Right to erasure. Buyer: anonymise after account deletion (retain order history for legal obligation, 7 years for financial records). Seller: anonymise after account deletion + payout completion + tax retention period (7 years NL).
COMPLIANCE: GDPR Article 20 — Right to data portability. Export: profile data, order history, messages, reviews in JSON/CSV.
Scoping Questions¶
CHECK: Can anyone become a seller or is it invite-only? CHECK: Can users have both buyer and seller roles simultaneously? CHECK: What business types are accepted (sole traders, companies, both)? CHECK: Is business registration (KVK/CoC) verification required? CHECK: Which PSP for KYC delegation (Stripe Connect or Mollie Connect)? CHECK: Is a trust score system desired? CHECK: What are the account suspension and appeal policies? CHECK: Are there geographic restrictions on sellers?