npm.io
0.0.42 • Published 15h ago

@86d-app/vendors

Licence
MIT
Version
0.0.42
Deps
1
Size
143 kB
Vulns
0
Weekly
0
Stars
5

86d

The Modern Foundation for Commerce

X · LinkedIn


This project is under active development and is not ready for production use. Please proceed with caution. Use at your own risk.

Documentation: 86d.app/docs/modules/vendors

Vendors Module

Multi-vendor marketplace module for managing vendor profiles, product assignments, commission rates, and payout tracking. Enables store owners to operate a marketplace where multiple vendors sell through a single storefront.

Installation

npm install @86d-app/vendors

Usage

import vendors from "@86d-app/vendors";

const module = vendors({
  defaultCommissionRate: "15",
  requireApproval: "true",
});

Configuration

Option Type Default Description
defaultCommissionRate string "10" Default commission percentage for new vendors
requireApproval string "true" Whether new vendor applications require admin approval

Store Endpoints

Method Path Description
GET /vendors List active vendors (paginated)
GET /vendors/:slug Get a vendor profile by slug
GET /vendors/:vendorId/products List active products for a vendor
POST /vendors/apply Submit a vendor application

Admin Endpoints

Method Path Description
GET /admin/vendors List all vendors with optional status filter
POST /admin/vendors/create Create a new vendor
GET /admin/vendors/stats Get marketplace statistics
GET /admin/vendors/:id Get vendor details
PATCH /admin/vendors/:id/update Update vendor profile
DELETE /admin/vendors/:id/delete Delete vendor (cascades to products and payouts)
PATCH /admin/vendors/:id/status Update vendor status
GET /admin/vendors/:vendorId/products List vendor's product assignments
POST /admin/vendors/:vendorId/products/assign Assign a product to a vendor
DELETE /admin/vendors/:vendorId/products/:productId/unassign Unassign a product
GET /admin/vendors/:vendorId/payouts List vendor payouts
POST /admin/vendors/:vendorId/payouts/create Create a payout for a vendor
PATCH /admin/vendors/payouts/:id/status Update payout status
GET /admin/vendors/payouts/stats Get payout statistics

Admin UI

The module includes admin UI components in src/admin/components/index.tsx (client components using useModuleClient):

Page Component Description
/admin/vendors VendorAdmin Vendor list with status filters, create/edit forms, and status management
/admin/vendors/payouts VendorPayouts Payout list with status tracking and payout creation

Controller API

The VendorController interface is exported for inter-module contracts.

interface VendorController {
  // Vendors
  createVendor(params: { name, slug, email, ... }): Promise<Vendor>;
  getVendor(id: string): Promise<Vendor | null>;
  getVendorBySlug(slug: string): Promise<Vendor | null>;
  updateVendor(id: string, params: { ... }): Promise<Vendor | null>;
  deleteVendor(id: string): Promise<boolean>;
  listVendors(params?: { status?, take?, skip? }): Promise<Vendor[]>;
  countVendors(params?: { status? }): Promise<number>;
  updateVendorStatus(id: string, status: VendorStatus): Promise<Vendor | null>;

  // Product assignments
  assignProduct(params: { vendorId, productId, commissionOverride? }): Promise<VendorProduct>;
  unassignProduct(params: { vendorId, productId }): Promise<boolean>;
  listVendorProducts(params: { vendorId, status?, take?, skip? }): Promise<VendorProduct[]>;
  countVendorProducts(params: { vendorId, status? }): Promise<number>;
  getProductVendor(productId: string): Promise<Vendor | null>;

  // Payouts
  createPayout(params: { vendorId, amount, currency, ... }): Promise<VendorPayout>;
  getPayout(id: string): Promise<VendorPayout | null>;
  updatePayoutStatus(id: string, status: PayoutStatus): Promise<VendorPayout | null>;
  listPayouts(params?: { vendorId?, status?, take?, skip? }): Promise<VendorPayout[]>;
  countPayouts(params?: { vendorId?, status? }): Promise<number>;
  getPayoutStats(vendorId?: string): Promise<PayoutStats>;

  // Admin
  getStats(): Promise<VendorStats>;
}

Types

type VendorStatus = "pending" | "active" | "suspended" | "closed";
type VendorProductStatus = "active" | "paused";
type PayoutStatus = "pending" | "processing" | "completed" | "failed";

interface Vendor {
  id: string;
  name: string;
  slug: string;
  email: string;
  phone?: string;
  description?: string;
  logo?: string;
  banner?: string;
  website?: string;
  commissionRate: number;
  status: VendorStatus;
  addressLine1?: string;
  addressLine2?: string;
  city?: string;
  state?: string;
  postalCode?: string;
  country?: string;
  metadata?: Record<string, unknown>;
  joinedAt: Date;
  createdAt: Date;
  updatedAt: Date;
}

interface VendorProduct {
  id: string;
  vendorId: string;
  productId: string;
  commissionOverride?: number;
  status: VendorProductStatus;
  createdAt: Date;
}

interface VendorPayout {
  id: string;
  vendorId: string;
  amount: number;
  currency: string;
  status: PayoutStatus;
  method?: string;
  reference?: string;
  periodStart: Date;
  periodEnd: Date;
  notes?: string;
  createdAt: Date;
  completedAt?: Date;
}

Notes

  • Vendors start as pending and must be approved by an admin (status → active) before they appear in store endpoints.
  • Product assignment is idempotent — assigning the same product twice returns the existing record.
  • Deleting a vendor cascades to all product assignments and payouts.
  • Commission can be overridden per-product via commissionOverride on the product assignment.
  • The completedAt timestamp is automatically set when a payout status transitions to completed.

Keywords