Skip to main content

Functional Requirements Specification (FRS): Drop — Fintech Payment App

Functional Requirements Specification (FRS): Drop — Fintech Payment App

Project: Drop — Remittance + QR Payments Version: 1.0 Date: 2026-02-23 Author: John (AI Director) Status: Approved Reviewers: Alem Bašić (CEO)

Document History

Version Date Author Changes
0.1 2026-02-23 John Initial draft based on CLAUDE.md, API-REFERENCE.md, DATABASE-SCHEMA.md

1. System Overview

System Name: Drop — Fintech Payment App System Purpose: Drop is a PSD2 pass-through payment app for residents of Norway/Scandinavia. It enables international remittance (PISP bank transfer at 0.5% fee) and QR-code merchant payments (PISP at 1% fee) directly from users' Norwegian bank accounts — without holding any customer funds. Users are onboarded via Norwegian BankID (18+ required).

System Context Diagram:

graph TB
    subgraph "Drop Application"
        UI[Next.js Web App - 10 screens]
        API[Next.js API Routes - 26 endpoints]
        DB[(SQLite → PostgreSQL)]
    end
    U1[Consumer User] -->|BankID login| UI
    U2[Merchant User] -->|QR management| UI
    API -->|Reads/Writes| DB
    API -->|PISP payment initiation| BAAS[BaaS Provider - Swan/SpareBank1]
    API -->|AISP balance read| BAAS
    API -->|KYC verification| KYC[KYC Provider - Sumsub]
    BAAS -->|Open Banking| BANKS[Norwegian Banks - PSD2]
    BAAS -->|SCA| BANKID[BankID]
    API -->|Remittance corridors| CORRIDOR[30+ countries]

2. Actors & Personas

Actor ID Actor Name Type Description Access Level
ACT-01 Consumer User Human Norwegian resident (18+) sending money abroad or paying merchants Authenticated user
ACT-02 Merchant User Human Local business owner accepting QR payments Authenticated merchant
ACT-03 BaaS Provider System Swan or SpareBank1 — Open Banking API (AISP/PISP) System integration
ACT-04 KYC Provider System Sumsub — identity verification and AML screening System integration
ACT-05 BankID System Norwegian strong customer authentication (SCA) System integration

Persona Detail

Persona: Amir (Consumer)

  • Role: Software developer, immigrant from Bosnia
  • Goal: Send 3,000 NOK/month to his mother in Sarajevo cheaply and reliably; also pay at Ahmet's kebab shop
  • Pain Points: Western Union charges 10%; needs 2 separate apps for remittance and local payments
  • Tech Savviness: High
  • Frequency of Use: Weekly (remittance monthly; QR payments weekly)

Persona: Ahmet (Merchant)

  • Role: Owner of kebab shop in Oslo
  • Goal: Accept payments without Vipps terminal; lower fees; understand daily revenue
  • Pain Points: Vipps charges 1.75-2.75%; requires hardware terminal; fees eat into margins
  • Tech Savviness: Medium
  • Frequency of Use: Daily (receives 20-50 QR payments/day)

3. Functional Requirements

3.1 Module: Authentication & BankID Onboarding

Module Overview

User registration and login via Norwegian BankID SCA. Age (18+) and residency (Norway, +47 phone) verified. JWT tokens issued in httpOnly cookies. 3-step onboarding: BankID verification → OTP verification → PIN setup.


FR-001: User Registration (3-step onboarding)

Attribute Value
Module Authentication
Priority Must Have
Trace BR-001, BR-002
UI Reference mockups/figma-make-export/src/components/Onboarding.js

Description: New users register via a 3-step flow: (1) personal details + BankID, (2) OTP verification via Norwegian phone number, (3) PIN setup. Users must be ≥18 years old (validated via BankID DOB). Norwegian phone (+47) required.

Acceptance Criteria:

  • Given a valid email, password (≥8 chars), Norwegian phone (+47), and DOB ≥18 years, when user submits registration, then account is created and user proceeds to OTP step
  • Given a user under 18 years old, when they submit registration, then system rejects with "Du må være minst 18 år"
  • Given an already-registered email, when user tries to register, then system returns 409 "Email already in use"
  • Given OTP is sent, when user enters correct 6-digit code, then user proceeds to PIN setup
  • Given PIN setup, when user enters and confirms 4-digit PIN, then account is activated
  • Given invalid email format, when user submits, then 422 validation error with specific field details

