Add optional Firma/USt-IdNr. fields to checkout and profile

B2B checkout fields, split out from the e-invoicing migration and
picked back up now that it's shipped. Both fields are independently
optional, format-validated (shared regex in lib/vatId.ts, mirrored
server-side in api/checkout and api/account/profile), persisted in
the checkout draft, and saved as a customer profile default that
pre-fills future checkouts. Order/customer snapshot fields land in a
companion Payload backend commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-07-23 17:53:21 +00:00
parent 2d88fb86a1
commit e48107470a
8 changed files with 119 additions and 1 deletions
@@ -45,6 +45,8 @@ export function ProfileForm({ profile }: { profile: CustomerProfile }) {
zip: String(form.get("zip") ?? ""),
city: String(form.get("city") ?? ""),
country: String(form.get("country") ?? ""),
companyName: String(form.get("companyName") ?? "") || undefined,
vatId: String(form.get("vatId") ?? "") || undefined,
};
try {
@@ -83,6 +85,22 @@ export function ProfileForm({ profile }: { profile: CustomerProfile }) {
<Field label="Nachname" name="lastName" type="text" defaultValue={profile.lastName} required />
</div>
{/* Optional B2B fields — prefills /checkout's own Firma/USt-IdNr.
fields, same "profile default, order keeps its own snapshot"
split as the address fields below (see Customers.ts). */}
<div className="flex flex-col sm:flex-row gap-4 w-full">
<Field label="Firma (optional)" name="companyName" type="text" defaultValue={profile.companyName ?? ""} />
<Field
label="USt-IdNr. (optional)"
name="vatId"
type="text"
defaultValue={profile.vatId ?? ""}
placeholder="DE123456789"
pattern="[A-Za-z]{2}[A-Za-z0-9]{2,12}"
title="EU-Format: 2 Buchstaben Länderpräfix + bis zu 12 alphanumerische Zeichen, z. B. DE123456789."
/>
</div>
<div className="w-full flex flex-col gap-2 items-start">
<span className="text-label text-text-muted">Lieferart</span>
<div className="flex w-full max-w-sm rounded-sm border border-border overflow-hidden">