Merchant Onboarding Flow
Flow: Merchant Onboarding
Document: LLD-006
Version: 1.0
Date: 2026-02-21
Author: Frontend Architect (AI Agent)
Status: Draft
Scope: Merchant registration, business verification, QR code generation, merchant dashboard, transaction monitoring, and settlement
1. Overview
Drop supports merchant onboarding for in-store QR payments. Any authenticated user can register as a merchant by providing business details and a valid Norwegian organization number. Upon registration, the user's role is upgraded from user to merchant , granting access to the merchant dashboard with transaction monitoring, daily summaries, and settlement views.
Key facts:
Merchant registration requires authenticated BankID login
Organization number verified against Brønnøysundregistrene (production; format validation in demo)
QR code format: drop://pay/{merchantId}
Merchant fee: 1% per QR transaction (lower than card terminal 1.75-2.75%)
Settlement: T+1 (planned) — funds from transactions deposited to merchant's bank account
2. Merchant Registration Flow
2.1 Sequence Diagram — Registration to Active Merchant
sequenceDiagram
actor User
participant App as Drop App
participant API as Drop API
(/api/merchants)
participant Brreg as Brønnøysund
Register (prod)
participant DB as Database
User->>App: Navigate to merchant registration
App->>App: useAuth() — verify authenticated
User->>App: Fill registration form
(businessName, orgNumber, address, bankAccount)
App->>App: Client-side validation
(name: validateName, orgNumber: 9 digits)
App->>API: POST /api/merchants/register
{ businessName, orgNumber, address, bankAccount }
API->>API: JWT verification
API->>API: Validate input fields
alt Production
API->>Brreg: GET /enhetsregisteret/api/enheter/{orgNumber}
Brreg-->>API: { organisasjonsnummer, navn, organisasjonsform, ... }
API->>API: Verify business exists and is active
else Demo
API->>API: Format validation only (9 digits, unique)
end
API->>DB: Check org_number uniqueness
API->>DB: INSERT merchant (user_id, business_name, org_number, bank_account, fee_rate=0.01)
API->>DB: UPDATE users SET role = 'merchant' WHERE id = ?
API->>API: Generate QR URI: drop://pay/{merchantId}
API-->>App: 201 { merchant: { id, businessName, orgNumber, qrUri } }
App->>App: Show success screen
(QR code display, "Vis min QR-kode" button)
App->>App: Navigate to merchant dashboard
3. Merchant Dashboard Components
3.1 Component Diagram
graph TD
subgraph "Merchant Dashboard"
Header["Header
'VELKOMMEN' + business name
+ Settings button"]
PeriodFilter["PeriodFilter
(I dag / Uke / Maaned)"]
RevenueCard["RevenueCard
(green gradient)"]
QRButton["QRButton
'Vis min QR-kode'"]
TransactionList["TransactionList
'Dagens transaksjoner'"]
BottomNav["BottomNav"]
end
subgraph "Revenue Card"
TotalRevenue["Total omsetning
(4xl Fraunces font)"]
StatsGrid["Stats Grid (2 cols)"]
TxCount["Transaksjoner
(count)"]
FeesInfo["Gebyrer betalt
(NOK amount)"]
end
subgraph "Transaction Item"
CustomerIcon["CheckCircle2
(green)"]
CustomerName["Customer Name
(partially anonymized)"]
TxTime["Timestamp"]
TxAmount["Amount
(+NOK, green)"]
end
RevenueCard --> TotalRevenue
RevenueCard --> StatsGrid
StatsGrid --> TxCount
StatsGrid --> FeesInfo
TransactionList --> CustomerIcon
TransactionList --> CustomerName
TransactionList --> TxTime
TransactionList --> TxAmount
4. Business Verification Checklist
4.1 Registration Requirements
Requirement
Field
Validation
Demo
Production
Business name
businessName
validateName() — 1-100 chars, at least one letter, no HTML/script
Format check only
Format check
Organization number
orgNumber
Exactly 9 digits, unique in DB
Format + uniqueness
Brønnøysund API lookup
Business address
address
Optional, sanitized to 300 chars
Optional
Required for settlement
Payout bank account
bankAccount
Required, non-empty
Format check
IBAN/account validation
User authentication
JWT
Valid BankID session
Required
Required
KYC status
user.kycStatus
Must be approved
Auto-approved via BankID
BankID verification
4.2 Brønnøysundregistrene Verification (Production)
Check
API
Response Field
Pass Criteria
Business exists
GET /enhetsregisteret/api/enheter/{orgNr}
organisasjonsnummer
Matches input
Business is active
Same
registreringsdatoEnhetsregisteret
Not null
Business type
Same
organisasjonsform.kode
AS, ENK, NUF, DA, ANS
Business name match
Same
navn
Approximate match to submitted name
5. Settlement Schedule
5.1 Settlement Schedule Table
Period
Settlement Day
Payout Time
Details
Daily transactions
T+1
08:00 CET
Next business day after transaction
Weekend transactions
Monday
08:00 CET
Batched for Monday payout
Holiday transactions
Next business day
08:00 CET
Following Norwegian business day
5.2 Settlement Calculation
Field
Formula
Example
Gross revenue
Sum of all QR payment amounts
4 350 NOK
Merchant fee
Gross x 1% (fee_rate)
43.50 NOK
Net payout
Gross - fee
4 306.50 NOK
Payout account
merchant.bankAccount
IBAN or Norwegian account
5.3 Merchant Dashboard API
Endpoint: GET /api/merchants/dashboard?period={today|week|month}
Response:
{
"data": {
"revenue": 4350,
"transactionCount": 12,
"fees": 43.5,
"netRevenue": 4306.5,
"nextPayout": "2026-02-22T07:00:00.000Z",
"payoutTime": "Neste virkedag kl. 08:00"
}
}
6. QR Code Generation
Property
Value
Format
URI: drop://pay/{merchantId}
Encoding
Standard QR code (alphanumeric)
Generation
Client-side (from returned qrUri )
Display
"Vis min QR-kode" button on merchant dashboard
Printing
Merchant can screenshot or print for in-store display
QR endpoint: GET /api/merchants/qr
{
"data": {
"merchantId": "mer_a1b2c3d4e5f6g7h8",
"businessName": "Ahmetov Kebab",
"qrValue": "drop://pay/mer_a1b2c3d4e5f6g7h8",
"address": "Gronlandsleiret 44, 0190 Oslo"
}
}
7. Merchant Transaction Monitoring
7.1 Transaction List
Endpoint: GET /api/merchants/transactions?page=1&limit=20
Field
Value
Privacy
Customer name
First name + last initial
Partially anonymized (e.g., "Ola N.")
Amount
Positive NOK value
Full amount shown
Status
"Vellykket" (green)
Color-coded
Timestamp
HH:MM format
Time only for today's transactions
7.2 Period Filtering
Period
API Value
Dashboard Label
Aggregation
Today
today
I dag
Sum of today's transactions
This week
week
Uke
Mon-Sun aggregation
This month
month
Maaned
Calendar month aggregation
8. UI Components (Web)
8.1 Merchant Dashboard Layout
Section
Component
Description
Header
Business name (Fraunces) + Settings icon
Welcome greeting + gear icon
Period tabs
Button group (I dag, Uke, Maaned)
Green active, gray inactive
Revenue card
Green gradient card (#0B6E35 to #095a2b)
Total omsetning (4xl), stats grid
QR button
Full-width green button with QrCode icon
"Vis min QR-kode"
Transaction list
Card list with CheckCircle2 icons
Customer name, time, +amount (green)
Navigation
BottomNav (5 tabs)
Standard bottom navigation
8.2 Figma Reference
Source of truth: mockups/figma-make-export/src/app/screens/MerchantDashboard.tsx
Welcome header with business name
Period filter tabs (I dag / Uke / Maaned)
Green gradient revenue card with stats
QR code button
Transaction list with customer names
9. Role Upgrade Flow
Step
Before
After
1
User has role = 'user'
Same
2
User submits merchant registration
Same
3
API validates and creates merchant record
role = 'merchant'
4
User's JWT still has old role
Valid until refresh
5
On next token refresh / re-login
New JWT has role = 'merchant'
Authorization gates:
GET /api/merchants/dashboard — requires role = 'merchant'
GET /api/merchants/qr — requires role = 'merchant'
GET /api/merchants/transactions — requires role = 'merchant'
10. Platform Differences
Feature
Web
Mobile
Merchant registration
Full form via web UI
Not implemented
Merchant dashboard
Dedicated screen with stats
Not implemented
QR code display
Button to show QR
Not implemented
Transaction monitoring
List with period filter
Not implemented
Settlement view
Inline in dashboard stats
Not implemented
11. Accessibility Considerations (WCAG 2.1 AA)
Requirement
Implementation
Form validation
Registration form shows inline error messages
Revenue card
Uses both visual (bold text) and semantic (heading) for amounts
Period tabs
Active tab indicated by color AND aria-selected
Transaction list
Each item has descriptive text (customer, amount, status)
QR code
Alt text: "QR-kode for {businessName}"
Color contrast
White text on green gradient meets 4.5:1
Settings icon
Has aria-label "Innstillinger"
12. Cross-References
Merchant registration API: POST /api/merchants/register — See API Reference
Merchant dashboard API: GET /api/merchants/dashboard — See API Reference
Merchant QR API: GET /api/merchants/qr — See API Reference
Merchant transactions API: GET /api/merchants/transactions — See API Reference
Merchants schema: merchants table — See Database Schema
Transactions schema: transactions table — See Database Schema
Component overview: See component-overview.md
Figma merchant dashboard: mockups/figma-make-export/src/app/screens/MerchantDashboard.tsx
QR payment flow: See flow-qr-payment.md
Authentication flow: See flow-login-authentication.md