Add DHL checkout integrations (autocomplete, postnummer, return label)

Wires the new backend DHL endpoints into checkout: an address-autocomplete
dropdown on the street fields, live Postnummer validation for Packstation
delivery, and a return-label download link on the order-detail page.
Proxied through Next.js API routes since DHL credentials are tenant-
specific and CheckoutContent is a Client Component.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-07-31 13:01:05 +00:00
parent 51e4860fe3
commit 8a4170a1e6
9 changed files with 338 additions and 22 deletions
+32
View File
@@ -2313,6 +2313,38 @@ features requires the matching `CompanySettings` toggle to actually be
switched on before it shows up anywhere in the frontend — if a feature
"isn't showing," check that first.
## DHL checkout integrations (2026-07-31)
Three checkout-facing pieces added, each invisible unless the tenant's
backend `dhl-settings` has the matching toggle on (checked indirectly —
the calls below 404 gracefully when a tenant hasn't activated a given DHL
sub-integration, same "no half-built UI" convention as the feature
toggles above). Full backend-side documentation:
`docker/payload`'s `src/lib/shipping/README.md`.
- **`app/lib/shippingDhl.ts`** — thin client for the backend's 2 public
DHL endpoints (Postnummer validation, DataFactory address autocomplete).
Own copy, no shared package — same convention as `app/lib/tracking.ts`.
- **`app/api/checkout/validate-dhl-postnumber/route.ts`** and
**`app/api/checkout/autocomplete-address/route.ts`** — Next.js API
routes proxying to the backend. Required because `CheckoutContent.tsx`
is a Client Component and DHL credentials are tenant-specific (live in
Payload) — unlike VIES (`validate-vat/route.ts`), the browser can never
call Payload's DHL endpoint directly.
- **`app/checkout/components/AddressAutocomplete.tsx`** — wraps the
billing and shipping street inputs with a debounced DHL DataFactory
suggestion dropdown; selecting a suggestion also fills zip/city.
- **Postnummer live validation** — `CheckoutContent.tsx`'s
`handlePostNumberBlur` (mirrors `handleVatIdBlur`'s shape/status-state
pattern) checks the Packstation Postnummer against DHL on blur, once the
existing format check (610 digits) already passes.
- **Return-label download** — `/konto/bestellungen/[orderNumber]` shows
a "Retourenschein herunterladen" link once the backend has generated a
DHL return label for that order (`order.dhlReturnLabelMedia`, resolved
via the new `getMediaUrlById()` in `app/lib/payload.ts` — the order
fetch itself stays `depth=0` for unrelated reasons, see
`getCustomerOrderDetail`'s own comment).
## Related design source
- `~/dev/einfach-produktiv/mockups/` — Figma-stage mockup PNGs