Tutorial: Bestellungs-Export in xt:Commerce VEYTON richtig konfigurieren

zurück zum Blog

Wenn man in xt:Commerce VEYTON versucht, Bestellungen mit Hilfe des Export-Managers zu exportieren, kann einen das bis zur Verzweiflung treiben. Trotzdem ist der Export-Manager eine sehr praktische Funktion. Mit Hilfe dieses Tools kann man ohne den Einsatz von zusätzlichen Plugins umfangreiche Exporte aus dem xt:Commerce VEYTON Shop realisieren.

Konfigurations-Backend von xt:Commerce VEYTON

Export-Manager

Der Export-Manager wurde augenscheinlich dafür entwickelt, Preis-Suchmaschinen Dateien mit den eigenen Produktpreisen bereitzustellen. Im Laufe der Zeit ist hier anscheinend die Möglichkeit hinzu gekommen, Bestellungen ebenfalls zu exportieren.

Export-Manager - xt:Commerce VEYTON

Dies kann man vielfältig nutzen. Zum Beispiel ermöglicht der Export es die Bestellungen an eine Warenwirtschaft zu übermitteln, per E-Mail zu versenden oder einfach nur die Lieferadressen an einen Paketdienst zu übermitteln.

Das ist eine tolle, flexible Funktion - wenn man sie denn zu bedienen weiß.

Typische Probleme mit dem Export-Manager

Leider wurde der Export-Manager nicht dafür optimiert, dem Benutzer bei Eingabefehlern zu unterstützen. So erwischt man sich, dass man schnell nach dem Trial-And-Error-Prinzip handelt, um die Fehler zu beseitigen. Dann tappt man lange im Dunkeln und muss viel ausprobieren. So erging es auch uns. Die folgenden Probleme haben uns viel Zeit gekostet:

  • Finden von möglichen Export-Feldern
  • Dateityp mit oder ohne Punkt
  • Stamm-Verzeichnis für Exporte auf dem Server anpassen
  • Einschränkungen wählen, dass nur bestimmte Bestellungen exportiert werden
  • Fehlermeldungen wurden kaum bis gar nicht ausgegeben
  • Im Fehlerfall wurde die Export-Datei einfach nicht erstellt

Schritt-für-Schritt Anleitung um Bestellungen zu exportieren

Diese Anleitung beschreibt den Export von offenen Bestellungen in einem nahezu vollständigen XML-Format (fast alle möglichen Felder der Bestellung sind enthalten). Dieses XML-Format kann z. B. von ERP-Systemen bzw. einer Warenwirtschaft eingelesen werden, um diese Bestellungen automatisch weiterzuverarbeiten.

Schritt 1: Export-Manager aufrufen

Nachdem die Anmeldung im Admin-Bereich des Shop-Systems abgeschlossen wurde, muss der Export-Manager geöffnet werden. Dies erfolg im Menü über "Inhalte / Exporte / Export-Manager".

Export-Manager aufrufen - xt:Commerce VEYTON - Export-Manager

Schritt 2: Neuen Export erstellen

Ein neuer Export wird über die Schaltfläche "Neu" erstellt. Danach öffnet sich eine neue Registerkarte.

Neuen Export erstellen - xt:Commerce VEYTON - Export-Manager

Schritt 3: Export-Einstellungen festlegen

Die Export-Einstellungen sollten wie folgt vorgenommen werden.

  • Shop-ID: 1 (ggf. abweichend)
  • Titel: Alle Bestellungen exportieren XML Structured
  • Export-Typ: 2
  • Header: (siehe unten)
  • Body: (siehe unten)
  • Footer: (siehe unten)
  • Dateiname: orders
  • Dateityp: .xml
  • Zeichensatz: UTF-8
  • Auf Server speichern: aktiviert
  • Datensätze pro Durchgang: 1000 (multiplizieren Sie hier die Anzahl Ihrer täglichen Bestellungen ca. mit 5)

Einstellungen für den neuen Export - xt:Commerce VEYTON - Export-Manager

Schritt 4: Header, Body und Footer festlegen

Header (1x am Anfang der Datei)

<?xml version="1.0" encoding="UTF-8" ?>
<orders>

