Zurück zum Blog

Vom Kundenprojekt zur eigenen SaaS-App: Was wir beim Smart Invoice Generator gelernt haben

Die meiste Software, die wir bauen, läuft irgendwann bei einem Kunden – nicht bei uns. Mit dem Smart Invoice Generator ist das anders: eine Shopify-App, die wir selbst entwickeln, betreiben und im Shopify App Store anbieten. Hier ist der ehrliche Weg dorthin – inklusive der Entscheidungen, die wir im Nachhinein nochmal treffen würden, und einiger, die wir anders machen würden.

Der Auslöser: ein Problem, das immer wieder auftauchte

Angefangen hat alles nicht mit der Idee "wir bauen eine SaaS-App", sondern mit einem wiederkehrenden Kundenproblem: Shopify-Händler in Deutschland brauchen rechtssichere Rechnungen, Lieferscheine und Gutschriften – aber Shopify selbst liefert dafür nur eine sehr generische Basis. Wir hatten das für mehrere Kunden bereits individuell gelöst, mit ähnlichem Code, ähnlichen Anforderungen, ähnlichen Diskussionen über Design und Rechtstexte.

Irgendwann war der Punkt erreicht, an dem es günstiger und sinnvoller war, eine einmal konfigurierbare, generische Lösung zu bauen, statt das Rad für jeden neuen Kunden wieder neu zu erfinden.

Von der Individuallösung zum Produkt

Der größte gedankliche Sprung war nicht technischer, sondern konzeptioneller Natur: Eine Individuallösung muss nur einen Anwendungsfall gut abdecken. Ein Produkt muss hunderte unterschiedliche Shops, Branchen, Steuersituationen und Design-Vorlieben abdecken – ohne dabei unübersichtlich zu werden.

  • Konfiguration statt Code: Was vorher ein Codeänderung für einen Kunden war (z. B. ein anderes Rechnungslayout), musste zu einer Einstellung werden, die jeder Händler selbst vornehmen kann.
  • Mehrsprachigkeit von Anfang an: Statt Deutsch fest zu verdrahten, haben wir früh auf ein Übersetzungssystem mit sieben Sprachen plus eigener Sprachoption gesetzt.
  • Pläne statt Pauschalpreis: Ein Ein-Personen-Shop hat andere Anforderungen als ein Shop mit 500 Bestellungen im Monat – das hat direkt unser Plan-Modell geprägt (Free, Basic, Business).

Was uns dabei überrascht hat: Der technische Aufwand für "Konfiguration statt Code" war größer, als wir anfangs eingeplant hatten. Eine Individuallösung hardcodiert ein Rechnungslayout einmal und ist fertig. Eine konfigurierbare Lösung muss jede denkbare Kombination aus Layout, Sprache, Währung, Steuersituation und Firmendaten sauber durchspielen – inklusive der Fälle, die ein einzelner Kunde nie gebraucht hätte, die aber irgendein anderer Händler garantiert ausprobiert.

Wie wir Free, Basic und Business tatsächlich abgegrenzt haben

Die schwierigste Produktentscheidung war nicht "was kostet die App", sondern "welche Funktion gehört in welchen Plan". Ein zu großzügiger Free-Plan macht die kostenpflichtigen Stufen unattraktiv, ein zu restriktiver Free-Plan lässt Händler die App nie ernsthaft testen. Unsere Lösung war, zwei Achsen getrennt zu betrachten: Volumen und Automatisierungsgrad.

Beim Volumen war die Logik einfach: 50 Rechnungen im Monat reichen für einen kleinen Shop zum Testen und für sehr kleine Betriebe dauerhaft aus, 500 im Basic-Plan decken die meisten wachsenden Shops ab, und Business ist bewusst unlimitiert, weil wir bei hohem Volumen nicht wollen, dass ein Händler wegen künstlicher Deckelung zu einem Wettbewerber wechselt.

Beim Automatisierungsgrad war die Trennlinie unschärfer. Am Ende haben wir uns an einer einfachen Frage orientiert: Spart die Funktion aktiv manuelle Arbeit, oder ist sie "nur" eine Komfortfunktion? Der automatische E-Mail-Versand bei Zahlungseingang, Bulk-E-Mail-Versand für mehrere Bestellungen und die Download- und Export-Historie sparen im Alltag messbar Zeit – die haben wir Basic und Business vorbehalten. Dinge wie Design-Vorlagen, Sprachen oder die grundsätzliche PDF-Erzeugung sind dagegen in jedem Plan enthalten, weil sie kein "Premium-Feature" sind, sondern die Grundfunktion des Produkts.

  • Free: 50 Rechnungen/Monat, alle Design-Vorlagen, manueller E-Mail-Versand, Community-Support
  • Basic ($9.99): 500 Rechnungen/Monat, automatischer E-Mail-Versand, Bulk-E-Mail, eigene Rechnungsnummerierung, Download-Historie, Priority-Support
  • Business ($19.99): unlimitierte Rechnungen, alle Basic-Funktionen, SFTP-Export, erweiterte Insights

