Installatie
Vereisten
Magento 2.4.x — getest op 2.4.9, compatibel met eerdere 2.4.*-releases. PHP 8.1–8.5. Vereist codingrow/module-core (automatisch geïnstalleerd als Composer-afhankelijkheid) voor het gedeelde Codingrow-beheermenu en de licentievalidatie.
Installatiestappen
- Voeg de gegevens die je per e-mail ontvangt toe aan
auth.jsonin de root van je Magento-project:{ "http-basic": { "repo.codingrow.com": { "username": "...", "password": "..." } } } composer config repositories.codingrow composer https://repo.codingrow.comcomposer require codingrow/module-oetibin/magento module:enable Codingrow_Oetibin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush- Plak je licentiesleutel in Admin → Stores → Configuration → Codingrow → Order Export & Tracking Import → License → Licentiesleutel, sla op en voer dan
bin/magento cache:flushuit. - Zet in de groep Algemeen van diezelfde sectie Module inschakelen op "Yes" — de module wordt op Magento-niveau ingeschakeld uitgeleverd, maar functioneel uitgeschakeld, zodat er nooit iets wordt geëxporteerd totdat je hem expliciet aanzet.
- Maak je eerste profiel aan onder Codingrow → Order Export & Tracking Import → Export Profiles — zie Profielen hieronder.
De volledige profielenadmin, de mappingbouwer, het logboek en elke notificatie-e-mail zijn beschikbaar in 7 talen, automatisch geselecteerd op basis van de admin-gebruikerstaal:
Admin-configuratie
De configuratie staat in Stores → Configuration → Codingrow Extensions → Order Export & Tracking Import (Licentie plus de export-/tracking-instellingen). Exportprofielen en hun veldmapping / triggervoorwaarden worden beheerd vanuit het speciale Order Export-raster.
Deïnstallatie
composer remove codingrow/module-oeti, daarna
bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento cache:flush.
Profielen en het export-/trackinglogboek (codingrow_oeti_profile,
codingrow_oeti_log, codingrow_oeti_tracking_log) worden nooit automatisch verwijderd —
gebruik eerst Profiel exporteren als je een kopie
van je profielconfiguratie wilt bewaren.
Gebruikershandleiding
Profielen
Alles in de module draait om profielen, weergegeven onder Codingrow → Order Export & Tracking Import → Export Profiles. Elk profiel is volledig onafhankelijk: eigen naam, eigen aan/uit-schakelaar, eigen triggerstatus(sen), eigen bestemming (kanaal + formaat), eigen veldmapping en een eigen rij in het exportlogboek — je kunt zoveel profielen naast elkaar laten draaien als je wilt (één per leverancier, één per vervoerder, één voor een intern ERP), en het uitschakelen of verwijderen van één profiel heeft nooit invloed op de andere.
Een uitgeschakeld profiel (Profiel ingeschakeld = "No") exporteert nooit iets, of het nu automatisch wordt getriggerd, via de handmatige actie, of via het CLI-commando — dit staat los van de module-brede schakelaar Module inschakelen onder System Config, die als één hoofdschakelaar alle profielen tegelijk uitzet.
Kanalen & formaten
Elk profiel kiest één kanaal (waar de payload wordt afgeleverd) en één formaat (hoe deze wordt geserialiseerd) — de twee keuzes staan los van elkaar, dus elk formaat werkt met elk kanaal.
| Kanaal | Typisch gebruik | Belangrijkste instellingen |
|---|---|---|
| REST API | Verstuurt de payload als een HTTP-request naar een webservice | Bestemmings-URL, HTTP-methode (GET/POST/PUT/PATCH), authenticatie (Geen, HTTP Basic, Bearer-token), minimum aantal seconden tussen requests (rate limiting, standaard 1 seconde) |
| FTP / SFTP | Uploadt de payload als bestand naar een externe server | Host, poort (standaard 21), gebruikersnaam, wachtwoord, extern pad, optioneel FTPS (expliciete TLS), passieve modus |
| Lokaal bestand | Schrijft de payload naar een bestand onder de
eigen pub/media/ van deze winkel, zodat een extern systeem het via HTTP kan ophalen |
Submap — het bestand komt terecht onder
pub/media/codingrow_oeti/<subfolder>/ (standaard submap:
"default") |
Formaten: JSON, XML of CSV, onafhankelijk van het kanaal hierboven gekozen — dezelfde veldmapping (zie hieronder) stuurt alle drie aan, het formaat verandert alleen hoe deze wordt geserialiseerd.
Veldmapping
Het tabblad Mapping is een tabel met rijen, elk koppelt een doelveld (de
veldnaam in de output — een punt betekent één niveau van nesting, bijv.
customer.email) aan een bronpad gekozen uit een keuzelijst met alle
beschikbare velden van bestelling/klant/item. Lege rijen worden bij het opslaan genegeerd.
Rijen worden van boven naar beneden gelezen, in dezelfde vorm als de output zelf: eerst een optionele Koptekst-template, dan de mappingrijen op bestelniveau, dan eventuele Herhaalblokken (zie hieronder), en tot slot een optionele Voettekst-template.
Transformaties
Elke mappingrij kan één transformatie toepassen op de bronwaarde voordat deze naar het doelveld wordt geschreven:
| Transformatie | Wat het doet |
|---|---|
| Geen | Directe kopie van de waarde van het bronpad (valt terug op "Standaardwaarde" wanneer de bron leeg is). |
| Statische waarde | Negeert de bron volledig, schrijft altijd de vaste tekst uit "Waarde". |
| HTML-tags verwijderen | Verwijdert HTML-markup uit de bronwaarde — handig voor een productnaam of -beschrijving met resterende opmaak. |
| Teksttemplate | Vrije tekst met plaatshouders, bijv.
{order.shipping_address.firstname} {order.shipping_address.lastname}.
Er is ook een functie beschikbaar binnen een plaatshouder:
striphtml{path} (hetzelfde als de transformatie HTML-tags verwijderen, inline te
gebruiken) en substr{path,N} (verwijdert de eerste N tekens, bijv.
substr{order.some_code,3}). |
| Zoeken en vervangen | Zoekt de tekst uit "Zoeken" in de bronwaarde (hoofdletterongevoelig) en vervangt deze door "Waarde", precies zoals ingevoerd. |
| Getal | Serialiseert de waarde als een echt JSON-getal in
plaats van een string tussen aanhalingstekens — gebruik dit wanneer de bestemming het
TYPE van het veld strikt valideert (een hoeveelheid verzonden als de ruwe
databasestring "1.0000" wordt door sommige API's geweigerd, terwijl
1.0 als echt getal wel wordt geaccepteerd). Dit is bewust
niet de standaard voor velden die er numeriek uitzien: het overal
inschakelen zou stilzwijgend voorloopnullen verwijderen uit dingen als een postcode of
een artikelcode, dus het is een bewuste keuze per rij, geen automatisch gedrag. |
Dezelfde {path} / striphtml{} / substr{}-syntax die
wordt gebruikt in Teksttemplate-rijen is ook beschikbaar in Herhaalblok-rijen en in de
optionele Koptekst/Voettekst van het profiel.
Herhaalblokken
Een herhaalblok bouwt een geneste array op in de output — het meest voorkomende geval is één item per bestelregel. Elk blok heeft een output-sleutel van het blok (waar de array in de output wordt geschreven) en een bronverzameling (waarover het herhaalt, bijv. de items van de bestelling), plus een eigen set mappingrijen daaronder, één keer per element geëvalueerd met "huidig" gescoped naar dat element — het bronpad van een rij binnen een herhaalblok verwijst dus naar velden van het huidige item, niet naar de bestelling als geheel.
items, bronverzameling
"Bestelitems", en twee rijen (sku ← SKU van het huidige item,
qty ← hoeveelheid van het huidige item) produceert:
{
"items": [
{ "sku": "43241", "qty": 2 }
]
}
Een profiel kan een willekeurig aantal onafhankelijke herhaalblokken definiëren — bijvoorbeeld
één voor de itemlijst en een aparte voor een lijst met toegepaste kortingen.
Triggervoorwaarden
Het tabblad Algemeen heeft een geneste AND/OR-voorwaardebouwer — dezelfde boomstructuur-
interface als Magento's eigen Cart Price Rules (een "Add"-link bij elke groep om een
voorwaarde of een geneste subgroep toe te voegen, een verwijderpictogram bij elk onderdeel) —
die zowel bepaalt welke bestelregels een profiel daadwerkelijk exporteert
als of het profiel de bestelling überhaupt exporteert. Elke voorwaarde
vergelijkt een productattribuut (bijvoorbeeld sku, een aangepast attribuut
"leverancierscode", price...) met een waarde, met een operator: gelijk aan/niet
gelijk aan, bevat/bevat niet, begint met/eindigt met, groter dan/kleiner dan (of gelijk aan),
is leeg/is niet leeg.
Voorwaarden binnen een groep worden gecombineerd met ALLE (AND) of MINSTENS ÉÉN (OR), en
groepen kunnen genest worden in groepen — bijvoorbeeld sku bevat "ABC" OR (supplier_code
= "Supplier2" AND price > 10). Geen voorwaarden geconfigureerd = geen filter, elke
regel wordt geëxporteerd (hetzelfde als het oude "Alleen leveranciersartikelen" = "No" vóór
versie 1.3.0).
Typisch gebruik met meerdere dropshippingleveranciers: één profiel per
leverancier, elk met zijn eigen voorwaarde (bijvoorbeeld Profiel A: supplier_code =
"Supplier1", Profiel B: supplier_code = "Supplier2") — een bestelling met
artikelen van beide leveranciers activeert correct beide profielen tegelijk, elk exporteert
alleen de regels die erbij horen. Als geen enkele regel overeenkomt met de voorwaarden van een
bepaald profiel, exporteert dat profiel die bestelling gewoon niet (zie de logboekstatus
"Overgeslagen" hieronder) — geen fout.
Elk attribuut dat in een voorwaarde wordt gebruikt, wordt automatisch beschikbaar als
koppelbaar veld in de payload (items.attributes.<code>, zie Veldmapping
hierboven). Wanneer de voorwaarden regels van een bestelling uitsluiten, toont de
live preview een expliciete waarschuwing met hoeveel regels zijn
weggelaten en waarom — zodat een lege of korter-dan-verwachte payload nooit een stille
verrassing is.
Live preview
De knop Preview op de bewerkingspagina van het profiel bouwt een tijdelijk, nooit opgeslagen profiel op basis van wat er op dat moment in het formulier staat — inclusief wijzigingen die je nog niet hebt opgeslagen — en voert dit uit tegen een echte bestelling die je kiest, via exact hetzelfde codepad als bij een echte export. Het resultaat is de letterlijke JSON/XML/CSV-payload die die bestelling zou opleveren, zodat je de mapping kunt corrigeren nog vóórdat je het profiel activeert, in plaats van dit pas te ontdekken na een mislukte echte export.
Trigger & deduplicatie
De multiselect Triggerstatus op het tabblad Algemeen geeft aan welke bestelstatus(sen) een automatische export voor dat profiel starten (Ctrl/Cmd-klik om er meer dan één te selecteren) — dit wordt alleen gecontroleerd bij de automatische, gebeurtenisgestuurde trigger; de handmatige rasteractie en het CLI-commando negeren dit bewust, aangezien handmatig triggeren zelf al de bewuste keuze is om te exporteren ongeacht de status. De handmatige actie "Export via Codingrow Order Export" op het raster Sales > Orders voert met één klik elk actief profiel uit op de geselecteerde bestellingen — de eigen Triggervoorwaarden van elk profiel bepalen wat het daadwerkelijk verstuurt, net als bij de automatische trigger.
Elke poging wordt weggeschreven naar het logboek van dat profiel (zie hieronder), en dat logboek voorkomt ook duplicaten: dezelfde bestelling wordt nooit automatisch twee keer geëxporteerd door hetzelfde profiel, wat er daarna ook met de bestelling gebeurt (verdere bewerkingen, statuswijzigingen heen en weer). Als een echte herverzending nodig is — bijvoorbeeld na het oplossen van een probleem aan de bestemmingskant — gebruik dan Opnieuw verzenden forceren, dat deze bescherming expliciet omzeilt.
Trackingimport
Een tabblad Trackingimport per profiel (standaard uitgeschakeld) voert een automatische controle per bestelling uit — in v1.5.0 opnieuw ontworpen. Elke bestelling die dit profiel met succes heeft geëxporteerd, die nog te verzenden items heeft en die niet ouder is dan 45 dagen, wordt afzonderlijk bevraagd op haar eigen verzendstatus; voor de als verzonden gemelde items maakt ze een native Magento-zending met trackingnummer aan, met hergebruik van de eigen Triggervoorwaarden van het profiel om te weten welke items van de bestelling erbij horen. Er is geen bulk-datumvenster — het model is strikt één verzoek per openstaande bestelling per ronde.
Een bestelling die na 45 dagen nog niet volledig is verzonden, verlaat de automatische cyclus: ze wordt eenmalig in het logboek geschreven met de status Timeout (plus een eventuele e-mail), zodat ze de leverancier nooit eindeloos blijft bevragen.
Request. De bovenste helft van het tabblad bepaalt de uitgaande aanroep:
| Veld | Betekenis |
|---|---|
| Check endpoint URL | Basis-URL van het statuseindpunt van de leverancier, zonder enige query string. |
| HTTP method | GET of POST. |
| Poll frequency (minutes) | Hoe vaak de cron van dit profiel draait. |
| Minimum seconds between requests | Snelheidslimiet tussen de afzonderlijke aanroepen per bestelling binnen één ronde (standaard 1s; 0 = geen limiet). |
| Different authentication than the profile | Bij Nee (standaard) hergebruikt de controle de inloggegevens van het eigen kanaal van het profiel; bij Ja krijgt het trackingeindpunt een eigen authenticatie. |
| Request parameters | Een raster van Name- + Type- + Value-rijen, één per parameter die naar het eindpunt verstuurd wordt (zie de vijf parametertypen hieronder). |
| Request preview (JSON) | Live voorbeeld van de exacte aanroep; de knop Send test request ernaast vuurt een echte HTTP-aanroep af, en het plakken van een voorbeeldverzoek in het voorbeeld herbouwt de parameterrijen eruit. |
Elke Request parameters-rij kiest een van vijf waarde-Types:
| Type | Verstuurde waarde |
|---|---|
| Fixed value | De letterlijke tekst uit Value. |
| Today | De datum van vandaag (Y-m-d). |
| Order export date | De datum waarop die bestelling is geëxporteerd. |
| Mapped export field | De waarde die de export heeft berekend voor een gekozen target van die bestelling — bijv. de bestelreferentie bij de leverancier. |
| Template | Vrije tekst met de functie date{N} (vandaag ±N
dagen), bijv. date{-7}. |
Response mapping. De onderste helft koppelt het antwoord van de leverancier. Je typt de antwoordpaden nooit met de hand in: verkrijg één echt antwoord — met Send test request, of door een vastgelegd antwoord in het kader Response sample te plakken — en elke keuzelijst hieronder wordt gevuld met de velden die daadwerkelijk in dat antwoord gevonden zijn.
| Veld | Betekenis |
|---|---|
| Reference field | Welk Order Export-target de bestelreferentie bevat (vastgelegd bij elke exportpoging, geslaagd of mislukt). |
| Order match field in response | Het antwoordveld waarmee het vergeleken wordt om de juiste bestelling te identificeren. |
| Tracking number / Tracking URL | Antwoordvelden met het trackingnummer en, indien aanwezig, de klikbare link. |
| Carrier code / Carrier name | Antwoordvelden met de vervoerderscode en het label. |
| Multiple tracking numbers for this shipment | Schakelaar voor leveranciers die meer dan één trackingnummer per zending teruggeven; toont Tracking numbers: collection (de array met trackingvermeldingen) en Tracking numbers: value path in each element (waar het nummer in elke vermelding staat). |
| Shipped items: collection | De array in het antwoord die de verzonden items opsomt. |
| Shipped items: SKU path in each element / Shipped items: quantity path in each element | Waar de artikelcode en de verzonden hoeveelheid in elk element van die array staan. |
| Item matching attribute | Het productattribuut waarmee de items van de leverancier herkend worden, aangezien leveranciers hun eigen code melden, niet de Magento-SKU. |
Gedeeltelijke zendingen. Als een bestelling items van meerdere leveranciers bevat (of een leverancier in meerdere golven verzendt), maakt elke controle alleen een zending aan voor de items die op dat moment daadwerkelijk als verzonden zijn gemeld, nooit meer dan wat nog te verzenden is — zodat een bestelling die na verloop van tijd terecht meerdere zendingen krijgt het bedoelde gedrag is, geen fout.
E-mail aan de klant. Wanneer de leverancier een klikbare trackinglink levert (een URL, niet alleen een nummer), ontvangt de klant een e-mail met een knop "Track your package" in plaats van de kale native Magento-mail (die alleen het nummer zou tonen, zonder klikbare link voor een vervoerder die Magento niet native herkent). Wanneer de leverancier geen URL levert, wordt de standaard native e-mail ongewijzigd gebruikt.
Automatische migratie. Profielen die al met de vorige versie zijn geconfigureerd, worden bij de update automatisch gemigreerd — geen herconfiguratie nodig.
Bij normaal gebruik is geen handmatige actie nodig: de controles per bestelling draaien zelfstandig op de achtergrond in het ingestelde tempo (Magento cron moet actief zijn, zoals voor elke geplande taak).
https://codingrow.com/sample-tracking.jsonOpenAPI:
https://codingrow.com/sample-api.openapi.yamlLog & geforceerd opnieuw verzenden
Vanaf versie 1.4.0 is het logboek niet langer per profiel opgesplitst (een logtabblad binnen elk profiel). Eén Log-pagina (knop op het overzicht Export Profiles) toont bestellingen — niet individuele pogingen — één per rij, gepagineerd, met de laatste exportstatus en de laatste trackingstatus naast elkaar: één oogopslag op een bestelling, ook wanneer er meerdere profielen/leveranciers bij betrokken zijn.
Klikken op Volledige geschiedenis bekijken opent de volledige geschiedenis van die bestelling, opgesplitst in twee secties — Exportlogboek en Trackinglogboek — elk met alle pogingen/controles van elk betrokken profiel, met een uitklapbare detailrij (exacte verzonden requestpayload, ontvangen responsebody) en, aan de exportkant, een knop Geforceerd opnieuw verzenden per rij.
Aan de exportkant is een poging Succes, Fout of Overgeslagen. Overgeslagen is geen fout: geen enkel bestelditem kwam overeen met de Triggervoorwaarden van dat profiel, dus er is niets verstuurd — handig bij meerdere profielen/leveranciers om in één oogopslag te zien waarom een bepaald profiel een bepaalde bestelling niet heeft geëxporteerd. Aan de trackingkant betekent een mislukte controle meestal alleen dat de leverancier voor die items nog niets als verzonden heeft gemeld; deze wordt automatisch opnieuw geprobeerd bij de volgende controle, zonder handmatige actie.
De knop Geforceerd opnieuw verzenden van een mislukte of overgeslagen rij (alleen aan de exportkant) voert de export voor precies die bestelling via precies dat profiel nu opnieuw uit, en omzeilt daarbij de deduplicatiebescherming — een bevestigingsdialoog legt dit eerst uit, aangezien het een bewuste override is, beschikbaar zowel vanaf de hoofdpagina Log als vanaf het besteldetail. Tracking heeft geen handmatig equivalent van "forceer controle": de volgende geplande controle probeert gewoon opnieuw.
E-mailmeldingen bij fouten
Twee instellingen in het tabblad Algemeen bepalen de foutmeldingen, los van het logboek (dat altijd elke poging vastlegt, ongeacht deze instellingen): Ontvangers van meldingen (één of meer e-mailadressen, gescheiden door komma's — laat leeg om niets te versturen) en E-mail verzenden voor (welke gebeurtenissen een melding triggeren).
De inhoud van de e-mail bevat de daadwerkelijke fout die door de bestemming is
teruggestuurd, niet alleen een generieke HTTP-statusregel: als de responsebody parseerbare JSON
is met een message-veld, wordt dat bericht letterlijk toegevoegd (bijv.
"Destination returned HTTP 422 - Minimum product quantity is 1.0"); anders wordt de ruwe
responsebody opgenomen, afgekapt tot 500 tekens — zodat de werkelijke oorzaak direct vanuit de
inbox zichtbaar is, zonder het logboek te openen.
Profiel importeren/exporteren
De knop Profiel exporteren op de bewerkingspagina van een profiel downloadt de volledige configuratie — algemene instellingen, bestemming, mappingrijen en herhaalblokken — als één enkel JSON-bestand, waarbij de bestemmingsgegevens (credentials) bewust worden uitgesloten, zodat het bestand veilig kan worden bewaard, gedeeld met support, of meegenomen bij een deployment. De knop Profiel importeren op het overzicht Export Profiles bouwt een profiel opnieuw op vanuit zo'n bestand — typisch gebruikt om een profiel van een staging-/demo-winkel naar productie te verplaatsen, of om een back-up te bewaren van een mapping waar je tevreden mee bent voordat je verder experimenteert. Inloggegevens moeten na een import altijd handmatig opnieuw worden ingevoerd, aangezien ze nooit in het bestand hebben gestaan.
Licentie
Eén licentie per domein, ingevoerd onder Admin → Stores → Configuration → Codingrow → Order Export & Tracking Import → License → Licentiesleutel. Inclusief alle updates voor dat domein. Moet je naar een ander domein verhuizen (staging → productie, of een sitemigratie)? Je eerste domeinwijziging is gratis en direct vanaf je accountpagina — geen wachttijd, geen ticket nodig. Vanaf de tweede wijziging is één wijziging per jaar toegestaan. Je kunt ook zelf, vanaf dezelfde accountpagina, binnen 30 dagen na aankoop een terugbetaling aanvragen.