Body (wird pro Bestellung wiederholt)

  <order id="{$data.order_data.orders_id}" shop_id="{$data.order_data.shop_id}" campaign_id="{$data.order_data.campaign_id}">
    <status id="{$data.order_data.orders_status_id}" name="{$data.order_data.orders_status}" />
    <payment code="{$data.order_data.payment_code}" name="{$data.order_data.payment_name}" subcode="{$data.order_data.subpayment_code}" />
    <shipping code="{$data.order_data.shipping_code}" name="{$data.order_data.shipping_name}" />
    <currency code="{$data.order_data.currency_code}" value="{$data.order_data.currency_value}" />
    <language code="{$data.order_data.language_code}" />
    <comments>{$data.order_data.comments}</comments>
    <allow_tax>{$data.order_data.allow_tax}</allow_tax>
    <date_purchased>{$data.order_data.date_purchased_plain}</date_purchased>
    <email_address>{$data.order_data.customers_email_address}</email_address>
    <customers_status>{$data.order_data.customers_status}</customers_status>
    <customers_cid>{$data.order_data.customers_cid}</customers_cid>
    <customers_vat_id>{$data.order_data.customers_vat_id}</customers_vat_id>
    <last_modified>{$data.order_data.last_modified}</last_modified>
    <customer id="{$data.order_customer.customers_id}" status="{$data.order_customer.status}" account_type="{$data.order_customer.account_type}" campaign_id="{$data.order_customer.campaign_id}">
      <external_id>{$data.order_customer.external_id}</external_id>
      <customer_cid>{$data.order_customer.customers_cid}</customer_cid>
      <vat id="{$data.order_customer.customers_vat_id}" status="{$data.order_customer.customers_vat_id_status}" />
      <email_address>{$data.order_customer.customers_email_address}</email_address>
      <payment_unallowed>{$data.order_customer.payment_unallowed}</payment_unallowed>
      <shipping_unallowed>{$data.order_customer.shipping_unallowed}</shipping_unallowed>
      <date_added>{$data.order_customer.date_added}</date_added>
      <default_currency>{$data.order_customer.customers_default_currency}</default_currency>
      <default_language>{$data.order_customer.customers_default_language}</default_language>
      <age>{$data.order_customer.customers_age}</age>
      <dob>{$data.order_customer.customers_dob}</dob>
      <gender>{$data.order_customer.customers_gender}</gender>
      <last_modified>{$data.order_customer.last_modified}</last_modified>
    </customer>
    <delivery_address address_book_id="{$data.order_data.delivery_address_book_id}">
      <gender>{$data.order_data.delivery_gender}</gender>
      <firstname>{$data.order_data.delivery_firstname}</firstname>
      <lastname>{$data.order_data.delivery_lastname}</lastname>
      <company>{$data.order_data.delivery_company}</company>
      <company_2>{$data.order_data.delivery_company_2}</company_2>
      <company_3>{$data.order_data.delivery_company_3}</company_3>
      <street_address>{$data.order_data.delivery_street_address}</street_address>
      <postcode>{$data.order_data.delivery_postcode}</postcode>
      <city>{$data.order_data.delivery_city}</city>
      <suburb>{$data.order_data.delivery_suburb}</suburb>
      <phone>{$data.order_data.delivery_phone}</phone>
      <fax>{$data.order_data.delivery_fax}</fax>
      <country code="{$data.order_data.delivery_country_code}" name="{$data.order_data.delivery_country}" />
      <zone id="{$data.order_data.delivery_zone}" code="{$data.order_data.delivery_zone_code}" />
      <federal_state code="{$data.order_data.delivery_federal_state_code}" iso="{$data.order_data.delivery_federal_state_code_iso}" />
    </delivery_address>
    <billing_address address_book_id="{$data.order_data.billing_address_book_id}">
      <gender>{$data.order_data.billing_gender}</gender>
      <firstname>{$data.order_data.billing_firstname}</firstname>
      <lastname>{$data.order_data.billing_lastname}</lastname>
      <company>{$data.order_data.billing_company}</company>
      <company_2>{$data.order_data.billing_company_2}</company_2>
      <company_3>{$data.order_data.billing_company_3}</company_3>
      <street_address>{$data.order_data.billing_street_address}</street_address>
      <postcode>{$data.order_data.billing_postcode}</postcode>
      <city>{$data.order_data.billing_city}</city>
      <suburb>{$data.order_data.billing_suburb}</suburb>
      <phone>{$data.order_data.billing_phone}</phone>
      <fax>{$data.order_data.billing_fax}</fax>
      <country iso_code="{$data.order_data.billing_country_code}" display_name="{$data.order_data.billing_country}" />
      <zone id="{$data.order_data.billing_zone}" code="{$data.order_data.billing_zone_code}" />
      <federal_state code="{$data.order_data.billing_federal_state_code}" iso="{$data.order_data.billing_federal_state_code_iso}" />
    </billing_address>
    <products>
{foreach from=$data.order_products item=row}
      <product id="{$row.products_id}" model="{$row.products_model}">
        <products_name>{$row.products_name}</products_name>
        <products_discount>{$row.products_discount}</products_discount>
        <quantity>{$row.products_quantity}</quantity>
        <data>{$row.products_data}</data>
        <allow_tax>{$row.allow_tax}</allow_tax>
        <shipping_time>{$row.products_shipping_time}</shipping_time>
        <tax rate="{$row.products_tax_rate}" class="{$row.products_tax_class}" />
        <price value="{$row.products_price.plain}" value_otax="{$row.products_price.plain_otax}" tax="{$row.products_tax.plain}" />
        <final_price value="{$row.products_final_price.plain}" value_otax="{$row.products_final_price.plain_otax}" tax="{$row.products_final_tax.plain}" />
      </product>
{/foreach}
    </products>
    <totals>
{foreach from=$data.order_total_data item=row}
      <total key="{$row.orders_total_key}" mode="{$row.orders_total_model}" name="{$row.orders_total_name}">
        <quantity>{$row.orders_total_quantity}</quantity>
        <allow_tax>{$row.allow_tax}</allow_tax>
        <tax rate="{$row.orders_total_tax_rate}" class="{$row.orders_total_tax_class}" />
        <price value="{$row.orders_total_price.plain}" value_otax="{$row.orders_total_price.plain_otax}" tax="{$row.orders_total_tax.plain}" />
        <final_price value="{$row.orders_total_final_price.plain}" value_otax="{$row.orders_total_final_price.plain_otax}" tax="{$row.orders_total_final_tax.plain}" />
      </total>
{/foreach}
    </totals>
    <sum>
      <products value="{$data.order_total.product_total.plain}" value_otax="{$data.order_total.product_total_otax.plain}" />
      <data value="{$data.order_total.data_total.plain}" value_otax="{$data.order_total.data_total_otax.plain}" />
      <final value="{$data.order_total.total.plain}" value_otax="{$data.order_total.total_otax.plain}" />
      <taxes>
{foreach from=$data.order_total.total_tax item=row}
        <tax rate="{$row.tax_key}" value="{$row.tax_value.plain}" />
{/foreach}
      </taxes>
    </sum>
  </order>

