Marketplace Service
core/services/marketplace_service.dart
Overview
Two endpoints: paginated/filtered list and single-product fetch. Both hit /store/physical-products with `fields=*variants.calculated_price` so the UI gets per-region pricing in the same response.
User Flow
- getProducts(...filters) → GET /store/physical-products with the dynamic query map.
- Empty / null filters are omitted via the spread + if-condition pattern.
- getProductById(id) → GET /store/physical-products/:id; throws 'Product not found' for null data.
Cases & Edge Cases
- Network errors are unwrapped (response.data['message']) when possible, then re-thrown as Exception for the controller to surface.
- Each filter list field uses Dio's auto-encoding (?category_id=X&category_id=Y) — relies on Dio's default ListFormat.
- title[$like] is escaped with a literal '$' in the query key — Medusa accepts that as the contains operator.
Code References
- lib/src/core/services/marketplace_service.dart:9 // getProducts
- lib/src/core/services/marketplace_service.dart:78 // getProductById
API Calls
- GET
/store/physical-productsno statusPaginated catalog of physical products with combined server-side filter, sort and search.
RequestQuery (all optional): limit, offset, q, category_id[], collection_id, tag_id[], type_id, order, is_giftcard, title[$like], variants[options][value], fields=*variants.calculated_price
Response{ products: Product[] }lib/src/features/shared/marketplace/views/marketplace_home_screen.dart + widgets/marketplace_product_list.dartauth: customer. title[$like] uses Medusa's contains operator (literal $).
- GET
/store/physical-products/:productId?fields=*variants.calculated_priceno statusFetch a single physical product (fallback when route extra is missing).
Response{ product: Product }lib/src/features/shared/product_details/views/product_details_screen.dart // loadProductauth: customer.
Notes
Pagination is via offset+limit; no cursor / nextLink — the controller increments offset by the actual response length, not by limit, so a partial last page still terminates cleanly.