From a4a79f3eb2423c45a513910c1e9a9c823b8b36bf Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Fri, 20 Mar 2026 13:58:52 -0500 Subject: [PATCH] pdf includes payment link --- src/routes/invoices.js | 30 +++++++++++++++++++++++++++--- templates/invoice-template.html | 1 + 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/routes/invoices.js b/src/routes/invoices.js index e490856..dc1896a 100644 --- a/src/routes/invoices.js +++ b/src/routes/invoices.js @@ -24,7 +24,28 @@ function calculateNextRecurringDate(invoiceDate, interval) { } return d.toISOString().split('T')[0]; } +/** + * Build HTML block for Stripe Payment Link on PDF invoice. + * Returns empty string if no link or invoice is already paid. + */ +function buildPaymentLinkHtml(invoice) { + if (!invoice.stripe_payment_link_url) return ''; + if (invoice.paid_date || invoice.stripe_payment_status === 'paid') return ''; + return ` +
+

+ Pay Online — Credit Card or ACH +

+ + ${invoice.stripe_payment_link_url} + +

+ Secure payment powered by Stripe. ACH payments incur lower processing fees. +

+
`; +} // GET all invoices router.get('/', async (req, res) => { try { @@ -745,7 +766,8 @@ router.get('/:id/pdf', async (req, res) => { .replace('{{INVOICE_DATE}}', formatDate(invoice.invoice_date)) .replace('{{TERMS}}', invoice.terms) .replace('{{AUTHORIZATION}}', authHTML) - .replace('{{ITEMS}}', itemsHTML); + .replace('{{ITEMS}}', itemsHTML) + .replace('{{PAYMENT_LINK}}', buildPaymentLinkHtml(invoice)); const pdf = await generatePdfFromHtml(html); @@ -808,7 +830,8 @@ router.get('/:id/html', async (req, res) => { .replace('{{INVOICE_DATE}}', formatDate(invoice.invoice_date)) .replace('{{TERMS}}', invoice.terms) .replace('{{AUTHORIZATION}}', authHTML) - .replace('{{ITEMS}}', itemsHTML); + .replace('{{ITEMS}}', itemsHTML) + .replace('{{PAYMENT_LINK}}', buildPaymentLinkHtml(invoice)); res.setHeader('Content-Type', 'text/html'); res.send(html); @@ -862,7 +885,8 @@ router.post('/:id/send-email', async (req, res) => { .replace('{{INVOICE_DATE}}', formatDate(invoice.invoice_date)) .replace('{{TERMS}}', invoice.terms) .replace('{{AUTHORIZATION}}', authHTML) - .replace('{{ITEMS}}', itemsHTML); + .replace('{{ITEMS}}', itemsHTML) + .replace('{{PAYMENT_LINK}}', buildPaymentLinkHtml(invoice)); const pdfBuffer = await generatePdfFromHtml(html); diff --git a/templates/invoice-template.html b/templates/invoice-template.html index d81e2c2..7cda1d1 100644 --- a/templates/invoice-template.html +++ b/templates/invoice-template.html @@ -282,6 +282,7 @@ {{ITEMS}} + {{PAYMENT_LINK}} \ No newline at end of file