Feld-Mapping Dokumentation: reybex → Shopify
Übersicht
Diese Dokumentation beschreibt, welche Felder von reybex nach Shopify übertragen werden und wie sie gemappt werden. Die Übertragung erfolgt über GraphQL-Mutationen an die Shopify Admin API (Version 2024-10).
⚠️ WICHTIGER HINWEIS
Diese Dokumentation unterliegt kontinuierlichen Änderungen.
Die Integration zwischen reybex und Shopify befindet sich in ständiger Entwicklung. Daher kann es vorkommen, dass:
- Neue Felder hinzugefügt werden - Um zusätzliche Funktionen zu unterstützen oder neue Shopify-Features zu nutzen
- Felder temporär entfernt werden - Wenn unerwartete Probleme auftreten, die negative Auswirkungen auf die Artikel haben
Beispiel:
Das Feld material.urlkey wurde normalerweise übertragen und sollte eindeutig (unique) sein. In früheren Shopify-Versionen wurde automatisch ein eindeutiger Suffix hinzugefügt, wenn das Feld nicht eindeutig war. Seit der neuesten Shopify-Version wird dies nicht mehr automatisch durchgeführt. Wenn das Feld nicht eindeutig übertragen wird, kann dies negative Auswirkungen auf den Artikel haben (z.B. doppelte URLs, SEO-Probleme). Daher wird das Feld in reybex automatisch deaktiviert, sobald ein Fehler erkannt wird.
Empfehlung:
Bitte überprüfen Sie regelmäßig die aktuelle Dokumentation und testen Sie Änderungen in einer Testumgebung, bevor Sie sie in der Produktion einsetzen.
Verwendung dieser Dokumentation
Diese Dokumentation zeigt, welche Felder von reybex nach Shopify übertragen werden. Für jedes Shopify-Feld wird angegeben:
- Welches reybex-Feld die Quelle ist
- Unter welcher Bedingung es übertragen wird (Export-Gruppe)
- Besondere Hinweise zur Übertragung
Wichtige Konzepte
reybex-Artikelstruktur
- Material: Ein Artikel/Produkt in reybex (entspricht Shopify Product)
- MaterialVariant: Eine Variante eines Artikels in reybex (z.B. Größe, Farbe) - entspricht Shopify ProductVariant
- MaterialMarktplace: Marktplatz-spezifische Einstellungen für einen Artikel (können Standard-Felder überschreiben)
Shopify-Produktstruktur
- Product: Das Hauptprodukt in Shopify
- ProductVariant: Eine Variante des Produkts in Shopify
- Metafields: Zusätzliche benutzerdefinierte Felder in Shopify
- Namespace "global": Für Artikelattribute
- Namespace "custom": Für Custom Fields
- Namespace "variantCustom": Für Varianten-spezifische Metafields
reybex-Felder: Bedeutung und Verwendung
Material-Felder (Hauptartikel)
| reybex Feld | Typ | Beschreibung | Beispiel |
|---|---|---|---|
material.name |
String | Produktname/Titel | "T-Shirt Premium" |
material.sku |
String | Artikelnummer (Standard) | "TSH-001" |
material.matCode |
String | Materialcode (Fallback für SKU) | "MAT-123" |
material.gtin |
String | EAN/GTIN (Barcode) | "1234567890123" |
material.detailDescription |
String (HTML) | Produktbeschreibung (HTML-Format) | " Hochwertiges T-Shirt... " |
material.materialType |
String | Produkttyp/Kategorie | "Kleidung" |
material.brand.name |
String | Marke/Hersteller | "Premium Brand" |
material.metaTitle |
String | SEO-Titel (Meta Title) | "T-Shirt Premium - Online kaufen" |
material.metaDescription |
String | SEO-Beschreibung (Meta Description) | "Hochwertiges T-Shirt aus Bio-Baumwolle..." |
material.urlkey |
String | URL-Slug für SEO | "t-shirt-premium" |
material.keyWord |
String | Suchbegriffe | "T-Shirt, Premium, Bio-Baumwolle" |
material.attributes[] |
Array | Artikelattribute | [{name: "Farbe", value: "Rot"}, ...] |
material.customFields[] |
Array | Benutzerdefinierte Felder | [{name: "Herstellungsland", value: "Deutschland", variableType: 2}, ...] |
material.categories[] |
Array | Kategorien | [{id: 1, name: "Herren"}, ...] |
material.images[] |
Array | Produktbilder | [{url: "https://...", fileName: "img1.jpg"}, ...] |
material.price.rrp |
Number | UVP/Listenpreis | 29.99 |
material.isOnlySellableWithPositiveStock |
Boolean | Verkauf nur bei positivem Bestand | true oder false |
MaterialMarktplace-Felder (Marktplatz-spezifisch)
| reybex Feld | Typ | Beschreibung | Beispiel |
|---|---|---|---|
materialMarktplace.marketplaceSku |
String | Marktplatz-spezifische SKU | "SHOPIFY-TSH-001" |
materialMarktplace.materialName |
String | Marktplatz-spezifischer Name | "T-Shirt Premium (Shopify Edition)" |
materialMarktplace.materialDescription |
String | Marktplatz-spezifische Beschreibung | "Spezielle Beschreibung für Shopify" |
materialMarktplace.marketplaceProductId |
String | Shopify Product ID (GID) | "gid://shopify/Product/123456" |
Varianten-Felder
| reybex Feld | Typ | Beschreibung | Beispiel |
|---|---|---|---|
variant.sku |
String | Varianten-SKU | "TSH-001-L-RED" |
variant.gtin |
String | Varianten-EAN/GTIN | "1234567890124" |
variant.name |
String | Variantenname | "Größe L, Farbe Rot" |
variant.price.value |
Number | Variantenpreis | 24.99 |
variant.stock |
Number | Variantenbestand (einzelner Wert) | 50 |
variant.locationBasedStocks[] |
Array | Bestand pro Standort | [{stock: 20, shopifyLocation: "gid://..."}, ...] |
variant.nameValuePairs[] |
Array | Varianten-Optionen | [{name: "Größe", value: "L", sortOrder: 1}, ...] |
variant.images[] |
Array | Variantenbilder | [{url: "https://...", fileName: "variant1.jpg"}, ...] |
variant.purchaseUnit |
Number | Kaufmenge (für Grundpreis) | 2 |
1. Produkt-Felder (Product Level)
Die folgenden Felder werden auf Produktebene in Shopify übertragen:
1.1 Basis-Informationen
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
product.title |
material.name |
Produktname/Titel | Export-Gruppe: ARTIKEL_DATA |
product.vendor |
material.brand.name |
Marke/Hersteller | Export-Gruppe: ARTIKEL_DATA |
product.productType |
material.materialType |
Produkttyp/Kategorie | Export-Gruppe: MATERIAL_TYPE |
product.descriptionHtml |
material.detailDescription |
HTML-Beschreibung des Produkts | Export-Gruppe: DESCRIPTION |
Hinweise:
- material.name kann durch materialMarktplace.materialName überschrieben werden (marktplatz-spezifischer Name)
- material.detailDescription kann durch materialMarktplace.materialDescription überschrieben werden
1.2 SEO-Felder
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
product.seo.title |
material.metaTitle |
SEO-Titel (Meta Title) | Export-Gruppe: SEO |
product.seo.description |
material.metaDescription |
SEO-Beschreibung (Meta Description) | Export-Gruppe: SEO |
product.handle |
material.urlkey |
URL-Slug für das Produkt | Export-Gruppe: SEO |
product.tags |
material.keyWord |
Suchbegriffe (max. 250 Zeichen) | Export-Gruppe: SEO |
Hinweise:
- material.keyWord wird auf 250 Zeichen gekürzt, falls länger
- material.urlkey bestimmt die URL-Struktur in Shopify (z.B. /products/mein-produkt)
1.3 Tags
Tags werden aus verschiedenen reybex-Quellen zusammengeführt:
| Shopify Feld | reybex Quelle | Beschreibung |
|---|---|---|
product.tags |
material.brand.name |
Markenname als Tag |
product.tags |
material.keyWord |
Suchbegriffe als Tags |
product.tags |
material.categories[].name |
Kategorienamen als Tags |
product.tags |
"${attribute.name}: ${attribute.value}" |
Attribute als "Name: Wert" Tags |
1.4 Bilder
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
product.media[] |
material.images[] |
Produktbilder | Export-Gruppe: IMAGE + refreshPictures = true |
Wichtige Hinweise:
- Bilder werden nur übertragen, wenn refreshPictures = true gesetzt ist
- Bei refreshPictures = true werden alle bestehenden Bilder in Shopify gelöscht und neue hochgeladen
- Variantenbilder werden ausgeschlossen (nur Hauptbilder werden auf Produktebene gesetzt)
- Format: originalSource (URL) und mediaContentType: "IMAGE"
1.5 Artikelattribute (Metafields - Namespace: "global")
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
product.metafields[] (namespace: "global") |
material.attributes[] |
Artikelattribute | Export-Gruppe: ARTIKEL_ATTRIBUTE |
Mapping-Details:
- Namespace: "global"
- Key: attribute.name
- Value: attribute.value (als String)
- Type: "single_line_text_field"
- Existierende Metafields werden aktualisiert (via ID)
- Nicht mehr vorhandene Metafields werden gelöscht
Beispiel:
- reybex: {name: "Farbe", value: "Rot"}
- Shopify: {namespace: "global", key: "Farbe", value: "Rot", type: "single_line_text_field"}
1.6 Custom Fields (Metafields - Namespace: "custom")
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
product.metafields[] (namespace: "custom") |
material.customFields[] |
Benutzerdefinierte Felder | Immer (wenn vorhanden) |
Typ-Mapping:
reybex variableType |
Shopify Metafield Type | Beschreibung |
|---|---|---|
0 |
number_integer |
Ganzzahl |
1 |
number_decimal |
Dezimalzahl |
2 |
single_line_text_field |
Text |
3 |
boolean |
Wahr/Falsch |
4 |
list.single_line_text_field |
Liste von Texten |
Mapping-Details:
- Namespace: "custom"
- Key: customField.name (Leerzeichen werden durch _ ersetzt)
- Value: Je nach variableType (siehe Tabelle oben)
- Existierende Metafields werden aktualisiert (via ID)
1.7 Kategorien
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
product.tags |
material.categories[].name |
Kategorienamen als Tags | Export-Gruppe: CATEGORY |
| Collections (via API) | material.categories[].id |
Verknüpfung mit Shopify Collections | Export-Gruppe: CATEGORY |
Hinweise:
- Kategorienamen werden als Tags hinzugefügt
- Die tatsächliche Verknüpfung mit Shopify Collections erfolgt separat über die collects.json REST API
- Jede Kategorie wird als collect (Verknüpfung zwischen Product und Collection) erstellt
2. Varianten-Felder (Variant Level)
Die folgenden Felder werden auf Variantenebene in Shopify übertragen:
2.1 Basis-Informationen
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
variant.sku |
variant.sku |
Artikelnummer der Variante | Export-Gruppe: VARIANT |
variant.barcode |
variant.gtin |
EAN/GTIN der Variante | Export-Gruppe: VARIANT |
variant.title |
variant.name |
Name der Variante | Export-Gruppe: VARIANT |
2.2 Preise
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
variant.price |
variant.price.value |
Verkaufspreis der Variante | Export-Gruppe: PRICE |
variant.compareAtPrice |
material.price.rrp |
UVP/Listenpreis (wird von Hauptartikel übernommen) | Export-Gruppe: PRICE |
Hinweise:
- Der Preis wird als Dezimalzahl übertragen
- compareAtPrice ist optional (wird nur übertragen, wenn vorhanden)
2.3 Bestand (Inventory)
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
variant.inventoryQuantities[] |
variant.stock |
Einzelner Bestandswert | Export-Gruppe: STOCK |
variant.inventoryQuantities[] |
variant.locationBasedStocks[] |
Bestand pro Standort | Export-Gruppe: STOCK |
Bestandslogik:
Fall 1: Einzelner Bestand
- Wenn variant.stock vorhanden: Wird an einen Standort (locationId) zugewiesen
- Format: [{availableQuantity: stock, locationId: locationId}]
Fall 2: Standortbasierte Bestände
- Wenn variant.locationBasedStocks vorhanden: Mehrere Standorte mit jeweiligem Bestand
- Format: [{availableQuantity: stock1, locationId: location1}, {availableQuantity: stock2, locationId: location2}, ...]
- Jeder Eintrag in locationBasedStocks enthält: {stock: X, shopifyLocation: "gid://shopify/Location/Y"}
Bestandsaktualisierung:
- Der Bestand wird immer überschrieben (nicht als Delta berechnet)
- Der aktuelle Bestandswert aus reybex wird direkt an Shopify übertragen
- Auch negative Werte werden übertragen, wenn sie in reybex vorhanden sind
- Verwendet GraphQL Mutation: inventoryAdjustQuantities
2.4 Bestandspolitik
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
variant.inventoryPolicy |
material.isOnlySellableWithPositiveStock |
Verkaufspolitik | Export-Gruppe: VARIANT |
Werte:
- material.isOnlySellableWithPositiveStock = true → inventoryPolicy = "DENY" (Verkauf nur bei positivem Bestand)
- material.isOnlySellableWithPositiveStock = false → inventoryPolicy = "CONTINUE" (Verkauf auch bei 0 Bestand)
2.5 Varianten-Optionen
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
variant.optionValues[] |
variant.nameValuePairs[] |
Varianten-Optionen (z.B. Größe, Farbe) | Export-Gruppe: VARIANT |
Mapping-Details:
- Jedes nameValuePair wird zu einem optionValue
- Format: {optionName: nameValuePair.name, name: nameValuePair.value}
- Sortierung: Nach sortOrder und name
Beispiel:
- reybex: {name: "Größe", value: "L", sortOrder: 1}
- Shopify: {optionName: "Größe", name: "L"}
Wichtig: Varianten-Optionen werden nur bei neuen Produkten gesetzt. Bei bestehenden Produkten werden die Optionen nicht aktualisiert.
2.6 Varianten-Bilder
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
variant.mediaId |
variant.images[0].url |
Erstes Variantenbild | Export-Gruppe: VARIANT + Bild vorhanden |
Hinweise:
- Nur das erste Bild (images[0]) wird der Variante zugewiesen
- Das Bild wird über fileCreate Mutation hochgeladen
- Die zurückgegebene file.id wird als mediaId verwendet
2.7 Varianten-Metafields
| Shopify Feld | reybex Feld | Beschreibung | Bedingung |
|---|---|---|---|
variant.metafields[] (namespace: "variantCustom") |
Berechneter Grundpreis | Grundpreis-Text (z.B. "2.50 EUR / 100 ml") | Export-Gruppe: VARIANT + purchaseUnit vorhanden |
Berechnungslogik:
- Wird nur erstellt, wenn alle drei Felder vorhanden sind:
- variant.purchaseUnit (Kaufmenge)
- material.referenceUnit (Referenzeinheit)
- material.basePriceUnit.name (Einheit des Grundpreises)
- Formel: (variant.price.value / purchaseUnit) * referenceUnit
- Format: "(X.XX CURRENCY / referenceUnit basePriceUnit)"
- Namespace: "variantCustom"
- Key: "variant_unitPrice"
- Type: "single_line_text_field"
Beispiel:
- reybex: price.value = 5.00, purchaseUnit = 2, referenceUnit = 100, basePriceUnit = "ml"
- Shopify: {namespace: "variantCustom", key: "variant_unitPrice", value: "(2.50 EUR / 100 ml)", type: "single_line_text_field"}
2.8 Varianten-Operationen
Erstellung:
- Neue Varianten werden via productVariantsBulkCreate erstellt
- Strategie: REMOVE_STANDALONE_VARIANT
Aktualisierung:
- Bestehende Varianten werden via productVariantsBulkUpdate aktualisiert
- allowPartialUpdates: true ermöglicht Teilaktualisierungen
Löschung:
- Varianten, die in Shopify existieren, aber nicht mehr in reybex vorhanden sind, werden gelöscht
- Verwendet productVariantsBulkDelete Mutation
3. Export-Felder-Gruppen
Die Übertragung wird durch Export-Felder-Gruppen gesteuert. Jede Gruppe bestimmt, welche Felder übertragen werden:
| Export-Gruppe | Beschreibung | Übertragene Shopify-Felder |
|---|---|---|
| MATERIAL_TYPE | Produkttyp | product.productType |
| VARIANT | Varianten | product.productOptions (nur bei neuen Produkten), alle Varianten-Felder |
| ARTIKEL_DATA | Artikeldaten | product.title, product.vendor, Tags (Marke) |
| DESCRIPTION | Beschreibung | product.descriptionHtml |
| SEO | SEO-Felder | product.seo.title, product.seo.description, product.handle, Tags (keyWord) |
| IMAGE | Bilder | product.media[] (nur wenn refreshPictures = true) |
| ARTIKEL_ATTRIBUTE | Artikelattribute | product.metafields[] (namespace: "global") |
| CATEGORY | Kategorien | product.tags (Kategorienamen), Collections-Verknüpfungen |
| STOCK | Bestand | variant.inventoryQuantities[], inventoryAdjustQuantities |
| PRICE | Preis | variant.price, variant.compareAtPrice |
Hinweis: Custom Fields werden immer übertragen (wenn vorhanden), unabhängig von den Export-Gruppen.
4. Besondere Verhaltensweisen
4.1 Neues vs. Bestehendes Produkt
Neues Produkt:
- Verwendet productCreate GraphQL Mutation
- product.productOptions werden gesetzt (Varianten-Optionen)
- Alle Felder werden übertragen (sofern in Export-Gruppen enthalten)
Bestehendes Produkt:
- Verwendet productUpdate GraphQL Mutation
- product.productOptions werden nicht aktualisiert (können nur bei Erstellung gesetzt werden)
- Nur Felder werden aktualisiert, die in den Export-Gruppen enthalten sind
4.2 Bild-Aktualisierung
refreshPictures = true:
- Alle bestehenden Bilder in Shopify werden gelöscht
- Neue Bilder werden hochgeladen
- Variantenbilder werden ausgeschlossen (nur Hauptbilder)
refreshPictures = false:
- Keine Bildänderungen
- Bestehende Bilder in Shopify bleiben unverändert
4.3 Standortbasierte Bestände
Wenn standortbasierte Bestände aktiviert sind:
- Bestand wird pro Standort verwaltet
- variant.locationBasedStocks enthält Liste: [{stock: X, shopifyLocation: "gid://shopify/Location/Y"}, ...]
- Bei Aktualisierung wird Bestand als Delta übertragen
- Verwendet inventoryAdjustQuantities Mutation
4.4 Varianten-Löschung
Varianten, die in Shopify existieren, aber nicht mehr in reybex vorhanden sind, werden automatisch gelöscht.
Logik:
- Alle Varianten in Shopify werden mit Varianten in reybex verglichen
- Varianten ohne passende SKU in reybex werden gelöscht
- Hauptvariante (SKU = Hauptartikel-SKU) wird nicht gelöscht
4.5 Veröffentlichung
Nach dem Update wird das Produkt automatisch in konfigurierten Shopify Publications veröffentlicht.
Hinweise:
- Publications werden aus authentication.shopifyPublications gelesen (komma-separierte Liste)
- Verwendet publishablePublish GraphQL Mutation
- Fehler bei der Veröffentlichung stoppen nicht den gesamten Prozess
4.6 Kategorien-Verknüpfung
Kategorien werden in zwei Schritten verarbeitet:
- Als Tags: Kategorienamen werden als
product.tagshinzugefügt - Als Collections: Über REST API
collects.jsonwerden Produkte mit Collections verknüpft
- Jede Kategorie wird alscollect(Verknüpfung) erstellt
- Format:{product_id: X, collection_id: Y}
5. Feld-Überschreibungen
Einige reybex-Felder können durch marktplatz-spezifische Einstellungen überschrieben werden:
| Standard-Feld | Überschreibung | Beschreibung |
|---|---|---|
material.name |
materialMarktplace.materialName |
Marktplatz-spezifischer Produktname |
material.detailDescription |
materialMarktplace.materialDescription |
Marktplatz-spezifische Beschreibung |
material.sku |
materialMarktplace.marketplaceSku |
Marktplatz-spezifische SKU |
6. Zusammenfassung: Vollständige Feld-Mappings
Produkt-Ebene
| Shopify Feld | reybex Feld | Export-Gruppe | Hinweise |
|---|---|---|---|
product.title |
material.name |
ARTIKEL_DATA | Kann durch materialMarktplace.materialName überschrieben werden |
product.vendor |
material.brand.name |
ARTIKEL_DATA | - |
product.productType |
material.materialType |
MATERIAL_TYPE | - |
product.descriptionHtml |
material.detailDescription |
DESCRIPTION | Kann durch materialMarktplace.materialDescription überschrieben werden |
product.seo.title |
material.metaTitle |
SEO | - |
product.seo.description |
material.metaDescription |
SEO | - |
product.handle |
material.urlkey |
SEO | Bestimmt URL-Struktur |
product.tags |
material.brand.name |
ARTIKEL_DATA | Marke als Tag |
product.tags |
material.keyWord |
SEO | Max. 250 Zeichen |
product.tags |
material.categories[].name |
CATEGORY | Kategorienamen als Tags |
product.tags |
"${attribute.name}: ${attribute.value}" |
ARTIKEL_ATTRIBUTE | Attribute als Tags |
product.metafields[] (global) |
material.attributes[] |
ARTIKEL_ATTRIBUTE | Namespace: "global" |
product.metafields[] (custom) |
material.customFields[] |
Immer | Namespace: "custom" |
product.media[] |
material.images[] |
IMAGE | Nur wenn refreshPictures = true |
Varianten-Ebene
| Shopify Feld | reybex Feld | Export-Gruppe | Hinweise |
|---|---|---|---|
variant.sku |
variant.sku |
VARIANT | - |
variant.barcode |
variant.gtin |
VARIANT | EAN/GTIN |
variant.title |
variant.name |
VARIANT | Variantenname |
variant.price |
variant.price.value |
PRICE | Verkaufspreis |
variant.compareAtPrice |
material.price.rrp |
PRICE | UVP/Listenpreis |
variant.inventoryQuantities[] |
variant.stock |
STOCK | Einzelner Bestand |
variant.inventoryQuantities[] |
variant.locationBasedStocks[] |
STOCK | Mehrere Standorte |
variant.inventoryPolicy |
material.isOnlySellableWithPositiveStock |
VARIANT | "DENY" oder "CONTINUE" |
variant.optionValues[] |
variant.nameValuePairs[] |
VARIANT | Nur bei neuen Produkten |
variant.mediaId |
variant.images[0].url |
VARIANT | Erstes Variantenbild |
variant.metafields[] (variantCustom) |
Berechneter Grundpreis | VARIANT | Nur wenn purchaseUnit vorhanden |
7. API-Versionen
- Shopify GraphQL API Version:
2024-10 - Shopify REST API: Für Bestandsaktualisierung (
inventory_levels/set.json) und Kategorien-Verknüpfung (collects.json)
Version: 2.0
Erstellt: 2024
Zielgruppe: Externe Nutzer ohne reybex-Kenntnisse