Skip to main content

Overview

Update the hierarchical commission policy JSON for a specific entity. Policies define commission percentages based on lottery, bet type, and multiplier ranges.

Endpoints

Set Banca Policy

PUT /api/v1/bancas/:id/commission-policy
Authorization: ADMIN only

Set Ventana Policy

PUT /api/v1/ventanas/:id/commission-policy
Authorization: ADMIN can manage any ventana, VENTANA can manage their own

Set User Policy

PUT /api/v1/users/:id/commission-policy
Authorization: ADMIN, or VENTANA managing their vendor

Path Parameters

id
string
required
UUID of the banca, ventana, or user

Request Body

commissionPolicyJson
object
required
Commission policy configuration (or null to remove policy)

Response

success
boolean
Indicates if the request was successful
data
object
Updated entity with commission policy

Examples

curl -X PUT "https://api.example.com/api/v1/bancas/550e8400-e29b-41d4-a716-446655440000/commission-policy" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "commissionPolicyJson": {
      "version": 1,
      "effectiveFrom": null,
      "effectiveTo": null,
      "defaultPercent": 5.0,
      "rules": [
        {
          "loteriaId": null,
          "betType": null,
          "multiplierRange": { "min": 0, "max": 0 },
          "percent": 5.0
        }
      ]
    }
  }'

Validation Rules

The policy schema version must be exactly 1. Future versions may support additional features.
If both effectiveFrom and effectiveTo are provided, effectiveFrom must be before or equal to effectiveTo.
All percentage values (defaultPercent and rule percent) must be between 0-100 with maximum 2 decimal places.
Currently, only specific multipliers are supported. The multiplierRange.min must equal multiplierRange.max.
Cannot have multiple rules with the same combination of:
  • loteriaId (or both null)
  • betType (or both null)
  • multiplierId or multiplierRange value
Duplicate rules will result in a validation error.
If a rule does not include an id field, a UUID will be automatically generated for tracking purposes.

Best Practices

Order rules from specific to generalRules are evaluated in array order with first-match-wins logic. Place more specific rules first:
  1. Specific loteria + specific bet type + specific multiplier
  2. Specific loteria + any bet type
  3. Any loteria + specific bet type
  4. Catch-all wildcard rule
Policies are snapshot at ticket creationCommission percentages are frozen when a ticket is created. Updating a policy does not affect existing tickets, only new ones created after the update.

Response Example

{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Banca Central",
    "code": "BC001",
    "commissionPolicyJson": {
      "version": 1,
      "effectiveFrom": null,
      "effectiveTo": null,
      "defaultPercent": 5.0,
      "rules": [
        {
          "id": "auto-generated-uuid",
          "loteriaId": null,
          "betType": null,
          "multiplierRange": { "min": 0, "max": 0 },
          "percent": 5.0
        }
      ]
    }
  }
}

Error Responses

{
  "success": false,
  "error": "Ventana no encontrada",
  "code": "VENTANA_NOT_FOUND"
}

Get Commission Policy

Retrieve current commission policy

Commission Analytics

View commission metrics and reports

Implementation Details

From src/api/v1/controllers/commission.controller.ts:102-131 and src/api/v1/validators/commission.validator.ts:86-126:
async updateBancaCommissionPolicy(req: AuthenticatedRequest, res: Response) {
  const { id } = req.params;
  const { commissionPolicyJson } = req.body;

  // Validate that banca exists
  const banca = await prisma.banca.findUnique({ where: { id } });
  if (!banca) {
    throw new AppError("Banca no encontrada", 404, { code: "BANCA_NOT_FOUND" });
  }

  // Update (Zod already validated and generated UUIDs)
  const updated = await prisma.banca.update({
    where: { id },
    data: { commissionPolicyJson },
    select: {
      id: true,
      name: true,
      code: true,
      commissionPolicyJson: true,
    },
  });

  return success(res, updated);
}
Validation is performed using Zod schemas that:
  1. Validate policy structure and constraints
  2. Check for duplicate rules
  3. Auto-generate UUIDs for rules without IDs
  4. Remove the read-only multiplier field if present

Build docs developers (and LLMs) love