Skip to main content

User Stories: Drop — Fintech Payment App

User Stories: 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 stories from user journeys in business-case-v2.md

1. Epic Overview

Epic ID Epic Name Business Goal Story Count Status Target Release
EP-01 User Onboarding & Authentication BO-02 — user acquisition 4 Done (Phase 0.5) Phase 1
EP-02 Remittance (Send Money) BO-01, BO-02 — revenue + users 5 Done (Phase 1) Phase 1
EP-03 QR Merchant Payments BO-01, BO-03 — revenue + merchants 5 Done (Phase 1) Phase 1
EP-04 Open Banking (AISP) BO-02 — user trust 2 Mock (Phase 2) Phase 2
EP-05 Transaction History & Notifications BO-02, BO-03 3 Done (Phase 1) Phase 1
EP-06 Merchant Analytics BO-03 — merchant retention 2 Done (Phase 1) Phase 1
EP-07 KYC & Compliance BO-05 — regulatory 2 Mock (Phase 2) Phase 2

2. Story Format Guide

Standard Story Format:

As a [persona/role],
I want [feature/action],
So that [benefit/outcome].

Acceptance Criteria Format (Given/When/Then):

Given [a precondition that must be true],
When [the user performs an action],
Then [the expected outcome occurs].

4. Story Backlog

Epic EP-01: User Onboarding & Authentication


US-001: Account Registration (3-step onboarding)

Attribute Value
Epic EP-01: Onboarding
Priority Must Have
Story Points 8
Sprint Sprint 1
Assigned To Builder agent
Status Done
FR Reference FR-001
BR Reference BR-001, BR-002

Story: As a Norwegian resident (18+), I want to register for Drop with my email and date of birth, So that I can access remittance and QR payments at lower fees than existing services.

Context: 3-step flow: (1) personal details + DOB validation, (2) OTP on Norwegian phone (+47), (3) PIN setup. BankID integration in Phase 2 replaces DOB validation with real SCA.

Acceptance Criteria:

  • Given valid email, password ≥8 chars, Norwegian phone (+47), DOB ≥18 years, when user submits registration, then 201 created; user proceeds to OTP step
  • Given DOB under 18 years, when user submits, then 422 "Du må være minst 18 år"
  • Given duplicate email, when submitted, then 409 "Email already in use"
  • Given OTP sent, when user enters correct 6 digits, then user proceeds to PIN setup
  • Given valid 4-digit PIN entered and confirmed, when submitted, then account activated; JWT cookie set

Technical Notes:

  • Age validation: (today - DOB) >= 18 years
  • OTP: 6-digit code; in MVP any code accepted (mock); real SMS in Phase 2
  • Password: bcrypt 12 rounds

UI/UX Notes:

  • Screen: mockups/figma-make-export/src/components/Onboarding.js
  • 3-step progress indicator shown

Dependencies: Blocked by: None | Blocks: US-002, US-003, US-010


US-002: User Login

Attribute Value
Epic EP-01
Priority Must Have
Story Points 3
Sprint Sprint 1
Status Done
FR Reference FR-002

Story: As a registered Drop user, I want to log in with my email and password, So that I can access my account and make payments.

Acceptance Criteria:

  • Given valid email + password, when login submitted, then JWT cookie set; redirected to dashboard
  • Given wrong password, when submitted, then 401 "Invalid email or password" (no enumeration)
  • Given 10 failed attempts from same IP, when next attempt, then 429 rate limit error

Dependencies: Blocked by: US-001


Attribute Value
Epic EP-01
Priority Must Have
Story Points 1
Sprint Sprint 1
Status Done
FR Reference FR-003

Story: As a logged-in Drop user, I want to log out of my account, So that my session is securely terminated on shared devices.

Acceptance Criteria:

  • Given authenticated user, when they POST /api/auth/logout, then JWT cookie cleared; session revoked in DB
  • Given logged-out user, when they access protected routes, then 401 redirect to login

Dependencies: Blocked by: US-002


US-004: BankID Verification (Phase 2)

Attribute Value
Epic EP-01
Priority Must Have
Story Points 8
Sprint Sprint 4 (Phase 2)
Status Backlog
FR Reference FR-001

Story: As a Norwegian resident, I want to verify my identity via Norwegian BankID, So that my account is secured with Strong Customer Authentication (SCA) as required by PSD2.

Acceptance Criteria:

  • Given user at onboarding step 1, when they complete BankID verification, then DOB, name, and national ID extracted from BankID response
  • Given BankID shows DOB < 18 years, when verification complete, then registration rejected with age error
  • Given successful BankID, when verification complete, then kyc_status set to approved

