Overview
Registers a payment for a winning ticket. Supports partial payments and idempotency for safe retries. Only tickets in EVALUATED status with isWinner=true can be paid.
Authentication
Requires JWT authentication. User role affects RBAC filtering:
- ADMIN: Can pay any ticket
- VENTANA: Can pay tickets from their window
- VENDEDOR: Can pay their own tickets
Request Body
UUID of the winning ticket to pay
Amount to pay (must be > 0 and ≤ total payout)
Payment method: cash, check, transfer, system
Mark as final payment (updates ticket status to PAID)
Optional notes (max 300 characters)
Unique key for idempotency (min 8, max 100 characters). If key already exists, returns cached payment with meta.cached: true
Optional ventana ID override (admin only)
Response
Whether this is marked as final payment
Whether this payment has been reversed
User ID who registered the payment
Present if payment was returned from idempotency cache (status 200 instead of 201)
Status Codes
201: Payment created successfully
200: Cached payment returned (idempotency key match)
400: Invalid amount or ticket not in EVALUATED status
403: RBAC violation (user cannot pay this ticket)
404: Ticket not found
409: Ticket is not a winner or already has pending payment
Example Request
{
"ticketId": "550e8400-e29b-41d4-a716-446655440000",
"amountPaid": 50000,
"method": "cash",
"isFinal": true,
"notes": "Pago completo en efectivo",
"idempotencyKey": "payment-2024-03-15-001"
}
Example Response
{
"success": true,
"data": {
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"ticketId": "550e8400-e29b-41d4-a716-446655440000",
"amountPaid": 50000,
"method": "cash",
"isFinal": true,
"isReversed": false,
"notes": "Pago completo en efectivo",
"paidById": "123e4567-e89b-12d3-a456-426614174000",
"createdAt": "2024-03-15T10:30:00.000Z"
}
}
Activity Logging
Logs action TICKET_PAY with details:
created: Whether payment was newly created
cached: Whether response was from idempotency cache