Download Stripe invoices from the Dashboard by going to Billing → Invoices, clicking an invoice, and clicking the PDF download button. For bulk or automated downloads, use the Stripe API to retrieve the invoice_pdf URL on each invoice object. You can also build a script to download all invoices for a customer or date range programmatically using Node.js.
| Fact | Value |
|---|---|
| Tool | Stripe |
| Difficulty | Beginner |
| Time required | 15 minutes |
| Compatibility | Stripe API v2024-12+, Node.js 18+ |
| Last updated | March 2026 |
How to Access and Download Stripe Invoices
Stripe automatically generates invoices for subscription payments and one-time invoice charges. Each invoice has a hosted URL (viewable in browser) and a PDF URL (downloadable). You can access these through the Dashboard for one-off downloads, or use the API to automate bulk downloads for accounting, tax filing, or customer self-service portals.
Prerequisites
- A Stripe account with at least one finalized invoice
- Node.js 18+ for API-based downloads
- The Stripe npm package installed
Step-by-step guide
Download from the Stripe Dashboard
Go to Stripe Dashboard → Billing → Invoices. Find the invoice you want and click on it. In the invoice detail view, click the download icon or 'Download PDF' button in the top-right area. You can also click 'View invoice' to see the hosted version in your browser.
Expected result: A PDF file is downloaded to your computer containing the full invoice details.
Get the invoice PDF URL via API
Each Stripe invoice object has an invoice_pdf field containing a direct URL to the PDF. Retrieve the invoice and access this URL to download programmatically.
1const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);23const invoice = await stripe.invoices.retrieve('in_abc123');45console.log('PDF URL:', invoice.invoice_pdf);6console.log('Hosted URL:', invoice.hosted_invoice_url);7// PDF URL is a direct download link — valid without authenticationExpected result: You have the direct PDF download URL and the hosted browser-viewable URL for the invoice.
List all invoices for a customer
Use the API to retrieve all invoices for a specific customer. Filter by status and date range to find exactly what you need.
1const invoices = await stripe.invoices.list({2 customer: 'cus_abc123',3 status: 'paid',4 limit: 100,5});67invoices.data.forEach(inv => {8 console.log(`${inv.number} | ${inv.amount_paid / 100} ${inv.currency.toUpperCase()} | ${inv.invoice_pdf}`);9});Expected result: A list of all paid invoices for the customer with their PDF download URLs.
Build a bulk download script
Download all invoices for a customer (or all customers) as PDF files to a local directory. This is useful for year-end accounting or tax preparation.
1const fs = require('fs');2const https = require('https');3const path = require('path');45async function downloadInvoicePDF(url, filename) {6 return new Promise((resolve, reject) => {7 const file = fs.createWriteStream(filename);8 https.get(url, (response) => {9 response.pipe(file);10 file.on('finish', () => { file.close(); resolve(); });11 }).on('error', reject);12 });13}1415async function downloadAllInvoices(customerId, outputDir) {16 fs.mkdirSync(outputDir, { recursive: true });1718 let hasMore = true;19 let startingAfter = undefined;2021 while (hasMore) {22 const params = { customer: customerId, status: 'paid', limit: 100 };23 if (startingAfter) params.starting_after = startingAfter;2425 const invoices = await stripe.invoices.list(params);2627 for (const inv of invoices.data) {28 if (inv.invoice_pdf) {29 const filename = path.join(outputDir, `${inv.number || inv.id}.pdf`);30 await downloadInvoicePDF(inv.invoice_pdf, filename);31 console.log(`Downloaded: ${filename}`);32 }33 }3435 hasMore = invoices.has_more;36 if (invoices.data.length > 0) {37 startingAfter = invoices.data[invoices.data.length - 1].id;38 }39 }40}Expected result: All paid invoices for the customer are downloaded as PDF files to the specified directory.
Complete working example
1require('dotenv').config();2const fs = require('fs');3const https = require('https');4const path = require('path');5const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);67function downloadFile(url, filepath) {8 return new Promise((resolve, reject) => {9 const file = fs.createWriteStream(filepath);10 https.get(url, (res) => {11 if (res.statusCode === 302 || res.statusCode === 301) {12 // Follow redirect13 https.get(res.headers.location, (redirectRes) => {14 redirectRes.pipe(file);15 file.on('finish', () => { file.close(resolve); });16 }).on('error', reject);17 } else {18 res.pipe(file);19 file.on('finish', () => { file.close(resolve); });20 }21 }).on('error', reject);22 });23}2425async function downloadCustomerInvoices(customerId, outputDir = './invoices') {26 fs.mkdirSync(outputDir, { recursive: true });2728 let downloaded = 0;29 let hasMore = true;30 let startingAfter;3132 while (hasMore) {33 const params = { customer: customerId, status: 'paid', limit: 100 };34 if (startingAfter) params.starting_after = startingAfter;3536 const invoices = await stripe.invoices.list(params);3738 for (const inv of invoices.data) {39 if (!inv.invoice_pdf) continue;40 const name = `${inv.number || inv.id}.pdf`;41 const filepath = path.join(outputDir, name);42 await downloadFile(inv.invoice_pdf, filepath);43 downloaded++;44 console.log(`[${downloaded}] ${name}`);45 }4647 hasMore = invoices.has_more;48 if (invoices.data.length) {49 startingAfter = invoices.data[invoices.data.length - 1].id;50 }51 }5253 console.log(`\nDone. Downloaded ${downloaded} invoices to ${outputDir}`);54}5556// Usage: pass customer ID as argument57const customerId = process.argv[2];58if (!customerId) {59 console.error('Usage: node download-invoices.js cus_xxx');60 process.exit(1);61}6263downloadCustomerInvoices(customerId).catch(console.error);Common mistakes when downloading invoices from Stripe
Why it's a problem: Trying to download invoice PDFs for draft invoices
How to avoid: Only finalized invoices (status: 'paid', 'open', or 'void') have PDF URLs. Draft invoices don't have invoice_pdf set.
Why it's a problem: Storing invoice PDF URLs permanently
How to avoid: Invoice PDF URLs are temporary. Always retrieve a fresh URL from the API when you need to download. Don't cache URLs for long-term use.
Why it's a problem: Not handling pagination when listing invoices
How to avoid: The API returns a maximum of 100 invoices per request. Use has_more and starting_after to paginate through all results.
Why it's a problem: Not following redirects when downloading PDFs
How to avoid: Stripe PDF URLs may redirect. Your download function should follow 301/302 redirects to reach the actual PDF file.
Best practices
- Use the Stripe Dashboard for quick one-off invoice downloads
- Use the API and invoice_pdf URL for automated or bulk downloads
- Always paginate when listing invoices — don't assume all results fit in one request
- Handle HTTP redirects in your download function
- Create a customer self-service portal using hosted_invoice_url for browser-viewable invoices
- Filter by status and date range to download only the invoices you need
- Store downloaded PDFs with the invoice number as filename for easy identification
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
Write a Node.js script that downloads all paid invoices for a Stripe customer as PDF files. Use the Stripe API to list invoices with pagination, get the invoice_pdf URL from each, and download them to a local directory. Handle redirects and use the invoice number as the filename.
Build a Stripe invoice bulk download tool in Node.js. List all paid invoices for a customer with pagination, download each PDF via the invoice_pdf URL, handle HTTP redirects, and save files with invoice numbers as filenames.
Frequently asked questions
Where do I find invoices in the Stripe Dashboard?
Go to Billing → Invoices. You can filter by status (paid, open, draft, void) and search by customer name or invoice number.
Can customers download their own invoices?
Yes. Share the hosted_invoice_url with customers — it opens the invoice in a browser where they can view and download it. You can also build a customer portal using these URLs.
Are invoice PDF URLs permanent?
No. Invoice PDF URLs are temporary. Always retrieve a fresh URL from the API when you need to download. Don't store or cache URLs for long-term use.
Can I download invoices for all customers at once?
Yes. Use stripe.invoices.list() without a customer filter and paginate through all results. This works for year-end bulk downloads or accounting exports.
Do draft invoices have PDF URLs?
No. Only finalized invoices have invoice_pdf URLs. You must finalize a draft invoice (stripe.invoices.finalizeInvoice) before a PDF is generated.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation