Payments & Billing Architecture
This document specifies the payment processing and SaaS billing architecture for the BusFlow platform.
1. Architecture Decision
We split our architecture into two distinct systems to optimize for cost, functional correctness, and minimal vendor lock-in.
SaaS Billing (BusFlow Revenue)
Engine: Lago
- Rationale: Lago is an open-source billing engine designed for complex, metered billing (ideal for API limits and feature toggles). It decouples pricing logic from the payment gateway, providing ownership and preventing lock-in. High scaling costs ruled out Stripe Billing. Fynn also fell short as it cannot handle multi-party marketplace routing.
Platform Payments (Operator to Passenger)
Engine: Mollie (Marketplaces)
- Rationale: Mollie provides a high trust factor in Europe, natively supporting DACH payment methods (SEPA, PayPal, Giropay, iDEAL). Its Marketplace routing allows for delayed payouts (acting as an escrow for bus trips) with simpler integration than Adyen for Platforms or Mangopay.
- Future Pivot: If escrow complexities rise significantly at the >€1,000,000/mo scale, Adyen or Mangopay are the documented fallback architectures.
2. Mollie Integration Specification
PRODUCT_mollie-integration.md specifies the full Mollie Marketplaces integration — including OAuth flow, sub-account provisioning, marketplace routing, webhook handling, payout scheduling, and deposit configuration.
Key payment flows documented there:
- B2C checkout pipeline:
CheckoutSession → Booking (DRAFT) → Payment (DEPOSIT) → Booking (DEPOSIT_PAID) → Payment (FINAL) → Booking (FULLY_PAID) - Webhook → Booking state transition mapping
- Deposit percentage resolution (Operator default → TourTemplate override)
- Final payment scheduling: operator-configurable timing via
FinalPaymentConfigcascade - Error handling and idempotency guarantees
3. Lago Billing Specification
Lago handles the subscription and usage billing for the operators using Busflow.
- Connects to operator accounts.
- Monitors seat capacity usage and active vehicle counts via internal orchestration events.
- Generates the B2B monthly subscription invoices.
4. Bank Statement Import & Automated Matching
Addresses the "Excel bookkeeping" pain point for operators.
Supported Formats
| Format | Standard | Use Case |
|---|---|---|
| MT940 | SWIFT | Legacy bank statements (still common in DACH) |
| CAMT.053 | ISO 20022 | Modern XML-based account statements |
| SEPA XML | EPC | Direct debit return files |
Auto-Matching Algorithm
- Parse: Extract transaction data: amount, reference (Verwendungszweck), counterparty, date.
- Match by reference: Compare reference field against
Booking.reference_numberandInvoice.invoice_numberusing fuzzy matching (Levenshtein distance ≤ 2 for typos). - Match by amount + date: If reference matching fails, attempt amount-based matching within a ±3 day window.
- Confidence scoring: Each match receives a confidence score (HIGH: exact reference, MEDIUM: fuzzy reference, LOW: amount-only). Only HIGH matches are auto-confirmed; MEDIUM and LOW go to a manual review queue.
- Partial payment handling: Support split payments (Teilzahlungen) where a single bank transaction covers part of a booking balance.
Integration with Financial Ledger
Once matched, bank transactions update the FinancialLedger directly, enabling the Soll/Ist margin comparison per departure. This closes the loop between projected costs (CostingSheet) and actual revenue/expenses.
DATEV Export
The system exports the reconciled ledger data as a DATEV-compliant CSV, formatted according to DATEV Unternehmen Online standards. Fields: Belegdatum, Buchungsdatum, Umsatz, Soll/Haben, Konto, Gegenkonto, Buchungstext, Belegnummer.