Commerce für einen Abo-Shop einsetzen

Wir haben einen Shop als Teil der News-Plattform südostschweiz.ch aufgebaut, in dem man digitale und Print-Abonnements kaufen kann: http://www.suedostschweiz.ch/somedia/shop. Die gesamte Website und die Benutzer- und Abonnementverwaltung sind eng mit einem externen Abonnementverwaltungssystem verbunden, das beispielsweise eine wiederkehrende Rechnungsstellung sowohl mit physischen Rechnungen als auch Kreditkarten erledigt. Dieses System verfügt nicht über eine öffentlich verfügbare Oberfläche. Wenn also beispielsweise eine Kreditkarte abläuft, muss der Benutzer in der Lage sein, das Abonnement über die Website zu erneuern. Produktinformationen werden mit dem externen System synchronisiert und fertiggestellte Bestellungen werden zur Verarbeitung automatisch an dieses System gesandt. Es unterstützt ausserdem nicht den Kauf mehrerer Abonnements gleichzeitig, weshalb wir keinen Einkaufswagen benötigen.

Aboshop

Commerce 2.x bietet ein Out-of-the-box-Shop-Erlebnis, das ganz anders ist als unsere Anforderungen an das suedostschweiz.ch-Projekt. Deshalb mussten wir einiges ändern. Wir konnten aber Lösungen für all diese Herausforderungen zu finden. Wir arbeiteten dafür eng mit dem CommerceGuys-Team zusammen, sodass wir unsere Lösungen danach Commerce zur Verfügung stellen konnten. Wir haben ausserdem an ein paar fehlenden Funktionen gearbeitet und konnten zudem existierende Funktionen flexibler zu machen, sodass wir es für unseren Anwendungsfall anpassen konnten.

Speichern und Wiederverwenden von Zahlungsmethoden ... aber nicht wirklich

Commerce 2.x hat den Support für das Speichern von Zahlungsmethoden und deren Wiederverwendung verbessert. Der unterstützte Standard-Anwendungsfall ist, diese gespeicherten Zahlungsmethoden für Benutzer beim Zahlungsvorgang wieder sichtbar zu machen. Dies erlaubt ihnen, die erneute Eingabe der Zahlungsinformationen zu verhindern.

Wir müssen Zahlungsmethoden intern speichern, sodass wir diese an das Abonnementsystem senden können. Die grosse Mehrheit der Benutzer kauft aber nur dann ein neues Abonnement, wenn sie noch keines hat oder wenn ihr altes abgelaufen ist, in welchen Fällen die Benutzer noch keine Kreditkarte haben oder sie abgelaufen ist.

Daher haben wir uns entschieden, den voreingestellten Check-out-Bereich zur Auswahl des Zahlungs-Gateways durch einen individuellen zu ersetzen, der die Wiederverwendung von existierenden Zahlungsmethoden nicht anbietet. Dennoch ist es eine grosse Verbesserung gegenüber Commerce 1.x, dass der integrierte Standardspeicher den Kreditkarten-Alias vom externen Zahlungs-Gateway speichert.

Check-out Zahlungsdienstleister
Check-out bei existierendem Kunden

Unterschiedliche Adresshandhabung

Ein zweiter Grund für diese Entscheidung war, dass eine gespeicherte Zahlungsmethode auch eine dazugehörige Rechnungsadresse hat, sodass die Auswahl der Rechnungsadresse mit der Auswahl der Zahlungsmethode in Commerce 2.x verbunden ist und das Zahlungs-Gateway und die Rechnungsadresse vor dem Überprüfungsschritt im selben Bereich ausgewählt/angegeben werden.

