Skip to main content

User Stories

User Stories: {{PROJECT_NAME}}Drop — Fintech Payment App

Project: {{PROJECT_NAME}}Drop — Remittance + QR Payments Version: {{VERSION}}1.0 Date: {{DATE}}2026-02-23 Author: {{AUTHOR}}John (AI Director) Status: Draft | In Review | Approved Reviewers: {{REVIEWERS}}Alem Bašić (CEO)

Document History

Version Date Author Changes
0.1 {{DATE}}2026-02-23 {{AUTHOR}}John Initial draftstories from user journeys in business-case-v2.md

1. Epic Overview

Epic ID Epic Name Business Goal Story Count Status Target Release
EP-01 {{EPIC_NAME}}User Onboarding & Authentication {{BUSINESS_GOAL}}BO-02 — user acquisition {{COUNT}}4 BacklogDone /(Phase In Progress0.5) {{RELEASE}}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-04Open Banking (AISP)BO-02 — user trust2Mock (Phase 2)Phase 2
EP-05Transaction History & NotificationsBO-02, BO-033Done (Phase 1)Phase 1
EP-06Merchant AnalyticsBO-03 — merchant retention2Done (Phase 1)Phase 1
EP-07KYC & ComplianceBO-05 — regulatory2Mock (Phase 2)Phase 2

2. Epic Templates

Epic: EP-01 — {{EPIC_NAME}}

Epic Statement: As a {{PERSONA}}, I need {{CAPABILITY}} so that {{BUSINESS_VALUE}}.

Business Goal: {{BUSINESS_OBJECTIVE_REFERENCE}} Priority: Must Have | Should Have | Could Have Estimated Size: {{X}} story points (rough) Target Sprint(s): Sprint {{X}} – Sprint {{Y}}

Acceptance Criteria at Epic Level:

  •  {{HIGH_LEVEL_CRITERION_1}}
  •  {{HIGH_LEVEL_CRITERION_2}}
  •  {{HIGH_LEVEL_CRITERION_3}}

Stories in This Epic:

  • US-001: {{STORY_TITLE}}
  • US-002: {{STORY_TITLE}}
  • US-003: {{STORY_TITLE}}

3. 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].

Key Principles:

  • Stories describe WHAT the user needs, not HOW to build it
  • Each story must be independently valuable and testable
  • Stories should be completable within a single sprint
  • If a story takes > 8 story points, break it into smaller stories
  • Acceptance criteria should be written as tests (they become test cases)

4. Story Backlog

Epic EP-01: {{EPIC_NAME}}User Onboarding & Authentication


US-001: {{STORY_TITLE}}Account Registration (3-step onboarding)

Attribute Value
Epic EP-01: {{EPIC_NAME}}Onboarding
Priority Must Have
Story Points 18
Sprint {{SPRINT_NUMBER}}Sprint 1
Assigned To {{AGENT/PERSON}}Builder agent
Status BacklogDone
FR Reference FR-{{XXX}}001
BR Reference BR-{{XXX}}001, BR-002

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

Context: {{ADDITIONAL_CONTEXT_THAT_HELPS_UNDERSTAND_THE_STORY}}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 {{PRECONDITION}}valid email, password ≥8 chars, Norwegian phone (+47), DOB ≥18 years, when {{USER_ACTION}},user submits registration, then {{EXPECTED_RESULT}}201 created; user proceeds to OTP step
  • Given {{PRECONDITION}},DOB under 18 years, when {{USER_ACTION}},user submits, then {{EXPECTED_RESULT}}422 "Du må være minst 18 år"
  • Given {{ERROR_CONDITION}},duplicate email, when {{USER_ACTION}},submitted, then {{ERROR_HANDLING}}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:

  • {{TECHNICAL_CONSTRAINT_OR_HINT}}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:

  • ScreenScreen: / component: {{SCREEN_NAME}}mockups/figma-make-export/src/components/Onboarding.js
  • Design3-step reference:progress {{FIGMA_LINK_OR_FILE}}
  • indicator
  • Responsive behavior: {{NOTES}}shown

Dependencies:

  • Blocked by: {{US-XXXNone | None}}
  • Blocks: {{US-XXX002, |US-003, None}}
  • External: {{THIRD_PARTY_DEPENDENCY | None}}

Definition of Done:US-010

  •  Code complete and follows coding standards
  •  Unit tests written (≥ 80% coverage on new code)
  •  Code review approved by Tech Lead
  •  Merged to develop
  •  Deployed to staging
  •  All acceptance criteria manually verified
  •  No critical or high bugs open
  •  Documentation updated (if applicable)

US-002: {{STORY_TITLE}}User Login

Attribute Value
Epic EP-01
Priority Must Have
Story Points {{POINTS}}3
Sprint {{SPRINT}}Sprint 1
Assigned ToStatus {{AGENT}}Done
FR ReferenceFR-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


AttributeValue
EpicEP-01
PriorityMust Have
Story Points1
SprintSprint 1
StatusDone
FR ReferenceFR-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)

AttributeValue
EpicEP-01
PriorityMust Have
Story Points8
SprintSprint 4 (Phase 2)
Status Backlog
FR Reference FR-{{XXX}}001

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