Data Requirements:

  • Input: email (unique), password (≥8 chars), first_name, last_name, phone (+47), date_of_birth
  • Output: user record (id, kyc_status=pending), JWT token in httpOnly cookie
  • Validation: email format (regex), password length, phone format, DOB ≥18

Business Rules: RUL-001, RUL-002, RUL-008

Dependencies: None


FR-002: User Login

Attribute Value
Module Authentication
Priority Must Have
Trace BR-001
UI Reference mockups/figma-make-export/src/components/Login.js

Description: Users log in with email + password. JWT token issued in httpOnly cookie (7-day expiry). Failed logins rate-limited.

Acceptance Criteria:

  • Given valid email + password, when user submits login, then JWT cookie set and user redirected to dashboard
  • Given invalid credentials, when user submits, then 401 "Invalid email or password" (no user enumeration)
  • Given 10+ attempts from same IP in 1 minute, when user tries again, then 429 rate limit response
  • Given authenticated session idle for 7 days, when user makes request, then token expired; redirect to login

Data Requirements:

  • Input: email, password
  • Output: JWT in httpOnly cookie (SameSite=Strict); user object (id, email, role, kyc_status)
  • Validation: email format, password non-empty

Business Rules: RUL-001, RUL-002

Dependencies: FR-001


FR-003: Session Management + Logout

Attribute Value
Module Authentication
Priority Must Have
Trace BR-001

Description: Authenticated routes require valid JWT. Logout clears the cookie and revokes the session in the database. GET /api/auth/me returns current user.

Acceptance Criteria:

  • Given authenticated user, when they call GET /api/auth/me, then current user object returned
  • Given unauthenticated user, when they access protected route, then 401 Unauthorized
  • Given authenticated user, when they POST /api/auth/logout, then cookie cleared and session revoked in DB

Business Rules: RUL-001

Dependencies: FR-002


3.2 Module: KYC Verification

Module Overview

Know-Your-Customer identity verification required before any transaction. In MVP: Sumsub integration (mocked in demo). Users with kyc_status=approved can transact; others are blocked with clear messaging.


FR-010: KYC Identity Verification

Attribute Value
Module KYC
Priority Must Have
Trace BR-001, BR-002

Description: Users must complete KYC verification before initiating their first transaction. KYC status stored per user: pending → in_review → approved | rejected. In production: Sumsub document + biometric verification.

Acceptance Criteria:

  • Given user with kyc_status=pending, when they attempt remittance, then 403 "KYC verification required" with link to complete
  • Given approved user, when they initiate transaction, then transaction proceeds
  • Given Sumsub webhook callback with approved status, when received, then user kyc_status updated to approved
  • Given rejected user, when they attempt transaction, then 403 with rejection reason

Business Rules: RUL-008

Dependencies: FR-001


3.3 Module: Remittance (Send Money)

Module Overview

Core revenue stream #1. Users send money to 30+ countries at 0.5% fee via PISP. The payment is initiated directly from the user's Norwegian bank account. Recipient receives bank transfer or cash pickup within 1-2 business days.


FR-020: Send Money — Remittance Flow

Attribute Value
Module Remittance
Priority Must Have
Trace BR-003, BR-005
UI Reference mockups/figma-make-export/src/components/SendMoney.js

Description: Authenticated, KYC-approved users can send money to recipients in 30+ countries. Fee: 0.5% of transaction amount. Supported MVP corridors: NOK→RSD, NOK→BAM, NOK→PKR, NOK→TRY, NOK→PLN, NOK→EUR.

Acceptance Criteria:

  • Given authenticated + KYC-approved user and valid recipient, when POST /api/transactions/remittance with amount 100-50,000 NOK, then 201 transaction created; fee calculated as amount × 0.005
  • Given unauthenticated user, when they attempt remittance, then 401 Unauthorized
  • Given user with insufficient balance, when they attempt remittance, then 402 "Insufficient balance"
  • Given amount below 100 NOK or above 50,000 NOK, when user submits, then 400 validation error
  • Given valid transaction, when completed, then transaction_history record created with status=completed, correct fee

