Audit cleanup of payment-status code paths uncovered while shipping
the partial-refund fix:
#1 Drop `viewModel.paid` (boolean). It was set from
`displayFinancialStatus === "PAID"` and never read anywhere. With
refunds in the picture it had become a footgun: a fully refunded
order that started PAID would still satisfy `paid === true`, but
`paymentStatus === "refunded"`. Callers should use `paymentStatus`
/ `requiresPayment` exclusively.
#2 Remove the unused `paidStamp` translation ("BEZAHLT" / "PAID").
Defined in both locales but never rendered.
#3 Classify VOIDED orders as a distinct `"voided"` payment status
(rendered "Annulliert" / "Voided") instead of "unpaid". A voided
order had its authorisation cancelled before capture — no money
was received and none is owed. The previous "Offen" / "Outstanding"
label combined with a GiroCode would have invited the customer to
pay an order that's already been called off. `requiresPayment`
now also excludes `"voided"`, so GiroCode + payment-terms
paragraph are suppressed (mirrors the `"refunded"` treatment).
"Annulliert" is used in German rather than "Storniert" to avoid
confusion with our storno cancellation document concept.
#6 `derivePaymentStatus` now logs a `console.warn` when it
encounters a non-empty `displayFinancialStatus` value that isn't
one of the documented Shopify enum members (PAID, PARTIALLY_PAID,
REFUNDED, PARTIALLY_REFUNDED, VOIDED, PENDING, AUTHORIZED,
EXPIRED). Future Shopify enum additions will surface in logs
instead of silently mapping to "unpaid".
EXPIRED stays mapped to "unpaid" — abandoned-checkout-style edge
case left intentionally for a separate decision (#4 in the audit).
Verification: render-sample now also exercises a VOIDED fixture
(status row "Annulliert", no GiroCode, no payment terms). tsc /
smoke / tests / build all green.