Rückblickend würden wir diese Grenzen wieder so ziehen – die Anfragen, die uns erreichen, bestätigen, dass Händler das Volumenmodell intuitiv verstehen, während eine reine Feature-Matrix ohne klare Logik (wie man sie bei manchen Konkurrenz-Apps sieht) für spürbar mehr Support-Nachfragen sorgt.

Technische Entscheidungen, die sich bewährt haben

Die App läuft auf Remix mit Anbindung an die Shopify Admin API, die eigentliche PDF-Erzeugung passiert serverseitig, Einstellungen und Verlaufsdaten liegen in Firebase. Für den E-Mail-Versand nutzen wir einen dedizierten Transactional-Mail-Anbieter statt eines Eigenbaus – bei Zustellraten für Rechnungen will man keine Experimente.

Eine Entscheidung, die sich besonders ausgezahlt hat: von Anfang an eine Download- und Export-Historie mitzudenken. Händler fragen früher oder später "wurde diese Rechnung wirklich verschickt?" – ohne nachvollziehbaren Verlauf ist das ein Supportfall, mit Verlauf eine Selbstauskunft.

Was wir rückblickend anders machen würden

Wir haben das Berechtigungs- und Plan-System (Free/Basic/Business) zu spät sauber zentralisiert – am Anfang gab es an mehreren Stellen im Code eigene kleine "darf dieser Shop das?"-Prüfungen. Das nachträglich zu vereinheitlichen war deutlich aufwendiger, als es von Beginn an konsequent an einer Stelle zu bündeln.

Mehrsprachigkeit als Architekturentscheidung, nicht als Übersetzungsprojekt

"Wir übersetzen die App später in weitere Sprachen" ist ein Satz, den wir bewusst vermieden haben. Wenn Text-Strings erst nachträglich aus dem Code herausgelöst werden müssen, entstehen fast immer hartcodierte Ausnahmen – ein Datumsformat hier, eine Pluralregel dort, die beim ersten Refactoring übersehen werden. Deshalb lief das Übersetzungssystem von Anfang an über eine zentrale Struktur: jedes Textfeld auf jedem Dokumenttyp (Rechnung, Lieferschein, Angebot, Gutschrift, Pro-Forma-Rechnung, Rückgabeformular, Zahlungserinnerung) hat einen eindeutigen Schlüssel, zu dem es in jeder unterstützten Sprache einen Wert gibt.

Aktuell deckt die App sieben Sprachen fest ab – Deutsch, Englisch, Französisch, Spanisch, Italienisch, Niederländisch und Portugiesisch – plus eine vollständig freie achte Sprachoption, bei der Händler jeden einzelnen Textbaustein selbst überschreiben und als JSON exportieren/importieren können. Diese Freitextoption war technisch der aufwendigere Teil, weil sie bedeutet, dass wir zur Laufzeit nicht mehr "eine von sieben festen Sprachen" annehmen dürfen, sondern beliebige, vom Händler gepflegte Textmengen zuverlässig validieren und in das PDF-Layout einpassen müssen – inklusive Sonderfällen wie deutlich längeren Übersetzungen, die in manchen Sprachen ein Vielfaches des englischen Originaltexts brauchen.

Der Aufwand hat sich ausgezahlt: Weil das System von Anfang an sprachagnostisch gedacht war, war das Hinzufügen jeder weiteren Sprache am Ende reine Übersetzungsarbeit statt Code-Änderung – ein Unterschied, der bei einem Produkt mit potenziell hunderten Shops in ganz unterschiedlichen Märkten den entscheidenden Skalierungsvorteil bringt.

Support & Weiterentwicklung als eigenes Produkt

Der größte Unterschied zum klassischen Kundenprojekt zeigt sich erst nach dem Launch: Bei einem Kundenprojekt endet die Verantwortung oft mit der Abnahme. Bei einer eigenen App ist der Launch erst der Anfang – Supportanfragen, Store-Reviews, Shopify-API-Änderungen und Feature-Wünsche laufen dauerhaft weiter. Das hat uns intern dazu gebracht, Support-Zeiten, Reaktionszeiten und einen klaren Update-Rhythmus genauso ernst zu nehmen wie bei einem Kundenauftrag mit SLA.