Data Requirements:

  • Input: recipientId, amount (100-50,000 NOK), currency (RSD/BAM/PKR/TRY/PLN/EUR), note (optional)
  • Output: transaction_id, amount, fee (amount × 0.005), recipient_amount, status, created_at
  • Validation: amount range, recipientId exists, KYC approved, balance sufficient

Business Rules: RUL-003, RUL-005, RUL-007, RUL-008

Dependencies: FR-002, FR-010, FR-040 (recipients)


FR-021: Exchange Rates

Attribute Value
Module Remittance
Priority Must Have
Trace BR-003

Description: Current NOK exchange rates for all supported corridors. GET /api/rates returns all; GET /api/rates/[currency] returns specific rate.

Acceptance Criteria:

  • Given GET /api/rates, when called, then returns all 6 NOK exchange rates (RSD, BAM, PKR, TRY, PLN, EUR)
  • Given GET /api/rates/RSD, when called, then returns NOK→RSD rate
  • Given GET /api/rates/XXX (invalid), when called, then 404 Not Found
  • Given rate query, when currency code is lowercase, then case-insensitive match

Dependencies: None


FR-022: Recipients Management

Attribute Value
Module Remittance
Priority Must Have
Trace BR-003

Description: Users can add, list, and reuse recipients for remittance. Recipients have name, country, bank account / IBAN.

Acceptance Criteria:

  • Given authenticated user, when POST /api/recipients with valid data, then recipient created and associated with user
  • Given authenticated user, when GET /api/recipients, then all user's recipients returned
  • Given IBAN provided, when validated, then reject invalid IBAN format
  • Given unauthenticated user, when accessing recipients, then 401 Unauthorized

Business Rules: RUL-003

Dependencies: FR-002


3.4 Module: QR Payments (Merchant + Consumer)

Module Overview

Core revenue stream #2. Merchants generate QR codes via Drop; consumers scan and pay. 1% merchant fee. Settlement via daily batch payout to merchant bank account.


FR-030: QR Payment — Consumer Flow

Attribute Value
Module QR Payments
Priority Must Have
Trace BR-004, BR-005
UI Reference mockups/figma-make-export/src/components/ScanQR.js

Description: Consumer scans merchant's QR code → enters amount → confirms → payment initiated via PISP from bank account. Fee: 1% charged to merchant. Consumer sees confirmation; merchant receives push notification.

Acceptance Criteria:

  • Given authenticated + KYC-approved user, when POST /api/transactions/qr-payment with valid merchantId and amount ≥1 NOK, then 201 transaction created; merchant fee calculated as amount × 0.01
  • Given invalid merchantId, when user pays, then 404 "Merchant not found"
  • Given amount < 1 NOK, when submitted, then 400 validation error
  • Given missing merchantId, when submitted, then 400 validation error
  • Given successful payment, when completed, then both user and merchant transaction records updated

Data Requirements:

  • Input: merchantId, amount (≥1 NOK), note (optional)
  • Output: transaction_id, amount, merchant_fee (amount × 0.01), status, merchant details
  • Validation: merchantId exists, amount ≥1, KYC approved, balance sufficient

Business Rules: RUL-003, RUL-006, RUL-008

Dependencies: FR-002, FR-010, FR-031


FR-031: Merchant Registration + QR Generation

Attribute Value
Module QR Payments
Priority Must Have
Trace BR-004, BR-006
UI Reference mockups/figma-make-export/src/components/MerchantDashboard.js

Description: Merchants register their business (name, address, bank account) and receive a unique QR code. Self-service onboarding < 5 minutes.

Acceptance Criteria:

  • Given authenticated user, when POST /api/merchants with valid business data, then merchant record created with unique QR code value
  • Given merchant, when GET /api/merchants/me, then merchant details + QR code returned
  • Given QR code, when scanned by Drop consumer app, then merchant identified and payment flow initiated

Business Rules: RUL-006

Dependencies: FR-002, FR-010


FR-032: Merchant Dashboard Analytics

