Script esemplificativo – Firma e Invio Fattura con SPID:
import lxml.etree as ET
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
import requests
import json
import time
# Configurazioni SPID (simulato con certificato auto-firmato per esempio)
cert_path = "/certs/spid_cert.pem"
key_path = "/certs/spid_key.pem"
gateway_url = "https://api.agenziafattura.it/validazione"
def fetch_public_key():
resp = requests.get("https://public-keys.agenziafattura.it", timeout=10)
pub_key = ET.parse(resp.content).getroot()
return pub_key
def sign_factura(xml_data, cert_path, key_path):
with open(cert_path, "rb") as f: cert = ET.parse(f).getroot()
with open(key_path, "rb") as f: priv_key = ET.parse(f).getroot()
xml = ET.fromstring(xml_data)
signer = priv_key.verify(
xml.data,
data_len=len(xml.data),
signature=xml.find("_Signature"),
padding=padding.PKCS1v15(),
hash_func=hashes.SHA256()
)
return signer.sign()
def invia_convalida(fattura_xml, firma):
headers = {"Content-Type": "application/xml", "Authorization": "Bearer SPID"}
payload = {
"fiscale": "IT12345678901",
"importo": "15000.00",
"dataFattura": "2024-06-15",
"soggettoPassivo": "MANUFATTURA SETTIMA SRL",
"fatturaId": "FACT-20240615-001",
"firmaDigitale": firma
}
resp = requests.post(gateway_url, headers=headers, data=fattura_xml, timeout=15)
return resp.json()
# Carica pubblica e firma
pub_key = fetch_public_key()
xml_data = """IT1234567890115000.002024-06-15MANUFATTURA SETTIMA SRLFACT-20240615-0012024-06"""
signature = sign_factura(xml_data, cert_path, key_path)
convalida = invia_convalida(xml_data, signature)
print(f"Risposta validazione: {json.dumps(convalida, indent=2)}")