Skip to content

Financial Overview

Craft Easy ships with a full-stack financial system: payments, invoicing, subscriptions, claims, payment plans, revenue splits, settlements, and double-entry bookkeeping. Every piece is opt-in — a plain CRUD API can ignore all of them — but if you turn on even one, the rest are designed to slot in cleanly alongside it.

This section documents each subsystem as a user would approach it: what it does, how to configure it, which endpoints to call, and how it connects to the rest. This page is the orientation map.

The money flow

A Craft Easy deployment has three financial actors:

                ┌──────────────────┐
                │ System Owner     │  the platform vendor
                │ (you)            │
                └────────┬─────────┘
                         │ service fees, self-billing
                         │ revenue share
                ┌──────────────────┐
                │ Tenant           │  a customer organization
                │ (your customer)  │
                └────────┬─────────┘
                         │ customer charges
                         │ claim recovery
                ┌──────────────────┐
                │ Customer         │  the tenant's end-user
                │ (their customer) │
                └──────────────────┘

Money moves in both directions:

  • Customer → Tenant — the tenant's revenue. Usually captured through a payment provider (Stripe, Klarna, Swish) and tracked as a Payment. If the payment fails, the debt becomes a Claim that can be recovered over time.
  • Tenant → System Owner — service fees and revenue share. Settled at the end of each billing period as a Settlement, with the system owner withholding its cut before paying the tenant.
  • System Owner → Tenant — payouts (the tenant's share of customer revenue) and credit notes. Paid out as a PayoutBatch, posted against the tenant's payout account.

Every arrow in that diagram is recorded twice: once as a business object (a payment, an invoice, a settlement) and once as a pair of ledger entries in the double-entry books. The business objects drive workflow; the ledger entries drive reporting and external accounting exports.

The subsystems at a glance

Subsystem Purpose Core service Models
Payments Customer-facing payment capture, refunds, payouts PaymentService Payment, PayoutBatch, PaymentAccount
Payment Providers Pluggable Stripe, Klarna, Swish, custom PaymentProviderRegistry TenantProviderConfig
Invoicing Service-fee, customer-charge, self-billing, credit notes InvoiceService Invoice, InvoiceLineItem
Billing & Subscriptions Recurring plans with retry schedules BillingService RecurringBillingPlan, Subscription
Claims Interest accrual, dispute and escalation ClaimService Claim, CollectionFlow
Payment Plans Installment plans attached to claims PaymentPlanService PaymentPlan, Installment
Revenue Splits Date-based percentage, fixed, tiered splits RevenueSplitService RevenueSplitRule, RevenueSplitRecord
Settlements & Payouts Period payout, auto-approval, allocation SettlementService, AllocationService Settlement, SettlementOrder
Bookkeeping Double-entry ledger, BAS chart of accounts, SIE4 export BookkeepingService LedgerEntry, Account
Client Funds Segregated client money accounts ClientFundAccount, ClientFundTransaction

Multi-currency

Every amount in the financial system is a Decimal — there are no float values anywhere in the code, because float arithmetic loses pennies. Currencies are represented by their ISO 4217 code, and craft_easy.core.money.CURRENCIES tracks how many decimal places each one uses:

Currency Decimal places
SEK, NOK, DKK, EUR, USD, GBP, CHF, PLN 2
ISK, JPY 0

The MoneyAmount value object wraps an amount and its currency together, and refuses to add two amounts in different currencies. Every service method that takes money values takes amount + currency so cross-currency mistakes surface immediately.

A tenant declares its default currency on the Tenant document, plus an optional list of allowed currencies. When a payment is created without specifying a currency, the default is used. Attempting to create a payment in a currency that is not in enabled_currencies fails at the service layer before any provider is called.

Enabling the financial stack

There is no "turn on the financial system" switch — each subsystem has its own:

class Settings(CraftEasySettings):
    PAYMENTS_ENABLED: bool = False
    DEFAULT_CURRENCY: str = "SEK"
    DEFAULT_VAT_RATE: Decimal = Decimal("0.25")
    SEED_DEFAULT_ACCOUNTS: bool = True   # seeds BAS chart of accounts on first boot
    # plus provider-specific keys — STRIPE_*, KLARNA_*, SWISH_* — documented per page

Typical rollout order, from easiest to most demanding:

  1. Bookkeeping — immediate, no external dependencies. Post ledger entries from day one, even if you have no payments yet.
  2. Invoicing — no payment provider required. Useful on its own for systems that bill by bank transfer.
  3. Payments + one provider — turn on PAYMENTS_ENABLED, register one provider (Stripe is usually the fastest to onboard), set up webhooks.
  4. Settlements — once payments are flowing, configure each tenant's SettlementOrder and turn on the settlement runner.
  5. Billing — add recurring plans once one-time payments work.
  6. Claims, payment plans, collection flow — add these when you need to recover failed or unpaid receivables.
  7. Revenue splits — once you have a partner model and need to share revenue with third parties.

Every subsystem is tenant-scoped, so you can enable them per tenant via their agreement — a tenant without the invoicing feature simply cannot reach the invoice routes.

Where to go next

If you are starting fresh, read Payments and Payment Providers first — they cover the core capture loop.

If you are adding recurring billing, jump to Billing & Subscriptions.

If you are implementing debt recovery, start at Claims, then Payment Plans.

If you need accounting-grade books, read Bookkeeping — it has the SIE4 example and the chart of accounts.

If you care about how money leaves the system, read Settlements & Payouts — that is where the tenant actually gets paid.