Attribute Value
Module QR Payments
Priority Should Have
Trace BR-011

Description: Merchants view transaction volume, revenue, and fees by time period (today/week/month).

Acceptance Criteria:

  • Given authenticated merchant, when GET /api/merchants/dashboard?period=week, then total transactions, gross volume, fees earned returned
  • Given invalid period, when queried, then defaults to today

Dependencies: FR-031


3.5 Module: Bank Accounts (AISP)

Module Overview

Read-only view of user's linked bank account balance via AISP (Open Banking). Drop never holds funds — balance displayed for user awareness only.


FR-040: Bank Account Balance View

Attribute Value
Module Bank Accounts
Priority Should Have
Trace BR-010
UI Reference mockups/figma-make-export/src/components/BankAccounts.js

Description: Users view their linked bank account balance from their Norwegian bank via AISP. In MVP: mock balance from demo account. In Phase 2: real Open Banking AISP via BaaS provider.

Acceptance Criteria:

  • Given authenticated user, when GET /api/bank-accounts, then linked bank account(s) with masked account number and balance returned
  • Given user with no linked account, when viewing accounts, then prompt to link bank via BankID

Business Rules: RUL-003

Dependencies: FR-002, FR-010


3.6 Module: Transaction History

Module Overview

Users view all their transactions (remittance, QR payments) with filters by type, date, status.


FR-050: Transaction History

Attribute Value
Module Transaction History
Priority Should Have
Trace BR-009
UI Reference mockups/figma-make-export/src/components/TransactionHistory.js

Description: Authenticated users view all transactions with pagination. Filterable by type (remittance/qr_payment) and date range.

Acceptance Criteria:

  • Given authenticated user, when GET /api/transactions, then all user's transactions returned (most recent first)
  • Given query params, when ?type=remittance, then filtered results returned
  • Given unauthenticated user, when accessing transactions, then 401 Unauthorized

Dependencies: FR-002


3.7 Module: Notifications

Module Overview

Push notifications for transaction events. Users receive alerts for incoming/outgoing transactions.


FR-060: Transaction Notifications

Attribute Value
Module Notifications
Priority Should Have
Trace BR-008
UI Reference mockups/figma-make-export/src/components/Notifications.js

Description: Users receive push notifications when transactions are created or completed. Notifications stored in DB and viewable in-app.

Acceptance Criteria:

  • Given authenticated user, when GET /api/notifications, then all user's notifications returned (unread first)
  • Given new transaction, when completed, then notification record created for relevant user(s)
  • Given user marks notification as read, when PATCH /api/notifications/[id], then status updated

Dependencies: FR-020, FR-030


3.8 Module: User Profile & Settings

Module Overview

Users view and update their profile information, manage app preferences.


FR-070: User Profile

Attribute Value
Module Profile
Priority Should Have
Trace BR-007
UI Reference mockups/figma-make-export/src/components/Profile.js

Description: Authenticated users view their profile details, update preferences, and initiate account deletion (GDPR right to erasure).

Acceptance Criteria:

  • Given authenticated user, when GET /api/auth/me, then user profile returned (no password hash)
  • Given authenticated user, when DELETE /api/user/account, then account deletion initiated per GDPR

Business Rules: RUL-007 (GDPR right to deletion)

Dependencies: FR-002


3.9 Module: Feature Flags

Module Overview

Feature flag system controls access to beta/future features without code deployment.


FR-080: Feature Flag Control

Attribute Value
Module Feature Flags
Priority Should Have
Trace BR-014

Description: 8 feature flags control access to Cards (feature-flagged), Top-up (removed), and other future features. Controlled via environment variables.

Acceptance Criteria:

  • Given FF_CARDS_ENABLED=false, when user accesses /cards, then 404-equivalent feature gate response
  • Given FF_CARDS_ENABLED=true, when user accesses /cards, then full cards feature accessible
  • Given GET /api/feature-flags, when called, then all 8 flags with current values returned

Business Rules: Cards feature requires card partner agreement (RUL-010)

Dependencies: None


4. Use Case Diagrams

4.1 Consumer User Use Cases

