B2B / Wholesale
El módulo B2B permite gestionar clientes mayoristas con precios diferenciados, listas de precios personalizadas y flujo de cotizaciones.
Base URL: /api/v1/b2b/
Clientes B2B
Los clientes B2B son empresas (no personas naturales) con crédito, RUC y precios negociados.
Listar clientes
GET /api/v1/b2b/customers?cursor=xxx&limit=25
Authorization: Bearer <token>
X-Tenant-ID: <tenant-id>
Respuesta (200):
{
"data": [
{
"id": "uuid",
"company_name": "Distribuidora Lima SAC",
"ruc": "20512345678",
"email": "compras@distribuidora.com",
"credit_limit": 5000000,
"price_list_id": "uuid-lista",
"status": "active",
"created_at": "2026-01-15T10:00:00Z"
}
],
"meta": {
"pagination": { "cursor": "next-cursor", "has_next": true }
}
}
Crear cliente B2B
POST /api/v1/b2b/customers
Authorization: Bearer <token>
X-Tenant-ID: <tenant-id>
Content-Type: application/json
{
"company_name": "Distribuidora Lima SAC",
"ruc": "20512345678",
"email": "compras@distribuidora.com",
"phone": "+51012345678",
"credit_limit": 5000000,
"price_list_id": "uuid-lista-precios"
}
Respuesta (201): Objeto customer completo.
Obtener cliente
GET /api/v1/b2b/customers/:id
Actualizar cliente
PATCH /api/v1/b2b/customers/:id
Content-Type: application/json
{
"credit_limit": 10000000,
"price_list_id": "uuid-nueva-lista"
}
Listas de precios
Las listas de precios definen descuentos especiales para clientes B2B. Cada lista tiene un conjunto de reglas que se aplican en orden.
Crear lista de precios
POST /api/v1/b2b/price-lists
Authorization: Bearer <token>
X-Tenant-ID: <tenant-id>
Content-Type: application/json
{
"name": "Distribuidores Tier 1",
"currency": "PEN",
"description": "Precios para distribuidores con volumen > S/ 50,000/mes"
}
Respuesta (201):
{
"data": {
"id": "uuid",
"name": "Distribuidores Tier 1",
"currency": "PEN",
"rules": [],
"created_at": "2026-01-15T10:00:00Z"
}
}
Listar listas de precios
GET /api/v1/b2b/price-lists
Actualizar lista de precios
PATCH /api/v1/b2b/price-lists/:id
Content-Type: application/json
{
"name": "Distribuidores Tier 1 — Actualizado"
}
Agregar regla de precio
Las reglas definen el descuento. Pueden ser por porcentaje o monto fijo, y se pueden filtrar por categoría o producto.
POST /api/v1/b2b/price-lists/:id/rules
Content-Type: application/json
{
"type": "percentage",
"value": 15,
"applies_to": "all"
}
POST /api/v1/b2b/price-lists/:id/rules
Content-Type: application/json
{
"type": "fixed",
"value": 500,
"applies_to": "category",
"category_id": "uuid-categoria"
}
| Campo | Tipo | Descripción |
|---|---|---|
type | "percentage" | "fixed" | Porcentaje de descuento o monto fijo en centavos |
value | integer | Para percentage: 1–100. Para fixed: centavos de descuento |
applies_to | "all" | "category" | "product" | Alcance de la regla |
category_id | UUID | Requerido si applies_to: "category" |
product_id | UUID | Requerido si applies_to: "product" |
Eliminar regla
DELETE /api/v1/b2b/price-lists/:list_id/rules/:rule_id
Respuesta: 204 No Content
Cotizaciones
El flujo de cotizaciones permite a los clientes B2B solicitar precios antes de confirmar una compra.
Estados de una cotización
draft → sent → accepted
↘ rejected
Crear cotización
POST /api/v1/b2b/quotes
Authorization: Bearer <token>
X-Tenant-ID: <tenant-id>
Content-Type: application/json
{
"b2b_customer_id": "uuid-cliente",
"items": [
{ "variant_id": "uuid-variante", "quantity": 100 },
{ "variant_id": "uuid-variante-2", "quantity": 50 }
],
"notes": "Solicito descuento adicional por volumen"
}
Respuesta (201):
{
"data": {
"id": "uuid",
"number": "QT-0042",
"status": "draft",
"b2b_customer_id": "uuid-cliente",
"items": [
{
"variant_id": "uuid-variante",
"title": "Producto X — Talla L",
"quantity": 100,
"unit_price": 2500,
"total": 250000
}
],
"subtotal": 287500,
"discount": 28750,
"total": 258750,
"created_at": "2026-01-15T10:00:00Z"
}
}
Listar cotizaciones
GET /api/v1/b2b/quotes?cursor=xxx&limit=25
Obtener cotización
GET /api/v1/b2b/quotes/:id
Enviar cotización al cliente
Cambia el estado de draft a sent y envía un email al cliente B2B con el PDF de la cotización.
POST /api/v1/b2b/quotes/:id/send
Respuesta (200):
{
"data": {
"id": "uuid",
"number": "QT-0042",
"status": "sent",
"sent_at": "2026-01-15T10:05:00Z"
}
}