everysize / checkout-prestashop
everysize Checkout for PrestaShop 8.1/9: imports everysize orders and reports shipping, tracking, cancellations, returns and refunds back to everysize
Package info
github.com/everysize/checkout-prestashop
Type:prestashop-module
pkg:composer/everysize/checkout-prestashop
Requires
- php: >=8.1
- ext-curl: *
- ext-json: *
- composer/installers: ^1.0 || ^2.0
Requires (Dev)
- phpunit/phpunit: ^10.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Bindet einen PrestaShop-Shop an den everysize-Direktkauf an: Bestellungen, die Kundinnen auf everysize.com aufgeben, landen als Bestellung im Shop; Bestellnummer, Versand, Storno, Retoure und Erstattungen gehen zurück an everysize.
Modul-Name everysize_checkout, Version 1.3.0, MIT.
Voraussetzungen
- PrestaShop 8.1 bis 9.x (getestet mit 9.2.0 / PHP 8.4)
- PHP ≥ 8.1 mit
curl - ein Cronjob (PrestaShop hat keinen eigenen Scheduler für Module)
Kein PayPal-Modul nötig: bezahlt wird bei everysize. Erstattet wird im Reiter „everysize" der Bestellung über everysize oder direkt im PayPal-Konto des Händlers. Ab 1.1.0 zahlt auch eine Gutschrift im Shop (Teil-/Standarderstattung, Rücksendung) den Betrag über everysize an PayPal zurück — abschaltbar, ab PrestaShop 9.
Installation
-
Im Backoffice unter Module → Modul-Manager → Modul hochladen das ZIP
everysize-checkout-prestashop-vX.Y.Z.ziphochladen (es enthält den Ordnereverysize_checkout/) und „everysize Checkout" installieren.Alternativ mit Composer im Verzeichnis des Shops:
composer config allow-plugins.composer/installers true composer require everysize/checkout-prestashopDas Paket landet in
modules/everysize_checkout/; danach im Modul-Manager installieren. Update:composer update everysize/checkout-prestashop, dann im Modul-Manager „Aktualisieren". -
Beim Update per ZIP das neue ZIP genauso hochladen; PrestaShop führt die Upgrade-Schritte des Moduls aus.
-
Module → Modul-Manager → everysize Checkout → Konfigurieren: Client-ID und Client-Secret aus everysize Business („Shop-Integration" → PrestaShop) eintragen, Versanddienstleister und Status-Zuordnungen prüfen, mit „Verbindung testen" prüfen.
-
Cronjob anlegen — alle 5 Minuten:
*/5 * * * * cd /pfad/zum/shop && php bin/console everysize:sync
Ohne Console-Zugang (Webcron):
https://<shop>/index.php?fc=module&module=everysize_checkout&controller=cron&token=<Token>(Token steht nach der Installation in den Moduleinstellungen.)
Ablauf
| Richtung | Was | Wann |
|---|---|---|
| everysize → Shop | neue Bestellungen (PROCESSING, auch bereits stornierte REVOKED) ohne Händler-Bestellnummer |
jeder Lauf |
| Shop → everysize | PrestaShop-Bestellnummer | direkt nach dem Import |
| everysize → Shop | Hinweis, wenn eine importierte Bestellung bei everysize storniert wurde (siehe „Storno bei everysize“) | nach Import und Export, jeder Lauf |
| Shop → everysize | Preis und Bestand des Artikels im Shop | direkt nach dem Import |
| Shop → everysize | Versand mit Sendungsnummer und Versanddienstleister | Bestellstatus = „Versandt" (einstellbar) |
| Shop → everysize | Sendungsnummer nachgetragen oder korrigiert | bis 14 Tage nach der Versandmeldung, nur wenn everysize sie noch nicht hat |
| Shop → everysize | Erstattung (ganz oder teilweise) | Button im Reiter „everysize" |
| Shop → everysize | Erstattung über Gutschrift (Teil-/Standarderstattung, Rücksendung im Shop) | Gutschrift im PS-Admin, abschaltbar (ab PrestaShop 9) |
| Shop → everysize | volle Erstattung | automatisch nach einem Storno vor dem Versand, nur wenn nachweislich nichts versendet und noch nichts erstattet wurde (abschaltbar, siehe unten) |
| Shop → everysize | Storno MERCHANT_DECLINE |
Bestellung storniert, bevor der Versand gemeldet war |
| Shop → everysize | Retoure RETOUR |
Rücksendung „Paket erhalten" oder Bestellstorno nachdem der Versand gemeldet war |
- Erstattung aus dem Reiter: Der Button fragt mit dem Betrag nach, das Feld ist mit dem offenen Betrag vorbelegt, ein leeres Feld erstattet nie. Das Formular sendet die beim Laden bekannte Erstattungssumme mit und erstattet nur bei lesbarer Liste: Hat sich die Summe geändert (veralteter Reiter), steht „bitte neu laden“. Der Aufruf wartet bis zu 90 Sekunden auf PayPal, geht nur per POST und trägt ein Formular-Token. Der Webserver des Händlers kann früher abbrechen, deshalb wird der Vorgang (Schlüssel, Betrag, Zeit) vor dem Senden gespeichert, höchstens einer je Bestellung.
- Ergebnis unklar: Nur eine nachweisliche Ablehnung (422 mit
PAYPAL_REFUND_FAILEDoderREFUND_AMOUNT_INVALID, 400 mitORDER_NOT_PAID_USING_EVERYSIZE_CHECKOUT_PAYMENTS) beendet den Vorgang: kein Geld geflossen, der nächste Versuch bekommt einen neuen Schlüssel. Alles andere (keine Antwort, Zeitüberschreitung, 3xx, 401, 403, 404, 408, 409, 425, 429, 5xx, unbekannte Antworten) lässt ihn offen: Das Geld kann geflossen sein, bitte in PayPal prüfen. Ein gescheiterter Token-Abruf vor dem Senden ist keine Ablehnung, es ist nichts passiert. Solange ein Vorgang offen ist, geht nichts anderes raus: weder ein anderer Betrag noch die automatische Erstattung noch eine Gutschrift. Das Wiederholen ist eine eigene Aktion, erst nach 150 Sekunden, und liest vorher die PayPal-Liste: Steht dort eine Erstattung mit gleichem Betrag, die der Shop noch nicht kennt, wird der Vorgang damit abgeschlossen und nichts gesendet; sonst wird der Betrag mit demselben Schlüssel gesendet – ging die erste Anfrage nicht durch, wird er jetzt ausgezahlt. Wer nichts mehr oder etwas anderes erstatten will, wählt „Als geklärt markieren“ (ab 150 Sekunden, sendet nichts, die automatische Erstattung bleibt für die Bestellung aus). - Reservieren, dann lesen: Der Vorgang wird zuerst reserviert, dann wird die Liste gelesen und
ihr Stand (die
refundIds) im Vorgang gespeichert; ist die Liste nicht lesbar oder keine echte Liste, wird der neu angelegte Vorgang wieder gelöscht und nichts gesendet. Als Treffer beim Wiederholen zählt nur eine Erstattung, die nicht im gespeicherten Stand und nicht in den Berichten des Shops steht. Eine 2xx-Antwort ohnerefundIdgilt als unklar, nicht als Erfolg. Lehnt der Checkout eine Wiederholung ab, bleibt der Vorgang offen; nur die Ablehnung des ersten Versuchs löscht ihn. Der offene Vorgang wird auch angezeigt, wenn die Liste nicht lesbar ist, mit „Als geklärt markieren“ (bedingtes Löschen, mit Protokolleintrag). - Gutschein: Wählt man bei Teil-/Standarderstattung oder Rücksendung „Gutschein erzeugen“, bleibt die Gutschrift im PrestaShop-Formular vorausgewählt; das Modul zahlt dann nichts über PayPal aus (sonst gäbe es Auszahlung und Gutschein über denselben Betrag) und warnt im Backoffice und im Protokoll.
- Gutschrift: Die Gutschrift bleibt im Shop gebucht, was auch passiert (PrestaShop legt sie schon an, der Hook kann sie nicht zurücknehmen). Ausgezahlt wird nur, wenn kein Vorgang offen ist, die Erstattungsliste lesbar ist und Erstattetes plus dieser Betrag die Summe aller Gutschriften nicht übersteigt. Sonst steht im Backoffice, warum nicht – und der Betrag wird im Reiter erstattet. Eine zweite Gutschrift über denselben Betrag erstattet nie mit dem Schlüssel der ersten und nie zweimal; es gibt keine Sofort-Wiederholung.
- Automatische Erstattung: Nach einem gemeldeten Storno vor dem Versand
erstattet das Modul den vollen Betrag – aber nur, wenn nachweislich nichts
versendet wurde (kein Versand-Status und kein „versendet“-Status in der Historie,
keine Sendungsnummer, kein Lieferschein –
delivery_numberan Bestellung oder Rechnung –, keine Versandmeldung) und nichts erstattet ist (keine Gutschrift, keine erstattete Position, nicht der Status „Erstattet“ und bei everysize keine ErstattungCOMPLETEDoderPENDING, auch keine direkt in PayPal gemachte). Lässt sich die Erstattungsliste nicht lesen, überspringt das Modul den Lauf und prüft im nächsten erneut. Der Lauf nutzt denselben offenen Vorgang wie der Reiter (Schlüsselauto-decline-<Bestellung>) und sendet höchstens einmal: Nur eine nachweisliche Ablehnung ist endgültig, alles andere bleibt offen; ein offener Vorgang wird vom Lauf danach nur noch mit der Liste abgeglichen (Treffer: abgeschlossen) und nie erneut gesendet – das tut nur ein Mensch. Direkt vor dem einen Senden werden Einstellung und Bedingungen für genau diese Bestellung noch einmal geprüft. Offene Vorgänge über 15 Minuten (seit dem Anlegen) stehen in jedem Lauf als Fehler im Protokoll. Schließt die Abfrage ein Storno aus (versendet, Sendungsnummer, Lieferschein, Gutschrift, frühere Erstattung), steht einmal ein Hinweis im Protokoll. Eine versendete Bestellung wird nie automatisch erstattet und alsRETOURgemeldet; scheitert die Versandmeldung, bleibt sie nachzuholen. Die Erstattung gilt nur für Stornos nach Installation bzw. Upgrade auf 1.2.0, nie rückwirkend – auch dann nicht, wenn die Revocation erst später rausgeht. Grenze: Offline-Erstattungen, die der Händler außerhalb von PrestaShop und PayPal gebucht hat (z. B. Überweisung ohne Gutschrift oder Statuswechsel), kennt das Modul nicht. - Zuordnung: Bestellpositionen über
sku= PrestaShop-Referenz der Kombination (z. B.CW2288-111-42.5); ohne Kombinationen die Artikel-Referenz. Exakter Treffer vor Groß-/Kleinschreibung, aktiver vor inaktivem Artikel; zwei gleich gute Treffer sind ein Fehler. - Preise: Bestellung mit den bei everysize bezahlten Bruttopreisen.
Netto und Mehrwertsteuer rechnet das Modul mit dem Steuersatz des Produkts
(Steuerregeln des Shops) zurück; Versandkosten erben den höchsten
Positionssatz. Weicht die erwartete Gesamtsumme von
grossPriceab, landet eine Warnung im Protokoll (Import läuft trotzdem). - Bestand: wird beim Import reduziert, auch unter 0 (Warnung im Protokoll); ein Storno/Rücksendung im Shop bucht ihn wie gewohnt zurück.
- Preis und Bestand melden: vor dem Schreiben liest das Modul den aktuellen Bruttopreis (inkl. Aktionspreis) und, wenn der Shop den Verkauf über den Bestand begrenzt, den Bestand des Artikels. Weicht der Preis ab oder ist der Bestand kleiner als die bestellte Menge, steht eine Warnung im Protokoll. Beide Werte gehen nach dem Import einmal an everysize. Die Bestellung bleibt zum bei everysize bezahlten Preis bestehen; scheitert die Meldung, läuft der Import trotzdem durch und die Meldung wird nicht wiederholt.
- Kunde:
customer.emailist eine Weiterleitungsadresse von everysize, stabil je Kundin; ein Wiederkauf landet am selben (Gast-)Konto. Mails des Shops gehen dorthin und laufen über everysize. Die Original-Adresse (customer.originalEmail) steht nur zur Information im Reiter „everysize". - Zahlart: importierte Bestellungen tragen „everysize (PayPal)" mit der PayPal-Capture-ID als Transaktions-ID. Das Geld ist bei everysize bezahlt.
- Status-Zuordnungen: welche Bestellstatus „bezahlt importiert", „storniert importiert", „versandt" und „storniert" bedeuten, ist in den Moduleinstellungen einstellbar (Defaults: „Zahlung akzeptiert", „Zahlung akzeptiert", „Versandt", „Storniert").
- Atomar: Validierung (Produkt, Land, Beträge) vor dem ersten Schreiben; schlägt ein Import fehl, bleibt die Bestellung bei everysize und wird im nächsten Lauf erneut versucht.
- Genau einmal: jede Meldung steht mit eindeutigem Schlüssel (Bestellung,
Art, SKU) in
everysize_report; ein zweiter Lauf meldet nichts doppelt. - Storno bei everysize: vor jeder Meldung fragt das Modul den Stand bei
everysize ab. Ist die Bestellung dort schon storniert (PayPal-Erstattung,
everysize Business), meldet es nichts: ein Versand würde sie auf
COMPLETEDzurücksetzen, ein Storno den Grund von everysize überschreiben. - Hinweis bei Storno durch everysize: Wird eine bereits importierte Bestellung
danach bei everysize storniert (z. B. von der Kundin widerrufen und erstattet), schreibt das
Modul einen privaten Hinweis in die Bestellung – sichtbar nur im Backoffice (Bestellseite,
„Nachrichten“, mit einem Mitarbeiter als Absender und dem Textanfang „everysize:“, als privat gekennzeichnet), nie an die Kundin, es geht keine E-Mail raus – und einen
Warnung-Eintrag ins Protokoll: „Bestellung wurde bei everysize storniert. Bitte nicht
versenden und im Shop stornieren.“ (in der Sprache der Bestellung, Deutsch oder Englisch). Ist die
Bestellung im Shop schon als versendet belegt, lautet der Hinweis: „… ist hier aber schon als
versendet markiert. Bitte prüfen.“ Ist sie im Shop schon storniert oder erstattet, gibt es keinen
Hinweis. Der Hinweis nennt nur die Bestellnummer. Das Modul ändert dabei nichts: kein
Statuswechsel, keine Bestandsbuchung, keine Erstattung, keine Meldung an everysize – das
entscheidet der Händler. Die Abfrage läuft nach Import und Export, betrachtet Bestellungen der
letzten 30 Tage (Anlegedatum), liest höchstens 500 Zeilen je Lauf (bei mehr die jüngsten) und einen Fehler dabei (keine
Antwort, 401, 404, 5xx, ungültige Antwort) sieht man höchstens einmal je Tag und Fehlerart als Warnung im Protokoll (weitere gehen ins PrestaShop-Log); Import
und Export laufen unabhängig davon. Jede Bestellung bekommt den Hinweis genau einmal (Marker
es-revokedineverysize_report, im Reiter „everysize“ als „Storniert bei everysize“). - Testumgebung: Umgebungsvariable
EVERYSIZE_CHECKOUT_API_URLauf eine HTTPS-Adresse untereverysize.comsetzen (z. B. im Docker-Compose); alles andere wird abgelehnt, nie still auf Produktion gefallen. Die Moduleinstellungen zeigen die aktive Umgebung.
CLI-Commands
| Command | Wirkung |
|---|---|
everysize:sync |
Import und Export — der Cron-Job (empfohlen */5 * * * *) |
everysize:order:import |
nur Bestellungen holen + Bestellnummer melden |
everysize:order:export |
nur Versand/Storno/Retoure/Erstattungen melden |
Cron einrichten
Der Sync holt Bestellungen und meldet Status zurück — er sollte alle
5 Minuten laufen. Voraussetzungen: PHP ≥ 8.1 mit pdo_mysql, curl,
mbstring; PrestaShop 8.1 oder 9.x.
Empfohlen: System-Cron über die Konsole des Shops
*/5 * * * * php /pfad/zum/shop/bin/console everysize:sync --no-interaction >> /var/log/everysize-sync.log 2>&1
Der Befehl steht auch in den Moduleinstellungen („Sync“). Bei Fehlern landet ein Lauf nicht in einer Endlosschleife — nicht gemeldete Änderungen holen die nächsten Läufe nach.
Alternative: Webcron (Hoster ohne Konsole)
Die Moduleinstellungen zeigen die Webcron-URL mit Token
(index.php?fc=module&module=everysize_checkout&controller=cron&token=…).
Das Token wird bei der Installation erzeugt und kann alternativ im Header
X-Everysize-Token: <Token> übergeben werden. Ein Beispiel für
cron-job.org: URL eintragen, Intervall 5 Minuten, Header
X-Everysize-Token mit dem Token aus den Moduleinstellungen.
Datenbank
Das Modul legt vier Tabellen an (Präfix des Shops, Default ps_):
| Tabelle | Inhalt |
|---|---|
everysize_order |
Verlinkung Bestellung ↔ everysize-Order-ID, PayPal-Capture-ID, Original-E-Mail, Bestellnummer gemeldet |
everysize_order_item |
Positionen mit SKU (exakt wie von everysize geschickt) |
everysize_report |
jede Meldung genau einmal: (id_order, kind, sku) — fulfillment / revocation / tracking / refund |
everysize_protocol |
Protokoll der Läufe (31 Tage Retention, Aufräumen am Ende jedes Laufs) |
Bei der Deinstallation bleiben Tabellen und Zuordnungen erhalten („Daten behalten"); zum vollständigen Entfernen die vier Tabellen löschen.
Bekannte Grenzen
-
Eine Rücksendung oder ein Storno meldet die ganze Position einmal an everysize; Teilmengen werden nicht gemeldet. Die Meldung wird pro
(Bestellung, Art, SKU)eindeutig gespeichert; eine weitere Rücksendung zur selben Position ändert die bereits gemeldete Revocation nicht. Einen Teilbetrag erstatten Sie über eine Gutschrift im Shop oder im Reiter „everysize" der Bestellung. -
Die Bestellhistorie wird ab dem Stichtag der Installation (
EVERYSIZE_CHECKOUT_HISTORY_SINCE, bei Installation/Upgrade auf „jetzt" gesetzt) durchsucht. Bestellungen, deren Historie vollständig davor liegt, werden nicht nachgemeldet — der erste Lauf nach der Installation meldet nicht den Altbestand. -
Eine Erstattung, die der Händler direkt in PayPal macht, ohne dass die Bestellung bei everysize storniert wird, kennt das Modul nicht und gibt keinen Hinweis. Stornos bei everysize für Bestellungen, die älter als 30 Tage sind, werden nicht mehr abgeglichen.
Lizenz
MIT — siehe LICENSE.