Skip to content

The runner

runCertification does the whole HTML side of the certification in the order the SII expects it, and resumes from a store: run it again after a fix and it continues where the saved state says, without repeating what already stands. Under it, every step is a function you can call on its own (sendTestSet, declareTestSets, runBooks…), and so is every portal operation (downloadTestSet, declareProgress, readProgress…).

Nothing here has been run against the portals yet. The tests use synthetic pages, so every page shape is still unproven. For your first enrolled run, keep the artefacts the store writes (every portal answer is there) as fixtures. See Status.

Two things cannot be undone. Downloading the test set again regenerates it at the SII and voids everything sent for the earlier one. The declaration of compliance is the sworn statement of the legal representative: the runner makes it only with declareCompliance: true. Without that option the run ends at the stop compliance.

Basic usage#

TypeScript
import { readFileSync } from 'node:fs'
import { createSiiClient, loadCertificateFromPkcs12 } from 'dte-sdk'
import { createDirectoryFolioRegistry } from 'dte-sdk/node'
import { createPortalClient, createDirectoryCertificationStore, runCertification } from 'dte-sdk/portal'
import { readPrintedSamples } from 'dte-sdk/pdf'
 
const certificate = loadCertificateFromPkcs12(readFileSync('firma.pfx'), process.env.PFX_PASSWORD!)
const companyRut = '76543210-3'
 
const deps = {
  portal: createPortalClient({ environment: 'certification', certificate, companyRut }),
  sii: createSiiClient({ environment: 'certification', certificate, companyRut }),
  store: createDirectoryCertificationStore({ dir: './certification' }), // state.json and the artefacts; holds CAF keys
  registry: createDirectoryFolioRegistry({ dir: './folios' }),
  issuer: { rut: companyRut, businessName: 'Comercial Andina SpA', address: 'Av. Los Aromos 1540' },
  certificate,
  // receiver: the test receiver 66666666-6 by default
  // resolution: number 0 with the UTC date of the day the run starts, by default
  onProgress: (event) => console.log(event.step),
}
 
// First run: downloads the test set, gets the folios, sends and declares the four sets,
// the books, the simulation, answers the exchange, then stops until the samples are given
const first = await runCertification(deps)
first.stopped // 'printedSamples' when everything went well
 
// Second run: uploads the samples and stops at `compliance`: the sworn statement needs an explicit go
const second = await runCertification(deps, { samples: () => readPrintedSamples('./certification/samples') })
second.stopped // 'compliance'
 
// Third run, once you have read the pages the store kept and you are sure
const third = await runCertification(deps, { declareCompliance: true })
third.stopped // 'done'

Run it again after any stop that is not done. A refusal, a block or a time-out comes back as data (stopped, detail) with the state saved, so you can read it, fix the cause and run again. An error thrown by the portal, the SII or the folios propagates after the state is saved, with a CERT_ERROR event.

Dependencies#

runCertification(dependencies, options) takes a CertificationDependencies. Every step function takes the same object.

FieldMeaning
portalPortalClient on the certification environment (createPortalClient)
siiSiiClient on the certification environment (createSiiClient)
storeThe CertificationStore where state and artefacts live
registryThe folio registry: createDirectoryFolioRegistry (dte-sdk/node) or createMemoryFolioRegistry
issuerThe company: rut, businessName and address are required. The line of business, activity code, commune and city take defaults
certificateThe signing certificate
receiverOptional, field by field: the test receiver by default
resolutionOptional { number, date }: number 0 and the UTC date of the run's day by default
nowClock. Dates the run writes for the SII are Chile dates of it
sleepWait function. The real waits by default; inject one to test without waiting
onProgressReceives every CertificationProgressEvent
contactThe contact (name, mail, phone) the exchange answers name

Options and result#

OptionMeaning
untilA CertificationStage: stop once that stage is complete
optionalSetsThe optional sets to tick when downloading, as SETnn codes. DEFAULT_OPTIONAL_SETS by default
declareComplianceMake the declaration of compliance. Off by default
exchangeSetXmlThe exchange set, when you downloaded it by hand
samplesThe PDFs to upload, or a function that returns them (readPrintedSamples). Without it the run stops at printedSamples

