A SaaS company in Europe has four accounting problems that a shop or an agency does not: revenue arrives before it is earned, the payment processor pays out in batches that do not match invoices, the VAT treatment of a subscription depends on where the customer is and whether it is a business, and every one of those facts lives in your own database rather than in a spreadsheet. The answer is not more bookkeeping hours. It is a ledger that receives customers, invoices and payments from your application through an API, records the VAT verdict per invoice, and leaves the tax filing to a professional.
Revenue recognition: an annual plan is not annual revenue
When a customer pays €1,200 for a year in advance, you have €1,200 of cash and €1,200 of a liability called deferred revenue; you earn €100 of it each month as you deliver the service. That is the basic rule behind IFRS 15 and its national equivalents, and it is why a SaaS balance sheet looks strange to founders who have only watched a bank account.
IFRS 15's core principle is that "an entity recognises revenue to depict the transfer of promised goods or services to the customer in an amount that reflects the consideration to which the entity expects to be entitled". The standard describes five steps: identify the contract, identify the performance obligations, determine the transaction price, allocate it, and recognise revenue when — or as — each obligation is satisfied. A subscription is usually satisfied over time, so revenue is recognised over the subscription period.
Which framework you actually apply is a matter for your accountant. Small companies in Germany, France, Belgium and Poland normally report under national GAAP, not IFRS, and some simplifications exist for small entities. The mechanism is the same in all of them: cash in advance is a liability first, revenue later. What changes is the detail — whether a set-up fee is a separate obligation, how to treat a discount for annual payment, what a free month does. Those points require professional confirmation.
- Deferred revenue (contract liability)
- Money received for service you still owe. A liability on the balance sheet, released to revenue over the service period.
- Accrued revenue (contract asset)
- Service you have delivered but not yet invoiced — usage-based plans billed in arrears produce this at month end.
- MRR / ARR
- Management figures, not accounting figures. Useful for investors; they are not what goes into the annual accounts.
Stripe payouts are not invoices
A Stripe payout is one bank transfer that bundles many charges, minus refunds and fees, after a settlement delay. Your revenue is the individual charges and the invoices behind them; the payout is only how the cash reached you. Book them as two different things.
Stripe's own documentation is clear on the sequence: "Stripe sends funds from your available balance to your bank account as payouts", following the account's payout schedule, and "the time when funds become available depends on your settlement timing". A payment first appears as a pending balance "less any Stripe fees" and becomes available later. The recommended starting point for reconciling is the balance transaction, which Stripe creates "for every type of transaction that comes into, or flows out of, your Stripe account's balance" — types such as charge, refund, stripe_fee, payout and currency_conversion.
A clean approach treats Stripe as a clearing account:
- When a customer is charged, record the sale: receivable (or directly the Stripe clearing account) against revenue or deferred revenue, with the VAT treatment decided for that customer.
- Record Stripe's fee as an expense against the same clearing account, using the balance transaction rather than an estimate.
- When the payout arrives in the bank feed, move the payout amount from the clearing account to the bank. If the clearing account does not return to zero, something — a refund, a dispute, a currency conversion — is missing.
Whether you issue a formal invoice for every card charge depends on the customer. For a business customer in the EU an invoice is required for VAT purposes; for a consumer it is often not, though many SaaS companies issue one anyway because customers ask for it. The invoice is the document that carries the VAT verdict; the Stripe receipt is not a VAT invoice unless it contains everything a VAT invoice needs.
EU VAT on a subscription: B2C uses OSS, B2B uses the reverse charge
A software subscription delivered online is an "electronically supplied service". Sold to a consumer in another EU country it is taxed where the consumer lives; sold to a VAT-registered business in another EU country it is taxed where the business is, and the business accounts for the VAT itself under the reverse charge. Two customers paying the same €20 can therefore carry four different VAT outcomes.
The Commission's place-of-supply summary states the three rules that matter here. For B2B services "the place of taxation is the place where the customer is established" (Article 44 of the VAT Directive). For B2C services the default is "the place where the supplier is established" (Article 45) — but "B2C supplies of telecommunications, broadcasting and electronic services are taxed where the customer resides" (Article 58). A SaaS sale to a consumer is therefore taxed at the consumer's national rate, not yours.
Charging 27 different national rates to consumers would normally mean 27 registrations. The One Stop Shop avoids that: it is an optional scheme, launched on 1 July 2021, under which a business registered in one member state declares and pays the VAT due in all the others in one quarterly return. The OSS covers, among other things, "cross-border supplies of services to non-taxable persons". An annual EUR 10,000 threshold for cross-border B2C TBE services exists — below it a supplier may keep taxing in its own country — and "the OSS schemes are optional for taxable persons". Whether OSS, the threshold or a local registration is right for your company requires professional confirmation.
| Customer | Where taxed | Who pays the VAT | What the invoice shows |
|---|---|---|---|
| Business in your own country | Your country | You charge and remit | Standard rate |
| VAT-registered business in another EU country | Customer's country (Art. 44) | Customer, under reverse charge | No VAT; both VAT IDs; a reverse-charge note |
| Consumer in another EU country | Consumer's country (Art. 58) | You, via OSS or a local registration | Consumer's national rate |
| Business or consumer outside the EU | Generally outside EU VAT scope | Depends on the destination country | No EU VAT; local rules may apply |
The reverse charge rests on the buyer really being a taxable person. VIES, the Commission's VAT Information Exchange System, "enables companies to obtain rapidly confirmation of the VAT numbers of their trading partners". The same page limits what a check proves: the data "is obtained from Member States' databases over which the Commission services have no control", and a confirmation "does not in itself give a right to exempt intra-Community supplies from Value Added Tax". Check the number at the time of sale, store the result with the invoice, and keep evidence of where the customer is.
Refunds, credit notes and disputes
A refund is not a deleted invoice. In the EU a sale that has been invoiced is corrected by a credit note that references the original invoice, so that both documents survive and the VAT can be corrected in the right period. The Stripe refund is then the payment of that credit note.
- Full refund inside the same VAT period — credit note for the full amount, refund recorded against it, net effect zero.
- Partial refund — credit note for the refunded portion; deferred revenue for the cancelled months is released, not recognised.
- Chargeback / dispute — Stripe deducts the amount as an
adjustmentbalance transaction; treat it like a refund until the dispute is resolved, then reverse if you win. - Failed refund — Stripe returns the funds to your balance (
refund_failure); the credit note stands, the payment side is reopened.
Multi-currency: which rate, and when
If you price in EUR, USD and GBP, your ledger still has one reporting currency, and every foreign-currency invoice is converted at the rate on the invoice date. The difference between that rate and the rate at which the money actually arrives is an exchange gain or loss, booked separately from revenue.
Stripe adds a layer: a USD charge paid out to a EUR bank account is converted by Stripe, and the conversion appears as its own balance transaction (currency_conversion, with a stripe_fx_fee where applicable). The realised difference is the gap between your invoice-date conversion and Stripe's settlement conversion. Open foreign-currency receivables at year end are usually retranslated at the closing rate, which produces an unrealised difference; the treatment depends on your GAAP and requires professional confirmation. A fuller treatment is on the page several companies, several currencies.
What to automate through an API, and what not to
Automate the events your application already knows about: a customer signs up, a subscription invoice is due, a payment succeeds, a refund is issued. Do not automate the judgements: which VAT regime applies to a borderline case, how to allocate a bundled price, when to write off a receivable.
A minimal integration has three flows. Your app creates the customer in the ledger with its country and VAT ID. When Stripe (or your billing logic) produces a subscription invoice, your app creates the corresponding invoice draft in the ledger, which decides the VAT treatment from the facts and validates the document. When Stripe reports a successful charge, your app records the payment. Stripe's webhook guide explains why the last step must be idempotent: "webhook endpoints might occasionally receive the same event more than once", and Stripe "doesn't guarantee the delivery of events in the order that they're generated". The ledger you write to needs the same protection on its side — an idempotency key on every write.
How KRONENWERK handles this
KRONENWERK is a double-entry ledger with invoicing, credit notes, bank feeds and a public API, built for companies in Germany, France, Belgium, Poland (limited), Canada and the United States. For a SaaS company the relevant pieces are the tax verdict, the API and the webhooks. SUPPORTED WITH LIMITATIONS
- Tax verdict per invoice. From the seller's and buyer's country, whether the buyer is a business or a consumer, and the kind of supply, each invoice receives a verdict: standard, zero-rated, exempt, reverse charge, outside scope, or "requires input" / "requires professional confirmation". Buyer VAT IDs are checked against VIES at issuance and the verdict is stored with the invoice. KRONENWERK does not guess.
- Customers, invoices and payments over the API. The API at
https://kronenwerk.org/api/extern/v1acceptsPOST /customers,POST /invoices/draftsandPOST /transactions, each with anIdempotency-Keyheader. Drafts are issued in the product after validation; the API does not issue legal invoices directly. See connecting a SaaS and the invoicing API. - Webhooks. Signed deliveries for
invoice.issued,invoice.paid,invoice.cancelled,purchase.recordedandpayment.recorded, with retries and anIdempotency-Keyper event. - Bank feeds. European bank accounts connect through Enable Banking, Canadian and US accounts through Plaid, so the Stripe payout shows up in the ledger to be matched.
- Multi-currency and multi-company. Invoices in foreign currencies, one ledger per company, one API key per company.
Frequently asked questions
Do I need to issue an invoice for every card payment?
For a business customer in the EU, yes — an invoice is required for VAT purposes for most B2B supplies. For consumers the rules are looser, but a document that carries the VAT treatment is still the safest record. Whether a simplified invoice suffices requires professional confirmation.
Can I charge my own country's VAT to every consumer in the EU?
Only while your cross-border B2C sales of electronic services stay under the EUR 10,000 annual threshold, and only if you do not opt out of it. Above the threshold the consumer's national rate applies and the OSS is the usual way to declare it.
What if the customer's VAT ID fails the VIES check?
Do not apply the reverse charge on the strength of a failed check. Treat the customer as a consumer until a valid number is provided, or ask for other evidence of business status. Keep the VIES result with the invoice either way.
Does KRONENWERK import my Stripe transactions?
Not directly. Payouts arrive through the bank connection; individual charges, fees and refunds are recorded by your application through the API or by hand. A Stripe connector is not part of the product today.
Does KRONENWERK calculate deferred revenue?
No. It records the invoice and the payment; the monthly release from deferred revenue to revenue is a transaction you or your integration post. Your accountant decides the schedule.
Sources
- European Commission — One Stop Shop: overview — read on
- European Commission — Where to tax: place of taxable transactions — read on
- European Commission — VIES (VAT Information Exchange System) — read on
- IFRS Foundation — IFRS 15 Revenue from Contracts with Customers — read on
- Stripe documentation — Receive payouts — read on
- Stripe documentation — Balance transaction types — read on
- Stripe documentation — Receive Stripe events in your webhook endpoint — read on
- KRONENWERK developer documentation — read on