Dependencies: Blocked by: BaaS provider confirmed (DEP-01)


Epic EP-02: Remittance (Send Money)


US-010: Send Money to Recipient

Attribute Value
Epic EP-02: Remittance
Priority Must Have
Story Points 8
Sprint Sprint 1
Status Done
FR Reference FR-020
BR Reference BR-003, BR-005

Story: As a Drop user who wants to support family abroad, I want to send money to a recipient in Serbia/Pakistan/Bosnia/Poland/Turkey/EUR zone at 0.5% fee, So that my family receives money faster and 10x cheaper than Western Union.

Context: "Amir wants to send 2,000 NOK to his mother Jasmina in Sarajevo. He opens Drop, taps 'Pošalji novac', selects Bosnia, enters Jasmina's IBAN, enters 2,000 NOK. Drop shows: mama receives 4,660 BAM, fee 10 NOK. He confirms. Mama gets SMS notification."

Acceptance Criteria:

  • Given authenticated + KYC-approved user, when POST /api/transactions/remittance with amount 100-50,000 NOK and valid recipientId, then 201; transaction created; fee = amount × 0.005
  • Given user with insufficient balance, when submitting, then 402 "Insufficient balance"
  • Given amount < 100 NOK or > 50,000 NOK, when submitted, then 400 validation error
  • Given unauthenticated user, when submitting, then 401 Unauthorized
  • Given KYC-pending user, when submitting, then 403 "KYC verification required"

Technical Notes:

  • 6 corridors in MVP: NOK→RSD, NOK→BAM, NOK→PKR, NOK→TRY, NOK→PLN, NOK→EUR
  • In Phase 2: real PISP via BaaS
  • Exchange rates from exchange_rates table, updated daily

UI/UX Notes: Screen: mockups/figma-make-export/src/components/SendMoney.js

Dependencies: Blocked by: US-001, US-012, US-013


US-011: View Exchange Rates

Attribute Value
Epic EP-02
Priority Must Have
Story Points 2
Sprint Sprint 1
Status Done
FR Reference FR-021

Story: As a Drop user planning to send money, I want to see current exchange rates before confirming a transfer, So that I know exactly how much my recipient will receive.

Acceptance Criteria:

  • Given any user, when GET /api/rates, then all 6 NOK exchange rates returned (RSD, BAM, PKR, TRY, PLN, EUR)
  • Given GET /api/rates/RSD, when called, then specific NOK→RSD rate returned
  • Given GET /api/rates/XXX invalid, when called, then 404 Not Found

Dependencies: None


US-012: Add Recipient

Attribute Value
Epic EP-02
Priority Must Have
Story Points 3
Sprint Sprint 1
Status Done
FR Reference FR-022

Story: As a Drop user sending money regularly to the same person, I want to save recipient details (name, IBAN, country), So that I don't have to re-enter them every time I send money.

Acceptance Criteria:

  • Given authenticated user, when POST /api/recipients with valid name, IBAN, country, then recipient saved
  • Given authenticated user, when GET /api/recipients, then all user's recipients returned
  • Given invalid IBAN format, when submitted, then 422 validation error

Dependencies: Blocked by: US-002


Epic EP-03: QR Merchant Payments


US-020: Pay Merchant via QR Scan

Attribute Value
Epic EP-03: QR Payments
Priority Must Have
Story Points 8
Sprint Sprint 2
Status Done
FR Reference FR-030
BR Reference BR-004, BR-005

Story: As a Drop user at a local merchant, I want to scan the merchant's QR code and pay directly from my bank account, So that I pay 1% merchant fee instead of Vipps' 1.75-2.75%, without needing cash or card terminal.

Context: "Amir walks into Ahmet's kebab shop. On the counter is a Drop QR sticker. Amir opens Drop, taps 'Skeniraj', points camera at QR → 'Ahmetov Kebab' appears. He enters 129 NOK, taps 'Betal'. Ahmet's phone buzzes: 129 NOK received."

Acceptance Criteria:

  • Given authenticated + KYC-approved user, when POST /api/transactions/qr-payment with valid merchantId and amount ≥1 NOK, then 201; merchant_fee = amount × 0.01
  • Given invalid merchantId, when submitted, then 404 "Merchant not found"
  • Given amount < 1 NOK, when submitted, then 400 validation error
  • Given missing merchantId, when submitted, then 400 validation error

UI/UX Notes: Screen: mockups/figma-make-export/src/components/ScanQR.js

Dependencies: Blocked by: US-001, US-021


US-021: Merchant Business Registration

Attribute Value
Epic EP-03
Priority Must Have
Story Points 5
Sprint Sprint 2
Status Done
FR Reference FR-031

