Submit VERI*FACTU from a TPV ticket
Send the stored VERI*FACTU record for an already invoiced TPV ticket, update the fiscal submission state and refresh the ticket detail. This action does not create the invoice or the fiscal record.
In this article
Use this guide when a TPV ticket already has an invoice and a VERI*FACTU fiscal record, but the record still needs manual submission from the ticket detail.
The operator sends the existing record through the location's configured fiscal transport. The app does not ask for a body, recipient or manual payload during submission.
For the en-GB documentation set, note the capture limitation: Harbor Soho is a GB demo location, while VERI*FACTU is currently allowlisted for ES locations only. Authentic captures need an ES documentation runtime.
Before you start
- The operator is signed in and working inside the protected app route for the current organisation and location.
- The location is eligible for VERI*FACTU. The current implementation allowlists this billing integration for ES only, so the GB Harbor Soho demo cannot naturally display or execute the action.
- The ticket belongs to the current location, is accessible to the operator and already has an invoice.
- The invoice already has a VERI*FACTU record created during invoice issue while VERI*FACTU was enabled.
- The operator has tpv:invoice or tickets:manage. If access relies on tpv:invoice, the backend can also require operational access to the ticket through the active service session.
- TPV billing settings have VERI*FACTU enabled and a working transport: custom_xml endpoint, AEAT SOAP proxy/platform authorisation, or direct SOAP credentials as configured for the runtime.
- The fiscal record is not already in a terminal UI state such as accepted, accepted_with_warnings, ready, registered or submitted. Terminal records hide the manual action in the UI.
Instructions
- 1.
Check VERI*FACTU readiness
Before opening the ticket, confirm that the location is an ES documentation runtime with VERI*FACTU enabled in TPV billing settings and a working submission transport. In the GB Harbor Soho runtime, record this as a demo gap rather than forcing the capture.
- 2.
Open the invoiced TPV ticket
From the TPV, open the detail for the already invoiced ticket. The backend will only work with a ticket that exists in the active location and passes the ticket access rules for the operator.
- 3.
Inspect the fiscal card
In the invoice area, find the VERI*FACTU card and check the series and number, issuer tax ID, system details, QR URL, record hash and current status. If the card is missing, the invoice was not issued with a VERI*FACTU record available.
- 4.
Submit the record
Select the Submit VERI*FACTU action. In current UI text this may appear as Enviar VERI*FACTU. The app sends no editable payload; it uses the ticket, invoice, TPV settings and existing fiscal record.
- 5.
Wait for the transport result
The service reads the VERI*FACTU billing configuration and sends the stored record through the configured transport. For custom_xml, a 2xx HTTP response is treated as accepted. For official SOAP, the response must parse and must not report an incorrect send or record state.
- 6.
Confirm the refreshed state
After success, the ticket detail refreshes, the success toast appears, the fiscal card moves to the returned terminal result, and the manual submit action is no longer shown. If the transport fails, use the stored status, response payload and error message for follow-up.
Validations and limits
- The submit action does not issue an invoice, generate a PDF or create a missing VERI*FACTU record.
- The backend route is POST /api/app/{orgId}/{locationId}/tickets/{ticketId}/invoice/verifactu/submit and accepts no request body.
- The backend rechecks location context, ticket ownership, tpv:invoice or tickets:manage, and ticket access before sending.
- VERI*FACTU must be enabled for the location and available for its country; GB demo locations are not eligible under the current allowlist.
- A ticket invoice and a VERI*FACTU record must already exist before this endpoint can return an updated record.
- custom_xml requires billing_config.verifactu.endpoint_url. Direct aeat_soap requires issuer_tax_id, client_cert_file_id and client_key_file_id; platform or proxy setups can hide those details from the operator UI.
- Successful submissions store submitted_at, request_payload and response_payload and return the updated VerifactuRecord. Current code can report accepted or accepted_with_warnings as successful terminal statuses, while older data may still show submitted.
- External transport failures can persist rejected, retrying, failed or failed_manual_review-style states with response/error details; the inspected implementation does not roll back the attempt.
Expected result
The existing VERI*FACTU record is updated with the transport result. On success, the ticket detail and ticket list are invalidated for refresh, the fiscal card shows the returned terminal state, and operators no longer see the manual submit action for that record.