1
Kapitel
Indledning
Kapitel
Nærværende dokument beskriver hvorledes man kan udvikle en applikation der anvender den publicerede SOAP webservice til at aflevere XBRL 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 Afsnit om testdata tilrettet med information om hvor de kan hentes Tilføjet information om ændringer til TLS og kryptering. Da Erhvervsstyrelsen ikke længere tillader TLS 1.0 og 1.1 eller kryptering med 128 bit, er der krav om visse minimumsversioner af Java. Det angivne afspejler de versioner vi har testet med. |
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. Beskrivelse af indberetning af inline XBRL regnskaber, gennem ny REST webservice. Beskrivelse af fejlkode 80, 81 og 82 tilføjet. Disse fejlkoder knytter sig alle til den nye REST webservice. |
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.2 | Tilføjet statuskoder 83-86. |
5.3 | Rettet fejl i URL’er. |
1.1. Værktøjer
Der er i denne beskrivelse anvendt følgende udviklingsværktøjer
- Eclipse version 3.5
- OpenJDK 1.8.0_152
OpenOCES 1.8.0 (www.openoces.org/opensign/download.html)
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, dels for at kunne anvende disse til signering af det indsendte XBRL regnskab, og dels for at kunne indgå i TLS kommunikation ved SOAP- og REST webservicekald .
Løsningen anvender de fælles offentlige OCES certifikater til virksomheder.
- Gå til anskaffelse af certifikater og digitale signaturer på NemID
- Gå til NETS for at hente testcertifikater
Der kan anvendes FOCES (funktionscertifikat) og VOCES (virksomhedscertifikat) certifikater, til webservicekald. Webservicen accepterer desuden MOCES (medarbejdercertifikat) certifikater.
2
Kapitel
Generering af webservice stubs
Kapitel
Kaldet af SOAP webservices foregår som en HTTP POST mod webservicens URL med et XML dokument, en supplerende instans (til nettoomsætning der ikke offentlliggøres) og et PDF dokument (for destination ERST), hvor argumenterne til webservicen er pakket ind i en SOAP envelope struktur.
Da det kan være vanskeligt at arbejde direkte med denne XML/SOAP struktur, indeholder de fleste udviklingsværktøjer en kodegenerering, der på baggrund af webservicens publicerede WSDL, kan generere klasser der gør det nemmere, dels at opbygge argument strukturen, og dels at udføre selve kaldet med argumenterne til webservicen.
Fælles for disse kodegenereringsværktøjer er, at de skal have en URL til WSDL’en for den publicerede webservice.
For XBRL webservicen er URL’en til WSDL’en:
- http://erst<env>.virk.dk/ri/s2s/RegisterXbrlEksternWS?wsdl eller
- https://erst<env>.virk.dk/ri/s2s/RegisterXbrlEksternWS?wsdl
hvor <env> er hhv. dev, test eller preprod.
URL’en til prod WSDL’en 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.
3
Kapitel
Generel struktur for eksempel klient
Kapitel
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 SOAP webservicen.
3.1. SOAP webservicen
De nødvendige data er:
- Et XBRL regnskab
- En supplerende instans (til nettoomsætning der ikke offentlliggøres)
- Regnskabet som PDF (for destination ERST).
- Afsendercertifikat i form af PKCS#12 fil inkl. password til generering af digitale signaturer for XBRL dokumentet.
- Destination for data – Erhvervsstyrelsen (ERST), Danmarks Statistik (DST), og SKAT (SKAT)
- En angivelse af om transporten skal foregå via HTTP eller HTTPS.
En egentlig produktions implementering vil altid anvende HTTPS til kaldet af webservicen, men i eksempel klienterne kan man vælge begge former for transport. - Valg af webservice der kaldes – der kan kaldes webservice på prod eller preprod miljøet (med mindre man er på styrelsens eget netværk hvor dev og test også er tilgængelige.
- En klasse til indpakning af de indsamlede argumenter for SOAP webservices.
En klasse der anvender de genererede klasser til at opbygge den nødvendige argument struktur og derefter kalder webservicen med argument strukturen via en genereret webservice stub.
Når der skal laves en produktionsklar implementering der anvender webservicen, skal denne naturligvis anvende produktionsversionen af webservicen.
- URL’en for produktionsversionen er:
https://erst.virk.dk/ri/s2s/RegisterXbrlEksternWS
3.3.1. Klasser til generering af digitale signaturer
SOAP webservicens API kræver, at XBRL regnskabet pakkes ind i et XML dokument der er signeret med afsenderens certifikat, jf. XML Digitale Signaturer (https://www.w3.org/TR/xmldsig-core).
Den digitale signatur der skal medsendes, er en OpenOCES (https://www.openoces.org) signatur med namespace “http://www.openoces.org/2006/07/signature#”.
Der er i eksempel klienten inkluderet klasser, der sikrer at der genereres en sådan signatur. Dette er uddybet under beskrivelsen af eksempel klienten.
4
Kapitel
Java Eksempel Klient
Kapitel
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
Java eksempel klienten installeres og køres ved at
Pakke zip filen ”s2s_xbrl_eksempel_java_klient_Marts2021.zip” ud i en passende folder.
Afvikle filen run_wsdl_klient.bat (windows) eller run_wsdl_klient.sh (MacOS/Linux).
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)
4.2. Generering af Webservice stub og klasser
Først oprettes et nyt Java projekt i Eclipse. Vælg derefter projektet, højreklik og vælg ”New → Other ...” for at vælge den rigtige wizard.
Vælg ”Web Service Client” og tryk ”Next >”

Dette vil bringe en dialog hvori webservicen skal vælges

Vælg ”Browse...” og i den fremkomne dialog, indtast placeringen af webservicens WSDL.

Vælg ”Ok” for at komme tilbage til den forrige dialog, nu med webservicen valgt:
Træk i ”slideren” så man blot opretter klienten (Develop Client) og klik ”Finish”. Dette vil generere stubs og hjælpeklasser til at kalde webservicen.

Følgende klasser vil blive genereret:

4.3. Wsimport til generering af Webservice stub og klasser
Java har også et værktøj (wsimport), som følger med i JDK’et, til generering af klasser ud fra et WSDL dokument.
Følgende kommando genererer klasser og interfaces, ud fra dev miljøets WSDL :
- wsimport -keep -p webservice_xbrl.registerXbrlEkstern -s src/main/java https://erstdev.virk.dk/ri/s2s/RegisterXbrlEksternWS?wsdl -verbosewsimport -keep -p webservice_xbrl.registerXbrlEkstern -s src/main/java https://erstdev.virk.dk/ri/s2s/RegisterXbrlEksternWS?wsdl -verbose
Nedenstående kodeeksempler benytter dog de klasser, som blev genereret af Eclipse.
4.4. Kald af webservice – RegisterXBRLInvoker
Klassen eksempel.soap.RegisterXBRLInvoker foretager kaldet til webservicen, ved hjælp af de genererede klasser.
Følgende detaljer kan fremhæves:
- Denne klasse modtager et argument der angiver om webservicen skal kaldes via http eller https.
Dette påvirker justeringen af endpoint til at anvende hhv. http eller https.
Ved hjælp af de generede klasser opbygges argument strukturen til kaldet af webservicen samt modtages resultatet af kaldet til webservicen.
4.5. Brugergrænseflade
Klassen eksempel.soap.RegisterXBRLFront indeholder en simpel brugergrænseflade der prompter brugeren for de nødvendige data.
4.5.1 XBRL
Samler data sammen, signerer XBRL’en med det valgte certifikat, og kalder metoden registerXBRL i eksempel.soap.RegisterXBRLInvoker.

4.6. Generering af Signeret XML dokument
Java implementeringen anvender funktionaliteten fra OpenOCES – OpenSign til at generere det Digitalt Signerede XML dokument i OpenOCES formatet.
De nødvendige klasser findes ikke som en selvstændig jar fil der kan downloades, men findes i stedet som en del af de plugin klasser der er tiltænkt anvendelse ved brug af OpenSign appletten.
For at lette pakningen af Java eksempel klienten, er de nødvendige klasser samlet og pakket sammen i en openoces-1.8.0.jar fil.
Procedureren i signatur genereringen er følgende:
- Opret en Pkcs12CertificateHandler på baggrund af den valgte PKCS#12 fil samt det tilhørende password
- Modificer CallBackHandleren på den oprettede Pkcs12CertificateHandler – dette er nødvendigt, da den normale CallBackHandler er lavet til at få password’et via en bruger interaktion – hvilket ikke sker her.
- Generer det signerede XML dokument via metoden SignatureGenerator.sign – denne metode returnerer en Enveloping signatur, dvs. at det signerede dokument er indeholdt i signaturen.
- XML prologen fjernes og den resterende XML Signatur er nu klar til at blive brugt som argument til webservicen.
5
Kapitel
Statusbeskeder fra webservicen
Kapitel
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 | Årsrapportens PDF overstiger den maksimale størrelse på 20 Mb |
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 |
44 | Der kan kun anvendes medarbejder- eller virksomhedscertifikat ved indberetning til SKAT |
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 |
57 | XBRL dokumentet til SKAT skal være en Selskabsselvangivelse |
58 | Mangler registerXbrlEkstern i SOAP |
59 | PDF dokumentet mangler |
60 | PDF dokumentet overholder ikke størrelsesbegræsningen 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. |
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 |
98 | Systemet er optaget - prøv venligst senere |
99 | Der er opstået en fejl - kontakt venligst Erhvervs- og Selskabsstyrelsen |
6
Kapitel
Appendix A: Advis håndtering i Erhvervsstyrelsens System-til-system service
Kapitel
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.
Både SOAP webserviceløsningen og REST webserviceløsningen understøtter brugen af token.
6.1. Skal eksisterende SOAP webserviceløsninger lave deres kode om til at bruge en ny service?
Nej, Erhvervsstyrelsen har haft som mål at bevare den eksisterende service, derfor er der kun tale om et ekstra valgfrit felt i det der sendes frem og tilbage. Indtil en indberetninger får en advis, vil der ikke kunne mærkes forskel.
6.2. En ny opdateret WSDL
Til formålet er der tilføjet en linje i WSDL’en; i henholdsvist registerXbrlEkstern og registerXbrlEksternResponse og begge ser sådan her ud:
<xs:element minOccurs="0" name="token" type="xs:string" />
Det nye element er et token; en streng som løsningen sender til dig og som du kan sende tilbage. Men den behøver ikke at være der.
6.3. Kodeeksempel
Det efterfølgende kodeeksempel tager udgangspunkt i den eksisterende eksempel-klient til Java, hvor vi har brugt wsdl2java til at lave en java-klasse ud af vores WSDL. Derfra kan man finde sit token hvis der er blevet sendt et med tilbage:
RegisterXbrlEksternWS stub = stubLocator.getRegisterXbrlEksternWSPort(); WsReturnRegister returnStatus; returnStatus = stub.registerXbrlEkstern(registerXbrlInput.getSignedXbrl(), registerXbrlInput.getPdf(), String result = invocationTime+ "Code: "+returnStatus.getStatusCode()+ "\nText: "+returnStatus.getStatusText()+ "\nDetail:\n"+returnStatus.getStatusDetail() + skatKvitMsg + "\nToken: " + returnStatus.getToken() + "\nSagsnummer: " + returnStatus.getUniqueReportIdentifier();
Tilsvarende hvis man vil acceptere sin advis, så skal token bare tilføjes til det indsendte:
// Saml input RegisterXBRLInput input = new RegisterXBRLInput(); input.setSendDst(dstBox.isSelected() ? "Y" : "N"); input.setSendEogS(eogsBox.isSelected() ? "Y" : "N"); input.setSendSkat(skatBox.isSelected() ? "Y" : "N"); input.setPdf(pdf); input.setSignedXbrl(xmlDSigSender); input.setToken(token.getText());
7
Kapitel
Appendix B: Omgørelse og berigtigelse
Kapitel
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.