Story: As a local business owner, I want to register my business in Drop and receive a QR code, So that I can start accepting payments at 1% fee within 5 minutes.

Acceptance Criteria:

  • Given authenticated user, when POST /api/merchants with business_name, bank_account, address, then merchant created with unique QR code
  • Given merchant, when GET /api/merchants/me, then merchant details + QR code returned
  • Given QR code scanned by Drop consumer, when payment submitted, then merchant correctly identified

Dependencies: Blocked by: US-002


US-022: Merchant Dashboard

Attribute Value
Epic EP-03
Priority Should Have
Story Points 5
Sprint Sprint 2
Status Done
FR Reference FR-032

Story: As a merchant using Drop, I want to see my daily/weekly/monthly transaction volume and fees, So that I can understand my Drop revenue and reconcile with my bank statement.

Acceptance Criteria:

  • Given authenticated merchant, when GET /api/merchants/dashboard?period=week, then total_transactions, gross_volume, total_fees returned for that period
  • Given GET with period=today, period=month, when called, then correct period data returned

Dependencies: Blocked by: US-021


Epic EP-04: Open Banking (AISP)


US-030: View Bank Account Balance

Attribute Value
Epic EP-04: Open Banking
Priority Should Have
Story Points 5
Sprint Sprint 4 (Phase 2)
Status Mock (Phase 2)
FR Reference FR-040

Story: As a Drop user, I want to see my Norwegian bank account balance in the Drop app, So that I know if I have enough funds before sending money — without needing to open my banking app.

Acceptance Criteria:

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

Technical Notes: Real AISP requires BaaS partner (DEP-01) — currently mock data in demo

Dependencies: Blocked by: DEP-01 (BaaS partner)


Epic EP-05: Transaction History & Notifications


US-040: Transaction History

Attribute Value
Epic EP-05
Priority Should Have
Story Points 3
Sprint Sprint 1
Status Done
FR Reference FR-050

Story: As a Drop user, I want to see a history of all my transactions, So that I can track my spending and verify payments went through.

Acceptance Criteria:

  • Given authenticated user, when GET /api/transactions, then all user's transactions returned (most recent first)
  • Given ?type=remittance query, when called, then only remittance transactions returned

Dependencies: Blocked by: US-010 or US-020


US-041: Transaction Notifications

Attribute Value
Epic EP-05
Priority Should Have
Story Points 3
Sprint Sprint 2
Status Done
FR Reference FR-060

Story: As a Drop user or merchant, I want to receive notifications when transactions occur, So that I know immediately when money is sent or received.

Acceptance Criteria:

  • Given completed transaction, when GET /api/notifications, then new notification appears in list
  • Given user marks notification as read, when PATCH /api/notifications/[id], then status updated to read

Dependencies: Blocked by: US-010 or US-020


5. Story Estimation Guide

Points Complexity Examples
1 Trivial Fix a label, add config option
2 Simple Read-only data display, static endpoint
3 Moderate CRUD for one entity, simple filter
5 Complex Multi-step form, API integration
8 Very Complex New module with CRUD + logic + UI + tests
13+ Too Large Break into smaller stories

6. Definition of Ready Checklist

Before a story enters a sprint:

  • Story is in As a / I want / So that format
  • Story has at least 2 acceptance criteria (Given/When/Then)
  • Story has been estimated in story points
  • Dependencies are identified and not blocking
  • UI/UX design exists (Figma Make export for core screens)
  • Technical approach is understood
  • Priority assigned (MoSCoW)
  • Story size ≤ 8 points
  • FR reference documented

7. Story Map

USER JOURNEY:  [Register] → [Verify KYC] → [Send Money] → [Pay QR] → [View History]

Phase 1        US-001       US-007(mock)  US-010        US-020     US-040
(Demo)         US-002                     US-011        US-021     US-041
               US-003                     US-012        US-022

Phase 2        US-004       US-007(real)  [Real PISP]   [Real PISP] US-030
(Banking)      (BankID)     (Sumsub)

8. Backlog Summary

Epic Total Stories Estimated Points Done Remaining
EP-01: Onboarding 4 20 3 1 (US-004, Phase 2)
EP-02: Remittance 3 13 3 0
EP-03: QR Payments 3 18 3 0
EP-04: Open Banking 1 5 0 1 (Phase 2)
EP-05: History/Notifications 2 6 2 0
Total 13 62 11 2 (Phase 2)

Approval

Role Name Date Signature
Author John (AI Director) 2026-02-23 Approved (AI)
Product Owner John 2026-02-23 Approved
AI Director (John) John 2026-02-23 Approved