Busflow Docs

Internal documentation portal

Skip to content
Reviewed 02 May 2026

Payments & Billing ​

This document specifies the payment processing and SaaS billing architecture for the BusFlow platform.

Accounting boundary: Busflow is a travel-domain sub-ledger, not a general ledger. It exports classified economic facts to DATEV/Steuerberater workflows instead of replacing them. See Accounting Boundary & DATEV Strategy.

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 FinalPaymentConfig cascade
  • Error handling and idempotency guarantees

3. Lago Billing Specification ​

Lago handles the B2B subscription and usage billing for the operators using Busflow. It operates within a two-layer billing model:

  1. Metering & Invoicing (Lago): Lago maintains the pricing rules, tracks metered usage (API calls, vehicles, users), and generates the monthly invoice.
  2. Payment Collection (Stripe): Lago pushes the generated invoice to Stripe, which handles the actual SEPA direct debit or credit card charge, mandate management, and dunning.

3.1. Implementation Architecture ​

We deliberately avoid creating a separate microservice for billing to minimize operational overhead. Instead, Lago integration is handled within the monolithic backend via a dedicated BillingModule (NestJS).

The BillingModule listens to Hasura Event Triggers (e.g., UserAdded, VehicleActivated, BookingConfirmed) and pushes corresponding usage events asynchronously to the Lago API.

3.2. Hybrid Pricing Model ​

The billing model is a hybrid structure combining a flat base and metered usage. Lago's "Charge Models" map perfectly to this requirement.

IMPORTANT

Tier catalog intentionally pending. The current commercial hypothesis is a three-tier catalog priced by a combination of seats/users and/or active buses. This is not yet a fixed pricing spec. The implementation must keep tier names, included limits, entitlement rules, and metered dimensions configurable so the product can later support per-user, per-vehicle, usage-based, negotiated, or enterprise-contract pricing without schema redesign.

Base Subscription:

  • Flat fee tied to the base subscription plan. Candidate base metrics include users/seats, active buses, or a bundled allowance combining both.

Metered Dimensions (Usage):

  • Users / Seats: Active workspace users or paid seats.
  • Vehicles: Active fleet size or active buses.
  • API / Automation Usage: API calls, AI parsing, message volume, or other premium usage dimensions.
  • Premium Add-ons: High-value features like AI itinerary parsing or advanced reporting.

(Note: Transaction commissions for online sales are NOT metered in Lago. They are deducted in real-time via Mollie Marketplaces split routing. See PRODUCT_mollie-integration.md).

(Note: The exact € amounts, tier names, included limits, and feature-to-tier mappings will be defined in a separate PRODUCT_pricing-tiers.md document).

CAUTION

Before the Booking Widget goes live, a lawyer must review the entire consumer-facing payment and checkout pipeline. This is a hard launch blocker. Items marked ✏️ have schema/architecture documentation but still require formal legal counsel review.

Areas requiring legal review:

  • [x] ✏️ AGB / Terms & Conditions β€” The checkout flow now requires explicit AGB acceptance via legal_consent.agb_accepted (schema-commerce.md Β§checkout_sessions). The operator_settings.agb_url stores the canonical URL. Still pending: Lawyer must review the actual AGB text content and confirm the consent UX meets BGB/Fernabsatzgesetz requirements.
  • [ ] Widerrufsrecht / Right of Withdrawal β€” Online B2C transactions trigger the Fernabsatzgesetz. Bus tours may be exempt under Β§ 312g Abs. 2 Nr. 9 BGB (leisure services at a specific date), but a lawyer must explicitly confirm that exemption and define required consumer disclosures.
  • [x] ✏️ EU Pauschalreiserichtlinie β€” tour_templates.is_pauschalreise flag controls Formblatt/Sicherungsschein enforcement. Schema supports auto-generation of Anlage 11 Formblatt via operator_settings.insolvency_insurance_* fields. sicherungsschein_url stores the certificate PDF. Pre-contractual Formblatt delivery is enforced in the checkout flow; post-contractual Sicherungsschein is attached via Communications pipeline. Still pending: Lawyer must confirm which obligations fall on the operator vs. the platform, and validate the auto-generated Formblatt content.
  • [ ] Mollie Marketplace Regulatory Status β€” The escrow-like delayed payout model (Busflow collects money on behalf of operators, takes commission, routes payouts) has PSD2 / ZAG (Zahlungsdiensteaufsichtsgesetz) implications. Confirm whether Mollie's marketplace licence covers Busflow or whether Busflow needs its own licence or exemption.
  • [ ] Deposit / Anzahlung Rules β€” Consumer law governs when and how much deposit the operator can charge. Validate the current DepositConfig cascade (operator default β†’ template override) against BGB Β§ 651t (Reisepreisabsicherung).
  • [ ] Cross-Border / Multi-Country Tours β€” Multi-day tours may cross jurisdictions and create applicable-law questions beyond German default assumptions. Legal review must define which consumer/travel-law regime applies to booking terms, deposit timing, cancellation, insolvency protection, passenger disclosures, and operator/platform responsibility when tours cross borders or include services in multiple countries.
  • [x] ✏️ DSGVO / Privacy Policy β€” The checkout flow now requires explicit privacy policy acceptance via legal_consent.privacy_accepted. The operator_settings.privacy_policy_url stores the canonical URL. Consent timestamps and URL snapshots are immutably recorded in bookings.legal_consent_snapshot. Still pending: Lawyer must review the privacy policy text to confirm it covers all data processing purposes (PII, DOB, passport for border manifests), retention periods, and Mollie as a data processor.

5. Bank Statement Import & Automated Matching [Planned β€” Phase 2] ​

Status: Planned for Phase 2. The underlying physical schema tables (bank_imports, bank_transactions) are not yet implemented in schema-commerce.md. The current reconciliation_uploads table handles DATEV BWA/SuSa imports, not raw bank transactions.

Addresses the "Excel bookkeeping" pain point for operators running offline businesses.

Supported Formats ​

FormatStandardUse Case
MT940SWIFTLegacy bank statements (still common in DACH)
CAMT.053ISO 20022Modern XML-based account statements
SEPA XMLEPCDirect debit return files

Auto-Matching Algorithm ​

  1. Parse: Extract transaction data: amount, reference (Verwendungszweck), counterparty, date.
  2. Match by reference: Compare reference field against Booking.reference_number and Invoice.invoice_number using fuzzy matching (Levenshtein distance ≀ 2 for typos).
  3. Match by amount + date: If reference matching fails, attempt amount-based matching within a Β±3 day window.
  4. 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.
  5. 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.

Export rows must carry or link back to Busflow's classified economic facts, not just flattened payment totals. For the product boundary between Busflow, DATEV, and the Steuerberater, see PRODUCT_accounting-boundary.md.

Internal documentation β€” Busflow