DACH Payments in Solidus: Kauf auf Rechnung, SEPA, Klarna, EPS and Twint
I once watched a UK brand launch in Germany with a checkout that offered Visa, Mastercard and Apple Pay. Nice checkout. Fast, clean, mobile friendly, the kind of thing you would show off in a portfolio. It converted at just under a third of the rate the same shop managed at home. Nobody could work out why until someone finally asked a German customer, who said, with the slightly puzzled tone of a person explaining that water is wet, that she does not give her card details to shops she has never bought from. She wanted to pay by invoice after the parcel arrived, or at the very least by PayPal. The shop offered neither. So she left. In an earlier article I wrote about why German buyers avoid subscriptions and expect to pay on invoice. That was the why. This one is the how. If you are running or building a Solidus store that sells into Germany, Austria or Switzerland, here is what your checkout needs to offer, to whom, and how each of those methods is actually wired in, including the parts that break your order flow if you do not plan for them.
The checkout that converted at a third of the rate
I once watched a UK brand launch in Germany with a checkout that offered Visa, Mastercard and Apple Pay. Nice checkout. Fast, clean, mobile friendly, the kind of thing you would show off in a portfolio. It converted at just under a third of the rate the same shop managed at home.
Nobody could work out why until someone finally asked a German customer, who said, with the slightly puzzled tone of a person explaining that water is wet, that she does not give her card details to shops she has never bought from. She wanted to pay by invoice after the parcel arrived, or at the very least by PayPal. The shop offered neither. So she left.
In an earlier article I wrote about why German buyers avoid subscriptions and expect to pay on invoice. That was the why. This one is the how. If you are running or building a Solidus store that sells into Germany, Austria or Switzerland, here is what your checkout needs to offer, to whom, and how each of those methods is actually wired in, including the parts that break your order flow if you do not plan for them.
I build on Solidus, so the implementation notes are Solidus specific. The market facts apply whatever you run.
Three countries, three different wallets
People lump DACH together as if it were one market with one language. For payments it is three markets that happen to share a language and disagree about almost everything else.
Germany. The largest, the most conservative and the most invoice loving of the three. If you take the various trade association surveys and average them out, PayPal is the single most used method at somewhere around a quarter to a third of online purchases. Kauf auf Rechnung, paying by invoice after delivery, is a close second at roughly a quarter. Then SEPA direct debit, then cards, which in Germany means a lot of Girocard holders who do not own a credit card at all, then Klarna's instalment and pay later products, then a long tail of Apple Pay, Google Pay and Amazon Pay. Sofort, the bank transfer method that half of Germany used for years, was absorbed into Klarna and is now just one option inside their widget. Giropay, the banks' own answer to PayPal, was shut down at the end of 2024 after a decade of never quite catching on.
The important thing about that list is what is not at the top. Cards are fourth. A checkout that leads with cards is leading with the method a German customer trusts least.
Austria. Smaller, more card friendly than Germany but still not card first. The Austrian speciality is EPS, the bank transfer scheme that most Austrian online banks support natively, and it takes a meaningful share, somewhere around a fifth of purchases depending on whose numbers you read. PayPal is strong. Cards are stronger than in Germany. Invoice is expected but a little less sacred. Klarna is growing. If you only add one thing for Austria that you did not have for Germany, add EPS.
Switzerland. A different country in every sense that matters here. The currency is the franc, not the euro, and a Swiss customer shown a euro price will assume you do not really sell to Switzerland. The dominant method is Twint, the app the Swiss banks built together, which has gone from a curiosity to the default in about five years and now beats cards for domestic online purchases in most surveys. Cards come second, PayPal is present but weaker than in Germany, invoice is expected for anything above a modest basket, and PostFinance still matters for a certain kind of customer. Switzerland is also outside the EU, which means customs, a separate VAT registration once you cross the threshold, and no OSS. I cover the logistics side in my shipping and returns article, but the payment implication is simple: CHF prices, Twint, and an invoice option, or do not bother.
What the checkout should show, and to whom
The single most common mistake I see is a checkout that shows every payment method to every customer. It feels generous. It is actually a conversion problem and a fraud problem at once.
A German customer scrolling past Twint and EPS to find Rechnung is a customer wondering whether this shop really sells to Germany. A Swiss customer offered SEPA direct debit, which needs a euro account, is a customer being offered something that will fail. And a fraudster likes nothing more than a shop that offers pay on invoice to an address in a country where the shop has no collections process.
In Solidus every payment method is attached to a zone, and a zone is a set of countries or states. That is the mechanism. Use it properly and the checkout only ever shows the methods that fit the billing address the customer just entered. My default setup for a DACH store looks roughly like this:
Zone Germany. PayPal, Kauf auf Rechnung, SEPA direct debit, cards, Klarna. In that order on the page.
Zone Austria. EPS, PayPal, cards, Kauf auf Rechnung, Klarna.
Zone Switzerland. Twint, cards, Kauf auf Rechnung, PayPal. Prices in CHF from the store's Swiss price list, never converted at the checkout.
Zone rest of EU. Cards, PayPal, and whatever the local favourite is if you have bothered to add it, iDEAL for the Netherlands, Bancontact for Belgium, and so on.
Zone UK and rest of world. Cards, PayPal, Apple Pay, Google Pay.
The ordering is not decoration. Most customers pick the first method they recognise. Put the trusted local one first and the checkout gets faster. Put cards first in Germany and you have built the shop I described in the opening paragraph.
Solidus lets you go further than zones if you want. You can hide a method below or above a basket value, hide invoice from customers with an unpaid order on file, show instalments only above a threshold, or show a B2B customer a different set entirely. All of that is a few lines in the payment method's availability check. The point is that the framework treats "which methods does this customer see" as your decision, not the platform's, and you should make it deliberately.
Cards, SEPA and wallets: Stripe as the rail
For cards, SEPA direct debit, Apple Pay, Google Pay and a handful of local methods, I use Stripe through the official Solidus Stripe extension, and I would need a good reason to use anything else. The extension handles the Payment Element, which renders the right methods for the customer's country, deals with Strong Customer Authentication, stores payment sources against the customer for repeat purchases, and maps Stripe's payment intents onto Solidus payments cleanly. It has been maintained by the same people who maintain Solidus itself, which matters more than any feature.
A few things to know about it in a DACH context.
SEPA direct debit is slow and reversible. A card payment is authorised in seconds and settled in days. A SEPA debit is submitted, then takes several business days to fail or succeed, and the customer can reverse it for eight weeks without giving a reason. Stripe surfaces this correctly: the payment sits in a processing state and you get a webhook when it settles. Your Solidus order needs to respect that. Do not ship on a SEPA debit that has not settled unless you have decided, consciously, that you are extending credit. For low value goods that is usually fine. For a two thousand euro item it is a decision.
Girocard is not a credit card. A lot of German customers have a Girocard, the domestic debit scheme, and no Visa or Mastercard. Historically Girocard could not be used online at all. That has changed slowly, and Stripe supports the co badged versions, but do not assume that "we accept cards" means what it means in the UK.
Wallets need the domain verified. Apple Pay and Google Pay in the Payment Element only appear once your domain is registered with Stripe and the verification file is served. I have seen shops go live with the wallets silently missing for weeks. Put it on the launch checklist.
SCA is not optional. Under PSD2 every card payment in the EU goes through Strong Customer Authentication unless it qualifies for an exemption. Stripe handles the challenge flow, but your checkout has to be able to redirect out and come back without losing the order. The Solidus Stripe extension does this. A hand rolled integration usually does not, and the failure mode is an order stuck in a half paid state that nobody notices until the customer complains.
Kauf auf Rechnung: the one you cannot skip
Now the method that decides whether you sell in Germany at all.
Pay on invoice means the customer places the order, you ship it, the parcel arrives with an invoice, and the customer pays within fourteen days by bank transfer. From the customer's point of view it is perfect: no card details, no trust required, inspect the goods first. From the shop's point of view you have just shipped goods to a stranger on the promise of a bank transfer.
There are two ways to run it and you need to pick one before you touch the code.
Run it yourself. You take the risk, you issue the invoice, you chase the payment. This is how German shops did it for decades and some still do, usually with a credit check against Schufa or a similar agency at the checkout and hard limits on basket size and delivery address. It costs nothing in fees and everything in operations. Someone has to reconcile the bank account against open orders every day. Someone has to send the first reminder, the second reminder, the Mahnung with the late fee, and hand the file to a collections agency. If you sell a thousand orders a month, a few percent of those will be late and a fraction of a percent will never pay. That fraction is your margin on invoice orders and you need to know it.
Hand it to a specialist. Klarna, Unzer, Mollie, PayPal's own pay later product and a few others will take the risk off you. The customer sees "Rechnung" in your checkout, the provider runs the credit check in the background, approves or declines in under a second, and you get paid by the provider whether or not the customer pays them. Fees are higher than cards, typically two to three percent plus a fixed amount per transaction, and the provider owns the customer relationship for the payment. In exchange you never chase anyone and your cash flow looks like card cash flow.
For almost every SME I work with the specialist route is right. The exception is B2B, where you know your customers, the baskets are large, and a provider's risk engine will decline exactly the orders you most want. For B2B you run invoice yourself, on account, with your own credit limits, and that is a topic for its own article.
In Solidus the specialist route is a payment method that talks to the provider's API during checkout, gets an approval token, and creates a payment that completes when you capture it, usually at shipment. The self run route is a payment method with no gateway at all, which Solidus supports out of the box as a "check" style method, plus your own logic on top: the credit check call, the limits, the invoice generation and the reminder schedule.
What pay on invoice does to your order flow
This is the section people skip and then call me about.
Solidus orders move through a state machine: cart, address, delivery, payment, confirm, complete. Payments have their own states: checkout, pending, processing, completed, failed, void, invalid. Shipments have theirs: pending, ready, shipped. The default behaviour is sensible for cards: an order completes when payment is authorised, the shipment becomes ready when payment is captured, you ship, done.
Invoice breaks that in a specific way. The order is complete and the shipment must be ready to ship while the payment is not merely uncaptured but not yet even attempted. You are shipping on an unpaid order by design.
The way I handle it:
The payment method's auto capture is off and its payment goes straight to pending at checkout. Nothing is owed yet.
Shipments are allowed to become ready when the order has a pending payment from an invoice method. In Solidus that is a small override of the shipment readiness check, and it is the single most important line of code in the integration. Get it wrong one way and invoice orders never ship. Get it wrong the other way and unpaid card orders ship.
Capture happens at shipment. When the warehouse marks the shipment shipped, the invoice payment is captured, which for a specialist provider means "we shipped, start the clock, pay us", and for a self run invoice means "generate the invoice document with today's date, attach it to the order, email it, and set a due date".
Settlement is a separate event. For a specialist, the payment is completed once the provider confirms they will pay you, which is usually at capture. For self run invoice, the payment stays in a captured but unsettled state until a bank transfer arrives and someone, or something, matches it to the order. I model that as a custom payment state and a daily reconciliation job that reads the bank feed and matches on the reference number printed on the invoice.
Dunning is a scheduled job, not a person. Day fifteen, friendly reminder. Day twenty two, second reminder. Day thirty, formal Mahnung with the statutory late fee and interest. Day forty five, handed to collections and the customer's account flagged so they never see invoice as an option again. Every step is logged on the order. This is a background worker with a schedule, tested with time travel in the specs, and it runs whether or not the person who used to do it is on holiday.
Returns on invoice orders reduce the invoice, they do not refund. If the customer sends half the order back before paying, you issue a credit note against the invoice and the due amount drops. If they have already paid, you refund by bank transfer, which means you need their IBAN, which means your returns flow needs to ask for it. Card refunds go back to the card automatically. Invoice refunds do not go anywhere automatically. Build the IBAN capture into the return form or you will be emailing customers for bank details for the rest of your life.
Klarna, Unzer, Mollie: picking the specialist
Three providers cover most of what I get asked for.
Klarna is the consumer brand. German customers know the pink logo, the widget handles invoice, instalments and pay now in one place, and the approval rates for consumers are high. The cost is that Klarna markets to your customers through their own app, the fees are at the upper end, and the integration is Klarna's checkout inside your checkout, which fights with your design. Solidus talks to it through the payments API rather than the embedded checkout, which keeps your flow yours.
Unzer, the former Heidelpay, is the German specialist that agencies reach for. Invoice, instalments, direct debit, cards, all under one contract, with a risk engine tuned for DACH and a proper B2B invoice product. Less consumer brand recognition than Klarna, more flexibility, and support that answers in German. My default for a shop that is serious about DACH and wants one provider for everything except cards.
Mollie is the Dutch aggregator that has quietly become the easiest way to add every European local method. iDEAL, Bancontact, EPS, Twint, SEPA, cards, PayPal, Klarna through Mollie, all through one API and one settlement. For a shop selling across the EU and Switzerland with a modest volume, Mollie plus Stripe covers everything. For a shop that lives and dies on German invoice volume, a specialist with its own risk engine will approve more orders.
Whichever you pick, read the contract for the two things that matter: the approval rate they will commit to, and what happens to a disputed order. Then wire it in through a single Solidus payment method class per provider, with the provider's SDK behind an adapter, so that switching later is a configuration change and not a rewrite. I wrote a cautionary tale about what happens when you switch payment gateways carelessly and I would rather you read it before you need it.
EPS for Austria, Twint for Switzerland
Both are bank driven, both are redirect methods, both are handled the same way in Solidus.
The customer picks the method, is redirected to their bank or to the Twint app, approves the payment there, and is sent back to your site with a success or failure. Stripe supports EPS directly. Twint is available through Stripe in some configurations and through Mollie, Datatrans, Adyen and the Swiss acquirers more reliably. For a shop that is serious about Switzerland I use a Swiss acquirer for Twint and cards in CHF, because settlement in francs into a Swiss account avoids a conversion fee on every order and Swiss customers notice a foreign merchant name on their statement.
The Solidus side is a payment method that creates the payment in a processing state, stores the redirect reference, sends the customer away, and completes or fails the payment on the return webhook. The order should not complete until the webhook arrives. A surprising number of integrations complete the order on the redirect back, which means a customer who closes the bank tab and reopens your site gets an order confirmation for a payment that never happened. The webhook is the truth. The redirect is a hint.
One more Swiss detail: rounding. Swiss cash prices round to five rappen and a lot of Swiss shops round electronic prices the same way out of habit. Your price list for CHF should carry prices that already look Swiss, so 49.95 or 50.00, not 49.37 from a conversion. In Solidus that is just a separate price per variant in the CHF price list, which is how it should be anyway.
Fraud and risk, per method
Every method has its own failure mode and your risk rules should match.
Cards. Stolen card numbers. Stripe Radar catches most of it, SCA catches more, and the remainder is chargebacks you will lose. Rules that help: block mismatched billing and shipping countries above a threshold, require SCA on first purchase, flag orders where the email domain was registered last week.
PayPal. Account takeovers and "item not received" disputes. Ship with tracking to the PayPal address only, and keep the tracking number on the order so you can win the dispute.
SEPA direct debit. The eight week reversal. Limit debit to returning customers, or to baskets below a value you can afford to lose, or accept the risk consciously.
Invoice. The big one. Someone orders to a parcel shop or a freight forwarder under a name that does not match any real person, and never pays. If a specialist is carrying the risk, their engine handles it and you accept their declines. If you carry it yourself, you need address verification, a credit check, a ban on parcel shops and forwarders for invoice orders, a basket limit for first time customers, and a velocity check that notices the same address ordering five times in a day. All of that is a set of rules in the payment method's availability check plus a pre authorisation call, and all of it should be logged so you can see why an order was declined when the customer phones.
Twint and EPS. Very low fraud, because the customer authenticated at their bank. The risk is operational: a webhook that never arrives. Monitor for payments stuck in processing for more than an hour.
Refunds, partial refunds and the returns you did not plan for
Refunds are where I find the most bugs in payment integrations, because nobody tests them until a customer wants one.
Solidus has a proper refund model: a refund belongs to a payment, has an amount and a reason, and calls the gateway to actually move the money. The Stripe extension does this correctly, including partial refunds and refunds of a payment that was captured in several pieces. The specialist providers vary. Some support partial refunds through their API, some need a credit note, some need a phone call. Find out before launch.
The DACH specific wrinkle is that returns are common and partial returns are very common. A German customer orders three sizes, keeps one, sends two back, and expects the refund within days. On a card that is a partial refund against the original payment. On PayPal, the same. On invoice, it is a credit note that reduces the open amount if unpaid, or a bank transfer refund if paid. On SEPA, a refund of a debit that may not have settled yet, which some providers cannot do until it has. On Twint, a refund to the app. Every one of those is a different code path and every one needs a test.
I build the return flow so that the refund method is chosen by the payment method, not by the person processing the return. The warehouse marks items received, the system works out what is owed, and the right refund happens on the right rail. The only manual step is entering an IBAN when the original payment cannot receive a refund, and even that is captured from the customer in the return request.
Reconciliation, or making your accountant like you
A shop with five payment methods has five settlement streams arriving in the bank account on five different schedules with five different fee structures, and an accountant who needs to match every line to an invoice.
Stripe pays out daily or weekly in a lump, with a report listing every payment and fee behind it. PayPal holds a balance you sweep manually or on a schedule. Klarna and Unzer settle on their own cycle, net of fees, with a settlement file. A Swiss acquirer settles in CHF into a Swiss account. Self run invoice payments arrive one bank transfer at a time with whatever reference the customer typed.
What the accountant needs from your Solidus store is an export, per period, that lists every order, the payment method, the gross amount, the fee, the net amount, and the settlement batch it landed in. In Solidus that is a reporting query over payments and their gateway responses, plus a stored settlement reference per payment that you populate from the provider's webhooks or settlement files. It is not glamorous. It is also the difference between month end taking an afternoon and taking a week.
For self run invoice, the reconciliation is the reverse: incoming bank transfers matched to open invoices. I do it with a daily import of the bank feed, a match on the invoice number in the reference field, a fuzzy match on amount and customer name for the ones where the customer typed something creative, and a queue of unmatched transfers for a human. That queue is usually a handful a week for a shop doing a thousand orders a month, and it is the only manual work in the whole flow.
Saved payment sources and the returning customer
A returning customer should not have to type anything. Stripe stores the payment source against the Solidus user, with the customer's consent, and the checkout offers it by default on the next order. SEPA mandates work the same way once the first debit has succeeded. PayPal has a reference transaction product that most shops do not bother with. Invoice does not need saving, but your risk rules should get friendlier for a customer with three paid invoices behind them, and that is a query on their order history at checkout time.
The consent matters. Under GDPR, storing a payment source for future use needs a clear opt in, not a pre ticked box, and the customer needs to be able to delete it from their account page. Build both.
What the wrong mix actually costs
Let me put some numbers on the opening story, because "conversion problem" is vague and vague does not get budget approved.
Take a shop sending ten thousand visitors a month into the checkout from Germany, with a basket of eighty euros. A checkout offering cards and PayPal only, no invoice, no direct debit, converts at somewhere around two percent in my experience, which is two hundred orders and sixteen thousand euros. The same shop with PayPal, invoice, SEPA, cards and Klarna, in that order, converts at more like three and a half percent. That is three hundred and fifty orders and twenty eight thousand euros. A hundred and fifty orders a month, twelve thousand euros of revenue, from the same traffic, because the checkout stopped asking Germans to do something they do not do.
The invoice orders in that mix cost you two to three percent more in fees than the card orders would have. On twelve thousand euros of incremental revenue that is a few hundred euros. Nobody negotiates a provider fee hard enough to make up for a checkout that turns away a third of the customers who reached it.
The same maths applies in reverse for Switzerland with Twint, and for Austria with EPS. The numbers are smaller because the markets are smaller. The ratio is not.
The launch checklist
If you take nothing else from this, take this list. Every item is something I have seen missing on a shop that had already gone live.
- Payment methods attached to zones, so each customer sees only what fits their address.
- Local method first in each zone: PayPal or invoice for Germany, EPS for Austria, Twint for Switzerland.
- CHF price list for Switzerland with Swiss looking prices, not conversions.
- Invoice method with shipment allowed on pending payment, capture at shipment, a dunning schedule that runs itself, and an IBAN capture in the returns flow.
- Stripe domain verified so Apple Pay and Google Pay actually appear.
- SCA redirect and return tested on a real card in test mode.
- Every redirect method completes the order on the webhook, never on the redirect.
- Partial refund tested on every method, including SEPA before settlement.
- Settlement reference stored per payment and a reconciliation export your accountant has approved.
- Fraud rules per method, logged, with a way to see why an order was declined.
- Payment source storage behind a real opt in, deletable from the account page.
- A monitor for payments stuck in processing for more than an hour.
Where this fits
Payments are one part of the DACH story, and arguably the one with the fastest payoff. Get the mix right and the checkout converts. Get the flow right and the invoice orders ship, get paid and reconcile without a person in the loop. Get the fraud rules right and the invoice orders that ship are the ones that get paid.
If you are choosing a platform and wondering whether this level of control is available to you, I compared the options in Solidus versus Shopify, Shopware, Magento and WooCommerce for a DACH SME. The short version is that everything in this article is a few well tested Ruby classes on Solidus, a plugin and a quote on Shopware, and an app plus a penalty fee on Shopify. Which one you want depends on how much of your German revenue you would like to keep.