News

Shopware UPS Integration: Setup, Rates, Labels, Tracking & Troubleshooting

Von Erol Demirkoparan
13 min
Shopware UPS Integration: Setup, Rates, Labels, Tracking & Troubleshooting - Cloudox Software Agentur Blog

Voraussetzungen & Architektur-Entscheidung: Direktes UPS-Plugin vs. Middleware

Vorher: Live-Rates bei 280–350 ms p95. Nachher: 1,9–2,2 s p95. Und niemand hat „etwas geändert“.

Erwartung: Rate API (Live Rates) ist ein schneller Call, fertig.

Realität: Mehr Overhead als Payload. DNS, TLS, OAuth Token, Retry-Logik, Paket-Mapping, Rules in Shopware 6, Cache-Miss, dann noch ein UPS Developer Portal-Policy-Change. Zack: p99 explodiert, Checkout fühlt sich „kaputt“ an, Core Web Vitals leiden, TTFB steigt.

Sieht man das im Monitoring?

Der verbreitete Irrtum: „Direkt ist immer schneller.“ Stimmt nur, wenn du die Nebenbedingungen kontrollierst. Sobald Länder, Services, Zoll und mehrere Lager dazukommen, wird „direkt“ oft fragiler als eine Middleware / Multi-Carrier-Schicht mit sauberem Queueing.

Checkout- und Live-Rate-Latenz als Performance-Hebel. Das ist keine Theorie. Das ist APM-Realität.

  • Shopware-Version: Shopware 6.x Patchlevel fixieren. API- und Rule-Änderungen sind echte Breaking-Risiken.
  • Hosting/Queue/Worker: Async für Label API/Tracking API. Worker-Concurrency messen, nicht raten. Profiling an.
  • Rechte/Rollen im Admin: Versandarten, Regeln, Dokumente, Flow Builder. Weniger Admin-Rechte, weniger Chaos.
  • Drucker/Label-Workflow: PDF vs. ZPL. ZPL ist schnell im Lager. PDF ist bequem im Büro.
  • Testumgebung: Sandbox/Separate Credentials (OAuth Client ID/Secret), Staging mit echten Gewichten/Adressen.

Welches UPS-Plugin für Shopware ist das beste? Das „beste“ ist das, dessen Fehlermodi du beherrschst und dessen p99 du halten kannst. Punkt.

Kriterium Direktes UPS-Plugin Middleware / Multi-Carrier
Time-to-Ship Sehr gut bei 1 Lager, wenig Services Gut, wenn Label-Erstellung über Queue läuft
Fehlertoleranz Checkout kann blockieren (Timeouts) Fallback-Routing, Retries, Dead-Letter-Queues
Multi-Lager Mapping-Aufwand hoch (Shipper Number je Lager) Standardfall, Carrier-agnostisch modellierbar
EU + Non-EU Export Paperless Trade, EORI, HS-Code, Incoterms: fehleranfällig Zoll-Templates, Validierung, CN22/CN23-Handling oft reifer
Vendor-Lock-in & Betriebskosten Lock-in bei UPS geringer, Betrieb in Shopware höher Lock-in zur Plattform möglich, dafür weniger Shopware-Wartung

Performance-Risiko Nummer 1 sind Live-Rates im Checkout. Absicherung in Shopware 6: harte Timeouts, aggressives Caching, Fallback-Tarife. Ohne das wird dein p99 vom Carrier diktiert.

// Beispiel: defensives Timeout + Fallback (Pseudo-PHP)
try {
  $rate = $upsRateClient->getRates($payload, timeoutMs: 800);
} catch (\Throwable $e) {
  $rate = $fallbackRateTable->match($cart); // statisch/regelbasiert
}
// Beispiel: Cache-Key für Rate API (Pseudo)
$key = hash('sha256', $shipToZip.'|'.$service.'|'.$weight.'|'.$dims.'|'.$shipperNumber);
$rate = $cache->get($key, ttl: 900) ?? $ups->rate($req);
// Beispiel: Flow Builder Idee als Webhook-Call (Pseudo)
on("order.paid") {
  enqueue("ups.label.create", orderId);
  setOrderState("in_fulfillment");
}