Unser Design/unsere Anforderungen erforderten einen anderen Arbeitsablauf für die Check-out-Seite mit den Adressinformationen

  • Eine erforderliche Lieferadresse und optional eine andere Rechnungsadresse
  • Ein paar zusätzliche Felder, um es existierenden Kunden zu ermöglichen, eine Verbindung mit einer Abonnementnummer herzustellen. Durch die Eingabe einer gültigen Abonnementnummer rufen wir die Adresse automatisch ab und füllen das Adressfeld aus.
  • Die Möglichkeit, ein späteres Anfangsdatum für das Abonnement festzulegen 
  • Kundenspezifische Überprüfung, um zu verhindern, dass Benutzer ein Abonnement für eine Zeitung kaufen können, die sie bereits haben.

Zusätzlich zum Ersetzen des Zahlungs-Gateway-Bereichs haben wir auch den Adressinformationsbereich durch unseren eigenen ersetzt, in dem all diese Felder und diese Überprüfungslogik an einem Ort enthalten waren, was den Betrieb vereinfacht.

Erneuern einer abgelaufenen Kreditkarte

Für den Fall, dass eine Kreditkarte abläuft oder die Zahlung aus einem anderen Grund fehlgeschlagen ist, erhält der Kunde eine E-Mail mit einem Link. Dieser Link führt zu einer Seite, wo er nochmals eine manuelle Zahlung vornehmen kann, welche dann erneut an das externe System gesandt wird. Wir wollten diesen Schritt möglichst schnell gestalten und direkt zu einer Check-out-Überprüfungs-/Informationsseite springen, auf der der Kunde einfach einmal klicken kann, um die Zahlung zu starten.

Dies war überraschend einfach umzusetzen. Wir haben einen zweiten Check-out-Ablauf definiert, bei dem wir alle unnötigen Check-out-Bereiche und -Seiten deaktiviert haben: eine Bestellart, die diesen Check-out-Fluss nutzte, eine Bestellartikelart, die diese Bestellart nutzte und kein referenziertes Produkt hatte. Anschliessend erstellen wir programmatisch einen Bestellartikel und eine Bestellung und senden den Benutzer zum Check-out-Vorgang.

Variante bearbeiten

Synchronisation von Produktvarianten und versendeten Bestellungen

Das externe System definiert das Konzept eines Angebots. Dies ist ein bestimmtes Abonnement mit einer vorgegebenen Laufzeit, einem Preis, einem Titel sowie einigen anderen Informationen wie zum Beispiel welche Zahlungs-Gateways erlaubt sind (monatliche Abonnements können nur mit Kreditkarte, andere auch mit Rechnungen bezahlt werden).

Es kann auch Sonderangebote geben. Um zu verhindern, dass die Synchronisierung zwischen diesen Informationen und der Website verloren geht, muss der Shop-Manager nur das Angebot auswählen sowie einige webspezifische Dinge bereitstellen. Alles andere wird dann automatisch von der API abgerufen und im Hintergrund aktualisiert. Inline-Entity-Form hat dies ziemlich vereinfacht, da wir leicht kontrollieren können, welche Felder angezeigt und in den Vorgang der Erstellung einer Entität eingebunden werden.

Das Gegenteil passiert, wenn ein Benutzer den Check-out-Vorgang abschliesst. Dann müssen wir diese Daten an das externe System senden, sodass sie überprüft und verarbeitet werden können. Dazu haben wir einen individuellen Bestell-Workflow definiert, welcher in einer YAML-Datei einfach zu definieren ist. Wir haben diesen anschliessend für unsere Bestellarten genutzt. Wenn eine Bestellung einen bestimmten Schritt in diesem Workflow erreicht, sammeln wir all die Informationen, wandeln sie in die Struktur um, die das externe System versteht, und leiten sie an diese weiter.

Checkout Registration

Registrierung nur per E-Mail-Adresse

Die Website verwendet keine Benutzernamen. Die Registrierung ist daher so eingerichtet, dass der Benutzername verborgen und aus der E-Mail gebildet wird. Commerce verfügt über eine integrierte Login- bzw. Registrier-Check-out-Seite, die nur mit ein paar spezifischen Feldern hardcodiert ist und sowohl den Benutzernamen als auch die E-Mail-Adresse anzeigt.