graph LR
    A1((Consumer)) --> UC1[FR-001: Register via BankID]
    A1 --> UC2[FR-002: Login]
    A1 --> UC3[FR-020: Send Money Remittance]
    A1 --> UC4[FR-030: Pay via QR Scan]
    A1 --> UC5[FR-040: View Bank Balance]
    A1 --> UC6[FR-050: View Transaction History]
    A1 --> UC7[FR-060: View Notifications]

4.2 Merchant User Use Cases

graph LR
    A2((Merchant)) --> UC1[FR-001: Register]
    A2 --> UC2[FR-031: Register Business + Get QR]
    A2 --> UC3[FR-032: View Dashboard Analytics]
    A2 --> UC4[FR-060: Receive Payment Notifications]

5. System Behavior Specifications

5.1 Error Handling

  • All errors return {error, message, details?} JSON format
  • Validation errors: 422 with details array listing per-field errors
  • Authentication errors: 401 (never reveal if email exists)
  • Rate limit errors: 429 with Retry-After header
  • No stack traces in production responses

5.2 Data Persistence

  • All mutations logged with user_id, ip, timestamp
  • Transaction records are immutable once created (status-only updates)
  • ACID compliance required for financial transactions

5.3 Session & State

  • JWT expiry: 7 days
  • httpOnly cookies (SameSite=Strict) prevent XSS token theft
  • CSRF protection on all state-changing endpoints (POST/PATCH/DELETE)

5.4 Notifications

  • In-app: all transaction events (create, complete, fail)
  • Push: Phase 2 (requires native mobile app)
  • Email: account registration, security alerts

5.5 Security Headers (Required)

  • HSTS, CSP, X-Frame-Options: DENY, X-Content-Type-Options: nosniff
  • Referrer-Policy: strict-origin-when-cross-origin

6. Requirements Summary Table

ID Feature Name Module Priority Status Trace
FR-001 User Registration (3-step onboarding) Auth Must Have Implemented BR-001, BR-002
FR-002 User Login Auth Must Have Implemented BR-001
FR-003 Session Management + Logout Auth Must Have Implemented BR-001
FR-010 KYC Identity Verification KYC Must Have Mock (prod pending) BR-001
FR-020 Send Money — Remittance Remittance Must Have Implemented BR-003, BR-005
FR-021 Exchange Rates API Remittance Must Have Implemented BR-003
FR-022 Recipients Management Remittance Must Have Implemented BR-003
FR-030 QR Payment — Consumer QR Payments Must Have Implemented BR-004, BR-005
FR-031 Merchant Registration + QR QR Payments Must Have Implemented BR-004, BR-006
FR-032 Merchant Dashboard Analytics QR Payments Should Have Implemented BR-011
FR-040 Bank Account Balance (AISP) Bank Accounts Should Have Mock (AISP pending) BR-010
FR-050 Transaction History History Should Have Implemented BR-009
FR-060 Transaction Notifications Notifications Should Have Implemented BR-008
FR-070 User Profile + GDPR deletion Profile Should Have Implemented BR-007
FR-080 Feature Flag Control Feature Flags Should Have Implemented BR-014

Requirements Count:

  • Must Have: 7
  • Should Have: 8
  • Could Have: 0
  • Won't Have (this release): Cards virtual/physical (BR-014), Loyalty rewards (BR-012)

7. Traceability to Business Requirements

FR ID Feature Name Business Requirement (BR ID) Business Objective (BO ID)
FR-001 User Registration BR-001, BR-002 BO-02, BO-05
FR-002 User Login BR-001 BO-02
FR-010 KYC Verification BR-001, BR-007 BO-05
FR-020 Remittance BR-003, BR-005 BO-01, BO-02
FR-030 QR Payments BR-004, BR-005 BO-01, BO-03
FR-031 Merchant Registration BR-004, BR-006 BO-03
FR-040 Bank Balance (AISP) BR-010 BO-02

Full traceability matrix: [requirements-traceability-matrix.md](requirements-traceability-matrix.md)


Approval

Role Name Date Signature
Author John (AI Director) 2026-02-23 Approved (AI)
Tech Lead John 2026-02-23 Approved
Product Owner John 2026-02-23 Approved
AI Director (John) John 2026-02-23 Approved
CEO (Alem) Alem Bašić TBD