mivita/dev/23-01-2026/dhl-return-label-fallback-summary.md
2026-01-23 17:35:23 +01:00

7.1 KiB

DHL Return Label - Fallback Implementierung

Datum: 23.01.2026
Status: Implementiert

Problem

Fehler: "DHL API authentication failed: Access to the resource is not allowed"

Grund: Viele DHL-Geschäftskundenaccounts haben keinen Zugriff auf den speziellen Returns-API-Endpunkt (/parcel/de/returns/v1/labels). Dieser Endpunkt benötigt oft:

  • Separate Freischaltung durch DHL
  • Spezielle Account-Berechtigung
  • Separate Billing-Nummer für Returns

Lösung: Intelligenter Fallback

Strategie

  1. Primär: Versuche Returns-API zu verwenden
  2. Fallback: Bei Authentifizierungsfehler → Nutze reguläre Shipping-API mit Produktcode V07PAK

Implementierung

public function createReturn(array $returnData): array
{
    try {
        // Try Returns API first
        return $this->createReturnViaReturnsAPI($returnData);
        
    } catch (Exception $e) {
        // Check if authentication/permission error
        if (str_contains($e->getMessage(), 'authentication') || 
            str_contains($e->getMessage(), 'not allowed') ||
            str_contains($e->getMessage(), '401') ||
            str_contains($e->getMessage(), '403')) {
            
            // Fallback to regular shipment
            return $this->createReturnViaRegularShipment($returnData);
        }
        
        throw $e; // Re-throw other errors
    }
}

Methode 1: Returns API

Endpunkt: POST /parcel/de/returns/v1/labels

Payload:

{
  "receiverId": "DEDE",
  "customerReference": "Return-12345",
  "billingNumber": "33333333330107",
  "shipper": {
    "name1": "Max Mustermann",
    "addressStreet": "Beispielstraße",
    "addressHouse": "10",
    "postalCode": "12345",
    "city": "Berlin",
    "country": "DEU"
  },
  "receiver": {
    "name1": "mivita care gmbh",
    "addressStreet": "Leinfeld",
    "addressHouse": "2",
    "postalCode": "87755",
    "city": "Kirchhaslach",
    "country": "DEU"
  }
}

Vorteile:

  • Speziell für Returns designt
  • Simplere Payload
  • Direkter Returns-Workflow

Nachteile:

  • Benötigt spezielle Freischaltung
  • Nicht für alle Accounts verfügbar

Methode 2: Regular Shipping API (Fallback)

Endpunkt: POST /parcel/de/shipping/v2/orders

Produkt: V07PAK (DHL Retoure Online)

Payload:

{
  "profile": "STANDARD_GRUPPENPROFIL",
  "shipments": [{
    "product": "V07PAK",
    "billingNumber": "33333333330107",
    "shipper": {
      "name1": "Max Mustermann",
      "addressStreet": "Beispielstraße",
      "addressHouse": "10",
      "postalCode": "12345",
      "city": "Berlin",
      "country": "DEU"
    },
    "consignee": {
      "name1": "mivita care gmbh",
      "addressStreet": "Leinfeld",
      "addressHouse": "2",
      "postalCode": "87755",
      "city": "Kirchhaslach",
      "country": "DEU"
    },
    "details": {
      "weight": { "value": 2500.0, "uom": "g" }
    },
    "print": { "format": "PDF" },
    "refNo": "Return-Order-12345"
  }]
}

Nach Erstellung:

// Update type to 'return'
DhlShipment::where('id', $result['shipmentId'])
    ->update([
        'type' => 'return',
        'related_shipment_id' => $originalShipmentId,
    ]);

Vorteile:

  • Funktioniert mit Standard-DHL-Account
  • Keine spezielle Freischaltung nötig
  • Gleiches Ergebnis für den Kunden

Nachteile:

  • Etwas komplexere Payload
  • Zusätzlicher DB-Update nach Erstellung

Produkt-Code V07PAK

Name: DHL Retoure Online

Beschreibung: Spezieller DHL-Produktcode für Retourensendungen