runCertification returns { state, stopped, detail? }: the state as saved, why it stopped, and a word or sentence on why.

stoppedMeaning
doneThe declaration of compliance was made
complianceEverything is done up to the declaration, which waits for declareCompliance: true
printedSamplesThe samples are waiting for the samples option
exchangeThe exchange set could not be downloaded, or the company is not in the exchange stage. detail says which: see Exchange and samples
untilThe stage you asked to stop at is complete
rejectedThe SII or the portal refused: a declaration that was not taken, a set or the simulation rejected, a review rejected, or a portal that did not move past the books. detail carries its sentence
blockedThe portal says the application is not at the stage (the samples, or the final declaration). detail carries its sentence
timedOutA wait ran out without an answer
incompleteA mandatory book could not be sent

The order of the run#

1

Test sets

The test set is downloaded once (when the state holds no plan), parsed and planned. The run gets the folios it needs, then issues and sends each set the plan holds and the state has not sent yet, in the order basic, guide, exempt, purchase. It declares the four track ids and waits for the approval.

2

Books

The purchase, sales and guide books (and the exempt purchase book when the test set brought one) are built, sent, declared and awaited. With the three mandatory books sent, the run asks the portal for the next stage.

3

Simulation

Fresh folios, every case issued again in one envelope, sent, declared and confirmed.

4

Exchange

The exchange set is downloaded (or given), answered with three signed files, uploaded and confirmed.

5

Printed samples

The PDFs in samples go up as a review, which is submitted and read again. Without samples the run stops here.

6

Compliance

The declaration of compliance, only with declareCompliance: true.

until is checked between stages: the run returns until as soon as the saved stage is later than the one you asked for.

Resuming from the store#

The state records where the run stands (stage), so a run starts at the stage it saved. Within it nothing is repeated:

  • a set with a track id is not sent again, and the test set is not downloaded again while the state holds a plan;
  • a simulation that is confirmed is not declared again, a confirmed exchange is not answered again, and a review already submitted is not uploaded again;
  • the books phase is the exception: it starts over on every run, and which books stand approved is what the portal shows, not what the state remembers. See The books phase.

An error that stops a step leaves the state as saved by the last thing that succeeded. Every CAF obtained is saved at once, so a step that ends short of folios leaves them in hand for the next attempt instead of asking the SII for them again.

Every step on its own#

Each step takes the dependencies and the state and returns { state, outcome, detail? } with the state it saved. Use them after the SII rejected a set with observations, to redo one piece without running the rest:

TypeScript
let state = (await deps.store.load())!
state = (await sendTestSet(deps, state, { kind: 'basic' })).state
state = (await declareTestSets(deps, state)).state
StepWhat it doesOutcomes
obtainTestSetDownloads the test set, parses it, plans it and keeps the text and the plan as artefacts. Downloading regenerates the set at the SII: a state that already had a plan starts over (everything sent is void), keeping only its CAFs and used foliosloaded, regenerated
prepareFoliosMakes sure the run holds the folios each type needs. See Foliosready (and the cafs to issue with)
sendTestSetIssues one set with the registry's folios, keeps the envelope and every document as artefacts, uploads it, marks the folios sent whatever happened, and records the track id and Chile datesent. Throws on a refusal
declareTestSetsDeclares the sets sent so far with today's Chile date, and keeps any diagnosisA DeclarationOutcome, plus success
waitForTestSetsApprovalPolls the progress page until the sets are approvedapproved, rejected, timedOut
runBooksThe books phaseapproved, incomplete, rejected, timedOut
advanceToNextStageAsks the portal for the stage after the booksadvanced, unchanged, failed, timedOut
sendSimulationGets fresh folios (never the sets' CAFs), issues and sends the simulationsent
declareSimulationDeclares the simulation, unless the portal already names the exchange as the stageA DeclarationOutcome or skipped, plus success
waitForSimulationApprovalPolls until the simulation is approved and confirmeddone, confirmed, rejected, timedOut
runExchangeThe exchange stagedone, alreadyDone, setUnavailable, notInExchange
uploadPrintedSamplesThe printed samples stagesubmitted, alreadySubmitted, blocked, rejected
declareComplianceFinalOne more request to advance, then the declaration of compliancedeclared, blocked

Details that matter when you call them alone:

  • sendTestSet throws MISSING_FIELD (plan) without the set's plan. When the upload fails it still marks the folios as sent in the registry (a time-out may have delivered the envelope, and a folio sent twice rejects the next envelope) and emits SET_ERROR.
  • declareTestSets throws MISSING_FIELD (sets) when nothing was sent.
  • sendSimulation and declareSimulation throw MISSING_FIELD (plan, simulation) when their input is missing.
  • declareComplianceFinal throws SII_PORTAL_UNEXPECTED_PAGE when the last page does not confirm. See The compliance stop.
  • setFolioNeeds, simulationFolioNeeds, previousPeriod and nextFreePeriod are exported helpers of the folio and books steps.

The portal operations beneath#

The steps are built on these functions of dte-sdk/portal. Each takes the PortalClient first and, as a last argument, optional call overrides.

OperationWhat it does
downloadTestSet(portal, { optionalSets, download, previousAttentionNumber })Generates and downloads the test set. Returns its text, attention number and whether it was regenerated. With download: false it only reads the state table. Throws SII_PORTAL_REJECTED with notEnrolled for a company that is not enrolled
queryCertificationSets(portal)Reads the state of every set and book, and whether the required ones are approved
declareProgress(portal, { entries })Declares track ids and dates. See Declarations
readProgress(portal)Reads the progress page: the stage, the state of each set and book, whether the simulation awaits confirmation
advanceStage(portal)Asks for the next stage: advanced, unchanged (the portal says it is already there) or failed, with the sentence
listBookHistory(portal, { year })Lists the books the SII holds for a year. Every period listed is occupied for a new total submission
declareCompliance(portal)The declaration of compliance: declared, blocked or unconfirmed, with the sentence

The store#

A CertificationStore is where the state and the artefacts of a run live:

TypeScript
type CertificationStore = {
  load: () => Promise<CertificationState | null>
  save: (state: CertificationState) => Promise<void>
  writeArtefact: (name: string, content: string) => Promise<void>
  readArtefact: (name: string) => Promise<string | null>
  listArtefacts: () => Promise<readonly string[]>
}

Artefact names are relative paths with / as separator, made only of letters, digits, ., _ and -; anything else throws INVALID_OPTION (name). createMemoryCertificationStore() keeps everything in memory, for tests and short runs. createDirectoryCertificationStore({ dir }) keeps state.json (written atomically, through a temporary file and a rename) and the artefacts as files, with a / in a name as a sub-directory. A service can implement the type over its own storage.

The state is a secret. It holds the CAF files, each with a private key. The directory store creates its directories private to you (mode 0700) and its files unreadable by others (0600); a directory that already exists keeps its mode. It is meant for a single process. Keep the directory out of version control.

createCertificationState(companyRut) makes a fresh state. The state is a plain JSON value; its main fields:

FieldHolds
stageWhere the run stands: a CertificationStage
setText, attentionNumber, planThe downloaded test set, its attention number and the plan
setReadDateThe UTC day the set was read on: its month is the base period of the books
cafsThe CAF files the run holds (with private keys)
usedFoliosEvery folio the run used
annulledRangesThe ranges the SII reported annulled or received, by document type
sets, setsApprovedThe sets sent (track id, Chile date, instant, cases) and whether they are approved
booksThe period in use, occupied periods, adjustments tried, accumulated totals and each book sent
simulationThe simulation sent, and whether it was confirmed
lastDeclarationThe last declaration made and how it ended
diagnosisWhat the SOAP status said of an envelope, by track id
exchange, samplesThe exchange and printed samples stages
blockedThe sentence that blocked the declaration of compliance

The artefacts are what you inspect, and what the printed samples are built from:

ArtefactWhat it is
set-texto.txt, estructuras.jsonThe test set text and the plan
sets-prueba/envio-set-basico.xml, …-guia.xml, …-exenta.xml, …-compra.xmlThe envelope of each set
sets-prueba/dtes/dte-<type>-<folio>.xmlEach document of the sets (SET_ARTEFACT_NAMES names the envelopes)
libro-ventas.xml, libro-compras.xml, libro-guias.xml, libro-compras-exentos.xmlThe books (BOOK_ARTEFACT_NAMES)
simulacion/envio-simulacion.xml, simulacion/dtes/…The simulation
declaracion-sets-<n>.html, declaracion-libros-<n>.html, declaracion-simulacion-<n>.html (and …-pe_avance2-<n>.html, …-estado-<key>-<trackId>.xml)Every declaration page and SOAP status answer
intercambio/…, muestras/…Every portal answer of the exchange and the printed samples, and the exchange answers

findEnvelopeFiles from dte-sdk/pdf picks the set and simulation envelopes out of this directory by name, so writePrintedSamples can build the PDFs straight from it. See Exchange and samples.

Progress events#

onProgress receives one CertificationProgressEvent per step of the run. The names are listed in CERTIFICATION_STEPS:

PhaseEvents
Test setSETS_DOWNLOADING, SETS_LOADED, SETS_REGENERATED
FoliosCAF_REQUESTING and CAF_OK, each with the document type
SetsSET_START (with set), SET_OK (with set and trackId), SET_ERROR (with set and error), SETS_DECLARING, SETS_DECLARED, SETS_APPROVED, SETS_REJECTED
WaitsPOLLING with attempt, max and label: sets, declaration, books or simulation
BooksBOOKS_START, BOOK_SKIPPED, BOOK_SENDING, BOOK_OK (with trackId), BOOK_ERROR (with error), BOOK_PERIOD_RETRY (with period and attempt), BOOKS_DECLARING, BOOKS_DONE (with books and success)
AdvanceADVANCE_WAITING, ADVANCE_DONE (with the portal's stage wording)
SimulationSIM_START, SIM_SENDING, SIM_OK (with trackId), SIM_DECLARING, SIM_DONE
ExchangeINTERCAMBIO_START, INTERCAMBIO_DESCARGADO, INTERCAMBIO_DONE (with uploaded)
SamplesMUESTRAS_UPLOADING (with count), MUESTRAS_DONE (with success)
EndCERT_DONE, CERT_ERROR (with error)

The final advance of declareComplianceFinal reads no stage, so it emits no event.

Folios#

prepareFolios makes sure the run holds the folios each type needs, in the order the SII rations them. It never asks for more than the sets not yet sent need, because unused authorized folios make the SII ration the next request.

  1. The CAFs in hand first. An expired CAF is skipped, because the SII refuses its folios. Folios of this run that the SII never received (a send that failed) are given back to the registry. Folios the SII already received, from an earlier run or other software, are marked used so they are skipped.
  2. Then the quota. The portal's maximum is read. A refusal or a failure reading it is not a stop: the run goes on with no maximum. A blocked quota, or a short one with unused folios at the SII, re-obtains them for the whole need of the type. A whole answer ends the type; a short one is kept, in place of the CAFs in hand, only if it downloaded something that covers more than they do.
  3. Then a request. A blocked maximum asks the portal for nothing. Otherwise one exact request, or batches when the maximum is below the need (as many batches as folios are missing), falling back to batches when the exact request falls short with a maximum that is not zero. A block on the person tries the re-obtaining once before anything else.
  4. Annulling is the last resort. Only when the refusal is rationing and the SII shows more unused folios than the run holds, unused ranges of the last 180 days are annulled: at most 10 per pass, in up to four passes. It never touches a range the run downloaded (the CAFs of the state, expired ones included, the ones just obtained, and the ones a re-obtaining brought and the run did not keep). The ranges the SII reported annulled are kept in the state (annulledRanges) and not tried again. If any was annulled, the maximum is read again and the request repeated following it. An annulment that fails before the SII answers counts as none.

Still short throws FOLIO_OUT_OF_RANGE with type, required, available, maxAuthorized, availableFolios, rejection and a reason (noUnusedFolios or unusedFoliosBlock). When the batches stopped on a failure and not on the SII's answer, the CAFs they obtained are already in the state, and the step throws that failure's code instead, with type, operation: 'requestCafInBatches' and step (queryFolioQuota or requestCaf). Before 0.5.0 the same code came out of the batches themselves, and the CAFs they had obtained were lost.

A re-obtaining whose downloads stopped on a failure, or an annulment cut short once the SII had answered, ends the step the same way: what the re-obtaining brought is kept by the rule of step 2, and what the annulment annulled goes into annulledRanges, then the step throws the failure's code with type, operation (reobtainFolios or annulFolios), step and, when the SII refused, rejection. Before 0.6.0 an annulment cut short counted as none and the step ended with FOLIO_OUT_OF_RANGE, which read a network failure as rationing. The thrown error, and the CERT_ERROR event, carry only the code and those keys: the original error, with its reason, httpStatus and attempts, goes to the portal client's logger as sii portal flow stopped, keeping what it holds, its texts redacted and without what a page said or its url.

A request the SII answers with the request form again, with no folios and no reason, ends with rejection: 'stampingUncertain'. It is not a rationing refusal, so nothing is annulled because of it. The SII may have authorized the range: check the ranges that can be re-obtained before running again.

A later batch the SII refuses keeps its kind too. Before 0.7.0 any refusal of a second or later trip, but stampingUncertain, came out of the batches as quotaCapReached, which reads as rationing: a refusal of the company or of the option led the step to annul folios, and a block on the person was not lifted first. Now only one folio over the maximum after a grant (quotaExceeded) reads as quotaCapReached, so a later refusal that is not rationing never leads to annulling, and a block on the person is first lifted by re-obtaining, as on the first trip.

Annulling cannot be undone and counts against the quota for six months. The runner does it only as the last resort, when the SII rations the type and shows more unused folios than the run holds. See Portal.

Folios are checked against the SII before issuing. Before a set is issued, the SII is asked whether it already holds the folios the run is about to use (as the company, up to 30 queries per CAF, oldest CAF first, until the need is covered); one it holds is marked used. A folio the SII cannot answer for is used. A range obtained again is used only through the folios the SII showed free: every other folio of it is marked used as soon as the CAF is kept, so the registry counts exactly the free ones. The registry hands out its lowest free folio, not the next after the last one. sendTestSet and sendSimulation mark every folio sent in the registry whatever the outcome of the send.

Declarations#

declareProgress(portal, { entries }) declares envelopes on the SII's progress form (pe_avance2). An entry is { trackId, date } with the date as YYYY-MM-DD; the keys are the rows of the form (basic, guide, exempt, purchase, the books, simulation).

  • The form is read for its hidden fields and for the index of each row's field, found by the row's label (the indexes move as sets are approved). A page without a form posts nothing and the outcome is declined.
  • Every NUM_ENV, FEC_ENV, SET and EST field up to TOTREG is posted in form order, with the values already on the page: the track id without leading zeros and the date as dd-mm-yyyy. A row with no field (approved, or in review) adds nothing and the form is posted all the same.
  • The page is read again to verify. The declaration stands when no declared field came back empty, or some row shows EN REVISION. A row left empty is asked again by the loop.
  • Today's Chile date goes with every track id, whatever day the envelope was sent on.
  • ENVIO CON ERRORES O REPAROS is a state of an envelope, not a failure of the declaration. The answer names the rows concerned (contentErrors); the declaration may still stand. The run asks the SOAP status of those envelopes once each and keeps the answer as a diagnosis.
outcomeMeaning
accepted, inReviewThe declaration stands
contentErrorsThe SII finds errors in some envelopes (the declaration itself may still stand, see success)
allRejectedEvery declared row came back empty: the SII took none
notSavedSome declared rows came back empty
inconsistentA date or number the SII says does not match
declinedThere was no form to post
failedA post the portal did not take

The loop of the run (declareTestSets, declareSimulation, and the books phase) waits 10 s, then makes up to 10 attempts 5 s apart. A declaration that stands ends it, unless the answer says the SII has not processed the envelopes yet, which is asked again (a lost session reads that way, and the next attempt logs in again). Content errors are asked again while the declared fields come back empty (the SII has not seen the track ids yet); with the fields in place they are diagnosed and the loop ends. A declaration that was not saved is asked again; every declared row empty ends the loop, except for the simulation, where it is retried because the portal shows the simulation as not declared while it still processes the track id. The last attempt returns whatever it got, and every page goes to the artefacts.

Uploads of the run#

Every envelope and book of the run goes through one upload routine.

  • Retries. An upload is sent again only for a network failure that names a reset socket, a timed-out connection or an unresolved host: 8 attempts, 2 s growing by 1.8 up to 15 s, no jitter. A request that timed out on the client's own clock, a refused connection and every answer of the SII are not retried.
  • Reading the reply. Only STATUS 0 with a TRACKID element is a sent file. STATUS 7 is a duplicate: with a TRACKID element the track id is recovered and the upload goes on as a sent one, unless its first error line names a charset or schema refusal. STATUS 99, and anything else, is a failed send: SII_UPLOAD_REJECTED with status and errors. A duplicate with no track id, where one is needed, is that same error with duplicate: true.
  • Reading a status. The status of an envelope is asked once, on the SOAP channel, without retries. States are classified by code: successful (EPR, RPR, LOK), intermediate (REC, SOK, FOK, PRD, CRT, DNK, PDR, LSO, 0, and the query service's own error codes -1 to -14, which read as "ask again") and rejected (RPT, RFR, VOF, RCT, RCH, RLV, RSC, LNC, LRH). A status that never answered, or that has no state, is neither.

The books phase#

runBooks builds, sends, declares and waits for the books.

  1. The period. The history of books the SII holds is read year by year (until two empty years) and marks the occupied periods. The period is the UTC month the test set was read in when the set brought a purchase book, otherwise the current UTC month, or the first free month below it, searched anew on every run.
  2. What is sent. A book the portal shows as REVISADO CONFORME is skipped. The purchase, sales and guide books (and the exempt purchase book, when the plan has one) are built, kept as artefacts and uploaded. A purchase book the SII already holds for the period goes again as an adjustment.
  3. Mandatory books. Without the three mandatory books (MANDATORY_BOOK_KEYS) sent or skipped, the phase ends incomplete. This is the only case where runBooks ends incomplete.
  4. Before declaring. The SOAP status of the books sent is read for about a minute. A rejected book is left out of the wait.
  5. Declaring. The books are declared together with the four sets. While every declared row comes back empty, at most 24 times, every book goes again: as an adjustment once per period when the totals of the sales or purchase book are kept, otherwise as a total submission in the next free period.
  6. Waiting. A declaration that stands is followed by the approval wait (40 polls 15 s apart, the SOAP status every second poll, because the portal shows a rejected envelope as declared forever). A row the page leaves rejected, closed or declared and never reviewed keeps the search going even if it is of a book this run does not send (an exempt purchase book the test set did not bring): nothing is sent for it, but the books are declared again and that row is awaited, up to 24 times.

When a period is taken, every book goes again as an adjustment, the guide book and the exempt purchase book too. Books the declaration names with ENVIO CON ERRORES O REPAROS, or that the SOAP status rejects, are not awaited but sent again. No portal read of this phase stops the run: a page that cannot be read only uses up its poll.

Advancing the stage#

With the three mandatory books sent, the runner asks the portal for the next stage whether or not the books were approved: the portal decides. advanceToNextStage reads the progress page (up to 30 times, 10 s apart, while it cannot be read), asks for the advance at once with the first page that reads, then reads the page again for the stage. The state's stage moves to the portal's when that is later.

OutcomeMeaning
advancedThe portal moved on
unchangedThe portal says it is already at that step
failedThe portal refused, or the request could not be made. detail is its sentence
timedOutThe progress page could not be read in 30 tries

Nothing in it throws for a portal answer. If the portal did not move and the stage is still the books, runCertification stops with rejected and the portal's sentence.

Defaults for the operator#

The operator gives less than the SII needs, and the run fills in the rest.

WhatDefault
ReceiverDEFAULT_CERTIFICATION_RECEIVER: RUT 66666666-6, CLIENTE TEST, ACTIVIDADES VARIAS, AVENIDA PRINCIPAL 123, Santiago. A field you give wins, field by field; an empty one takes the default
IssuerDEFAULT_CERTIFICATION_ISSUER: line of business ACTIVIDADES DE PROGRAMACION INFORMATICA, activity code 620200, commune and city Santiago. The RUT, business name and address have no default
ResolutionNumber 0 and the UTC date of the day the run started

The default resolution date is only right on the day the SII resolved the application. On any other day, give resolution.date yourself. A resolution left out is dated once, when the run starts, so every envelope of the run carries the same date.

A receiver's line of business is cut at its 40 characters instead of being refused, and so is the issuer's where the issuer is the receiver of its own documents (the purchase set, internal transfers, the simulation). As issuer, it keeps its 80.

The waits#

WaitBehaviour
Approval of the sets5 polls 10 s apart, sleeping first
Declaration loop10 s first, then up to 10 attempts 5 s apart
Approval of the books40 polls 15 s apart, sleeping first
Approval of the simulation30 polls 10 s apart, polling first
Reading the progress page to advanceUp to 30 reads 10 s apart
SOAP status of the books before declaring3 rounds 15 s apart, after a first wait of 15 s

Inject sleep and now in the dependencies to test without waiting. A read that fails during a wait only uses up its attempt.

The compliance stop#

When the printed samples are submitted, the stage is compliance and the run stops with compliance until you pass declareCompliance: true. Then declareComplianceFinal asks the portal to advance the stage once more (a refusal or an error only goes to the log), and makes the declaration.

  • The declaration counts as made when the last page no longer shows its form. Keep the page the store saves and check it.
  • A block (the portal says the certification is not finished) is data: stopped: 'blocked', with the sentence also in state.blocked.
  • A last page that does not confirm throws SII_PORTAL_UNEXPECTED_PAGE.
  • A declaration ends the run: the stage is done and CERT_DONE is emitted.

Only the legal representative can make the declaration, and it cannot be undone. Check the printed samples review is approved in the portal first.

Catalogs#

ExportWhat it holds
SET_KEYSThe four sets in the order they are sent: basic, guide, exempt, purchase
BOOK_KEYSThe books in the order they are sent: purchaseBook, salesBook, guideBook, exemptPurchaseBook
MANDATORY_BOOK_KEYSThe books every certification must get approved: purchaseBook, salesBook, guideBook
CERTIFICATION_STAGEStestSets, books, simulation, exchange, printedSamples, compliance, done
CERTIFICATION_STEPSThe names of the progress events
DEFAULT_OPTIONAL_SETSSET03 guides, SET06 exempt invoices, SET07 sales book, SET08 purchase book, SET09 guide book, SET15 purchase book for exempt taxpayers and SET72 the purchase set. The basic set (SET01) is always requested. Export and settlement are never ticked
BOOK_FILE_NAMES, BOOK_ARTEFACT_NAMES, SET_ARTEFACT_NAMESThe file name each book travels under, and the artefact names of the books and of the set envelopes
PORTAL_STAGE_WORDSThe wording the portal uses for each stage

Errors#

Refusals come back as data. Everything else is a DteError that propagates after the state is saved: the portal codes (SII_PORTAL_REJECTED with a rejection, SII_PORTAL_SESSION_EXPIRED, SII_PORTAL_UNEXPECTED_PAGE, SII_PORTAL_CERT_NOT_ENABLED), the SII upload codes (SII_UPLOAD_REJECTED), FOLIO_OUT_OF_RANGE and MISSING_FIELD. See Errors.

Next steps#