Footer (1x am Ende Datei)

</orders>

Weitere Formate

Es sind auch beliebige andere Format-Einstellungen möglich, zum Beispiel für bestimmte Warenwirtschaften oder in Standard-Formaten. Einige Formate sind entsprechend vorbereitet und können hier abgerufen werden:

Die folgenden Formate lassen sich mit Hilfe von Konvertern erstellen:

  • Lexware eCommerce Auftragsimport (als eine dem OpenTrans-Format ähnliche-Variante)
  • Bestellimport für die HS Auftragsbearbeitung (als Textdatei)

Schritt 5: Filter für Bestellungen wählen

Nachdem die Standard-Einstellungen in Schritt 3 und 4 gemacht worden sind, sollten spezielle Filterkriterien für den Export gewählt werden. Ein wenig verwirrend ist in diesem Zusammenhang leider die Gestaltung der Oberfläche. Obwohl der Export-Typ "2 - Bestellungen" ausgewählt worden ist, werden Einstellungen zu dem Artikel-Export immer noch angezeigt und sind auch ausfüllbar. Wenn man dort Artikel-Einstellungen wählt, haben diese natürlich keine Funktion. Deshalb muss zunächst die Registerkarte "Bestellungen" ausgewählt werden. Dort sollten dann folgende Einstellungen vorgenommen werden:

  • Kundengruppe: 0 (alle)
  • Bestellstatus: 16 (kann ggf. abweichen - gilt hier für offene Bestellungen)
  • Anzahl Stunden: 0
  • Von Datum: -leer-
  • Bis Datum: -leer-