Eigenschaften:

  • Für Retouren innerhalb Deutschlands
  • Tracking inklusive
  • Verschiedene Zustelloptionen
  • Abholung oder Einlieferung möglich

Konfiguration:

// config/dhl.php
'account_numbers' => [
    'V07PAK' => env('DHL_ACCOUNT_NUMBER_V07PAK', '63144073550701'),
],

'dimensions' => [
    'V07PAK' => [
        'length' => 120,
        'width' => 60,
        'height' => 60,
    ],
],

Logging

Returns API (Erfolg)

[DHL Returns] Creating return label
[DHL Returns] Using Returns API endpoint
[DHL Returns] Returns API Response received
[DHL Returns] Return label created successfully via Returns API

Fallback (Nach Auth-Fehler)

[DHL Returns] Creating return label
[DHL Returns] Using Returns API endpoint
[ERROR] DHL API authentication failed: Access to the resource is not allowed
[DHL Returns] Returns API not available, falling back to regular shipment
[DHL Returns] Using regular Shipping API as fallback
[DHL Returns] Return label created successfully via Shipping API fallback

Response-Struktur

Beide Methoden geben dieselbe Struktur zurück:

[
    'returnNumber' => '222209876543210',
    'label_path' => 'dhl/returns/222209876543210.pdf',
    'returnShipment' => DhlShipment { ... },
    'raw' => [ ... ],
    'method' => 'returns_api' | 'shipping_api_fallback'
]

Das method Feld zeigt an, welche Methode verwendet wurde.

Geänderte Dateien

  1. packages/acme-laravel-dhl/src/Services/ReturnsService.php
    • createReturn() mit Try-Catch-Fallback
    • createReturnViaReturnsAPI() - Returns API Methode
    • createReturnViaRegularShipment() - Fallback Methode
    • Import von ShippingService hinzugefügt

Testen

Test 1: Returns API verfügbar

# Return-Label erstellen
# Erwartung: Erfolg mit method='returns_api'

# Logs prüfen:
tail -f storage/logs/laravel.log | grep "DHL Returns"
# Sollte zeigen: "Using Returns API endpoint"

Test 2: Returns API nicht verfügbar (aktueller Fall)

# Return-Label erstellen
# Erwartung: Erfolg mit method='shipping_api_fallback'

# Logs prüfen:
tail -f storage/logs/laravel.log | grep "DHL Returns"
# Sollte zeigen: "falling back to regular shipment"

Verification

Nach erfolgreicher Erstellung prüfen:

-- Prüfe ob Return-Sendung korrekt erstellt wurde
SELECT id, dhl_shipment_no, type, related_shipment_id, status 
FROM dhl_package_shipments 
WHERE type = 'return' 
ORDER BY id DESC 
LIMIT 1;

-- Erwartung:
-- type = 'return'
-- related_shipment_id = Original-Sendungs-ID
-- status = 'created'
-- dhl_shipment_no = neue Tracking-Nummer

Vorteile der Fallback-Lösung

  1. Keine manuelle Konfiguration: Funktioniert automatisch
  2. Transparent: Logging zeigt verwendete Methode
  3. Robust: Kein Ausfall bei fehlenden Berechtigungen
  4. Flexibel: Nutzt automatisch Returns API wenn verfügbar
  5. Einheitlich: Gleiche Response-Struktur für beide Methoden

Häufige Fragen

Q: Sieht der Kunde einen Unterschied?

A: Nein, das Retourenlabel sieht identisch aus.

Q: Funktioniert Tracking für beide Methoden?

A: Ja, beide Methoden generieren gültige DHL Tracking-Nummern.

Q: Welche Methode ist besser?

A: Returns API ist spezialisiert, aber Fallback ist genauso funktional.

Q: Kann ich die Returns API aktivieren lassen?

A: Kontaktieren Sie Ihren DHL-Geschäftskundenberater.

Q: Kostet die Fallback-Methode mehr?

A: Nein, die Kosten sind identisch (V07PAK Produktcode).

Nächste Schritte

  1. Fallback implementiert
  2. Mit echter Sendung testen
  3. Label PDF prüfen
  4. Tracking testen
  5. Bei Bedarf: Returns API Freischaltung beantragen