Overview
The payment system handles disbursement of winnings to ticket holders. It supports full payments, partial payments, payment reversal, and finalization of partial payments.Payment Workflow
Payment States
| Ticket Status | Description | Can Pay? | Can Reverse? |
|---|---|---|---|
| EVALUATED (unpaid) | Winning ticket, no payment | ✅ Yes | ❌ No |
| EVALUATED (partial) | Some amount paid, balance remains | ✅ Yes | ✅ Last payment |
| PAID | Fully paid | ❌ No | ✅ Last payment |
| FINALIZED | Partial payment accepted as final | ❌ No | ✅ Last payment |
Registering Payments
Full Payment
Pay the complete prize amount in one transaction.src/api/v1/controllers/ticket.controller.ts:173-183:
Partial Payment
Pay a portion of the prize, with remaining balance tracked.- Total payout: ₡15,000
- Payment 1: ₡5,000 →
remainingAmount = 10,000 - Payment 2: ₡5,000 →
remainingAmount = 5,000 - Payment 3: ₡5,000 →
remainingAmount = 0,status = PAID
Payment Methods
Payment Tracking
Ticket Payment Fields
Get Payment History
src/api/v1/controllers/ticketPayment.controller.ts:170-181:
Reversing Payments
Revert the most recent payment (undo last transaction).src/api/v1/controllers/ticket.controller.ts:189-200:
Finalizing Partial Payments
Mark a partial payment as final, accepting remaining debt.src/api/v1/controllers/ticket.controller.ts:206-217:
- Ticket
statuschanges toFINALIZED remainingAmountstays as-is (not zeroed)- No further payments can be registered
- Finance team can track unpaid balance
Use finalization when:
- Customer accepts partial payment as settlement
- Operational cash limits prevent full payout
- Agreement reached for installment completion later
TicketPayment Entity
Dedicated payment records inTicketPayment model.
Create Payment (Standalone API)
src/api/v1/controllers/ticketPayment.controller.ts:19-55:
Idempotency Support
Include
idempotencyKey to prevent duplicate payments on network retry:- Same key returns cached payment with
200 OKandmeta.cached: true - Different key creates new payment with
201 Created
List All Payments
ventanaId: Filter by ventanavendedorId: Filter by vendedorticketId: Filter by specific ticketstatus: Filter by statusfromDate,toDate: Date range (YYYY-MM-DD)sortBy:createdAt|amount|ticketNumbersortOrder:asc|descpage,pageSize: Pagination
src/api/v1/controllers/ticketPayment.controller.ts:61-96:
Get Payment Details
src/api/v1/controllers/ticketPayment.controller.ts:102-113:
Update Payment
src/api/v1/controllers/ticketPayment.controller.ts:119-138:
Reverse Payment (Standalone)
src/api/v1/controllers/ticketPayment.controller.ts:144-164:
Payment Analytics
Summary Metrics
Payment metrics are included in sales summary endpoints.Dashboard Payment Tracking
src/api/v1/controllers/dashboard.controller.ts:44-74:
Best Practices
Always use idempotency keys
Always use idempotency keys
Include
idempotencyKey in payment requests to prevent duplicates on network retry or user double-click.Record detailed notes
Record detailed notes
Include
notes field with payment context: location, payment method details, supervisor approval, etc.Verify ticket status before payment
Verify ticket status before payment
Always fetch ticket details first to check:
status === 'EVALUATED'(not already paid)remainingAmount > 0totalPayoutmatches expectation
Handle partial payments gracefully
Handle partial payments gracefully
For large prizes:
- Show
remainingAmountprominently - Allow multiple small payments
- Track payment history in UI
- Use finalization when appropriate
Implement reversal workflow
Implement reversal workflow
Require supervisor approval for payment reversals. Log detailed reasons.
Common Workflows
Full Payment Flow
Partial Payment Flow
Related Guides
- Ticket Creation - Understanding ticket lifecycle
- Sorteo Management - Evaluation triggers payment eligibility
- Analytics - Payment tracking and reports