Filter für Bestellungen konfigurieren - xt:Commerce VEYTON - Export-Manager

Achtung: Diese Filter verleiten sehr zum Ausprobieren. Hier sollte man nur sehr vorsichtig Änderungen machten, weil ansonsten vielleicht zu wenige Bestellungen oder gar keine mehr exportiert werden. Nach jeder Änderung sollte der Export erneut getestet werden.

Unter den Registerkarten "E-Mail", "FTP" und "Formular" werden in diesem Beispiel keine Einstellungen mehr vorgenommen, weil die Daten vom Webserver direkt heruntergeladen werden sollen. Wer es benötigt, kann natürlich auch eine der Übertragungsvarianten wählen.

Jetzt kann der neue Export mit einem Klick auf "Speichern" gesichert werden. Anschließend gelangt man wieder in die Haupt-Übersicht.

Export speichern - xt:Commerce VEYTON - Export-Manager

Schritt 6: Export testen

Nach einem Wechsel in die Übersicht des Export-Managers kann der Export getestet werden. Hierzu genügt ein Klick auf die orangefarbene Feed-Schaltfläche.

Export über die Feed-Schaltfläche testen - xt:Commerce VEYTON - Export-Manager

Wenn der Export erfolgreich ausgeführt wurde, wird dies über die Meldung "Export finished" quittiert.

Quittierung des erfolgreichen Exports - xt:Commerce VEYTON - Export-Manager

Schritt 7: Verzeichnis per HTACCESS absichern und Export in dieses Verzeichnis umleiten

Auf dem Webserver wird im Export-Verzeichnis von xt:Commerce VEYTON jetzt noch ein geschütztes Unterverzeichnis angelegt. In diesem Beispiel ist der Name des geschützten Verzeichnisses "hidden".

In dieses Verzeichnis muss eine HTACCESS-Datei und eine Passwortdatei abgelegt werden.

.htaccess
AuthType Basic
AuthName "Exporte"
AuthUserFile C:/xampp/htdocs/xtc/export/hidden/.htpasswd
require valid-user
Achtung: Der kursiv geschriebene Teil muss durch den vollständigen Serverpfad zur Passwortdatei ersetzt werden. In diesem Beispiel wurde eine lokale XAMPP-Installation auf einem Windows-Rechner eingesetzt.

Die zu diesem Beispiel passende Passwortdatei mit dem Namen ".htpasswd" kann über das Dienstprogramm "htpasswd" (in XAMPP enthalten) erzeugt werden. Das Dienstprogramm befindet sich bei einer Standard-Installation von XAMPP unter "C:\xampp\apache\bin". Alternativ ist es bei der Apache-Installation unter Linux und Windows ebenfalls enthalten.

Hier wird eine Passworddatei unter "C:\xampp\htdocs\xtc\export\hidden\.htpasswd" für den Benutzer "export" angelegt.

htpasswd -c C:\xampp\htdocs\xtc\export\hidden\.htpasswd export

Ausgabe:

Automatically using MD5 format.
New password: ******
Re-type new password: ******
Adding password for user export

Schritt 8: Passwort im Export festlegen

Neben der Registerkarte "Standard" befindet sich die Registerkarte "Sicherheit". Hier kann eingestellt werden, dass der Export nur dann funktionieren soll, wenn per GET-Parameter eine Anmeldung bestehend aus Benutzername und Passwort verwendet wird.

Sicherheitseinstellungen festlegen - xt:Commerce VEYTON - Export-Manager

Hinweis: Sobald der Passwortschutz aktiv ist, kann der Export unter Umständen nicht mehr im Backend mit dem Feed-Button getestet werden. Der Aufruf muss in dem Fall direkt im Webbrowser gemacht werden (siehe Schritt 10).

