emitirFacturaCore, which submits the DocumentoElectronico payload to the TFHKA /api/Emision endpoint.
Billing flow
Order completes
A ticket sale is finalized. The
order_created function writes the order to Firestore, and order_process settles transactions and payouts.process_order_billing
Called separately (to avoid Cloud Function timeouts) with the completed order data. It enriches
purchaser_info from u_users, fetches tercero_info from u_clients, retrieves the exchange rate from data/exchange_rates, and calls getNextInvoiceNumber() to reserve the next sequential invoice number.billing_emision
process_order_billing builds the full DocumentoElectronico object via generateBillingDataFromOrder, then passes body_emision to billing_emision. billing_emision calls emitirFacturaCore, which authenticates with TFHKA and POSTs to /api/Emision.TFHKA API
TFHKA validates the document, registers it with the Venezuelan tax authority (SENIAT), and returns a response containing
resultado.numeroDocumento and resultado.urlConsulta.billing_emision
Manually emits a digital invoice by forwarding a pre-builtDocumentoElectronico payload directly to the TFHKA /api/Emision endpoint. Use this when you have already assembled the billing data and need to submit it without the enrichment logic of generateBillingFromExpenses.
Trigger: POST /billing_emision
Request
A fully formed
DocumentoElectronico object as expected by the TFHKA API. See the DocumentoElectronico structure section below for all fields.Response (success)
The raw JSON response from the TFHKA API is returned directly with HTTP 200.The sequential invoice number assigned by TFHKA, zero-padded to 8 digits.
A URL where the issued invoice can be consulted or downloaded.
Response (failure)
HTTP 500 with the TFHKA error body or the exception message.generateBillingFromExpenses
Generates and emits an invoice from a list of expense line items tied to an event. The function resolves the event’s associated client, fetches the current exchange rate, assigns an invoice number, builds theDocumentoElectronico, submits it to TFHKA, and stores the result in event_invoices.
Trigger: POST /generateBillingFromExpenses
Request
Firestore ID of the event the expenses belong to. Used to look up the associated
client_id.Category label for the expense (e.g.
"Producción", "Logística"). Appended to each line item description on the invoice.Currency of the expense amounts. Accepted values:
"USD" or "BSD". When "USD", IGTF (3%) is applied and amounts are converted to BSD using the current exchange rate.One or more expense line items. Each item must have:
name(string) — display name for the line item.amount(number) — total amount including IVA in the specifiedcurrency.
Response (success)
true when the invoice was emitted and stored successfully.The
numeroDocumento returned by TFHKA, used as the Firestore document ID in event_invoices.Direct URL to view or download the issued invoice from TFHKA.
The complete raw response object from the TFHKA
/api/Emision call.Response (failure)
generateBillingFromExpenses reads the exchange rate from data/exchange_rates at the moment of the call. Make sure this document is kept up to date — it is not pulled from the order record.Internal functions
getNextInvoiceNumber
Reads and atomically increments thelast_number counter in data/invoice_counter using a Firestore transaction. Returns the new integer, which is then zero-padded to 8 digits (String(invoiceNumber).padStart(8, '0')) before being placed in NumeroDocumento.
generateBillingDataFromOrder
Builds the completeDocumentoElectronico from a completed order. Called by process_order_billing.
Signature:
- Groups tickets by
zoneand creates oneDetallesItemsentry per zone. - Computes IVA at 16% on the subtotal.
- Applies IGTF (3%) if any transaction used
payment_namein['Zelle', 'Efectivo Dolares', 'Efectivo Divisa']. The IGTF base ismin(subtotal + IVA, totalPaidInForeignCurrency). - Populates
CompradorfromorderData.purchaser_infoandTercerofromorderData.tercero_info. - Sets
Vendedor.nombretoorderData.box_office_name.
generateBillingDataFromExpenses
Builds theDocumentoElectronico from an expense record. Called by generateBillingFromExpenses.
Signature:
- When
currency === 'USD': assumes the itemamountvalues are total-including-IGTF. Back-calculates:totalConIVA = total / 1.03, thensubtotal = totalConIVA / 1.16. - When
currency === 'BSD': assumes amounts are total-including-IVA only. No IGTF is applied. - Creates one
DetallesItemsentry per item, with description"${item.name} (${expenseData.expense_type})". - Sets
Vendedor.nombreto"Trade Master Transaction L.L.C". - Populates
CompradorfromclientData(id_type,id,name_commercial,address.line,phone,email).
emitirFacturaCore
Low-level wrapper that authenticates with TFHKA and POSTs to/api/Emision. Returns a normalized result object:
{ success: false } shape so callers can handle them without try/catch.
DocumentoElectronico structure
The following is the full structure of theDocumentoElectronico object submitted to TFHKA. All monetary strings are formatted with 2 decimal places (.toFixed(2)). Exchange rates use 4 decimal places.
Key field notes
| Field | Notes |
|---|---|
TipoDocumento | Always "01" (factura) |
NumeroDocumento | Zero-padded 8-digit sequential number from data/invoice_counter |
Moneda | Always "BSD" in the primary Totales block |
TipoDeVenta | Always "Interna" |
TipoDePago | Always "Inmediato" |
IndicadorBienoServicio | Always "2" (service) |
UnidadMedida | Always "4L" |
CodigoImpuesto | Always "G" (General — IVA) |
TasaIVA | Always "16" |
CodigoTotalImp | "G" for IVA, "IGTF" for the foreign-currency tax |
AlicuotaImp | "16.00" for IVA, "3.00" for IGTF |
Tercero.tipo | Always "PRODUCTORA" |
Firestore storage
event_invoices (expense invoices)
AftergenerateBillingFromExpenses succeeds, a document is written to event_invoices/{numeroDocumento}:
orders (order invoices)
Afterprocess_order_billing succeeds, the billing_info field is written to the existing orders/{order_id} document. This field contains the full TFHKA API response.
The Firestore document ID for expense invoices is the
numeroDocumento string returned by TFHKA (e.g. "00000043"), making it easy to cross-reference a physical invoice number with the stored record.