Passa al contenuto principale

Download di file

Alcuni endpoint delle API non restituiscono un oggetto JSON con i campi error, message, data e meta, ma restituiscono direttamente un file da scaricare.

È il caso, ad esempio, dei download di fatture e note di credito in formato PDF o XML.

Come riconoscere un endpoint di download

Negli endpoint di download, una risposta 200 OK restituisce direttamente il contenuto binario del file.

In pratica:

  • se la richiesta va a buon fine, il body della risposta contiene il file;
  • se invece si verifica un errore, la risposta torna nel formato JSON standard delle API.

Questo significa che il tuo client deve gestire in modo diverso i casi di successo e di errore:

  • successo: salva il file;
  • errore: leggi il JSON di risposta e gestiscilo come una normale risposta API.

Header utili nella risposta

Gli endpoint di download possono restituire alcuni header molto utili:

  • Content-Disposition: indica che il contenuto è un allegato e può includere il nome file;
  • Content-Length: indica la dimensione del file in byte;
  • Last-Modified: indica la data di ultima modifica del file;
  • Cache-Control: contiene eventuali indicazioni di cache;
  • X-Content-Type-Options: header di protezione del contenuto.

Quando possibile, è buona pratica leggere Content-Disposition per determinare il nome del file da salvare.

Content-Type da aspettarsi

Il tipo di file restituito dipende dall'endpoint:

  • per i PDF, il content type è application/pdf;
  • per i file XML, il content type può essere text/xml;
  • in alcuni casi, per documenti firmati, può essere restituito application/x-pkcs7-mime, cioè il file firmato in formato .p7m.

Download PDF

Per i documenti PDF il comportamento è diretto: l'endpoint restituisce il file PDF.

Esempi:

  • GET /api/v3/invoices/{invoice_id}/download/pdf
  • GET /api/v3/creditnotes/{creditnote_id}/download/pdf

In questi casi, se la richiesta va a buon fine, puoi salvare direttamente il body della risposta come file PDF.

Download XML e file firmati

Per i documenti XML esistono endpoint dedicati, ad esempio:

  • GET /api/v3/invoices/{invoice_id}/download
  • GET /api/v3/creditnotes/{creditnote_id}/download

Questi endpoint possono restituire:

  • il file XML;
  • oppure, se il documento è firmato, il file originale in formato .p7m.

Per questi endpoint è disponibile il parametro query string prefer_xml.

Se imposti prefer_xml=true, forzi il download della versione XML anche quando il documento firmato originale è disponibile.

Esempio

Questo esempio scarica il PDF di una fattura e lo salva su disco.

curl --request GET \
--url 'https://api.shellrent.com/api/v3/invoices/00001111/download/pdf' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--output fattura-00001111.pdf

In questo caso:

  • se la richiesta ha esito positivo, il file viene salvato come fattura-123456.pdf;
  • se la richiesta fallisce, la risposta non sarà un PDF ma un JSON di errore.

Esempio in PHP

Questo esempio mostra come scaricare un file PDF con Guzzle e salvarlo localmente.

<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

$client = new Client([
'base_uri' => 'https://api.shellrent.com',
'http_errors' => false,
]);

$response = $client->request('GET', '/api/v3/invoices/123456/download/pdf', [
'headers' => [
'Authorization' => 'Bearer YOUR_ACCESS_TOKEN',
'Accept' => 'application/pdf',
],
]);

$statusCode = $response->getStatusCode();
$contentType = $response->getHeaderLine('Content-Type');

if ($statusCode === 200 && str_contains($contentType, 'application/pdf')) {
file_put_contents(__DIR__ . '/fattura-123456.pdf', $response->getBody()->getContents());
echo "File salvato correttamente.\n";
exit;
}

$body = (string) $response->getBody();
$data = json_decode($body, true);

echo "Errore API:\n";
print_r($data);

Esempio con prefer_xml

Questo esempio richiede il download XML di una fattura, forzando la versione XML anche se il documento è disponibile in formato firmato.

curl --request GET \
--url 'https://api.shellrent.com/api/v3/invoices/00001111/download?prefer_xml=true' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--output fattura-123456.xml

Se non imposti prefer_xml=true, il server potrebbe restituire il file firmato originale invece del file XML.

Come gestire correttamente la risposta

Quando lavori con endpoint di download, ti conviene seguire sempre questo flusso:

  1. invia la richiesta autenticata;
  2. controlla lo status code;
  3. verifica il Content-Type;
  4. se la risposta è un file, salva il body;
  5. se la risposta non è un file, interpreta il body come JSON di errore.

Questo approccio evita errori comuni, ad esempio tentare di decodificare come JSON una risposta che in realtà contiene un PDF.

Buone pratiche

suggerimento

Se disponibile, usa Content-Disposition per recuperare il nome file proposto dal server invece di costruirlo manualmente.

suggerimento

Quando scarichi XML da endpoint che possono restituire anche file firmati, controlla sempre il Content-Type ricevuto prima di decidere l'estensione del file.

warning

Una risposta 200 OK su un endpoint di download non contiene il wrapper JSON standard: contiene direttamente il file.

warning

Gli errori continuano invece a usare il formato JSON standard delle API, quindi il tuo codice deve saper distinguere chiaramente i due casi.