How to close a paid TPV ticket
Close a Harbor Soho TPV ticket once it has been fully paid. The action moves the ticket from `paid` to `closed`, records the closing staff member when the TPV flow sends one, and refreshes the ticket detail for the operator.
In this article
Closing a ticket is the final TPV lifecycle step after payment. It is used when the bill is complete and the table or reservation should no longer stay active in the service view.
The close action does not replace payment. The ticket must already be paid, and the normal operator path closes it from the TPV ticket detail or the selected-ticket actions.
Before you start
- You are signed in to Harbor Demo Group and working in the Harbor Soho location.
- The ticket belongs to the current Harbor Soho TPV context and is opened from the TPV floor or ticket detail screen.
- The ticket is already fully paid. In the GB demo runtime, use `TPV_PAID_TICKET_ID` for the paid close case.
- The route includes `ticketId` and `terminalId`; include `staffId` when the guide should show who closed the ticket. In the demo this is Olivia Hart via `TPV_STAFF_ID`.
- Your role can manage the ticket. With `tpv:use`, the ticket must belong to the active service session; with `tickets:manage`, the backend does not require that active-session match.
Instructions
- 1.
Open the paid ticket
Open the paid TPV ticket for Harbor Soho from the floor view or from the direct ticket detail link. The ticket must already be in `paid` state before the close action is available.
- 2.
Open ticket actions
Open the ticket action menu from the ticket header or selected-ticket panel. The close action should only be enabled for a paid ticket that the current operator can manage.
- 3.
Close the ticket
Choose `Close ticket` when the bill is complete and the table should leave active service. The app sends the close request and includes the TPV staff member when available.
- 4.
Confirm the result
Wait for the ticket detail to refresh. The ticket is now `closed`, remains available for later review, and cannot be closed again from the normal TPV flow.
Validations and limits
- Pending, partially paid, void and already closed tickets cannot be closed.
- The client close path is `POST /api/app/{orgId}/{locationId}/tickets/{ticketId}/close`; do not document `PUT /api/app/{orgId}/{locationId}/tickets/{ticketId}` as the close operation.
- The request body must be valid JSON and may include `closed_by_staff_id`. The backend trims that value before saving it.
- The ticket must belong to the `locationId` in the app context. Empty ids or tickets from another location are treated as not found.
- If the operator only has `tpv:use`, the ticket must match the active service session. `tickets:manage` does not require that active-session match.
- A closed ticket is removed from active table or reservation assignments in the TPV surface.
- The paid-ticket close capture mutates `TPV_PAID_TICKET_ID`; run it only in a disposable or cleaned documentation runtime.
Expected result
The ticket detail refreshes with the updated `closed` lifecycle state. Existing ticket items, payments, allocations and invoice information remain available when they already exist, while the ticket no longer stays in active TPV assignments.