GET /v2/merchant/shops/:shopId/abandoned-carts/:cartId returns the full report-ready envelope for one abandoned cart: line items (with thumbnails, SKUs, qty × unit price, line total), customer contact, subtotal in the cart’s currency, the recovery-event timeline, and the recovery token (until the cart is recovered).
This endpoint pairs with the merchant list + stats endpoints. The list returns row summaries; this endpoint returns the drawer-ready detail. Use this when a merchant clicks a row to see what was actually in the cart and how the recovery has progressed.
When to use this
- The merchant dashboard renders a cart-details drawer when a merchant clicks a row in the abandoned-carts list
- A future details page wants the full cart payload + recovery timeline in one round-trip
- A pre-resend preview surface needs to confirm the contents before re-sending the recovery email
Authentication
Merchant JWT (PRODUCER role) plus shop-ownership enforced server-side by the shared MerchantShopScope guard. The JWT-bound shopId claim must equal the :shopId path parameter. Cross-shop access returns 404 — never 403 — to avoid leaking the existence of :cartId to an enumeration attacker.
Request
Curl example
Response (200)
Field reference
Money fields are MAJOR units
Unlike the list endpoint which serializescartTotalCents (cents, integer minor units), the details endpoint returns subtotal, unitPrice, and lineTotal in MAJOR units of currency. The backend’s projection layer converts once at the boundary using a zero-decimal-currency table (e.g. JPY/KRW have no fractional unit; USD/EUR have 2 decimals). The client can pass the values straight into Intl.NumberFormat({ style: 'currency', currency }) without dividing by 100.
This contract diverges from the list endpoint intentionally — the list optimizes for the table cell where minor-unit integers avoid float drift across aggregates; the drawer endpoint pre-formats the merchant-friendly value so the UI doesn’t need to know the currency-decimals table.
Recovery token redaction
The backend includesrecoveryToken in the response only while recoveredAt === null. After the checkout-success chokepoint flips the row, the token is operationally useless (the cart cannot be re-recovered) and exposing it widens the leak surface. The merchant dashboard hides the “copy recovery link” CTA whenever the field is null — defense-in-depth even though the BE already redacts.
Recovery event channels
Error responses
The list + stats endpoints documented on the merchant page are migrating from a
403 to a 404 posture on cross-shop access to match this endpoint (tracked in droplinked-backend PR #1980). Once that lands, all three endpoints will share the unified 404 + abandoned_cart_not_found body.Drawer-style flow
Related
- Abandoned carts (merchant) — list + recovery-stats endpoints (the table this drawer is launched from)
- Resume an abandoned cart (public) — the storefront-side endpoint customers hit from the recovery email link
- Embed the trust-fabric widget — the dashboard chrome the drawer launches inside
- Order lifecycle — the chokepoint that flips a row to
RECOVERED