Business & Partnerships
Requirements Document
Requirements Document: [PROJECT NAME]
Version: 1.0 Date: YYYY-MM-DD Author: Business Analyst / Product Owner Status: Draft | In Review | Approved Client Sign-off: ☐
1. Introduction
1.1 Purpose
[Why this document exists, what it covers]
1.2 Project Reference
- Project Charter: [link]
- Scope Statement: [link]
1.3 Stakeholders
| Name | Role | Interest | Contact |
|---|---|---|---|
2. Functional Requirements
FR-001: [Feature Name]
- Priority: Must Have | Should Have | Could Have | Won't Have
- Description: [What the system must do]
- Acceptance Criteria:
- Given [context], when [action], then [result]
- Given [context], when [action], then [result]
- User Stories: US-001, US-002
- Dependencies: [None / FR-xxx]
FR-002: [Feature Name]
- Priority:
- Description:
- Acceptance Criteria:
- [ ]
- User Stories:
- Dependencies:
3. Non-Functional Requirements
3.1 Performance
| Metric | Target | Measurement |
|---|---|---|
| Page load time | < 2s | Lighthouse |
| API response time | < 500ms | Server logs |
| Concurrent users | [X] | Load test |
3.2 Security
- Authentication method: [JWT / Session / OAuth]
- Authorization model: [RBAC / ABAC]
- Data encryption: [At rest / In transit]
- GDPR compliance: [Yes/No — specify requirements]
3.3 Accessibility
- WCAG 2.1 AA compliance
- Keyboard navigation
- Screen reader support
3.4 Scalability
- Expected growth: [X users/month]
- Horizontal scaling: [Yes/No]
3.5 Reliability
- Uptime target: [99.9%]
- Backup frequency: [Daily]
- Recovery time objective: [X hours]
4. Data Requirements
4.1 Data Entities
| Entity | Description | Source | Volume |
|---|---|---|---|
4.2 Data Retention
| Data Type | Retention Period | Deletion Method |
|---|---|---|
5. Integration Requirements
| System | Direction | Protocol | Data | Frequency |
|---|---|---|---|---|
| In/Out/Both | REST/GraphQL/Webhook | Real-time/Batch |
6. Constraints
- [Technical constraint 1]
- [Business constraint 1]
- [Regulatory constraint 1]
7. Assumptions
- [Assumption 1]
- [Assumption 2]
8. MoSCoW Prioritization Summary
| Priority | Count | Items |
|---|---|---|
| Must Have | FR-001, FR-002... | |
| Should Have | ||
| Could Have | ||
| Won't Have |
9. Sign-off
| Role | Name | Date | Approved |
|---|---|---|---|
| Product Owner | ☐ | ||
| Tech Lead | ☐ | ||
| Client | ☐ |
SpareBank1 Partnership Pitch
Drop x Sparebanken — Partnership Proposal
Prepared by: ALAI Holding AS Date: February 2026 Contact: Alem Bašić, CEO — alem@alai.no Confidential
The Opportunity
There are 1 million immigrants living in Norway. They send 5.7 billion NOK home every year. They shop at 30,000+ immigrant-owned businesses across the country.
Today, they use Western Union (5-10% fees), Wise (no local presence), or cash. Their local shops pay Vipps 1.75-2.75% per transaction. Neither side is well-served.
Drop fixes both — in one app.
What is Drop?
Drop is a fintech app for everyone in Norway with two core features:
1. Remittance
Send money to family abroad. Receiver needs no app — money arrives to their bank account or cash pickup point.
- Fee: 0.5% (vs 5-10% Western Union, 0.7-1.5% Wise)
- Corridors: Serbia, Bosnia, Pakistan, Turkey, Poland, and more
- Speed: 1-2 business days
2. QR Merchant Payments
Pay at local shops by scanning a QR code. Cheaper than Vipps for merchants.
- Merchant fee: 1% (vs Vipps 1.75-2.75%)
- Settlement: Daily batch payout to merchant bank account
- Onboarding: 3 minutes — no hardware needed
The Flywheel
User sends remittance → gets familiar with Drop → pays at local shop with QR
Merchant accepts QR → recommends Drop → more users send remittance
→ REPEAT
No one in Norway combines remittance + QR payments. That's our edge.
Why Sparebanken?
We're not building another bank. We're building the interface for a community that banks don't reach effectively. But we need a banking partner to do it right.
What we need from Sparebanken:
| Capability | Purpose |
|---|---|
| Open Banking (PSD2) | AISP (account information) and PISP (payment initiation) |
| KYC/AML infrastructure | Compliant onboarding for users and merchants |
| Payment rails | Settlement, SEPA, domestic transfers |
| Regulatory umbrella | Operate under Sparebanken's licence (agent model) |
| Trust | A Norwegian bank brand behind the product |
What Sparebanken gets:
1. Access to an underserved 1M-person market Immigrants in Norway are underbanked in cross-border services. Drop is the distribution channel into this community — a community that trusts word-of-mouth over advertising.
2. New revenue stream — zero development cost
3. Innovation & ESG story Financial inclusion for immigrants is a powerful narrative. Sparebanken gets positioned as the bank that actually serves all of Norway — not just ethnic Norwegians.
4. Fintech partnership without the risk Drop builds and operates the product. Sparebanken provides infrastructure. Low investment, high upside.
Market Size
| Metric | Value | Source |
|---|---|---|
| Immigrants in Norway | ~1,000,000 | SSB |
| Annual remittance from Norway | 5.7 billion NOK | World Bank |
| Immigrant-owned businesses | 30,000-50,000 | SSB estimate |
| Average remittance transaction | ~1,000 NOK | World Bank |
| Vipps merchant fee | 1.75-2.75% | Vipps.no |
| Drop merchant fee | 1.0% | — |
Serviceable market (Year 1): Balkan + Pakistani diaspora in Oslo area = ~200,000 people, ~5,000 businesses.
Financial Projections
| Period | Users | Merchants | Monthly Revenue |
|---|---|---|---|
| Month 1-3 | 200 | 20 | 12,000 NOK |
| Month 4-6 | 1,000 | 80 | 50,000 NOK |
| Month 7-12 | 3,000 | 200 | 130,000 NOK |
| Year 2 | 8,000 | 500 | 330,000 NOK |
| Year 3 | 15,000 | 1,000 | 650,000 NOK |
Year 3 ARR: ~7.8M NOK
Revenue split model TBD — we propose 70/30 (Drop/Sparebanken) on transaction fees, with Sparebanken retaining 100% of float income and cross-sell revenue.
Competitive Landscape
| Remittance | QR Payments | Diaspora Focus | Bank Partner | |
|---|---|---|---|---|
| Vipps | No | Yes (expensive) | No | DNB |
| Wise | Yes | No | No | None in Norway |
| Western Union | Yes (expensive) | No | Yes (bad UX) | Various |
| Revolut | Yes (generic) | Limited | No | None in Norway |
| Drop | Yes (cheap) | Yes (cheap) | Yes (core) | Available |
Drop is the only product in Norway that combines remittance + QR payments. First bank partner gets exclusivity.
Detailed Comparison: Drop vs Alternatives
Why not PayPal?
| PayPal | Drop | |
|---|---|---|
| NOK → RSD/BAM corridor | Not supported | Core feature |
| NOK → PKR corridor | Limited, poor rates | Supported |
| Cross-border fee | 3-5% + currency markup | 0.5% flat |
| Receiver requirement | Must have PayPal account | No app needed — bank transfer or cash pickup |
| In-store QR payment | Not available in Norway | Core feature (1% merchant fee) |
| Target audience | No — generic global | Yes — built for everyone in Norway |
| Norwegian language | Partial | Full (nb/nn) |
| Local bank partner | None in Norway | SpareBank 1 (proposed) |
PayPal does not support the corridors that matter most to Norwegian diaspora (Balkans, Pakistan, Turkey). Drop is purpose-built for these communities.
Why not Revolut?
| Revolut | Drop | |
|---|---|---|
| Remittance | Person-to-person only (both need account) | Receiver needs NO app |
| Fee | 0.5-1.5% + weekend markup | 0.5% flat, no markup |
| Merchant payments | Limited (no QR in Norway) | QR code — 1% fee |
| Regulatory | Lithuanian banking licence | Norwegian bank partner (proposed) |
| Community | Generic fintech | Local community, word-of-mouth growth |
| Cash pickup | Not available | Planned for Phase 2 |
Revolut requires the receiver to also have a Revolut account. For a grandmother in rural Bosnia or Pakistan, that's not realistic. Drop sends directly to local bank accounts.
Why not Wise?
| Wise | Drop | |
|---|---|---|
| Fee | 0.7-1.5% (variable) | 0.5% flat |
| QR payments | None | Core feature |
| Merchant services | None | Dashboard, settlement, QR |
| Norwegian presence | No local office or support | Norwegian company, Norwegian bank |
| Community features | None | Locally-focused UX and corridors |
Wise is excellent for one-off international transfers but offers no merchant services, no QR payments, and no local banking relationship in Norway.
Security, Compliance & Trust
Regulatory Framework
Drop will operate under the agent model (betalingsforetak-agent) as defined in the Norwegian Financial Institutions Act (finansforetaksloven). This means:
| Aspect | Approach |
|---|---|
| Licence | SpareBank 1 holds the licence; Drop operates as registered agent |
| Regulator | Finanstilsynet (Norwegian FSA) |
| EU Directive | PSD2 compliant — Strong Customer Authentication (SCA) |
| Pass-through | Drop never holds customer money — PISP/AISP via Open Banking |
| Reporting | All regulatory reporting through SpareBank 1's existing infrastructure |
This model is proven — it's how Vipps originally launched under DNB's licence, and how several European fintech apps operate today.
AML/KYC — Anti-Money Laundering & Know Your Customer
| Requirement | Implementation |
|---|---|
| User onboarding | ID verification via BankID or passport + selfie |
| KYC provider | Flexible — Sumsub, Onfido, or SpareBank 1's existing KYC system |
| Risk scoring | Automatic risk assessment at onboarding based on country, amount, frequency |
| Transaction monitoring | Real-time screening against sanctions lists (EU, UN, OFAC) |
| Suspicious Activity Reports (SAR) | Automated flagging + manual review, reported to Enheten for finansiell etterretning (EFE) |
| PEP screening | Politically Exposed Persons check at onboarding and ongoing |
| Transaction limits | Tiered limits based on KYC level (basic: 10,000 NOK/month, full: 50,000 NOK/month) |
| Record keeping | All KYC data and transaction records stored for minimum 5 years per hvitvaskingsloven |
Data Protection & Privacy
| Aspect | Implementation |
|---|---|
| GDPR compliance | Full — data processing agreement (DPA) with SpareBank 1 |
| Data residency | All user data stored in EU/EEA (Norwegian data centres preferred) |
| Encryption in transit | TLS 1.3 for all API communication |
| Encryption at rest | AES-256 for stored personal data and credentials |
| Data minimisation | Only necessary data collected per GDPR Art. 5(1)(c) |
| Right to deletion | GDPR Art. 17 — users can request account deletion (except regulatory-required records) |
| Privacy policy | Norwegian and English, clearly written for non-native speakers |
Application Security
| Layer | Measure |
|---|---|
| Authentication | JWT tokens in httpOnly cookies (XSS-resistant) |
| Password storage | bcrypt hashing (never stored in plaintext) |
| SQL injection | Parameterised queries throughout (prepared statements) |
| Rate limiting | Per-IP rate limiting on all public endpoints |
| Input validation | Server-side validation on all user input |
| CORS policy | Strict origin policy — no wildcard |
| Dependency audit | Automated npm audit in CI/CD pipeline |
| Penetration testing | Planned before pilot launch — external auditor (e.g., mnemonic, NorSIS-certified) |
Audit & Certification Roadmap
| Milestone | Timeline | Description |
|---|---|---|
| Internal security review | Before pilot | Full codebase review, threat modelling |
| External penetration test | Before pilot | Third-party audit by certified Norwegian security firm |
| SOC 2 Type I | Within 6 months of launch | Controls documentation and assessment |
| SOC 2 Type II | Within 12 months | Operational effectiveness over time |
| ISO 27001 | Year 2 target | Information security management system certification |
| PCI DSS | If card issuing implemented | Payment card industry compliance |
Fraud Prevention
| Mechanism | Description |
|---|---|
| Velocity checks | Maximum transactions per hour/day per user |
| Amount thresholds | Transactions above threshold require additional verification |
| Device fingerprinting | Track trusted devices, flag new device logins |
| Geo-anomaly detection | Flag transactions from unusual locations |
| Recipient patterns | Alert on new recipients in high-risk corridors |
| Manual review queue | Flagged transactions reviewed by compliance team before processing |
Risk Assessment
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| Corridor closure (geopolitical) | Low | High | Multi-corridor strategy; no single-country dependency; partner with multiple payment providers |
| Regulatory change | Medium | High | Agent model reduces direct regulatory burden; SpareBank 1 handles compliance changes |
| Fraud / money laundering | Medium | High | Multi-layer AML/KYC; real-time monitoring; transaction limits; SAR reporting |
| User account compromise | Medium | Medium | 2FA via BankID; device tracking; session management; instant account freeze |
| Technical outage | Low | Medium | Cloud-hosted with redundancy; health monitoring; <1h recovery target |
| Competition (Vipps enters remittance) | Medium | Medium | First-mover in diaspora niche; community lock-in; merchant network effect |
| Low adoption | Medium | Medium | Word-of-mouth growth model; community ambassadors; zero marketing spend needed for pilot |
| Partner bank exit | Low | High | Modular architecture allows switching BaaS provider; data portability by design |
Product Status
Drop MVP is built and functional:
- Next.js web app (mobile-first, installable as PWA)
- 22 API endpoints (auth, transactions, merchants, rates, recipients, cards)
- QR generation + scanning
- Merchant dashboard
- User dashboard with balance, send money, transaction history
Ready for: BaaS integration, compliance review, pilot launch.
Proposed Partnership Model
Phase 1: Pilot (3 months)
- 200 users, 20 merchants in Oslo
- Sparebanken provides sandbox BaaS environment
- Drop handles all development and user acquisition
- Joint compliance review
Phase 2: Launch (6 months)
- Full rollout in Oslo, Bergen, Trondheim
- Marketing co-funded (Drop leads, Sparebanken contributes brand)
- Target: 1,000 users, 80 merchants
Phase 3: Scale (12+ months)
- Nationwide rollout
- Additional corridors
- Cross-sell Sparebanken products to Drop users
- White-label option for other banks
About ALAI Holding AS
ALAI Holding AS is an AI-native digital agency based in Norway. We build software, design, and infrastructure — powered by AI at every level.
- Team: Lean, AI-augmented (lower costs, faster iteration)
- Track record: Shopify integrations, web platforms, API development
- Approach: Ship fast, iterate with real users, data-driven decisions
Next Steps
- Intro meeting — 30 min, virtual or in-person
- Technical deep-dive — Drop architecture + Sparebanken BaaS capabilities
- Compliance review — Joint assessment of regulatory requirements
- Pilot agreement — Terms for Phase 1
We're ready when you are.
ALAI Holding AS — We build digital. You build business. Confidential — Not for distribution
Features, Merchants & Rates
Drop — Merchant, Recipients & Rates
Note (2026-02-14): This document predates the current architecture. Drop now uses a pass-through PSD2 model (PISP/AISP) — Drop NEVER holds customer money. Some sections below reference wallet/balance concepts from the earlier BaaS design. The current architecture is defined in architecture-document.md and Drop CLAUDE.md.
1. Recipients
Data Model
interface Contact {
id: string;
name: string;
iban: string;
avatar: string; // 2-char initials
}
Current Implementation
Sample contacts (hardcoded in src/app/send/page.tsx):
| Name | IBAN | Country |
|---|---|---|
| Sara M. | DE89370400440532013000 | Germany |
| Amir K. | FR7630006000011234567890189 | France |
| Lejla H. | AT611904300234573201 | Austria |
Mock contacts (src/lib/mockData.ts):
| Name | IBAN | Country |
|---|---|---|
| John Doe | DE89 3704 0044 0532 0130 00 | Germany |
| Jane Smith | FR76 3000 6000 0112 3456 7890 189 | France |
| Mike Wilson | GB29 NWBK 6016 1331 9268 19 | UK |
RecipientStep UI (src/app/send/page.tsx)
- Search bar (filters by name or IBAN)
- Contact list with avatar, name, truncated IBAN
- "Add new recipient" button (placeholder — not wired)
- Click to select → moves to AmountStep
Send Money Flow (6 steps)
RecipientStep → AmountStep → ConfirmStep → Processing → Success/Error
- Recipient — select from contacts or search
- Amount — input + quick buttons (€10, €50, €100, €200) + optional note
- Confirm — review: amount, recipient, IBAN, note, fee (Free)
- Processing — loading animation
- Success — confirmation with amount and name
- Error — message + retry
API: Send Money
POST /api/transactions
Authorization: Bearer <jwt>
Body: { toIban: string, amount: number, reference?: string }
Validations:
- Required:
toIban,amount amount > 0- Balance sufficient
- Creates
SepaCredittransaction with directionDebit - Updates account balance atomically
Future (not yet implemented)
- Add/edit/delete saved recipients
- Favorite/frequent contacts
- Import from phone contacts (mobile app)
- Recipient groups
2. Merchant Payments
Current State: Demo Only
Merchant payments exist as:
CardTransactiontype in schemasimulatePurchase()method in AppContext (no-op, logs to console)- Demo buttons on dashboard: "Netflix €9.99", "Groceries €45"
Transaction Types
| Type | Direction | Use Case |
|---|---|---|
SepaCredit |
Debit | Outgoing SEPA transfer |
SepaDebit |
Credit | Incoming SEPA transfer |
CardTransaction |
Debit | Card purchase at merchant |
AppContext Method
const simulatePurchase = async (amount: number, merchant: string) => {
// No-op — no API route for card purchases yet
console.log("[AppContext] simulatePurchase not implemented:", { amount, merchant });
return { id: 'demo_auth', amount, merchant };
};
Stripe Issuing Mock (src/lib/services/mock-stripe.ts)
- Checks card status (active)
- Checks spending limit (
spending_limitvsspent_this_month + amount) - Returns approved/declined
- Physical card ordering supported
Transaction Display (src/components/TransactionItem.tsx)
Shows for each transaction:
- Icon (emoji for type)
- Description (merchant name or counterparty)
- Date (formatted)
- Amount (green for incoming, gray for outgoing)
Future (post-MVP)
- Merchant directory/discovery
- Bill pay integration
- Recurring payments to merchants
- Purchase categorization (AI)
- Merchant notifications
3. Rates, Fees & Limits
Currency
MVP: EUR only (single account)
Formatting (src/lib/mockData.ts):
formatCurrency(amount, currency = "EUR")
// Uses Intl.NumberFormat("de-DE") → "€1.234,56"
Fees
| Transaction Type | Fee |
|---|---|
| SEPA transfer | Free |
| Card top-up | Free |
| Card payment | Free (interchange 0.2-0.3% from merchant) |
All transfers show "Free" in the UI confirmation step.
Transfer Limits (from MVP spec)
| Type | Daily | Monthly |
|---|---|---|
| Internal P2P | €5,000 | €20,000 |
| SEPA | €2,000 | €10,000 |
Top-up Limits
| Parameter | Value |
|---|---|
| Minimum | €5 |
| Maximum | €10,000 |
| Preset options | €20, €50, €100, €200, €500 |
Card Spending
| Parameter | Value |
|---|---|
| Monthly limit (default) | €5,000 |
| Tracked via | spent_this_month column |
Revenue Model (post-MVP)
| Stream | Rate |
|---|---|
| Interchange fees | 0.2-0.3% of card transactions |
| FX markup | 0.5-2% on currency conversion |
| Premium subscription | €5-15/month |
| Interest income | On deposits |
| Lending | Personal loans, BNPL, overdrafts |
Multi-Currency (Future)
- Additional currency accounts (GBP, USD, etc.)
- Real-time FX rates display
- FX conversion with 0.5-2% markup
- Currency selection at transfer time
4. Database Schema Reference
transactions
CREATE TABLE transactions (
id TEXT PRIMARY KEY,
account_id TEXT NOT NULL REFERENCES accounts(id),
type TEXT NOT NULL, -- SepaCredit | SepaDebit | CardTransaction
amount REAL NOT NULL,
currency TEXT DEFAULT 'EUR',
direction TEXT NOT NULL, -- Credit | Debit
status TEXT DEFAULT 'Pending', -- Pending | Booked | Rejected
counterparty TEXT, -- Recipient IBAN or merchant name
reference TEXT, -- Payment note
created_at TEXT DEFAULT (datetime('now'))
);
accounts
CREATE TABLE accounts (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL REFERENCES users(id),
iban TEXT UNIQUE NOT NULL, -- Format: BA393912XXXXXXXX
bic TEXT DEFAULT 'FONLBA22',
currency TEXT DEFAULT 'EUR',
balance REAL DEFAULT 0,
status TEXT DEFAULT 'Opened',
created_at TEXT DEFAULT (datetime('now'))
);
cards
CREATE TABLE cards (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL REFERENCES users(id),
type TEXT NOT NULL DEFAULT 'virtual',
brand TEXT DEFAULT 'Visa',
last4 TEXT NOT NULL,
exp_month INTEGER NOT NULL,
exp_year INTEGER NOT NULL,
status TEXT DEFAULT 'active',
spending_limit REAL DEFAULT 5000,
spent_this_month REAL DEFAULT 0,
cardholder_name TEXT,
created_at TEXT DEFAULT (datetime('now'))
);
5. Open Tasks (Related)
| Task | Priority | Description |
|---|---|---|
| #191 | HIGH | Wire /send page to /api/transactions/remittance |
| #192 | HIGH | Wire /scan page to /api/transactions/qr-payment |
| #193 | HIGH | Wire /merchant page to real APIs |
| #198 | LOW | Delete mock-data.ts and orphaned components |