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.
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.
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ß.
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:
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.
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".
Ein neuer Export wird über die Schaltfläche "Neu" erstellt. Danach öffnet sich eine neue Registerkarte.
Die Export-Einstellungen sollten wie folgt vorgenommen werden.
<?xml version="1.0" encoding="UTF-8" ?> <orders>
<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>
</orders>
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:
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:
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.
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.
Wenn der Export erfolgreich ausgeführt wurde, wird dies über die Meldung "Export finished" quittiert.
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.
.htaccessAuthType Basic AuthName "Exporte" AuthUserFile C:/xampp/htdocs/xtc/export/hidden/.htpasswd require valid-userAchtung: 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
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.
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).
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"
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".
http://localhost/xtc/cronjob.php?feed_id=3&user=benutzername&pass=passwort
Der Abruf der Bestellung kann ebenfalls im Browser erfolgen.
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).
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
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.
Nach einem ersten sehr erfolglosen Versuch, bei dem gar nichts funktionieren wollte, entschied ich mich für eine strukturiertere Vorgehensweise.
Folgebeitrag: Tutorial: Bestellungen aus xt:Commerce mit cURL herunterladen
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.