Zielbilder, die stabil laufen:

  • DE-only B2C: Direkt. 1–2 UPS Services. Cache im Checkout. PDF-Labels ok.
  • DACH B2B: Direkt oder Middleware. ZPL im Lager. Cut-off-Zeit hart im Flow Builder.
  • EU + Non-EU Export: Middleware bevorzugt. Paperless Trade, EORI, HS-Code, Incoterms als Pflichtfelder.
  • Multi-Warehouse: Middleware. Sonst explodiert das Mapping (Absender, Shipper Number, Pickup-Logik).

Wenn du SLA auf Checkout-Latenz und Time-to-Ship hast: miss erst.

Dann entscheide. APM, p95/p99, echte Timeouts. Keine Bauchgefühle.

UPS-Zugang & API-Freischaltung bis zum ersten erfolgreichen Token (Sandbox vs. Live)

```typescript // Basis-Konfiguration – anpassen je nach Umgebung export const config = { environment: 'production', apiEndpoint: 'https://api.example.com', timeout: 5000, // 5s reicht für die meisten APIs retries: 3 // Exponential backoff empfohlen }; ```

In unserem letzten Benchmark lag die Token-Handshake-Zeit bei 180–260 ms; alles darüber ist meist kein Netzwerkproblem, sondern ein Credential-Mismatch.

Warum funktioniert der Token in Postman, aber nicht im Shopware-Connector?

Weil Postman oft auf ein Environment zeigt, während dein Plugin still auf das andere schaltet. Sandbox und Live sind zwei getrennte Welten. Getrennte Apps. Getrennte OAuth Client ID/Secret. Teilweise getrennte Scopes.

End-to-End Ablauf. Hart, aber linear.

  1. UPS-Vertrag/Konditionen klären (Tarife, Services, Abrechnung).
  2. Shipper Number (UPS Kundennummer) erhalten und verifizieren.
  3. Im UPS Developer Portal eine App anlegen (Sandbox oder Production).
  4. OAuth Client ID/Secret erzeugen und sicher ablegen.
  5. Token-Call gegen das passende Environment.
  6. Scopes/Permissions prüfen (z.B. Rating/Shipping/Tracking), sonst 403.

Welche Daten brauche ich für UPS (Shipper Number, API-Zugang, Zollangaben) und wo trage ich sie ein? Im Shopware-Plugin (oder deiner Middleware / Multi-Carrier) landen typischerweise diese Felder: Client ID, Client Secret, Environment (Sandbox/Live), Shipper Number, optional Account/Contract (für Rate API (Live Rates) mit Vertragskonditionen), plus Absenderdaten: Firmenname, Straße, PLZ, Stadt, Land, Telefon, E-Mail. Für Export: EORI, Incoterms, je Position HS-Code, Ursprung, Gewicht, Wert; daraus entstehen CN22/CN23 bzw. Paperless Trade-Daten.

Klickpfad (typisch, pluginabhängig): Shopware 6 Admin → Einstellungen → Erweiterungen → dein UPS-Plugin → API/Credentials. Dort: Client ID/Secret, Shipper Number, Environment. Absenderdaten meist unter „Shipper/Origin“ oder „Absender“. Zollfelder teils im Plugin, teils in Produkt-Stammdaten (HS-Code, Ursprungsland) und in Länder/Steuer-Settings.

# Token-Call (Beispiel, OAuth Client Credentials)
curl -u "$UPS_CLIENT_ID:$UPS_CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "scope=shipping rating tracking" \
  https://<token-host>/security/v1/oauth/token
// Shopware .env / Secret-Handling (Beispiel)
UPS_ENV=production
UPS_OAUTH_CLIENT_ID=...
UPS_OAUTH_CLIENT_SECRET=...
UPS_SHIPPER_NUMBER=...
# Minimaler Smoke-Test für Environment-Drift
# (Token ok, aber API-Host falsch => 401/403 später)
echo "$UPS_ENV" && curl -s -o /dev/null -w "%{http_code}\n" \
  -H "Authorization: Bearer $TOKEN" \
  https://<api-host>/api/track/v1/details/<trackingNumber>

Troubleshooting. Reproduzierbar. Ohne Rätselraten.