Konkret bedeutet das: ein Support-Formular direkt in der App (inklusive Dateianhang für Screenshots), feste Erreichbarkeitszeiten Montag bis Samstag, und eine interne Regel, dass jede Supportanfrage, die öfter als zweimal in ähnlicher Form auftaucht, als potenzielles Produktproblem und nicht nur als Einzelfall behandelt wird. Diese Regel hat mehrere kleinere Funktionen direkt ausgelöst – etwa die Download-Filialnamen-Einstellung für Sammel-Downloads, die aus wiederkehrenden Anfragen zur Dateibenennung bei Bulk-Exporten entstanden ist.

Genauso wichtig wie reaktiver Support ist die Reaktion auf Shopify selbst: Die Plattform ändert regelmäßig APIs, Checkout-Verhalten und Admin-Oberflächen. Als eigenständiges Produkt können wir uns nicht erlauben, auf eine deprecated API erst zu reagieren, wenn ein Kunde sich meldet – wir beobachten Shopifys Changelogs aktiv und planen Breaking Changes vorausschauend ein, was bei einem einmalig abgenommenen Kundenprojekt in dieser Konsequenz schlicht nicht nötig wäre.

Was der Shopify App Store selbst an Herausforderungen mitbringt

Ein Produkt zu bauen ist die eine Hälfte der Arbeit – gefunden zu werden die andere. Der Shopify App Store ist mittlerweile ein gut gefüllter Marktplatz, gerade in der Kategorie Rechnungen/Belege gibt es etablierte Wettbewerber, von denen einige seit Jahren Suchbegriffe wie "Order Printer" besetzen, weil genau so Shopifys eigenes, früheres natives Tool hieß. Wer in dieser Kategorie startet, konkurriert also nicht nur um Funktionsumfang, sondern auch um Sichtbarkeit für Begriffe, die historisch gewachsen sind.

Wir haben deshalb bewusst Zeit in die App-Store-Listung selbst investiert: eine präzise Beschreibung, die tatsächliche Funktionen statt Marketing-Floskeln nennt, Suchbegriffe, die reale Sucheingaben von Händlern abbilden (nicht nur unseren eigenen Produktnamen), und – aus unserer Sicht am wichtigsten – ehrliches Erwartungsmanagement in Screenshots und Beschreibungstext. Eine 1-Stern-Bewertung wegen einer Erwartung, die die App nie erfüllen sollte, ist vermeidbarer Schaden, den man sich als kleines Team kaum leisten kann.

Der zweite große Faktor ist Shopifys eigener Review- und Freigabeprozess: Jede neue Version, die sicherheitsrelevante Berechtigungen (Scopes) ändert, durchläuft eine manuelle Prüfung. Das ist inhaltlich sinnvoll – schützt letztlich auch unsere eigenen Nutzer – bedeutet aber, dass Release-Zyklen für sicherheitsrelevante Änderungen länger sind als bei einer internen Unternehmensanwendung, bei der man selbst über den Deploy-Zeitpunkt entscheidet. Diese Vorlaufzeit fest einzuplanen, statt sie bei jedem Release neu zu unterschätzen, war eine der praktischeren Lektionen der letzten Monate.

Fazit

Der Smart Invoice Generator ist für uns der Beweis, dass wir nicht nur Softwarelösungen für andere bauen, sondern die gleiche Sorgfalt auch auf ein eigenes Produkt anwenden können – von der ersten Konfigurationsoption bis zum laufenden Support. Für Kunden, die mit uns über eine eigene Produktidee statt einem klassischen Projekt sprechen wollen, ist genau diese Erfahrung oft der ausschlaggebende Punkt.

Was wir am Ende am meisten mitgenommen haben, ist eine Verschiebung der Perspektive: Bei einem Kundenprojekt fragt man "erfüllt das die Anforderung?". Bei einem eigenen Produkt fragt man zusätzlich "würde ich das jedem der nächsten hundert Shops so erklären können, ohne es individuell anzupassen?" – eine Frage, die man sich in klassischen Projekten selten stellen muss, die aber jede einzelne Produktentscheidung schärfer macht.

Sie planen ein eigenes Produkt statt ein Kundenprojekt?

Wir haben den Weg von der Idee bis zum Shopify App Store selbst gegangen – und teilen diese Erfahrung gerne mit Ihnen.

Projekt besprechen Smart Invoice Generator ansehen
← Shopify Functions & Checkout Extensibility