vsmsconnect — API — fiscalisation-jobs

← all endpoints

POST/api/v1/businesses/:businessId/fiscalisation-jobs auth: jwt (administrator | submit_invoices)

Trigger fiscalisation for a batch of payments. Pre-flight eligibility validator re-reads persisted EligibleForFiscalisation / FiscalisationBlockReasons + checks the business's TaxCore config, then partitions the batch into dispatched and blocked. Blocked payments come back with per-payment reason codes so operators can fix the root cause and retry. Batch size capped at MAX_PAYMENTS_PER_FISCALISATION_JOB (currently 10).

handlers: FiscalisationJobsController.trigger

Inputs

Request body type: TriggerFiscalisationBody

namerequireddefaultdescription
businessId path
uuid
yes—Target business UUID.
paymentIds body
uuid[]
yes—1..MAX_PAYMENTS_PER_FISCALISATION_JOB payment UUIDs to dispatch.
options.omitTextualRepresentation body
0 | 1
no00 = include textual representation (default); 1 = omit.
options.omitQRCodeGen body
0 | 1
no00 = generate QR code (default); 1 = skip.
tillId body
uuid | null
no—Optional till to print receipts to after fiscalisation completes.

Outputs

200
APIResponseDataObject<{ message: string; skippedIds: string[] }>
outcome = 'already_fiscalised' — every payment was already terminal; nothing dispatched.
202
APIResponseDataObject<{ jobId: string; skippedIds?: string[]; blocked?: TriggerBlockedPayment[]; warning?: string }>
outcome = 'queued' — job dispatched. skippedIds/blocked/warning included when partial.
404
APIError
BUSINESS_NOT_FOUND.
422
APIResponseDataObject<{ message: string; blocked: TriggerBlockedPayment[] }> | APIError
outcome = 'all_blocked' — every payment failed eligibility (returned as a structured body, not a thrown APIError). Also: CERTIFICATE_NOT_CONFIGURED | VALIDATION_ERROR (schema bound exceeded).
POST/api/v1/businesses/:businessId/fiscalisation-jobs/by-invoice auth: jwt (administrator | submit_invoices)

Invoice-level fiscalisation trigger for PROFORMA (quote) rows. Accepts invoiceIds[]; the service translates each to a synthetic payment (idempotent) before delegating to the standard per-payment dispatch. Same partitioned-response contract as POST /fiscalisation-jobs.

handlers: FiscalisationJobsController.triggerByInvoice

Inputs

Request body type: TriggerFiscalisationByInvoiceBody

namerequireddefaultdescription
businessId path
uuid
yes—Target business UUID.
invoiceIds body
uuid[]
yes—1..MAX_PAYMENTS_PER_FISCALISATION_JOB invoice UUIDs. Each is translated to a synthetic payment idempotently.
options.omitTextualRepresentation body
0 | 1
no00 = include textual representation (default); 1 = omit.
options.omitQRCodeGen body
0 | 1
no00 = generate QR code (default); 1 = skip.

Outputs

200
APIResponseDataObject<{ message: string; skippedIds: string[] }>
outcome = 'already_fiscalised'.
202
APIResponseDataObject<{ jobId: string; skippedIds?: string[]; blocked?: TriggerBlockedPayment[]; warning?: string }>
outcome = 'queued'. Partial-success metadata included when present.
404
APIError
BUSINESS_NOT_FOUND | INVOICE_NOT_FOUND.
422
APIResponseDataObject<{ message: string; blocked: TriggerBlockedPayment[] }> | APIError
outcome = 'all_blocked'. Also: INVOICE_NOT_QUOTE | CERTIFICATE_NOT_CONFIGURED | VALIDATION_ERROR.
GET/api/v1/businesses/:businessId/fiscalisation-jobs/:jobId auth: jwt (administrator | view_invoices | submit_invoices)

Poll fiscalisation job status and per-payment results. The Results array carries per-payment fiscal data (FiscalInvoiceNumber, FiscalTimestamp, FiscalVerificationUrl, errorMessage, attempts). IDOR-guarded — a job belonging to another business returns 404. Add ?lite=true to omit the Results array — returns counts + status only, reducing repeated-poll payload from MB → ~200 bytes for large jobs.

handlers: FiscalisationJobsController.getById

Inputs

namerequireddefaultdescription
businessId path
uuid
yes—Target business UUID.
jobId path
uuid
yes—FiscalisationJob UUID. Must belong to businessId.
lite query
'true' | 'false'
no—When 'true', omits the per-invoice Results array from the response. Useful for high-frequency polling. Schema (GetFiscalisationJobQuerySchema) is defined but the controller reads the raw query value directly — only the literal string 'true' triggers lite mode.

Outputs

200
APIResponseDataObject<FiscalisationJobDTO>
Job record with results: [] when lite=true, otherwise full Results array.
404
APIError
FISCAL_JOB_NOT_FOUND — job does not exist or belongs to a different business (IDOR guard).