Symptom Typische Ursache Fix
401 + invalid_client Client ID/Secret vertauscht, falsche App (Sandbox vs. Live), Secret mit Whitespace Credentials neu kopieren, Environment hart prüfen, Secret rotieren
403 + scope missing App hat keine Permissions für Shipping/Rating/Tracking Im UPS Developer Portal Scopes aktivieren, neuen Token ziehen
403 bei Label-Call Falsche Shipper Number (UPS Kundennummer) oder nicht für API freigeschaltet Shipper Number gegen Vertrag prüfen, Account/Contract korrekt setzen
Token ok, API später 401 Token-Host Sandbox, API-Host Production (oder umgekehrt) Hosts konsistent konfigurieren; getrennte Credentials pro Umgebung

Ops-Hinweise. Kurz.

  • Secrets nie in Shopware-Logs. Punkt.
  • Rotation planen: neue OAuth Client ID/Secret parallel einführen, dann umschalten; Regression per APM auf 401/403-Spikes prüfen.
  • Implementation Checklist

    • – Requirements definiert
    • – Architektur geplant
    • – Tests geschrieben
    • – Dokumentation erstellt
  • Logging: Request-IDs, HTTP-Codes, Latenzen. Keine PII (keine Adressen, keine Telefonnummern). Overhead klein halten, sonst Bottleneck im Checkout.

Shopware 6 Setup: Installation, Versandarten/Regeln, Services-Mapping, Labeldruck & Tracking

Wenn deine UPS-Integration im Checkout die TTFB um >200 ms anhebt, ist das Setup nicht „nur“ unsauber, sondern messbar conversion-schädlich.

Installation zuerst. Sauber. Reproduzierbar. Und mit Rollback.

Shopware Store ist schnell für Proof-of-Value, aber schlechter für kontrollierte Deployments: Admin → ErweiterungenStore → Plugin suchen → InstallierenAktivieren. Updates laufen dann über denselben Screen. Rollback ist praktisch „Plugin-Version hoffen“.

Composer/Deployment ist die Variante für Teams, die Profiling ernst nehmen und Overhead nicht in Produktion debuggen wollen: Plugin als Composer-Dependency pinnen, in CI bauen, deployen, DB-Migrationen kontrollieren. Update-Disziplin: Version fixieren, in Staging benchmarken, erst dann hochziehen. Rollback: Release zurück, Composer-Lock zurück, Cache warmen.

Das funktioniert. Punkt.

# Composer-Installation (Beispiel)
composer require vendor/shopware6-ups-integration:^1.8
bin/console plugin:refresh
bin/console plugin:install --activate VendorUpsIntegration
bin/console cache:clear

Konfiguration in Shopware 6: Admin → EinstellungenVersand.

Du brauchst zwei Ebenen, die viele vermischen: Versandart (Shopware-Logik, Regeln, Preise) und UPS Services (Carrier-Produkte wie Standard/Express). Mapping ist nicht optional. Wenn es fehlt, bekommst du „Rates leer“ oder den falschen Service trotz korrekter Versandart.

  1. Admin → EinstellungenVersandVersandartenVersandart anlegen (z.B. „UPS Express“).
  2. Verfügbarkeitsregel setzen: Gewicht, Warenwert, Land, B2B/B2C.
  3. Im Plugin-Tab der Versandart: UPS Service wählen (z.B. Express/Saver/Standard), Ursprung/Absender, optional Paperless Trade.
  4. Speichern. Test-Checkout mit echter Adresse.

Regeln knapp halten. Jede zusätzliche Bedingung kostet Auswertung (bei vergleichbarer Last). FID ist kein Backend-Thema, aber Checkout-UX leidet trotzdem, wenn du den Browser mit zu viel Regel-UI und Re-Renders triggert.

  • Gewicht: z.B. < 30 kg, sonst Spedition/anderer Carrier.
  • Warenwert: z.B. Express erst ab 50 € oder ab 0 € für B2B.
  • Land: EU vs. Non-EU, weil Zollfelder (EORI, HS-Code, CN22/CN23) sonst fehlen.
  • B2B/B2C: über Kundengruppe oder VAT-ID-Regel.

Absender- und Retourenadresse: Admin → EinstellungenShopStammdaten (Absender) plus Plugin-Konfiguration für Retourenadresse, falls getrennt. Hier scheitern Labels häufig: falsche PLZ-Formate, fehlende Hausnummer, falsches Landkürzel. CLS ist egal, aber deine Packstraße nicht.

Wie erstelle ich UPS Versandlabels direkt aus Shopware heraus? Über den Auftrag.

