Preamble: Everything that follows is to be taken with some distance (both technical and human), and all comments are my personal opinion. This is just my experience as a developer.
This text was originally written in French (in next post), then translated into English. Sorry if there are any odd turns of phrase.
As I’m a new member I can’t add more than 4 links in my message so I’ve had to enter them without it being a real link, sorry. I’ll edit my message once I can.
Hello everyone,
I’ve just finished integrating Ricezione in very basic mode (only “WSR01” the first item in the test plan, i.e. receive an invoice or batch, and answer OK = ER01) for a French company, and I’m posting this information in English/French to help as many people as possible in my case, as I had to consult and translate many, many resources to do so, since the English documentation is incomplete and poorly translated, the test system complex and obscure, and pretty much the only useful exchanges are here, in Italian - quite logical since it’s your official language, and thanks to all of you for posting all this and exchanging in public!
So our integration concerns a company under French law (with a French VAT number) and our server/webapp uses the technologies mentioned in the title, but I think 95% of what I’m presenting is adaptable and will be useful to everyone.
STEP 0 - Acquire a PEC address
This is essential for accreditation.
Not all PEC providers accept French companies, there are several possibilities, but we have chosen Intesi Group: www.intesigroup. com/en/pec/
STEP 1 - “Richiesta di accreditamento canale” channel accreditation request
The FAQ in English: www.fatturapa.gov.it/en/faq/faq-accreditamento-canale/
The form: www.fatturapa.gov.it/en/servizionline/accreditare-il-canale/
Here we will choose only “SDICoop - Reception Service”.
Fill in the information, bearing in mind that for the “Riferimento Accordo” / “Contact for the service agreement” tax code you need to enter the company’s VAT number again, since you don’t have an Italian personal tax code.
Then put in bogus endpoints like sdi.votredomaine. fr/sdi_reception. There’s no instant test, and you can change them later.
For CSR and certificates (for a french company with a SIREN) :
- Generate a private key
openssl genrsa -out sdi-{{SIREN}}-client.key 2048
- Generate CSR
openssl req -new -key sdi-{{SIREN}}-client.key -out sdi-{{SIREN}}-client.csr
- Enter
Country Name : FR
State or Province Name : {{postal code}}
Locality Name : {{city}}
Organization Name : {{legal company name entered on 1st page}}
Common Name : SDI-{{SIREN}}
openssl genrsa -out sdi-{{SIREN}}-server.key 2048
openssl req -new -key sdi-{{SIREN}}-server.key -out sdi-{{SIREN}}-server.csr
Keep all these files in a safe place…
At the end, you’ll get a “RichiestaAccreditamento.zip” file, which you should also keep.
STEP 2 - Sign the zip
This step was imho totally uncalled-for, but you’re going to have to buy a QES eIDAS certificate from a company recognized by ADIG (spoiler it’s only Italian companies, the list is here www.agid. gov.it/it/piattaforme/firma-elettronica-qualificata/prestatori-di-servizi-fiduciari-attivi-in-italia) even though it’s a European standard and all QES eIDAS should be recognized. Anyway.
That’s all it’ll do, sign the zip at the start. Then you can throw it away…
We chose Infocert:
infocert. digital/consumer/qes/
checkout.infocert. digital/articles/SIGN-QES-EDOCID
We had the QES drawn up in the name of the company CEO, who is also the “Riferimento Accordo” / “Contact for the service agreement” and it was OK.
They have a signature system in their Gosign webapp that works pretty well, so we didn’t look any further.
You need to sign the zip in CAdES (.p7m), not detached (.p7s).
Keep the RichiestaAccreditamento.zip.p7m in a safe place, as this is what will allow you to connect to the SdI accreditation webapp !!!
STEP 3 - Send the signed zip
Connect to your PEC and send an email to the address given at the end of the accreditation form, type “sdi01@pec.fatturapa.it” (01 can be 02 03 etc), with the RichiestaAccreditamento.zip.p7m in attachment.
If everything is OK, you’ll receive an email back fairly quickly with the subject line “POSTA CERTIFICATA: [Sistema di Interscambio]: richiesta presa in carico”.
STEP 4 - Log in to Manage the channel “Gestire il canale“ / “Manage the channel“
Once you’ve received the email from sdi confirming that it’s OK, go to Fatturazione elettronica per la P.A., select the .zip.p7m and enter the captcha.
The interface is one time out of 2 in English or Italian…no way to change it manually.
Go to “Test Interoperabilità (Sdicoop)” / “Interoperability tests”, you’ll first be asked to download the “KitDiTest”, then you can access “Gestione test di Interoperabilità” / “Manage interoperability tests”.
You can also modify endpoints at any time by clicking on “Modificare Endpoint” / “Change Endpoint“.
STEP 5 - Preparing certificates
- Convert the cer server supplied to pem
openssl x509 -inform der -in SDI-{{SIREN}}-server.cer -out SDI-{{SIREN}}-server.pem
- Convert CA certs to pem
openssl x509 -keyform DER -in caentrate.cer -out caentrate.pem
openssl x509 -keyform DER -in SistemaInterscambioFatturaPA.cer -out SistemaInterscambioFatturaPA.pem
openssl x509 -keyform DER -in CAEntratetest.cer -out CAEntratetest.pem
openssl x509 -keyform DER -in SistemaInterscambioFatturaPATest.cer -out SistemaInterscambioFatturaPATest.pem
-
Create the certificate chain for nginx
Copy these 5 certificates into sdi-chain-all.pem, putting the SDI-{{SIREN}}-server.pem FIRST (very important!).
You can, of course, put only the test certs in test and prod in prod. -
Optional : Create the certificate chain to verify the client certificate from SdICoop (= authenticate it’s really the SdI sending you invoices)
Copy the last 4 certificates (not the SDI-{{SIREN}}-server.pem) into sdi-chain-trusted.pem
STEP 6 - Configuring the server
I won’t go into detail here, but you’ll need to :
-
Set up a dedicated sub-domain (to be able to configure another server directive on nginx with specific TLS certs)
-
Configure a dedicated uwsgi worker (simpler for debugging, maintenance etc.)
-
Configure nginx, that’s our conf.
!!! VERY IMPORTANT!!!
SdI doesn’t manage SNI (Server Name Indication)…So this server directive for SdI must be the 1st one in your nginx conf otherwise it won’t work…
server {
listen {{server_ip}}:80 ssl;
listen {{server_ip}}:443 ssl;
server_name sdicoop.{{domain}}.com;
proxy_connect_timeout 100s;
proxy_send_timeout 100s;
proxy_read_timeout 100s;
send_timeout 100s;
uwsgi_connect_timeout 100s;
uwsgi_send_timeout 100s;
uwsgi_read_timeout 100s;
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate {{certs_dir}}/sdi-chain-all.pem;
ssl_certificate_key {{certs_dir}}/sdi-{{SIREN}}-server.key;
###
# Either that
ssl_verify_client off;
# Or that
ssl_verify_client on;
ssl_verify_depth 5;
ssl_certificate {{certs_dir}}/sdi-chain-trusted.pem;
###
ssl_stapling off;
ssl_stapling_verify off;
...
location /sdicoop_reception {
# Useful for debugging, you can put 2 different files back in production
access_log {{logs_dir}}/nginx-sdicoop-access.log;
error_log {{logs_dir}}/nginx-sdicoop-access.log warn;
uwsgi_pass unix:/path/to/uwsgi_sdi.sock;
uwsgi_param Host $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
}
}
- Serving SOAP code
This is fairly simple for the dev stage, but you can add to it as needed: I have a Django url+view that logs and responds to ER01 in the correct SOAP format
@csrf_exempt
def sdicoop_reception(request):
logger.debug(“sdicoop_reception !”)
logger.debug(request.headers)
logger.debug(request.body)
response = “<soapenv:Envelope xmlns:soapenv=\”http://schemas.xmlsoap.org/soap/envelope/\“>”
response += “<soapenv:Body>”
response += “<ns2:fileSdIConMetadati xmlns:ns2=\”http://www.fatturapa.gov.it/sdi/ws/ricezione/v1.0/types\“>”
response += “<Esito>ER01</Esito>”
response += “</ns2:fileSdIConMetadati>”
response += “</soapenv:Body>”
response += “</soapenv:Envelope>”
return HttpResponse(response, content_type=“text/xml”)
STEP 8 - Testing TLS
- Test, you should have a line “Verify return code: 19 (self-signed certificate in certificate chain)”
openssl s_client -connect sdicoop.{{domain}}.com:443 -CAfile CAEntratetest.pem
- Prod, you should have a line “Verify return code: 0 (ok)”
openssl s_client -connect sdicoop.{{domain}}.com:443 -CAfile CAEntratetest.pem
If you don’t have these lines, there’s no point in going any further, there’s a problem in your configuration somewhere… Repeat all the points 1 by 1.
STEP 7 - Simulate shipments “Simulatore invio“ / “Simulator sending“
Once all this is available online, go to “Simulatore invio”. To start simple you can choose the 1st option of the 3 choices, then “Invia”.
You can see the progress and history on “Flussi” (flows).
Normally this should go straight through and you’ll see a green tick on Flussi and the first WSR01 “Ricezione Fattura” test validated on “Avanzamento“ (progress)!
This is the only compulsory test, so afterwards you can go to “Richiesta di passaggio in produzione” (Request passage into production).
NB: Once you’ve gone into production, you won’t be able to run tests or access this section (“Test Interoperabilità”), but you will still be able to access “Modificare Endpoint”. So if you want to validate the other 3 optional tests for B2G, or run more extensive tests with batches of invoices, Cades, etc., don’t go to prod just yet!
I’d like to take this opportunity to say that it’s a real shame not to leave the possibility of continuing to simulate sendings, which would make it possible to gradually integrate and potentially debug more easily. If ever someone from SdI reads me…
Don’t hesitate if you have any questions in English or French, I’ll try to answer them!
Good luck to you all!
JB