This commit is contained in:
2026-03-19 16:28:37 -05:00
parent 5a7ba66c27
commit 229e658831
9 changed files with 687 additions and 46 deletions

View File

@@ -14,14 +14,33 @@ const transporter = nodemailer.createTransport({
}
});
function generateInvoiceEmailHtml(invoice, customText, melioLink) {
function generateInvoiceEmailHtml(invoice, customText, stripePaymentUrl) {
const formattedText = customText || '';
const buttonMjml = melioLink
? `<mj-button background-color="#2563eb" color="white" border-radius="6px" href="${melioLink}" font-weight="600" font-size="16px" padding-top="25px">
Pay Now (Free ACH)
</mj-button>`
: '';
// Stripe Pay Button — only if payment link exists
let paymentButtonMjml = '';
if (stripePaymentUrl) {
paymentButtonMjml = `
<mj-section background-color="#ffffff" padding="0 30px">
<mj-column>
<mj-button
background-color="#635bff"
color="white"
border-radius="6px"
href="${stripePaymentUrl}"
font-weight="600"
font-size="16px"
padding="25px 0 10px 0"
inner-padding="14px 30px"
width="100%">
Pay Online — Credit Card or ACH
</mj-button>
<mj-text font-size="12px" color="#94a3b8" align="center" padding="0 0 20px 0">
ACH payments incur lower processing fees. Secure payment powered by Stripe.
</mj-text>
</mj-column>
</mj-section>`;
}
const template = `
<mjml>
@@ -62,10 +81,14 @@ function generateInvoiceEmailHtml(invoice, customText, melioLink) {
<mj-text css-class="email-body" font-size="15px" color="#334155" line-height="1.5" padding="0">
${formattedText}
</mj-text>
${buttonMjml}
</mj-column>
</mj-section>
<mj-divider border-color="#e2e8f0" border-width="1px" padding-top="30px" padding-bottom="20px" />
${paymentButtonMjml}
<mj-section background-color="#ffffff" padding="0 30px 30px 30px" border-radius="0 0 8px 8px">
<mj-column>
<mj-divider border-color="#e2e8f0" border-width="1px" padding-top="10px" padding-bottom="20px" />
<mj-text font-size="14px" color="#64748b" line-height="1.5" padding="0">
<strong>Prefer to pay by check?</strong><br/>
@@ -79,7 +102,6 @@ function generateInvoiceEmailHtml(invoice, customText, melioLink) {
</mjml>
`;
// validationLevel: 'strict' fängt falsche Attribute ab, bevor sie an den Kunden gehen
const result = mjml2html(template, { validationLevel: 'strict' });
if (result.errors && result.errors.length > 0) {
@@ -89,8 +111,8 @@ function generateInvoiceEmailHtml(invoice, customText, melioLink) {
return result.html;
}
async function sendInvoiceEmail(invoice, recipientEmail, customText, melioLink, pdfBuffer) {
const htmlContent = generateInvoiceEmailHtml(invoice, customText, melioLink);
async function sendInvoiceEmail(invoice, recipientEmail, customText, stripePaymentUrl, pdfBuffer) {
const htmlContent = generateInvoiceEmailHtml(invoice, customText, stripePaymentUrl);
const mailOptions = {
from: '"Bay Area Affiliates Inc. Accounting" <accounting@bayarea-cc.com>',