Initial commit: nick docs
This commit is contained in:
499
03 - API Reference/Marketplace API.md
Normal file
499
03 - API Reference/Marketplace API.md
Normal file
@@ -0,0 +1,499 @@
|
||||
---
|
||||
title: Marketplace API
|
||||
tags: [api, marketplace, reference]
|
||||
---
|
||||
|
||||
# Marketplace API
|
||||
|
||||
All marketplace endpoints live under `/api/marketplace/*`. The router is composed of several files mounted from `app.ts`:
|
||||
|
||||
- New controller-pattern routes: [`backend/src/services/marketplace/controllerRoutes.ts`](../../backend/src/services/marketplace/controllerRoutes.ts) (`marketplaceControllerRouter`)
|
||||
- Legacy + delivery-code routes: [`backend/src/services/marketplace/routes.ts`](../../backend/src/services/marketplace/routes.ts) (`marketplaceRouter`)
|
||||
- Request templates: [`requestTemplateRoutes.ts`](../../backend/src/services/marketplace/requestTemplateRoutes.ts) (`/api/marketplace/request-templates/*`)
|
||||
- Shop settings: [`shopSettingsRoutes.ts`](../../backend/src/services/marketplace/shopSettingsRoutes.ts) (`/api/marketplace/shop/*`)
|
||||
- Reviews: [`reviewRoutes.ts`](../../backend/src/services/marketplace/reviewRoutes.ts) (`/api/marketplace/reviews/*`)
|
||||
|
||||
Core models: [[PurchaseRequest]], [[SellerOffer]], [[Category]], [[RequestTemplate]], [[ShopSettings]], [[Review]]. Real-time updates are emitted on the `request-<id>`, `seller-<id>`, `buyer-<id>`, and `sellers`/`buyers` rooms — see [[Socket Events]].
|
||||
|
||||
## Categories
|
||||
|
||||
### GET /api/marketplace/categories
|
||||
|
||||
**Description:** Flat list of all categories.
|
||||
**Auth required:** No
|
||||
**Response 200:** `{ success: true, data: [Category, ...] }`
|
||||
|
||||
### GET /api/marketplace/categories/tree
|
||||
|
||||
**Description:** Nested tree based on `parentId`.
|
||||
**Auth required:** No
|
||||
|
||||
### GET /api/marketplace/categories/:id
|
||||
|
||||
**Description:** Single category by id.
|
||||
**Auth required:** No
|
||||
**Errors:** `404` not found.
|
||||
|
||||
## Sellers
|
||||
|
||||
### GET /api/marketplace/sellers
|
||||
|
||||
**Description:** Public seller directory (users with `role: 'seller'`). Includes aggregated stats (completed orders, ratings).
|
||||
**Auth required:** No
|
||||
|
||||
### GET /api/marketplace/request-templates/sellers
|
||||
|
||||
**Description:** Sellers who currently expose at least one active [[RequestTemplate]] (used by the shop discovery page).
|
||||
**Auth required:** No
|
||||
|
||||
### GET /api/marketplace/request-templates/sellers/:sellerId
|
||||
|
||||
**Description:** Public shop profile for a seller, including their templates and shop settings.
|
||||
**Auth required:** No
|
||||
|
||||
## Purchase Requests
|
||||
|
||||
The buyer-facing CRUD plus seller-side workflow endpoints. Model: [[PurchaseRequest]].
|
||||
|
||||
### POST /api/marketplace/purchase-requests
|
||||
|
||||
**Description:** Create a purchase request (new controller path).
|
||||
**Auth required:** Bearer JWT (buyer)
|
||||
**Request body:**
|
||||
```ts
|
||||
{
|
||||
title: string;
|
||||
description: string;
|
||||
categoryId: string;
|
||||
productLink?: string;
|
||||
size?: string;
|
||||
color?: string;
|
||||
quantity?: number; // default 1
|
||||
budget?: { min?: number; max?: number; currency: "USD" | "EUR" | "IRR" };
|
||||
urgency?: "low" | "medium" | "high";
|
||||
deliveryInfo?: {
|
||||
deliveryType: "physical" | "online";
|
||||
addressId?: string; // when physical
|
||||
email?: string; // when online
|
||||
};
|
||||
preferredSellerIds?: string[];
|
||||
attachments?: string[]; // URLs from [[File API]]
|
||||
}
|
||||
```
|
||||
**Response 201:** `{ success, data: { purchaseRequest } }`
|
||||
**Side effects:** Emits `new-purchase-request` to the `sellers` room (broadcast).
|
||||
**Source:** `marketplaceController.createPurchaseRequest`
|
||||
|
||||
### POST /api/marketplace/purchase-requests/bulk
|
||||
|
||||
**Description:** Bulk creation (used by the template checkout flow).
|
||||
**Auth required:** Bearer JWT
|
||||
**Request body:** `{ items: Array<PurchaseRequestInput> }`
|
||||
|
||||
### GET /api/marketplace/purchase-requests
|
||||
|
||||
**Description:** List requests with filters. Buyers see their own; sellers see ones routed to them; admins see all.
|
||||
**Auth required:** Bearer JWT
|
||||
**Query params:** `status`, `categoryId`, `urgency`, `search`, `page`, `limit`, `sortBy`, `sortOrder`
|
||||
|
||||
### GET /api/marketplace/purchase-requests/my
|
||||
|
||||
**Description:** Shortcut for the caller's own purchase requests.
|
||||
**Auth required:** Bearer JWT
|
||||
|
||||
### GET /api/marketplace/purchase-requests/:id
|
||||
|
||||
**Description:** Single request with populated category and selected offer.
|
||||
**Auth required:** No (public read for shareable links)
|
||||
**Errors:** `404` not found.
|
||||
|
||||
### PATCH /api/marketplace/purchase-requests/:id
|
||||
|
||||
**Description:** Buyer edits draft / pending request fields.
|
||||
**Auth required:** Bearer JWT (owner)
|
||||
|
||||
### PATCH /api/marketplace/purchase-requests/:id/status
|
||||
|
||||
**Description:** Transition the request status (`draft` → `pending` → `payment` → `processing` → `delivery` → `delivered` → `seller_paid` → `completed`, or `cancelled`).
|
||||
**Auth required:** Bearer JWT (owner or admin)
|
||||
**Request body:** `{ status: string }`
|
||||
**Side effects:** Emits `purchase-request-update` to `request-<id>`.
|
||||
|
||||
### DELETE /api/marketplace/purchase-requests/:id
|
||||
|
||||
**Description:** Cancel/delete a request that has no committed payment.
|
||||
**Auth required:** Bearer JWT (owner)
|
||||
|
||||
### GET /api/marketplace/purchase-requests/:id/workflow-steps
|
||||
|
||||
**Description:** Returns the ordered workflow steps + current pointer used by the frontend stepper.
|
||||
**Auth required:** No
|
||||
|
||||
### GET /api/marketplace/purchase-requests/:id/payment-status
|
||||
|
||||
**Description:** Returns the latest payment + escrow state for the request.
|
||||
**Auth required:** Bearer JWT
|
||||
|
||||
### POST /api/marketplace/purchase-requests/:id/sync-payment-status
|
||||
|
||||
**Description:** Force a re-check against the payment provider ([[Payment API]]).
|
||||
**Auth required:** Bearer JWT
|
||||
|
||||
### POST /api/marketplace/purchase-requests/:id/confirm-payment
|
||||
|
||||
**Description:** Legacy buyer-confirmation endpoint kept for old clients.
|
||||
**Auth required:** Bearer JWT
|
||||
|
||||
### POST /api/marketplace/purchase-requests/:id/release-payment
|
||||
|
||||
**Description:** Triggers admin escrow release (mirror of `POST /api/payment/shkeeper/:id/release`).
|
||||
**Auth required:** Bearer JWT (admin)
|
||||
|
||||
### PUT /api/marketplace/purchase-requests/:id/delivery (controller route)
|
||||
|
||||
**Description:** Seller submits shipping details (carrier, tracking number, expected date).
|
||||
**Auth required:** Bearer JWT (selected seller)
|
||||
|
||||
### POST /api/marketplace/purchase-requests/:id/update-delivery (legacy)
|
||||
|
||||
**Description:** Older equivalent retained for compatibility.
|
||||
|
||||
### POST /api/marketplace/requests/:id/start-delivery
|
||||
|
||||
**Description:** Marks the request as `delivery` and notifies the buyer.
|
||||
**Auth required:** Bearer JWT (seller)
|
||||
**Side effects:** Emits `purchase-request-update` event.
|
||||
|
||||
### PATCH /api/marketplace/purchase-requests/:id/confirm-delivery
|
||||
|
||||
**Description:** Buyer confirms goods received (transitions to `delivered`).
|
||||
**Auth required:** Bearer JWT (buyer)
|
||||
|
||||
### POST /api/marketplace/purchase-requests/:id/final-approval
|
||||
|
||||
**Description:** Buyer's final approval that releases escrow to the seller.
|
||||
**Auth required:** Bearer JWT (buyer)
|
||||
|
||||
### GET /api/marketplace/buyers/:buyerId/purchase-requests
|
||||
|
||||
**Description:** Admin/seller view of a buyer's request history.
|
||||
**Auth required:** Bearer JWT
|
||||
|
||||
## Delivery codes
|
||||
|
||||
Six-digit codes the buyer hands to the seller at handover. Backed by `deliveryService`.
|
||||
|
||||
### POST /api/marketplace/purchase-requests/:id/delivery-code/generate
|
||||
|
||||
**Description:** Buyer generates a delivery code. Request must be in `delivery` status.
|
||||
**Auth required:** Bearer JWT (buyer)
|
||||
**Response 200:** `{ success: true, data: { deliveryCode: "123456" } }`
|
||||
**Errors:** `400` wrong status, `403` not buyer, `404` request not found.
|
||||
**Side effects:** Emits `delivery-code-generated` on `request-<id>`.
|
||||
|
||||
### POST /api/marketplace/purchase-requests/:id/delivery-code/verify
|
||||
|
||||
**Description:** Seller verifies the code. On success the status moves to `delivered`.
|
||||
**Auth required:** Bearer JWT (selected seller)
|
||||
**Request body:** `{ code: string }` (exactly 6 chars)
|
||||
**Errors:** `400` bad code, `403` not the selected seller.
|
||||
**Side effects:** Emits `delivery-confirmed` and `buyer-confirmed-delivery`.
|
||||
|
||||
### GET /api/marketplace/purchase-requests/:id/delivery-code
|
||||
|
||||
**Description:** Buyer or seller fetches the current code metadata.
|
||||
**Auth required:** Bearer JWT
|
||||
|
||||
### GET /api/marketplace/purchase-requests/:id/delivery-code/status
|
||||
|
||||
**Description:** Returns `{ isValid, hasDeliveryCode, ... }` so the UI can decide whether to show "regenerate".
|
||||
**Auth required:** Bearer JWT
|
||||
|
||||
## Seller Offers
|
||||
|
||||
Model: [[SellerOffer]].
|
||||
|
||||
### POST /api/marketplace/purchase-requests/:id/offers
|
||||
|
||||
**Description:** Submit an offer against a purchase request.
|
||||
**Auth required:** Bearer JWT (seller)
|
||||
**Request body:**
|
||||
```ts
|
||||
{
|
||||
price: { amount: number; currency: "USD" | "EUR" | "IRR" };
|
||||
deliveryEstimate: { days: number; note?: string };
|
||||
notes?: string;
|
||||
attachments?: string[];
|
||||
}
|
||||
```
|
||||
**Response 201:** `{ success, data: { offer } }`
|
||||
**Side effects:** Emits `new-offer` to `buyer-<buyerId>` and `seller-offer-update` to `seller-<sellerId>`.
|
||||
|
||||
### PUT /api/marketplace/purchase-requests/:id/offers (legacy)
|
||||
|
||||
**Description:** Older offer-update endpoint kept for compatibility.
|
||||
|
||||
### GET /api/marketplace/purchase-requests/:id/offers
|
||||
|
||||
**Description:** List all offers for a request.
|
||||
**Auth required:** No (buyers and prospective sellers compare offers)
|
||||
|
||||
### GET /api/marketplace/purchase-requests/:id/has-offer
|
||||
|
||||
**Description:** Returns `{ hasOffer: boolean }` for the caller (seller-side helper).
|
||||
**Auth required:** Bearer JWT (seller)
|
||||
|
||||
### GET /api/marketplace/purchase-requests/:id/offers/:sellerId
|
||||
|
||||
**Description:** Fetch a specific seller's offer on a request.
|
||||
**Auth required:** No
|
||||
|
||||
### PATCH /api/marketplace/offers/:id
|
||||
|
||||
**Description:** Seller edits their pending offer (price, delivery estimate, notes).
|
||||
**Auth required:** Bearer JWT (offer owner)
|
||||
|
||||
### DELETE /api/marketplace/offers/:id
|
||||
|
||||
**Description:** Seller withdraws their offer.
|
||||
**Auth required:** Bearer JWT (offer owner)
|
||||
|
||||
### PUT /api/marketplace/offers/:id/status
|
||||
|
||||
**Description:** Direct status mutation (admin override / counter-offer states).
|
||||
**Auth required:** Bearer JWT
|
||||
**Request body:** `{ status: "pending" | "accepted" | "rejected" | "withdrawn" | "countered" }`
|
||||
|
||||
### POST /api/marketplace/purchase-requests/:id/select-offer
|
||||
|
||||
**Description:** Buyer selects/accepts an offer; this triggers payment intent creation in [[Payment API]] and rejects all other offers automatically once payment lands.
|
||||
**Auth required:** Bearer JWT (buyer)
|
||||
**Request body:** `{ offerId: string }`
|
||||
**Side effects:**
|
||||
- Updates [[PurchaseRequest]] `selectedOfferId`, status moves toward `payment`.
|
||||
- Emits `seller-offer-update` to all sellers for the request.
|
||||
|
||||
### POST /api/marketplace/offers/:id/accept (legacy)
|
||||
|
||||
**Description:** Older synonym retained for backward compatibility with old clients.
|
||||
|
||||
### DELETE /api/marketplace/offers/:id (controller route)
|
||||
|
||||
**Description:** Controller-pattern delete that also notifies the buyer.
|
||||
|
||||
## Request Templates
|
||||
|
||||
A [[RequestTemplate]] is a re-usable "shop product" a seller can publish. Buyers convert templates into actual purchase requests via the shareable link, individually or in bulk (cart checkout).
|
||||
|
||||
### POST /api/marketplace/request-templates
|
||||
|
||||
**Description:** Create a new template.
|
||||
**Auth required:** Bearer JWT (seller)
|
||||
**Request body:**
|
||||
```ts
|
||||
{
|
||||
title: string; // 1-200 chars
|
||||
description: string; // 1-2000
|
||||
categoryId: string; // MongoId
|
||||
productLink?: string; // valid URL
|
||||
size?: string; // <=100
|
||||
color?: string; // <=100
|
||||
quantity?: number; // 1-10000
|
||||
budget?: { min?: number; max?: number; currency: "USD" | "EUR" | "IRR" };
|
||||
urgency?: "low" | "medium" | "high";
|
||||
deliveryInfo?: { deliveryType: "physical" | "online"; email?: string };
|
||||
maxUsage?: number | null; // 0/null = unlimited
|
||||
expiresAt?: string | null; // ISO date
|
||||
images?: string[]; // URLs from [[File API]]
|
||||
}
|
||||
```
|
||||
**Response 201:** `{ data: { template } }` with a generated `shareableLink`.
|
||||
|
||||
### GET /api/marketplace/request-templates
|
||||
|
||||
**Description:** Paginated list of the caller's templates.
|
||||
**Auth required:** Bearer JWT (seller)
|
||||
**Query params:** `page`, `limit` (1-100), `isActive`, `categoryId`, `search`
|
||||
|
||||
### GET /api/marketplace/request-templates/stats
|
||||
|
||||
**Description:** Aggregate counts of the caller's templates (active, expired, usage).
|
||||
**Auth required:** Bearer JWT (seller)
|
||||
|
||||
### GET /api/marketplace/request-templates/:id
|
||||
|
||||
**Description:** Full template by id (owner view).
|
||||
**Auth required:** Bearer JWT (owner)
|
||||
|
||||
### PUT /api/marketplace/request-templates/:id
|
||||
|
||||
**Description:** Update the template. Same body as create.
|
||||
**Auth required:** Bearer JWT (owner)
|
||||
|
||||
### DELETE /api/marketplace/request-templates/:id
|
||||
|
||||
**Description:** Delete a template.
|
||||
**Auth required:** Bearer JWT (owner)
|
||||
|
||||
### PATCH /api/marketplace/request-templates/:id/toggle-status
|
||||
|
||||
**Description:** Toggle `isActive`.
|
||||
**Auth required:** Bearer JWT (owner)
|
||||
|
||||
### GET /api/marketplace/request-templates/public/:shareableLink
|
||||
|
||||
**Description:** Public read of a template via its shareable slug. Used by the shop preview page.
|
||||
**Auth required:** No
|
||||
**Errors:** `404` link not found or template inactive/expired.
|
||||
|
||||
### POST /api/marketplace/request-templates/:shareableLink/convert
|
||||
|
||||
**Description:** Buyer converts the template into a real [[PurchaseRequest]].
|
||||
**Auth required:** Bearer JWT (buyer)
|
||||
**Request body:** Overrides (quantity, address, etc.)
|
||||
**Response 201:** `{ data: { purchaseRequest } }`
|
||||
|
||||
### POST /api/marketplace/request-templates/batch-convert
|
||||
|
||||
**Description:** Convert several templates at once (cart checkout).
|
||||
**Auth required:** Bearer JWT (buyer)
|
||||
**Request body:**
|
||||
```ts
|
||||
{
|
||||
items: Array<{
|
||||
shareableLink: string;
|
||||
quantity: number; // 1-100
|
||||
sellerId: string; // MongoId
|
||||
}>;
|
||||
status?: "pending" | "pending_payment" | "active";
|
||||
}
|
||||
```
|
||||
|
||||
### POST /api/marketplace/request-templates/complete-payment
|
||||
|
||||
**Description:** Marks the requests created by `batch-convert` as paid (called after a successful checkout).
|
||||
**Auth required:** Bearer JWT
|
||||
**Request body:**
|
||||
```ts
|
||||
{
|
||||
requestIds: string[]; // 1+ MongoIds
|
||||
newStatus?: "pending" | "active" | "processing";
|
||||
paymentData?: Record<string, unknown>;
|
||||
}
|
||||
```
|
||||
|
||||
## Shop Settings
|
||||
|
||||
Per-seller storefront preferences. Model: [[ShopSettings]].
|
||||
|
||||
### GET /api/marketplace/shop/settings/:sellerId
|
||||
|
||||
**Description:** Public shop settings for the given seller (used by the shop landing page).
|
||||
**Auth required:** No
|
||||
**Response 200:** `{ data: ShopSettings }`
|
||||
|
||||
### GET /api/marketplace/shop/settings
|
||||
|
||||
**Description:** The authenticated seller's own settings.
|
||||
**Auth required:** Bearer JWT (seller)
|
||||
|
||||
### PUT /api/marketplace/shop/settings
|
||||
|
||||
**Description:** Update shop settings (banner, bio, policies, `allowSellerReviews`, `allowTemplateReviews`, ...).
|
||||
**Auth required:** Bearer JWT (seller)
|
||||
|
||||
## Reviews
|
||||
|
||||
Model: [[Review]]. Reviews can target a seller or a template. Subject must be `seller` or `template`.
|
||||
|
||||
### GET /api/marketplace/reviews/:subjectType/:subjectId
|
||||
|
||||
**Description:** Published reviews + aggregate stats. Honours `allowSellerReviews` / `allowTemplateReviews` from [[ShopSettings]].
|
||||
**Auth required:** No
|
||||
**Query params:** `page` (default 1), `limit` (default 10)
|
||||
**Response 200:**
|
||||
```json
|
||||
{
|
||||
"data": [Review, ...],
|
||||
"pagination": { "page": 1, "limit": 10, "total": 42, "pages": 5 },
|
||||
"stats": { "count": 42, "avg": 4.6, "one": 1, "two": 0, "three": 3, "four": 10, "five": 28 }
|
||||
}
|
||||
```
|
||||
**Errors:** `400` bad subjectType / invalid id, `403` reviews disabled by seller.
|
||||
|
||||
### GET /api/marketplace/reviews/:subjectType/:subjectId/summary
|
||||
|
||||
**Description:** Stats only (no review list).
|
||||
**Auth required:** No
|
||||
|
||||
### POST /api/marketplace/reviews
|
||||
|
||||
**Description:** Submit a review. The server computes `isVerifiedBuyer` when `purchaseRequestId` is given and the request is in a terminal state (`delivery`, `delivered`, `seller_paid`, `completed`).
|
||||
**Auth required:** Bearer JWT
|
||||
**Request body:**
|
||||
```ts
|
||||
{
|
||||
subjectType: "seller" | "template";
|
||||
subjectId: string;
|
||||
rating: 1 | 2 | 3 | 4 | 5;
|
||||
comment?: string;
|
||||
purchaseRequestId?: string;
|
||||
}
|
||||
```
|
||||
**Errors:** `400` validation, `403` reviews disabled, `404` template not found, `409` duplicate review.
|
||||
**Response 201:** `{ data: Review, stats: { ... } }`
|
||||
|
||||
## Payments (legacy under marketplace)
|
||||
|
||||
These routes are duplicates of the main [[Payment API]] kept under `/api/marketplace/payments/*` for backward compatibility with the early frontend. Prefer the canonical endpoints.
|
||||
|
||||
### POST /api/marketplace/payments
|
||||
### GET /api/marketplace/payments
|
||||
### GET /api/marketplace/payments/:paymentId
|
||||
### PATCH /api/marketplace/payments/:paymentId
|
||||
|
||||
See [[Payment API]] for the canonical descriptions.
|
||||
|
||||
## Verify Web3 payment (legacy)
|
||||
|
||||
### POST /api/marketplace/payments/verify
|
||||
|
||||
**Description:** Legacy Web3 verification endpoint that records a transaction and moves the purchase request to `processing`. Modern flows use `POST /api/payment/shkeeper/confirm-transaction` instead.
|
||||
**Auth required:** Bearer JWT
|
||||
**Request body:**
|
||||
```ts
|
||||
{
|
||||
purchaseRequestId: string;
|
||||
sellerOfferId: string;
|
||||
buyerId: string;
|
||||
sellerId: string;
|
||||
amount: number;
|
||||
currency: "USDT" | string;
|
||||
paymentHash: string;
|
||||
paymentMethod?: string;
|
||||
token?: string;
|
||||
network?: string;
|
||||
escrowWalletAddress?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
```
|
||||
**Side effects:** Creates a [[Payment]] record, updates [[PurchaseRequest]] status, emits `payment-received` to `user-<sellerId>`.
|
||||
|
||||
## Real-time events
|
||||
|
||||
Most marketplace mutations fan out via `global.io` to the rooms below — see [[Socket Events]] for payloads:
|
||||
|
||||
- `purchase-request-update` → `request-<id>`
|
||||
- `new-purchase-request` → `sellers`
|
||||
- `new-offer` → `buyer-<buyerId>`
|
||||
- `seller-offer-update` → `seller-<sellerId>` (and global on payment confirm)
|
||||
- `delivery-code-generated` / `delivery-confirmed` / `delivery-update` → `request-<id>`
|
||||
- `request-cancelled` → `user-<buyerId>`, `user-<sellerId>`
|
||||
- `transaction-completed` → `user-<buyerId>`, `user-<sellerId>`
|
||||
|
||||
## Related
|
||||
|
||||
- [[Purchase Request Flow]]
|
||||
- [[Seller Offer Flow]]
|
||||
- [[Template Checkout Flow]]
|
||||
- [[Delivery Code Flow]]
|
||||
Reference in New Issue
Block a user