Hide failed-payment order attempts from the customer's own order history
A cancelled order with no invoiceNumber is a Stripe payment that never succeeded (failed or timed out before ever reaching received/invoiced), not a real cancellation of something that actually happened — from the customer's point of view it was never really an order. Filtered out of getCustomerOrders/getCustomerOrderDetail by default; the row stays in Payload for admin/audit purposes (shown there as "Zahlung fehlgeschlagen", see backend). getCustomerOrderDetail's filter is opt-in via a new optional parameter, not the default — /api/checkout/status/route.ts's post-payment polling needs to keep seeing exactly this order to show the "Zahlung fehlgeschlagen, bitte erneut versuchen" retry state. The GDPR export route also opts out for the same reason a legal completeness export can't silently drop rows. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -374,7 +374,12 @@ exactly as before: no gateway involved, order goes straight to `received`.
|
||||
(`app/lib/payments/confirmPaymentEmail.ts`, only when the response isn't
|
||||
`alreadyProcessed: true` — a repeat webhook delivery must never resend
|
||||
it), mirroring exactly what the checkout route already does inline for
|
||||
a manual/Überweisung order.
|
||||
a manual/Überweisung order. Product photos in that snapshot's
|
||||
`items[].imageUrl` need no frontend change to work —
|
||||
`ConfirmPaymentOrderSnapshot`/`OrderConfirmationItem` already typed the
|
||||
field; the backend just wasn't populating it (fixed there, see its own
|
||||
README — needed `depth: 2` so `item.product.image` resolves to a real
|
||||
`Media` doc).
|
||||
- **`/checkout/verarbeitung`** (`VerarbeitungContent.tsx`) is the
|
||||
`return_url` target. Neither a client-side `confirmPayment()` success nor
|
||||
landing back from a PayPal redirect is trusted as proof of payment on its
|
||||
@@ -1172,6 +1177,24 @@ ref isn't attached to anything yet at that exact synchronous point.
|
||||
`cancelled`/`return_requested`/`returned`) is maintained by hand in the
|
||||
Payload admin for the shipping states — no shipping-carrier API
|
||||
integration.
|
||||
- **A `cancelled` Stripe order with no `invoiceNumber` never shows up
|
||||
here** — that's a `pending_payment` order whose payment failed or timed
|
||||
out (see the backend's `expirePendingPayments`/`confirmPayment.ts`), not
|
||||
a real Storno (which is always of an already-`received`, already-
|
||||
invoiced order, so it always has an `invoiceNumber`). From the
|
||||
customer's point of view a payment that never went through was never
|
||||
really an order, so `getCustomerOrders`/`getCustomerOrderDetail`
|
||||
(`app/lib/customerAuth.ts`) filter these out by default — the row still
|
||||
exists in Payload for admin/audit purposes (shown there as "Zahlung
|
||||
fehlgeschlagen", see the backend's own README), just not surfaced to
|
||||
the customer. `getCustomerOrderDetail` takes this as an **optional**
|
||||
4th param, defaulting `false` — `/api/checkout/status/route.ts`'s
|
||||
post-payment polling deliberately calls it unfiltered, since that flow
|
||||
needs to keep seeing exactly this order (to show "Zahlung
|
||||
fehlgeschlagen, bitte erneut versuchen") for the one case this filter
|
||||
would otherwise hide. `/api/account/export/route.ts`'s GDPR export also
|
||||
opts out (`false`) — a legal completeness export can't silently drop
|
||||
rows.
|
||||
- **`Navbar.tsx`'s `AccountLink`** (account icon, always visible in the
|
||||
header itself — not duplicated inside the mobile fullscreen menu, see
|
||||
"Mobile navigation" below) is the only *always*-reachable way into
|
||||
|
||||
Reference in New Issue
Block a user