ADR-003: PSD2 Pass-Through Model ADR-003: Adopt PSD2 Pass-through Model (No Wallet) Status: Accepted Date: 2026-02-12 Deciders: Alem (CEO), John (AI Director) Category: Architecture Context The original Drop codebase implemented a wallet model where: Users had a local balance stored in the users database table Users could "top up" their wallet via /api/users/top-up (no payment verification) Transactions deducted from local balance Drop effectively held customer funds This wallet model had significant regulatory implications under Norwegian law: Aspect Wallet Model (EMI) Pass-through Model (PISP/AISP) License type E-money Institution (EMI) PISP/AISP registration Norwegian law Finansforetaksloven Betalingstjenesteloven Initial capital 350,000 EUR 20,000-50,000 EUR Timeline to license 12-18 months 6-12 months Fund safeguarding Required (segregated accounts or insurance) Not needed PCI-DSS scope Full (card data stored) Minimal (no card data) The alternative PSD2 pass-through model positions Drop as a Payment Initiation Service Provider (PISP) and Account Information Service Provider (AISP) where Drop never holds customer funds . graph LR subgraph wallet["Wallet Model (Rejected)"] user1["User"] -->|"Top-up"| drop_wallet["Drop Wallet
(holds funds)"] drop_wallet -->|"Pay"| merchant1["Merchant"] drop_wallet -->|"Send"| receiver1["Receiver"] end subgraph passthrough["Pass-through Model (Adopted)"] user2["User"] -->|"PISP: Initiate payment"| bank["User's Bank
(holds funds)"] bank -->|"Execute transfer"| merchant2["Merchant"] bank -->|"Execute transfer"| receiver2["Receiver"] drop_pt["Drop
(orchestrator)"] -.->|"AISP: Read balance"| bank drop_pt -.->|"PISP: Initiate"| bank end classDef rejected fill:#FFCDD2,stroke:#C62828 classDef adopted fill:#C8E6C9,stroke:#2E7D32 class user1,drop_wallet,merchant1,receiver1 rejected class user2,bank,merchant2,receiver2,drop_pt adopted Decision Drop adopts the PSD2 pass-through model. Specifically: No wallet: Remove all local balance, top-up, and fund-holding functionality AISP for balance: User sees their bank account balance via Open Banking API (read-only). The bank_accounts.balance field stores a cached AISP read -- not a Drop-held balance PISP for payments: Remittance and QR payments are initiated from the user's own bank account via Open Banking payment initiation with SCA No card storage: Cards feature gated behind feature flags (all default false ); future card issuance via PCI-compliant partner only BankID for SCA: Strong Customer Authentication via Norwegian BankID replaces email+password for all financial operations Code Impact Feature Wallet Model (removed) Pass-through Model (current) Balance Local balance column in users table bank_accounts.balance = cached AISP read from bank Top-up /api/users/top-up endpoint Removed -- no top-up needed Remittance Deduct from local balance POST /api/transactions/remittance triggers PISP QR Payment Deduct from local balance POST /api/transactions/qr-payment triggers PISP Cards Stored locally (PAN, CVV in DB) Feature-flagged; future partner integration (token-only) Auth Email + password (single factor) BankID OIDC for SCA Transaction Local DB update only Local record + bank payment confirmation sequenceDiagram participant User participant Drop participant BankID participant Bank participant Recipient Note over User,Recipient: PSD2 Pass-through Remittance Flow User->>Drop: Initiate remittance (amount, recipient) Drop->>Drop: Fee disclosure (0.5%) Drop->>User: Show total cost + exchange rate User->>Drop: Confirm payment Drop->>BankID: SCA challenge (amount + payee) BankID->>User: Authenticate (BankID app) User->>BankID: Approve BankID->>Drop: SCA confirmed Drop->>Bank: PISP: Initiate payment Bank->>Bank: Debit user account Bank->>Drop: Payment status: processing Drop->>Drop: Record transaction (status: processing) Bank->>Recipient: Transfer funds (SEPA/SWIFT) Bank->>Drop: Payment status: completed Drop->>Drop: Update transaction (status: completed) Drop->>User: Notification: transfer complete Consequences Positive Lower regulatory barrier to market entry (PISP/AISP vs EMI license) Faster licensing timeline (6-12 months vs 12-18 months) Lower capital requirements (20-50K EUR vs 350K EUR) No PCI-DSS card data storage obligations No fund safeguarding requirements (no funds to protect) Simpler security model -- Drop cannot lose customer funds Users keep their money in their trusted bank until payment execution Negative Dependent on banking partner / BaaS provider for Open Banking API access User experience may be slower (bank confirmation for each payment vs instant local deduction) Cannot offer instant transfers (limited by bank processing times: 1-2 days SEPA, 2-4 days SWIFT) Revenue model changes: no float income from held funds BankID integration adds complexity and requires BankID Norge partnership Risks Banking partner dependency: If no Norwegian bank provides Open Banking access, Drop cannot function. Mitigation: SpareBank1 already pitched; Swan (BaaS) as backup provider. UX friction: Each payment requires bank authentication via SCA. Mitigation: BankID app provides smooth mobile flow; consider session-based consent for repeat payments within limits. Corridor coverage: PISP may not support all 30+ target countries directly. Mitigation: use licensed remittance partner for non-SEPA corridors. References System Context (C4 Level 1) -- Shows Drop's external system relationships Open Banking Integration -- AISP/PISP integration specification Security Architecture -- Security controls for pass-through model Compliance Status -- Regulatory compliance tracking Roadmap -- Phase 2 banking integration plan Original source: comms/decisions/ADR-003-psd2-passthrough-model.md