Cart Module API & Integration Guide
API contracts for customer/mobile cart operations, manual delivery address flow, quantity operations, and admin cart read.
Cart Module - API & Integration Guide
1. Base Routes
- Customer API:
/api/cart - Mobile-composed customer API:
/api/mobile/cart - Admin API:
/api/admin/cart
All successful responses use ResponseDto<T>.
2. Customer/Mobile Endpoints
| Method | Path | Auth | Request | Response |
|---|---|---|---|---|
GET | /api/cart | JWT | none | CartResponseDto |
GET | /api/mobile/cart | JWT | none | CartResponseDto |
POST | /api/cart/items | JWT | AddToCartDto | CartResponseDto |
POST | /api/mobile/cart/items | JWT | AddToCartDto | CartResponseDto |
POST | /api/cart/sync | JWT | SyncCartDto | CartResponseDto |
POST | /api/mobile/cart/sync | JWT | SyncCartDto | CartResponseDto |
DELETE | /api/cart/items/:itemId | JWT | path itemId | CartResponseDto |
DELETE | /api/mobile/cart/items/:itemId | JWT | path itemId | CartResponseDto |
POST | /api/cart/items/:itemId/increase | JWT | path itemId | CartResponseDto |
POST | /api/mobile/cart/items/:itemId/increase | JWT | path itemId | CartResponseDto |
POST | /api/cart/items/:itemId/decrease | JWT | path itemId | CartResponseDto |
POST | /api/mobile/cart/items/:itemId/decrease | JWT | path itemId | CartResponseDto |
PUT | /api/cart/items/:itemId/quantity | JWT | UpdateCartItemDto | CartResponseDto |
PUT | /api/mobile/cart/items/:itemId/quantity | JWT | UpdateCartItemDto | CartResponseDto |
GET | /api/cart/location | JWT | none | CartLocationResponseDto |
GET | /api/mobile/cart/location | JWT | none | CartLocationResponseDto |
GET | /api/cart/location/districts | Public | none | CartShippingDistrictResponseDto[] |
GET | /api/mobile/cart/location/districts | Public | none | CartShippingDistrictResponseDto[] |
POST | /api/cart/guest/quote | Public | GuestCartQuoteDto | GuestCartQuoteResponseDto |
POST | /api/mobile/cart/guest/quote | Public | GuestCartQuoteDto | GuestCartQuoteResponseDto |
POST | /api/cart/location | JWT | SetCartLocationDto | CartLocationResponseDto |
POST | /api/mobile/cart/location | JWT | SetCartLocationDto | CartLocationResponseDto |
POST | /api/cart/location/auto | JWT | GeocodeLocationDto | Disabled by default (410) |
POST | /api/mobile/cart/location/auto | JWT | GeocodeLocationDto | Disabled by default (410) |
DELETE | /api/cart/location | JWT | none | CartClearResponseDto |
DELETE | /api/mobile/cart/location | JWT | none | CartClearResponseDto |
DELETE | /api/cart | JWT | none | CartClearResponseDto |
DELETE | /api/mobile/cart | JWT | none | CartClearResponseDto |
3. Admin Endpoint
| Method | Path | Auth | Permission | Response |
|---|---|---|---|---|
GET | /api/admin/cart/users/:userId | JWT + RBAC | Cart_READ | CartAdminUserCartResponseDto | null |
4. Care-Package Cart Endpoints
These endpoints are mounted under /api/cart/items/:cartItemId/care-package (and /api/mobile/cart/items/:cartItemId/care-package via MobileModule routing).
The direct add/remove endpoints are authenticated only. Guest care-package pricing is supported through POST /api/mobile/cart/guest/quote; persistence happens after login through POST /api/mobile/cart/sync.
| Method | Path | Auth | Request | Response |
|---|---|---|---|---|
POST | /api/cart/items/:cartItemId/care-package | JWT | AddCarePackageToCartDto | CartCarePackageItemResponseDto |
POST | /api/mobile/cart/items/:cartItemId/care-package | JWT | AddCarePackageToCartDto | CartCarePackageItemResponseDto |
DELETE | /api/cart/items/:cartItemId/care-package | JWT | path cartItemId | RemoveCarePackageFromCartResponseDto |
DELETE | /api/mobile/cart/items/:cartItemId/care-package | JWT | path cartItemId | RemoveCarePackageFromCartResponseDto |
Add request DTO:
POST /api/mobile/cart/items/:cartItemId/care-package
{
"carePackageId": 1,
"pricingTierId": 3
}Response note: DELETE returns HTTP 200 (not 204) with a RemoveCarePackageFromCartResponseDto confirming the removed item details.
5. Request DTOs
4.1 Add item
{
"productId": 101,
"quantity": 2
}quantityis optional, defaults to1.- allowed range:
1..99.
4.2 Set quantity
{
"operation": "set",
"quantity": 3
}- for this endpoint,
operationmust beset.
4.3 Sync cart (replace active cart, no merge)
{
"items": [
{
"productId": 101,
"quantity": 2,
"carePackage": {
"carePackageId": 2,
"pricingTierId": 3
}
},
{ "productId": 202, "quantity": 1 }
]
}Rules:
- If
itemsis empty, backend returns current authenticated cart unchanged. - If
itemshas data, backend replaces existing active cart content with this payload. - Existing active cart is not merged; it is replaced.
- Optional
carePackagepersists one care package add-on for that synced product line. - Duplicate entries for the same
productIdmust carry the same care package selection.
4.4 Set location (manual canonical)
{
"districtName": "Kathmandu",
"addressLine1": "Boudha Stupa Road",
"addressLine2": "House 12, Floor 2",
"city": "Kathmandu",
"state": "Bagmati",
"postalCode": "44600",
"landmark": "Near the main gate",
"mobileNum": "+977-9800000000",
"instructions": "Leave at reception if not available.",
"latitude": 27.7172,
"longitude": 85.324
}Required fields:
districtNameaddressLine1citypostalCode
Optional fields:
addressLine2statelandmarkmobileNuminstructionslatitudelongitude
4.5 Guest quote (public, read-only)
{
"districtName": "Kathmandu",
"items": [
{
"productId": 101,
"quantity": 2,
"carePackage": {
"carePackageId": 2,
"pricingTierId": 3
}
},
{ "productId": 202, "quantity": 1 }
]
}Rules:
- backend recalculates product and care package prices from records; client price inputs are ignored.
- optional
carePackageis allowed only for physical products when the selected care package is active, the pricing tier is active, and the package eligibility rules match the product. - care package price is counted once per selected product line, not multiplied by product quantity.
- max
50unique products per quote request. - per-item quantity must be within
1..99. - no cart write, no order creation, no stock reservation.
5. Cart Response Contract
{
"id": 1,
"status": "active",
"items": [
{
"id": 10,
"productId": 101,
"productTitle": "Dell XPS 15 Laptop",
"productSlug": "dell-xps-15-laptop",
"productThumbnail": "https://cdn.example.com/thumb.jpg",
"productType": "laptop",
"unitMrp": 15000,
"unitSp": 12000,
"quantity": 2,
"discount": 3000
}
],
"carePackageItems": [
{
"id": 1,
"cartItemId": 10,
"carePackageId": 2,
"carePackageName": "Extended Warranty",
"pricingTierId": 3,
"durationMonths": 12,
"unitPrice": 149900
}
],
"totalMrp": 179900,
"totalSp": 173900,
"totalDiscount": 6000,
"shippingDistrict": "Kathmandu",
"shippingMobileNum": "+977-9800000000",
"shippingInstructions": "Leave at reception if not available.",
"shippingFee": 50000,
"shippingAddressLine1": "Boudha Stupa Road",
"shippingAddressLine2": "House 12, Floor 2",
"shippingCity": "Kathmandu",
"shippingState": "Bagmati",
"shippingPostalCode": "44600",
"shippingLandmark": "Near the main gate",
"shippingLatitude": 27.7172,
"shippingLongitude": 85.324,
"appliedCoupon": {
"promotionId": 1,
"code": "SUMMER2024",
"discount": 1000
},
"promoNotice": {
"status": "promo_removed",
"reason": "min_cart_value_not_met",
"message": "This promo is no longer valid for your current cart."
},
"finalPayable": 222900
}Promo revalidation on cart mutations
After a coupon is successfully applied to the cart, the backend owns promo maintenance for all cart-changing operations:
POST /cart/itemsPOST /cart/syncDELETE /cart/items/:itemIdPOST /cart/items/:itemId/increasePOST /cart/items/:itemId/decreasePUT /cart/items/:itemId/quantity
Flow:
- backend applies the cart mutation first
- backend revalidates the already-applied coupon against the updated cart
- if still valid, backend recalculates and returns the updated cart totals
- if no longer valid, backend removes the coupon from active pricing and returns the updated cart with
promoNotice
promoNotice contract:
{
"status": "promo_removed",
"reason": "min_cart_value_not_met",
"message": "This promo is no longer valid for your current cart."
}Supported promoNotice.reason values:
promotion_inactivepromotion_expiredpromotion_not_startedusage_limit_reachedper_user_limit_reachedmin_cart_value_not_metscope_mismatchcart_type_mismatch
Frontend integration rule:
- call only the normal cart mutation endpoint
- render the returned
CartResponseDto - if
promoNoticeexists, show itsmessageto the user
Monetary contract (important)
- All money fields in cart APIs are integer minor units (USD cents in current Stripe flow).
unitSpfallback is backend-authoritative: whenunitSp <= 0, effective sell price becomesunitMrp.- Response item
discountis per-unit:discount = unitMrp - effectiveUnitSp
totalDiscountis quantity-aware across product lines.- Clients must not divide/multiply these values for API/payment calls; convert only for display formatting.
Final payable formula
For physical products:
finalPayable = totalSp - appliedDiscount + shippingFee
Where:
appliedDiscount = appliedCoupon.discountif coupon exists, else0shippingFee = shippingFeeif location is set, else0
Checkout safety guard
Cart mutation responses keep pricing and coupon state current, but checkout still performs final promotion validation as a safety guard.
Payment-method mismatch is still enforced at checkout/order creation, not in cart mutation promoNotice.
6. Location Response Contract
{
"districtName": "Kathmandu",
"shippingFee": 50000,
"addressLine1": "Boudha Stupa Road",
"addressLine2": "House 12, Floor 2",
"city": "Kathmandu",
"state": "Bagmati",
"postalCode": "44600",
"landmark": "Near the main gate",
"mobileNum": "+977-9800000000",
"instructions": "Leave at reception if not available.",
"latitude": 27.7172,
"longitude": 85.324,
"isAutoDetected": false
}GET /location returns {} when no location is set.
6.1 Guest Quote Response Contract
{
"items": [
{
"productId": 101,
"productTitle": "Dell XPS 15 Laptop",
"productSlug": "dell-xps-15-laptop",
"productThumbnail": "https://cdn.example.com/thumb.jpg",
"productType": "laptop",
"unitMrp": 15000,
"unitSp": 12000,
"quantity": 2,
"discount": 3000,
"carePackage": {
"carePackageId": 2,
"carePackageName": "IT Mart Care Plus",
"pricingTierId": 3,
"durationMonths": 12,
"unitPrice": 149900
}
}
],
"totalMrp": 179900,
"totalSp": 173900,
"totalDiscount": 6000,
"shippingDistrict": "Kathmandu",
"shippingFee": 180000,
"finalPayable": 353900
}Guest quote final payable formula:
finalPayable = product totalSp + selected care package unitPrice values + shippingFee
7. Available Shipping Districts Response Contract
GET /location/districts returns active shipping destinations:
[
{
"districtName": "Kathmandu",
"shippingFee": 50000,
"currency": "NPR"
},
{
"districtName": "Pokhara",
"shippingFee": 75000,
"currency": "NPR"
}
]8. Clear Response Contract
{
"cleared": true
}9. Error Codes (Common)
| HTTP | errorCode | Meaning |
|---|---|---|
| 400 | CART_PRODUCT_NOT_ELIGIBLE | Product type cannot be added to cart |
| 400 | CART_INVALID_ITEM | Invalid quantity operation/payload |
| 400 | CART_LOCATION_SHIPPING_NOT_AVAILABLE | Shipping not configured for selected destination (legacy) |
| 400 | CART_LOCATION_DISTRICT_NOT_AVAILABLE | Shipping fee not configured for the selected district |
| 400 | CART_PRODUCT_NOT_SELLABLE | Product is not currently purchasable |
| 404 | CART_PRODUCT_NOT_FOUND | Product does not exist |
| 404 | CART_ITEM_NOT_FOUND | Cart item does not exist |
| 404 | CART_NOT_FOUND | Cart not found |
| 410 | CART_LOCATION_AUTO_DISABLED | Auto-locate endpoint is disabled |
| 429 | RATE_LIMIT_EXCEEDED | Cart operation rate limit exceeded |
10. Notes for Frontend
- Use
/api/mobile/cart/*routes in mobile/web app integration. - Item
discountis per-unit:unitMrp - unitSp; usetotalDiscountfor quantity-aware discount totals. - Always read
quantityfrom each item; do not infer from totals. - For guest users, call
POST /api/mobile/cart/guest/quotewith optionalitems[].carePackageto render backend-trusted totals before login. - After login, send the same guest cart shape to
POST /api/mobile/cart/syncso selected care packages are persisted. - Fetch available districts via
GET /location/districtsbefore showing district selector. - Use manual location flow (
POST /location) as canonical. - Do not depend on
/location/autounless backend explicitly re-enables it.
Auth Module Feature Guide
Functional behavior of admin auth, customer mobile auth, Google login/signup/linking, and verification edge cases.
Cart Module Backend Documentation
Backend architecture and data contracts for cart, quantity operations, manual address shipping projection, caching, and admin support reads.