Zunächst erstellten wir einen Issue, der eine Einstellung bereitstellt, mit der kontrolliert werden kann, ob die E-Mail-Adresse angezeigt werden soll oder nicht. Aber dies ist ein etwas umstrittener Ansatz, der wahrscheinlich eine Reihe von zusätzlichen Einstellungen erfordert, um definieren zu können, wie der Benutzername definiert ist etc. Wie wir im vorangegangenen Blogbeitrag bereits erwähnt haben, versucht Commerce 2.x zu verhindern, zu viele Einstellungsmöglichkeiten zu haben, sodass wir etwas anderes probieren mussten.

Unser zweiter und derzeitiger Ansatz ist es, stattdessen den Check-out-Bereich zu verbessern, sodass dieser einfacher anzupassen und zu erweitern ist. Wir stellten schliesslich fest, dass wir dies sowieso brauchen, da wir auch ein paar zusätzliche Felder im Registrierungsformular anzeigen müssen.

Direkter Check-out

Häufig ist es eine Anforderung, dass kein Warenkorb vorhanden ist und man stattdessen direkt zum Check-out gelangen soll. Daher gab es bereits einen Issue dafür, da andere Leute bereits nach dieser Funktion suchen.

Wir haben daran gearbeitet und einen ersten Patch bereitgestellt, der zurzeit überprüft wird. Eine neue Einstellung ändert den Button derart, dass man direkt zur Check-out-Seite gelangt und jegliche Nachrichten über den Warenkorb übersprungen werden. Commerce 2.x hat im Moment dieselbe Einschränkung wie 1.x, sodass anonyme Benutzer nur dann den Check-out durchlaufen können, wenn sich die Bestellung in der Warenkorbsitzung befindet. Wir müssen dies deshalb zurzeit ein wenig umgehen. Das heißt auch, dass der Check-out und die Warenkorbfunktionalität immer noch eng verbunden sind. Der Check-out hängt derzeit vom Warenkorb ab, sodass kein Check-out möglich ist, wenn das Warenkorbmodul vollständig deaktiviert ist. Das ist möglicherweise etwas, das künftig verbessert wird.

Schlussfolgerung

Durch die Kombination von all diesen Änderungen endeten wir schliesslich damit, dass wir jeden Check-out-Bereich und ein paar andere Komponenten, die Commerce 2.x bereitstellt, ersetzten oder erweiterten. All dies, um in der Lage zu sein, Benutzerschnittstelle und die Vorgänge zu erhalten, die in diesem Projekt erforderlich sind. Wir konnten dies auf eine sehr saubere Weise zu tun und konnten einen grossen Anteil des Codes wiederverwenden, weil Commerce 2.x dank der Flexibilität des Frameworks hinter der Benutzeroberfläche genau dafür gebaut ist, um das zu unterstützen.

Die Integration in externe Systeme wurde in Drupal 8/Commerce 2.x wesentlich einfacher im Vergleich einem Projekt mit ähnlichen Anforderungen in einem Commerce-1.x-Projekt. Die Konvertierung von Datenstrukturen, Fehlerbehandlung und allgemeiner Interaktion mit einem oder mehreren externen Systemen erfordert nach wie vor eine beträchtliche Menge an Code und Entwicklungszeit. Dienste, Plugins und verbesserte APIs unterstützen die Entwickler beim Schreiben eines sauberen und betriebsfreundlichen Codes.

Wir sind davon überzeugt, dass Commerce 2 ein grossartiges Framework ist, das sowohl für Standard-Shops mit Produkten, Lieferung und einem üblichen Check-out-Vorgang als auch für stark angepasste E-Commerce-Lösungen genutzt werden kann. Wir freuen uns auf unsere nächsten E-Commerce-Projekte.

Kontaktieren Sie uns, falls Sie ein Drupal-Commerce-Projekt planen.

Eager to read more? Check related projects!