Schritt 9: Datei im geschützten Verzeichnis ablegen

Damit die Export-Datei "orders.xml" auch wirklich im geschützten Verzeichnis ankommt, muss der Export noch einmal angepasst werden.

Hierzu wird auf der Registerkarte "Standard" unter Dateiname der Verzeichnisname vorangestellt: "hidden/orders"

Export-Datei in ein Unterverzeichnis umleiten - xt:Commerce VEYTON - Export-Manager

Schritt 10: Erstellung der Export-Datei

Nachdem nun alle Einstellungen vorgenommen worden sind, kann der Export durchgeführt werden. Hierzu erfolgt der Aufruf direkt im Browser. Die Parameter "feed_id", "user" und "pass" müssen natürlich entsprechend den eigenen Einstellungen angepasst werden.

Tipp: Den Wert für den Parameter "feed_id" findet man in der Übersicht der Exporte in der ersten Spalte "Feed ID".

Feed ID herausfinden - xt:Commerce VEYTON - Export-Manager

Anmeldung per GET-Parameter

http://localhost/xtc/cronjob.php?feed_id=3&user=benutzername&pass=passwort

Der Abruf der Bestellung kann ebenfalls im Browser erfolgen.

Mehr Sicherheit durch den "SecKey"

Ab der Version 4.1.10 ist eine CSRF-Protection sowie ein Security-Key im Shop implementiert. [...] Der Security-Key ist in der Datenbank und muss bei Funktionen genutzt werden, die von externen Diensten gestartet werden sollen können (z.B. Im und Exporte).

https://xtcommerce.atlassian.net/wiki/pages/viewpage.action?pageId=26968070

Dieser Security-Key muss, sofern diese Funktion nicht deaktiviert wurde, mit angegeben werden. Wo der Security-Key zu finden ist, kann hier nachgelesen werden.

http://localhost/xtc/cronjob.php?feed_id=3&user=benutzername&pass=passwort&seckey=security_key

Abruf der Bestellung als XML-Datei

http://localhost/xtc/export/hidden/orders.xml

Beim Abruf der Bestellung als XML-Datei erfolgt zuvor noch die HTTP-Passwortabfrage, die mittels .htaccess und .htpasswd eingerichtet wurde.

Tipps zur Vorgehensweise

Nach einem ersten sehr erfolglosen Versuch, bei dem gar nichts funktionieren wollte, entschied ich mich für eine strukturiertere Vorgehensweise.

  • Ich habe einen möglichst einfachen Export konfiguriert, um die generelle Funktionsweise zu prüfen. Dazu habe ich lediglich ein paar Zeichen in den Header geschrieben.
  • Nachdem eine leere oder fast leere Datei erstellt wurde, habe ich begonnen, die Inhalte (Body) einzupflegen.
  • Jetzt konnte ich weitere Einschränkungen wählen.
  • Die Bestellungen habe ich auf "offene Bestellungen" gefiltert, damit die abgeschlossenen Bestellungen nicht mehr exportiert werden.
  • Ich habe die maximale Anzahl der Datensätze auf 1000 erweitert - damit erst einmal genug Reserven zur Verfügung stehen. Achtung: Das kann den Export aber verlangsamen und den Server belasten.
  • Nach jedem Schritt habe ich getestet, ob der Export noch funktioniert.

Folgebeitrag: Tutorial: Bestellungen aus xt:Commerce mit cURL herunterladen


Über Daniel Peters

Daniel Peters

Ich helfe E-Commerce-Agenturen und Online-Händlern Stolperfallen beim Verbinden von IT-Systemen (wie etwa Warenwirtschaften) mit dem Onlineshop zu vermeiden.

Sie wollen mehr über mich wissen? Dann bitte hier entlang.

Sie haben eine dringende Frage zum Thema Schnittstellen-Software, wünschen Beratung bei E-Commerce-Prozessen, sowie unkomplizierte Betreuung? Sprechen Sie mich gern an und lassen Sie uns gemeinsam an Ihrem Projekt arbeiten.

Kontakt Twitter Xing