Acceptance Criteria:

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

Dependencies: Blocked by: {{US-001BaaS |provider None}}

confirmed

Definition of Done: (same as standard DoD above)DEP-01)


Epic EP-02: {{EPIC_NAME}}Remittance (Send Money)


US-010: {{STORY_TITLE}}Send Money to Recipient

AttributeValue
EpicEP-02: Remittance
PriorityMust Have
Story Points8
SprintSprint 1
StatusDone
FR ReferenceFR-020
BR ReferenceBR-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

Sprint
Attribute Value
Epic EP-02
Priority ShouldMust Have
Story Points {{POINTS}}2
Sprint {{SPRINT}}
Assigned To{{AGENT}}1
Status BacklogDone
FR ReferenceFR-021

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

Acceptance Criteria:

  • Given {{PRECONDITION}},any user, when {{USER_ACTION}},GET /api/rates, then {{EXPECTED_RESULT}}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

AttributeValue
EpicEP-02
PriorityMust Have
Story Points3
SprintSprint 1
StatusDone
FR ReferenceFR-022

DefinitionStory: 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

AttributeValue
EpicEP-03: QR Payments
PriorityMust Have
Story Points8
SprintSprint 2
StatusDone
FR ReferenceFR-030
BR ReferenceBR-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 Done: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

AttributeValue
EpicEP-03
PriorityMust Have
Story Points5
SprintSprint 2
StatusDone
FR ReferenceFR-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

AttributeValue
EpicEP-03
PriorityShould Have
Story Points5
SprintSprint 2
StatusDone
FR ReferenceFR-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 (standardAISP)

DoD)

US-030: View Bank Account Balance

AttributeValue
EpicEP-04: Open Banking
PriorityShould Have
Story Points5
SprintSprint 4 (Phase 2)
StatusMock (Phase 2)
FR ReferenceFR-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

AttributeValue
EpicEP-05
PriorityShould Have
Story Points3
SprintSprint 1
StatusDone
FR ReferenceFR-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

AttributeValue
EpicEP-05
PriorityShould Have
Story Points3
SprintSprint 2
StatusDone
FR ReferenceFR-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 UpdateFix a label, fix a CSS bug, add a config option
2 Simple Simple form field, read-Read-only data display, static pageendpoint
3 Moderate CRUD for one entity, simple filter, email notificationfilter
5 Complex Multi-step form, API integration, complex UI componentintegration
8 Very Complex New module with CRUD + logic + UI + tests
13+ Too Large Break into smaller stories

Planning Poker: Use async estimation — each team member estimates independently, then compare and discuss outliers.


6. Definition of Ready Checklist

Before a story can be added toenters a sprint, verify:sprint:

  • Story is written in As a / I want / So that format
  • Story has at least 2 acceptance criteria in (Given/When/Then formatThen)
  • Story has been estimated in story points
  • Dependencies are identified and not blocking
  • UI/UX design exists (orFigma storyMake isexport backend-only)for core screens)
  • Technical approach is understood (no major unknowns)
  • Priority is assigned (MoSCoW)
  • Story size is ≤ 8 points (or confirmed as a spike)
  •  Acceptance criteria are testable by QA
  • FR reference documented

7. Story Breakdown TechniquesMap

TechniqueWhen to UseHow
CRUD SplitCreate/Read/Update/Delete are all in one storySplit into 4 stories (View, Create, Edit, Delete)
Happy Path FirstStory handles many edge casesFirst story = happy path only; subsequent stories = edge cases
Data VariationsStory handles many data typesSplit by data type or category
Workflow StepsMulti-step process in one storySplit by step (Step 1 as standalone value, etc.)
User Type SplitDifferent users, different experiencesOne story per user type
Performance DeferredCore function + performance optimization mixedFunctional story first; performance story second
UI + API SplitFull-stack story too largeAPI story first; UI story depends on API story

8. Story Mapping Visualization

USER JOURNEY:  [Discovery]Register] → [Registration]Verify KYC] → [CoreSend Feature]Money] → [Management]Pay QR] → [Reporting]View MVPHistory]

Phase 1        US-001       US-020007(mock)  US-030010        US-020     US-040
(Demo)         (ReleaseUS-002                     1)

Release 2     —US-011        US-021     US-031           US-041
               US-050

Release 3     —              —003                     US-032012        US-042022

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

Replace with actual story IDs mapped to user journey steps and release priority


9.8. Backlog Summary

1 2
Epic Total Stories Estimated Points In SprintDone Remaining
EP-01: {{NAME}}Onboarding {{COUNT}}4 {{POINTS}}20 {{COUNT}}3 {{COUNT}} {{COUNT}}(US-004, Phase 2)
EP-02: {{NAME}}Remittance 3 13 3 0
EP-03: QR Payments 31830
EP-04: Open Banking1501 (Phase 2)
EP-05: History/Notifications2620
Total 13 62 11 (Phase 2)

Velocity (last sprint): {{STORY_POINTS_COMPLETED}} Projected completion: Sprint {{X}} ({{DATE}})


Approval

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