Kapitel
1
Indledning
1
Nærværende dokument beskriver hvorledes man kan udvikle en applikation der anvender den publicerede REST webservice til at aflevere XBRL eller inline XBRL (iXBRL) regnskaber.
Beskrivelsen tager udgangspunkt i et eksempel på en webservice klient der derved kan anvendes som udgangspunkt/inspiration.
Dokumentet beskriver dels generelle forhold omkring denne udvikling og dernæst specifikke forhold om udvikling i Java.
Version | Ændringer |
---|---|
3.7 | Fejlkode 75 ang. Grønland udgår som følge af at indberetning for Grønlandske virksomheder bliver muligt |
3.8 |
Fejl i URL til hentning af testcertifikater rettet
|
3.9 | Tilføjet højere versionsnummer af .NET Framework, af hensyn til understøttelse af nyere versioner af TLS. |
4.0 |
URL’er til SOAP webservice er blevet opdaterede.
|
4.1 | Beskrivelse af fejlkode 45, 46, 47 og 48 tilføjet. Fejlkoderne knytter sig til problemer med det anvendte certifikat. |
4.2 | Beskrivelse af returnerede dokumenter, genereret ved indberetning af inline XBRL, gennem ny REST webservice. |
5.0 | Beskrivelsen er delt op i tre specifikke dokumenter: .Net, Java via SOAP og Java via REST. |
5.1 | Beskrivelse af returnerede dokumenter er rettet til kun at nævne XBRL dokumentet. |
5.2 | Tilføjet statuskoder 83-86. |
5.3 | Tilføjet beskrivelse af test-endpoints. |
5.4 | Tilføjet statuskode 75. |
5.5 | Tilføjet statuskode 79. |
5.6 | Tilføjet legatarfortegnelse og statuskode 31 |
5.7 | Tilføjet statuskode 76. |
5.8 | Opdateret afsnit om kørsel af testklient Tilføjet statuskoder 87, 88 og 89 Slettet statuskoder 44 og 57 |
5.9 | Opdateret afsnit om Oces3 certifikater |
5.10 | Soap udgår |
1.1. Værktøjer
Der er i denne beskrivelse anvendt følgende udviklingsværktøjer
- OpenJDK 1.8.0_152
- OpenOCES 1.8.0 (Findes i eksempelklient under lib)
1.2. Anskaffelse af nødvendige certifikater
For at kunne anvende den integrerede XBRL løsning er det nødvendigt at have certifikater til rådighed for at kunne indgå i TLS kommunikation ved REST webservicekald.
Løsningen anvender OCES3 – Brugercertifikater til virksomheder. Læs mere om anskaffelse af certifikater på https://www.mitid-erhverv.dk/avanceret/certifikater/
Det er vigtigt at man har slået Brugercertifikater til for MitID-erhverv. Nedenstående guide fortæller hvordan det gøres. Bemærk at for support vedrørende udstedelse af certifikater, kontakt Digitaliseringsstyrelsen via https://www.mitid-erhverv.dk.
Aktiver Brugercertifikat.
For testcertifikater (non-prod), åben https://erhvervsadministration.devtest4-nemlog-in.dk/
For prodcertifikater åben https://erhvervsadministration.nemlog-in.dk/
Tryk på Indstillinger -> Certifikater -> Sæt hak i "Tillad brug af brugercertifikater (20,00 DKK per certifikat)". Brugercertifikater kan derefter oprettes under den enkelte bruger via menupunktet "Brugere" -> Vælg bruger -> "Brugercertifikat".
Bemærk:
Efter 31-10-2023 kan der udelukkende anvendes OCES3 – Brugercertifikater.
Kapitel
2
Beskrivelse af REST webservice
2
2.1. Basis URL
Basis-URL for REST webservices findes på:
https://erst-api<env>.virk.dk/ri/api
hvor <env> er hhv. dev, test eller preprod.
URL’en til produktionssystemet (prod) er:
Bemærk
Adgang til dev og test miljøerne er forbeholdt udviklere der er på Erhvervsstyrelsens eget netværk. Det er ikke muligt at anvende disse miljøer udefra.
2.2. JSON-skema
Efterfølgende viser skemaerne for hvilke data der bliver returneret.
Hvordan du skal læse skemaet, kan du læse mere om her:
http://json-schema.org/understanding-json-schema/
2.3. Endpoints
- Inline XBRL REST webservicen findes på
/ixbrl/indberet - Test Inline XBRL REST webservicen findes på
/ixbrl/test - XBRL REST webservicen findes på
/xbrl/indberet - Test XBRL REST webservicen findes på
/xbrl/test
Endpoints understøtter GET og POST
GET (InlineXBRL)
Det accepterede dataskema, som benyttes i forbindelse med ovenstående POST, returneres ved en http GET til ovenstående endpoint. Der returneres følgende JSON skema:
{ "$id": "https://erst.virk.dk/ri/api/ixbrl/indberet.json/v2", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Indberetning af ixbrl", "type": "object", "required": [ "destinationErst", "iXbrl" ], "properties": { "destinationErst": { "type": "boolean" }, "supplerendeInstans": { "type": "string", "minLength": 10 }, "token": { "type": "string" }, "legatarfortegnelse": { "type": "string" }, "iXbrl": { "type": "string", "minLength": 10 }, "returnDocuments": { "type": "boolean" }, "dirigent": { "type": "string" }, "godkendelsesdato": { "type": "string" } }, "additionalProperties": false }
Property | Krævet | |
---|---|---|
destinationErst | Ja | Feltet skal altid være der, og have værdien ’true’ |
iXbrl | Ja | Indeholder inline XBRL. Værdien er Base64 kodet |
supplerendeInstans | Nej | Indeholder en supplerende instans. Værdien er Base64 kodet |
token | Nej | Medsendes, hvis første kald til REST webservicen returnerede en advis og en token. Denne token medsendes, for at indberette trods advis’en |
returnDocuments | Nej | ’true’ hvis genereret XML skal returneres |
dirigent | Nej | Indeholder dirigenten |
godkendelsesdato | Nej | Indeholder godkendelsesdatoen |
legatarfortegnelse | Nej | Indeholder legatarfortegnelsen. Værdien er Base64 kodet |
POST (InlineXBRL)
Kaldet af REST webservicen, når et inline XBRL regnskab skal indberettes, foregår som en HTTP POST.
Returværdier – skema (InlineXBRL)
REST webservicen svarer med data på følgende JSON skema:
{ "$id": "https://erst.virk.dk/ri/api/ixbrl/indberet_response.json/v21", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Response fra indberetning af ixbrl", "type": "object", "required": true, "properties": { "statusCode": { "type": "string", "required": true }, "statusText": { "type": "string", }, "statusDetail": { "type": "string", }, "companyCvr": { "type": "string", }, "companyName": { "type": "string", }, "registrationDate": { "type": "string", }, "reportPeriod": { "type": "string", }, "uniqueReportIdentifier": { "type": "string", }, "token": { "type": "string" }, "xbrl": { "type": "string", "description": "Base64 kodet indhold af XBRL filen" }, "pdf": { "type": "string", "description": "Base64 kodet indhold af PDF filen" }, "validationErrors": { "type": "array", "items": { "$ref": "#/definitions/validationError" } } }, "definitions": { "validationError" : { "type": "object", "required": ["path", "instance", "message", "schema"], "properties": { "path": { "type": "string", "description": "Hvad kunne ikke valideres? f.eks. this.iXbrl" } "instance": { "type": "string", "description": "Værdien som ikke kunne valideres" }, "message": { "type": "string", "description": "Beskrivelse af valideringsfejlen" }, "schema": { "type": "object", "required": ["type", "required"], "properties": { "type": { "type": "string", "description": "Datatypen (f.eks. string)" } "required": { "type": "boolean", "description": "Er datafeltet krævet" }, "minLength": { "type": "integer", "description": "Minimum længde af datafeltet" } } } } } } }
GET (Test InlineXBRL)
Det accepterede dataskema, som benyttes i forbindelse med POST, returneres ved en http GET til ovenstående endpoint. Der returneres følgende JSON skema:
{ "$id": "ri/api/ixbrl/indberet.json/v1", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Indberetning af ixbrl", "type": "object", "required": [ "destinationErst", "iXbrl" ], "properties": { "destinationErst": { "type": "boolean" }, "iXbrl": { "type": "string", "minLength": 10 }, "supplerendeInstans": { "type": "string", "minLength": 10 }, "token": { "type": "string" }, "returnDocuments": { "type": "boolean" }, "dirigent": { "type": "string", "required": false }, "godkendelsesdato": { "type": "string" } , "testadgangstegn": { "type": "string" } }, "additionalProperties": false }
Property | Krævet | |
---|---|---|
destinationErst | Ja | Feltet skal altid være der, og have værdien ’true’ |
iXbrl | Ja | Indeholder inline XBRL. Værdien er Base64 kodet |
supplerendeInstans | Nej | Indeholder en supplerende instans. Værdien er Base64 kodet |
token | Nej | Medsendes, hvis første kald til REST webservicen returnerede en advis og en token. Denne token medsendes, for at indberette trods advis’en |
returnDocuments | Nej | ’true’ hvis genereret XML skal returneres |
dirigent | Nej | Indeholder dirigenten |
godkendelsesdato | Nej | Indeholder godkendelsesdatoen |
testadgangstegn | Nej | Indeholder det tildelte testadgangstegn |
legatarfortegnelse | Nej | Indeholder legatarfortegnelsen. Værdien er Base64 kodet |
POST (Test InlineXBRL)
Kaldet af REST webservicen, når et inline XBRL regnskab skal testes, foregår som en HTTP POST.
Returværdier – skema (InlineXBRL)
REST webservicen svarer med data på følgende JSON skema:
{ "$id": "ri/api/ixbrl/indberet_response.json/v1", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Response fra indberetning af ixbrl", "type": "object", "required": true, "properties": { "statusCode": { "type": "string", "required": true }, "statusText": { "type": "string", }, "statusDetail": { "type": "string", }, "companyCvr": { "type": "string", }, "companyName": { "type": "string", }, "registrationDate": { "type": "string", }, "reportPeriod": { "type": "string", }, "uniqueReportIdentifier": { "type": "string", }, "token": { "type": "string" }, "pdf": { "type": "string", "description": "Base64 kodet indhold af PDF filen" }, "validationErrors": { "type": "array", "items": { "$ref": "#/definitions/validationError" } } }, "definitions": { "validationError" : { "type": "object", "required": ["path", "instance", "message", "schema"], "properties": { "path": { "type": "string", "description": "Hvad kunne ikke valideres? f.eks. this.iXbrl" } "instance": { "type": "string", "description": "Værdien som ikke kunne valideres" }, "message": { "type": "string", "description": "Beskrivelse af valideringsfejlen" }, "schema": { "type": "object", "required": ["type", "required"], "properties": { "type": { "type": "string", "description": "Datatypen (f.eks. string)" } "required": { "type": "boolean", "description": "Er datafeltet krævet" }, "minLength": { "type": "integer", "description": "Minimum længde af datafeltet" } } } } } } }
GET (XBRL)
Det accepterede dataskema, som benyttes i forbindelse med POST, returneres ved en http GET til ovenstående endpoint. Der returneres følgende JSON skema:
{ "$id": "ri/api/xbrl/indberet.json/v1", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Indberetning af xbrl", "type": "object", "required": [ "destinationErst", "xbrl", "pdf" ], "properties": { "destinationErst": { "type": "boolean }, "xbrl": { "type": "string", "minLength": 10 }, "pdf": { "type": "string", "minLength": 10 }, "supplerendeInstans": { "type": "string", "minLength": 10 }, "token": { "type": "string" } } , "additionalProperties": false }
Property | Krævet | |
---|---|---|
destinationErst | Ja | Feltet skal altid være der, og have værdien ’true’ |
xbrl | Ja | Indeholder XBRL. Værdien er Base64 kodet |
Ja | Indeholder pdf-udgaven af indberetningen. Værdien er Base64 kodet | |
supplerendeInstans | Nej | Indeholder en supplerende instans. Værdien er Base64 kodet |
token | Nej | Medsendes, hvis første kald til REST webservicen returnerede en advis og en token. Denne token medsendes, for at indberette trods advis’en |
legatarfortegnelse | Nej | Indeholder legatarfortegnelsen. Værdien er Base64 kodet |
POST (XBRL)
Kaldet af REST webservicen, når et XBRL regnskab skal indberettes, foregår som en HTTP POST.
Returværdier – skema (XBRL)
REST webservicen svarer med data på følgende JSON skema:
{ "$id": "ri/api/xbrl/indberet_response.json/v1", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Response fra indberetning af xbrl", "type": "object", "required": true, "properties": { "statusCode": { "type": "string", "required": true }, "statusText": { "type": "string", }, "statusDetail": { "type": "string", }, "companyCvr": { "type": "string", }, "companyName": { "type": "string", }, "registrationDate": { "type": "string", }, "reportPeriod": { "type": "string", }, "uniqueReportIdentifier": { "type": "string", }, "token": { "type": "string" }, "validationErrors": { "type": "array", "items": { "$ref": "#/definitions/validationError" } } }, "definitions": { "validationError" : { "type": "object", "required": ["path", "instance", "message", "schema"], "properties": { "path": { "type": "string", "description": "Hvad kunne ikke valideres? f.eks. this.iXbrl" } "instance": { "type": "string", "description": "Værdien som ikke kunne valideres" }, "message": { "type": "string", "description": "Beskrivelse af valideringsfejlen" }, "schema": { "type": "object", "required": ["type", "required"], "properties": { "type": { "type": "string", "description": "Datatypen (f.eks. string)" } "required": { "type": "boolean", "description": "Er datafeltet krævet" }, "minLength": { "type": "integer", "description": "Minimum længde af datafeltet" } } } } } } }
GET (Test XBRL)
Det accepterede dataskema, som benyttes i forbindelse med POST, returneres ved en http GET til ovenstående endpoint. Der returneres følgende JSON skema:
{ "$id": "ri/api/xbrl/indberet.json/v1", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Indberetning af xbrl", "type": "object", "required": [ "destinationErst", "xbrl", "pdf" ], "properties": { "destinationErst": { "type": "boolean }, "xbrl": { "type": "string", "minLength": 10 }, "pdf": { "type": "string", "minLength": 10 }, "supplerendeInstans": { "type": "string", "minLength": 10 }, "token": { "type": "string" }, "testadgangstegn": { "type": "string" } }, "additionalProperties": false }
Property | Krævet | |
---|---|---|
destinationErst | Ja | Feltet skal altid være der, og have værdien ’true’ |
xbrl | Ja | Indeholder XBRL. Værdien er Base64 kodet |
Ja | Indeholder pdf-udgaven af indberetningen. Værdien er Base64 kodet | |
supplerendeInstans | Nej | Indeholder en supplerende instans. Værdien er Base64 kodet |
token | Nej | Medsendes, hvis første kald til REST webservicen returnerede en advis og en token. Denne token medsendes, for at indberette trods advis’en |
testadgangstegn | Nej | Indeholder det tildelte testadgangstegn |
legetarfortegnelse | Nej | Indeholder legatarfortegnelsen. Værdien er Base64 kodet |
POST (Test XBRL)
REST webservicen svarer med data på følgende JSON skema:
Returværdier – skema (XBRL)
REST webservicen svarer med data på følgende JSON skema:
{ "$id": "ri/api/xbrl/indberet_response.json/v1", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Response fra indberetning af xbrl", "type": "object", "required": true, "properties": { "statusCode": { "type": "string", "required": true }, "statusText": { "type": "string", }, "statusDetail": { "type": "string", }, "companyCvr": { "type": "string", }, "companyName": { "type": "string", }, "registrationDate": { "type": "string", }, "reportPeriod": { "type": "string", }, "uniqueReportIdentifier": { "type": "string", }, "token": { "type": "string" }, "validationErrors": { "type": "array", "items": { "$ref": "#/definitions/validationError" } } }, "definitions": { "validationError" : { "type": "object", "required": ["path", "instance", "message", "schema"], "properties": { "path": { "type": "string", "description": "Hvad kunne ikke valideres? f.eks. this.iXbrl" } "instance": { "type": "string", "description": "Værdien som ikke kunne valideres" }, "message": { "type": "string", "description": "Beskrivelse af valideringsfejlen" }, "schema": { "type": "object", "required": ["type", "required"], "properties": { "type": { "type": "string", "description": "Datatypen (f.eks. string)" } "required": { "type": "boolean", "description": "Er datafeltet krævet" }, "minLength": { "type": "integer", "description": "Minimum længde af datafeltet" } } } } } } }
Kapitel
3
Generel struktur for eksempel klient
3
Eksempel klienterne har følgende struktur:
En simpel grænseflade til at prompte brugeren for de nødvendige data der skal anvendes som argumenter til kaldet af REST webservicen.
3.1. REST webservicen
De nødvendige data er:
- Et XBRL eller inline XBRL (iXBRL) regnskab
- En supplerende instans (til nettoomsætning der ikke offentlliggøres)
- Regnskabet som PDF (for regnskab der afleveres som XBRL)
- Afsendercertifikat i form af PKCS#12 fil inkl. password. Certifikatet benyttes til TLS kommunikation med webservicen
- Destination for data – kun ERST er understøttet
- En angivelse af om transporten skal foregå via http eller HTTPS (TLS). I produktion vil det altid være HTTPS
- Valg af REST webservice der kaldes
- Valg af webservice der kaldes – der kan kaldes webservice på prod eller preprod miljøet (medmindre man er på styrelsens eget netværk hvor dev og test også er tilgængelige
- En angivelse af om det genererede (på basis af inline XBRL) XBRL dokument skal returneres i svaret
- En klasse til indkapsling af de indsamlede argumenter for REST webservicen
Kapitel
4
Java Eksempel Klient
4
Denne sektion beskriver hvorledes Java Eksempel Klienten kan anvendes og hvordan den er lavet.
Klassenavne etc. refererer til specifikke klasser der kan findes i zip filen, som indeholder Java Eksempel Klienten.
Denne zip fil indeholder et Eclipse projekt, der kan importeres til et lokalt Eclipse workspace.
4.1. Installation og kørsel af eksempel klient
Windows
Java eksempel klienten installeres og køres ved at
- Pakke zip filen ”s2s_rest_eksempel_java_klient_Juni2021.zip” ud i en passende folder
- Bygge artifakter med ”gradlew.bat build”
- Afvikle filen run_rest_klient.bat
MacOS/Linux
Java eksempel klienten installeres og køres ved at:
- Pakke zip filen ”s2s_rest_eksempel_java_klient_Juni2021.zip” ud i en passende folder
- Bygge artifakter med ”./gradlew build”
- Afvikle filen run_rest_klient.sh
4.2. Testfiler
Testfiler kan hentes på følgende steder
- XBRL regnskaber kan downloades via https://datacvr.virk.dk/data/. Vi kan dog ikke garantere at alle CVR numre er tilgængelige i preprodution. Desuden kan man modtage fejlbeskeden at der allerede er registreret et regnskab for dette CVR nummer og periode hvis andre tester på dette CVR nummer.
- regnskabets pdf (dette er blot en tilfældig pdf fil som ikke er password-beskyttet)
- Testcertifikat kan downloades fra Nets, jævnfør afsnittet ”Værktøjer”.
4.3. Brugergrænseflade
Klassen eksempel.rest.RegisterInlineXBRLFront indeholder en simpel brugergrænseflade der prompter brugeren for de nødvendige data.
Indholdet varierer lidt, afhængig af om der er valgt XBRL eller inline XBRL.
XBRL
Samler data sammen, signerer XBRL’en med det valgte certifikat, og kalder metoden registerXBRL i eksempel.rest.RegisterXBRLInvoker.
Inline XBRL
Samler data sammen, kalder registerInlineXbrl i klassen RegisterInlineXBRLInvoker, og bruger det valgte certifikat til at instantiere en TLS 1.2 forbindelse til serveren.
Kapitel
5
Statusbeskeder fra webservicen
5
Hvert kald til webservicen returnerer en status kode, tekst og evt. detaljer, der beskriver resultatet af behandlingen af det foretagne kald.
Kode 0 betyder OK, øvrige koder er fejlkoder. Ved kode 0 kan tekst og detaljer indeholder advis.
Bemærk at fejlkode 73 tidligere fejlagtigt var angivet som “CVR-nummer ikke fundet”.
Kode | Tekst |
---|---|
10 | XBRL dokumentet kan ikke valideres |
23 | XBRL dokumentet opfylder ikke Erhvervsstyrelsens krav |
24 | XBRL dokumentet er valideret med Advis |
30 | Årsrapportens PDF dokument kan ikke valideres |
31 | Legatarfortegnelsen kan ikke valideres |
40 | Det signerede XML dokuments signatur kan ikke valideres |
41 | Certifikatet der har signeret XML dokumentet er ikke validt |
43 | Det signerede XML dokument kan ikke valideres |
45 | Det anvendte certifikat har ukendt udsteder |
46 | Det anvendte certifikat er endnu ikke gyldigt |
47 | Det anvendte certifikat er udløbet |
48 | Det anvendte certifikat er tilbagekaldt |
50 | Der er allerede registreret et regnskab for dette CVR nummer i denne periode – der kan ikke |
51 | Der skal angives netop een destination |
55 | XBRL dokumentet til Erhvervsstyrelsen skal være en Årsrapport eller Likvidationsregnskab |
56 | XBRL dokumentet til Danmarks Statistik skal være en Regnskabsstatistik |
59 | PDF dokumentet mangler |
60 | PDF dokumentet overholder ikke størrelsesbegrænsningen på 20 Mb |
72 | CVR-nummer ikke fundet |
73 | Danmarks Statistik svarer at der er fejl i den indberettede selskabsstatistik. |
74 | Vi kan i øjeblikket ikke få forbindelse til Danmarks Statistiks systemer. |
75 | IXBRL dokument mangler |
76 | Entrypointet {0} er ikke understøttet i indberetning via System til System. |
79 | Godkendelsesdatoen er formateret forkert (korrekt format er 'dd-MM-yyyy') |
80 | REST-kaldets JSON data kunne valideres imod skemaet |
81 | Kun ERST er understøttet som destination i REST-kaldet |
82 | Inline XBRL (IXBRL) er ikke Base64 kodet i REST-kaldet |
83 | XBRL er ikke base64encoded |
84 | Dirigent og/eller godkendelsesdato er ikke ens i xbrl’en og de indsendte properties |
85 | Den supplerende instans er ikke base64encoded |
86 | PDF er ikke base64encoded |
87 | Testfunktionalitet i S2S er deaktiveret |
88 | Det angivne adgangstegn kan ikke anvende testfunktionaliteten i S2S |
89 | Legatarfortegnelsen er ikke base64 encoded |
98 | Systemet er optaget - prøv venligst senere |
99 | Der er opstået en fejl - kontakt venligst Erhvervs- og Selskabsstyrelsen |
Kapitel
6
Appendix A: Advis håndtering i Erhvervsstyrelsens System-til-system service
6
Erhvervsstyrelsen indfører fra 23/8 2016 et nyt niveau i sin modtagekontrol kaldet 'Advis'. En advis adskiller sig fra en fejl ved at indberetter har mulighed for at fortsætte indberetningen efter at have accepteret den.
Fremover vil alle indberetninger i system-til-system som har fået en advis få et svar tilbage indeholdende en ”token”. Såfremt brugeren vælger at indberette trods advis’en da gentages indberetningen, sammen med den modtagede token.
Token kan kun anvendes hvis der er tale om en indberetning der er identisk med den indberetning der adstedkom advis’en. Tilsvarende løsningen indarbejdes i styrelsens løsninger på virk.dk.
REST webserviceløsningen understøtter brugen af token.
Kapitel
7
Appendix B: Omgørelse og berigtigelse
7
Da det ikke er muligt at omgøre og berigtige regnskaber via via System-til-system servicen skal udviklere og testere som anvender klienten være opmærksom på at når der er indberettet korrekt på et CVR-nummer for en periode vil det ikke være muligt at indberette igen på samme CVR-nummer og regnskabsperiode.
Da Erhvervsstyrelsen anvender preproduktions-miljøet til forskellige andre tests af systemet kan der forekomme løbende ændringer i testdata.