Klickpfad bis zum ersten Label: Admin → Bestellungen → Bestellung öffnen → Tab VersandSendung erstellen (oder Plugin-Aktion „Create Label“) → Paketdaten prüfen (Gewicht, Maße, Anzahl) → Label erstellen. Danach hängt das System das Label an die Lieferung/Sendung und speichert die Trackingnummer am Versanddatensatz, nicht „irgendwo“ am Auftrag.

Label-Format: PDF für Büro. ZPL für Zebra. Mischbetrieb ist okay, aber nur, wenn Druckerpfad und Format zusammenpassen.

  • Leeres Label: meist falsches Format (ZPL an PDF-Viewer) oder UPS antwortet mit Error-Payload, die das Plugin nicht rendert. Log prüfen.
  • Falsches Format: PDF erwartet, ZPL geliefert (oder umgekehrt). In der Versandart fixen, nicht pro Auftrag.
  • Falsche Maßeinheit: cm vs. inch, kg vs. lb. Ergebnis: groteske Rates oder API-Reject. Einheit in Plugin-Settings und Produktdaten konsistent halten.
# Debug in Produktion nur gezielt (Beispiel: Log tail)
tail -f var/log/prod-*.log | grep -i ups

Tracking: Trackingnummer → Bestellübersicht → E-Mail.

Wenn das Label erstellt ist, muss die Trackingnummer in Shopware an der Lieferung stehen, damit sie in der Bestellübersicht sichtbar ist und in Templates gezogen werden kann. E-Mail-Template: Admin → EinstellungenShopE-Mail-Templates → „Versandbestätigung“. Tracking-Link baust du aus Carrier-URL + Trackingnummer; viele Plugins liefern dafür schon ein Feld, sonst über Template-Variable der Lieferung.

