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
US-003: Session Logout
| 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_ratestable, 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 |
No comments to display
No comments to display