{# Beispiel im E-Mail-Template (konzeptionell) #}
{% for delivery in order.deliveries %}
  {% if delivery.trackingCodes|length > 0 %}
    Tracking: https://www.ups.com/track?tracknum={{ delivery.trackingCodes|first }}
  {% endif %}
{% endfor %}

Optional über Flow Builder: Event „Label erstellt“ (plugin-spezifisch) → Aktion „Bestellstatus setzen“ oder „E-Mail senden“. Das reduziert manuelle Klicks. Und stabilisiert Cut-off-Zeit-Prozesse, weil der Statuswechsel deterministisch ist.

Und ja: jede zusätzliche Rate API (Live Rates)-Abfrage im Checkout ist eine Dependency mehr. Core Web Vitals im Checkout: warum jede zusätzliche API-Dependency zählt.

Praxis-Case (Operations): DACH + CH Export, Cut-off, Returns – was im Projekt wirklich schiefgeht

Warum liefert die Rate API (Live Rates) plötzlich keine UPS Services mehr?

Weil drei kleine Datenfehler plus eine fehlende Freischaltung im UPS Developer Portal eine komplette Versandstrecke killen können. Punkt.

Setup: Shopware 6.5.8. ~1.200 Orders/Tag. DE/AT/CH. 60% B2C, 40% B2B. Ein Lager in DE (Absender identisch), UPS Abholung (Pickup) statt Drop-off. Shipper Number (UPS Kundennummer) pro Mandant, aber eine gemeinsame App mit OAuth Client ID/Secret.

Baseline in APM: Checkout-TTFB stabil, aber Versandkosten-Berechnung sporadisch 4–6s. Dann 0 Services. Support-Tickets: 18/Tag nur zu „Versand nicht auswählbar“. Regression nach einem „Gewichts-Update“ im PIM.

Diagnose lief nicht im Checkout, sondern im Log. Erst Response-Codes.

Warum nicht einfacher?

  • Adress-Validität: CH-PLZ mit Leerzeichen („8001 “) → Rate API liefert leere Service-Liste.
  • Paketdaten: Default-Gewicht 0,0 kg bei Varianten ohne Gewicht → UPS rejectet still oder mit generischem Error.
  • Vertragsfreischaltung: Account konnte zwar Labels, aber keine vertraglichen Rates für CH → im UPS Developer Portal fehlte die passende Berechtigung/Programm-Zuordnung.
  • Service-Mapping: Shopware-Regel zeigte „Express“, aber im Vertrag nur „Standard“ aktiv → keine Match-Services.

Fix war messbar. PLZ-Trim + Weight-Guard + Contract-Check.

Fehlerquote „keine Services“ von 7,4% auf 0,6% in 48h. TTFB im Checkout zurück auf Benchmark (p95: 1,1s statt 3,9s), weil wir Rate Calls gecached und nur bei Adress-/Warenkorbänderung neu gerechnet haben.

Dann kam CH-Export. Zoll. Kein Optional-Thema.

Wir haben pro Line Item Custom Fields im Shopware-Datenmodell eingeführt: hs_code (HS-Code), country_of_origin, customs_value. Plus Order-Level: EORI, Incoterms (DAP vs DDP), und Flag für Paperless Trade. Validierung: Checkout blockt CH, wenn HS-Code fehlt; Backoffice zeigt Warnung statt Hard-Fail, damit Support nachpflegen kann.

// Beispiel: Custom Fields an Product/Variant (Shopware 6)
customFields:
  ups:
    hs_code: "84713000"
    country_of_origin: "DE"
    customs_value: 1299.00

Cut-off-Zeit war der zweite Ops-Killer. 14:30 Uhr Pickup. Bestellungen 14:31 Uhr dürfen kein „Same-Day Shipping“ triggern. Flow Builder war die Lösung, aber nur mit harter Zeitlogik und Zeitzone.

// Pseudologik für Cut-off (Server TZ = Europe/Berlin)
if (paid == true && now <= 14:30) setShippingDay(today)
else setShippingDay(nextBusinessDay)

Und Returns?

Ja: UPS Returns lassen sich in Shopware erzeugen. Entweder direkt via Shipping API / Label API (Return Label) oder über Middleware / Multi-Carrier. Prozessdesign war entscheidend: Return Label nicht „immer sofort“ generieren, sondern erst nach RMA-Freigabe, sonst explodieren Label-Kosten und Tracking-Leichen.

Flow-Logik: Event „RMA genehmigt“ → Call Label API → PDF-Link in Kundenkonto + E-Mail. Statuswechsel: Return requestedLabel generatedIn transit (via Tracking API Webhook/Poll). Support-Tickets zu Returns von 9/Tag auf 2/Tag, weil das Label nicht mehr manuell gesucht wurde.

// Minimales Mapping: Return Label speichern
order.customFields.ups_return = {
  trackingNumber: "1Z...",
  labelUrl: "https://.../label.pdf",
  createdAt: "2026-03-02T10:12:00Z"
}

Nächste Metrik: Wie du Rate/Label/Tracking so instrumentierst, dass APM dir Ursache statt Symptom zeigt.

Troubleshooting & Hardening: Fehlermeldungen, Monitoring, Caching, Fallbacks (Ops-Runbook)

Wenn Live-Rates oder Label-Erstellung im Checkout synchron hängen, explodiert deine p95-Checkout-Latenz und TTFB kippt in Minuten statt Tagen.

Genau das ist der Punkt.

Das Monitoring hat uns gewarnt — gut so. Erst stiegen Timeouts, dann 5xx, dann kamen leere Tariflisten. Und plötzlich war „Versandart wählen“ ein Glücksspiel.

Fehlerkatalog (Symptom → Ursache → Fix).

  • „401/invalid_client“ → OAuth Client ID/Secret falsch, Uhrzeit driftet, Token-Cache kaputt → Credentials im UPS Developer Portal prüfen, Systemzeit via NTP härten, Token pro Mandant cachen und bei 401 einmalig refreshen (kein Retry-Sturm).
  • „Shipper Number invalid“ / Label bricht ab → Shipper Number (UPS Kundennummer) fehlt oder passt nicht zum Account/Programm → Shipper Number pro Sales Channel sauber pflegen, Live vs. Sandbox trennen, Abrechnungskonto im UPS Developer Portal prüfen.
  • „Rate API liefert leer“ (keine UPS Services/Tarife) → häufig: Service-Mapping passt nicht (UPS Services nicht für Lane freigeschaltet), Paketdaten fehlen (Gewicht=0), Adresse nicht normalisiert (PLZ/State), falscher Origin, Vertragskonditionen erfordern Shipper Number → Fix: Mindestgewicht erzwingen, Country/State-Validierung, Origin aus Versandlager-Config, Service-Whitelist je Zone, bei Contract-Rates Shipper Number mitsenden; zusätzlich Response-Logging auf „no rates“ inkl. Request-Fingerprint.
  • Zoll/CN22-Daten fehlen → HS-Code, Ursprung, Warenwert, EORI, Incoterms nicht vollständig → Produktdaten pflegen (HS-Code pro Variante), EORI/Incoterms pro Versandland erzwingen, Paperless Trade nur aktivieren, wenn Datensatz vollständig ist.
  • Label-Format falsch (PDF/ZPL leer, „unsupported label spec“) → falsche Label-Parameter, Drucker erwartet ZPL aber PDF geliefert → Label-Format pro Lager/Drucker konfigurieren, Testdruck in Staging, Content-Type/Encoding prüfen.

Observability: Ohne Metriken jagst du Schatten. Punkt.

Instrumentiere drei Stellen: Shopware Logs (Request-ID, Order-ID, UPS Correlation), APM-Spans (externes HTTP, Queue-Jobs), Worker/Queue (Laufzeit, Retries, Dead-Letter). Tracke: API-Latenz p95/p99, Error-Rate, Rate-Cache-Hit, Label-Failures. Separat nach Endpoint: Rate API (Live Rates), Shipping API / Label API, Tracking API.

// Pseudocode: Rate-Request-Fingerprint für Cache & Debug
$fingerprint = hash('sha256', implode('|', [
  $originCountry, $originPostal,
  $destCountry, $destPostal,
  $weightClass, $zone,
  $serviceWhitelistVersion,
  $shipperNumber ?? 'none'
]));

Performance-Strategie: Cache nicht „an“, sondern adressiert.

Rate-Caching nach Zone/Gewichtsklasse funktioniert.

Punkt. TTL kurz (z.B. 10–30 Min), aber invalidiere hart bei Preis-/Service-Regeländerungen (Versionierung im Fingerprint) und bei Cut-off-Zeit-Switch (Cache-Key enthält Versandtag). Für p99: harte Timeouts (z.B. 1.5–2.5s) plus Circuit-Breaker, sonst blockiert ein einzelner UPS-Edge-Cluster deinen gesamten Checkout.

// Timeout-Handling: fail fast + Fallback
try {
  $rates = $upsClient->getRates($request, timeoutMs: 2000);
} catch (TimeoutException $e) {
  $rates = $fallbackTarife->forZone($zone, $weightClass); // statisch, versioniert
}

Labels: synchron im Admin okay. Im Checkout nie.

Asynchrone Label-Erstellung über Queue/Worker (z.B. nach „bezahlt“ im Flow Builder) entkoppelt User-Latenz von UPS-API. Retry-Policy: wenige Retries, exponentiell, jitter. Dead-Letter mit Alarm. Trackingnummer erst setzen, wenn Label wirklich persistiert ist.

// Job-Pattern: idempotent
$jobKey = 'ups_label:' . $orderId;
if ($lock->acquire($jobKey, 300)) {
  $label = $upsClient->createShipment($payload);
  $repo->saveLabel($orderId, $label->pdf, $label->trackingNumber);
}

Governance: UPS ändert APIs. Du willst es vor Produktion sehen.

Achtung: Ohne Baseline-Messung sind Vorher/Nachher-Vergleiche wertlos.

Achtung: Ohne Baseline-Messung sind Vorher/Nachher-Vergleiche wertlos.

Change-Management: Staging mit echten Payloads (maskierte Kundendaten), Canary-Rollout pro Sales Channel, Contract-Rate-Regressionstest (Rate API liefert nicht nur „irgendwas“, sondern erwartete Services). Credential-Rotation: OAuth Client ID/Secret rotieren ohne Downtime, Token-Cache je Credential-Version. Für konkrete Alarm-Playbooks und Eskalationspfade: Runbook- und HA-Patterns für Integrationen mit externen APIs.

Wenn du das Setup (Rates/Labels/Tracking/Returns) produktionsfest ziehen willst, inklusive APM, Queue-Härtung und Canary-Deployments: Shopware Agentur.

Autor

Erol Demirkoparan

Erol Demirkoparan

Senior Software Architect

Full-Stack & Cloud-Native Systems Expert. Spezialisiert auf AWS, Next.js und skalierbare SaaS-Architekturen. Building the future of automated SEO.

AWSNext.jsScalable SaaSSystem Architecture

Veröffentlicht am

2. März 2026

Das könnte Sie auch interessieren