failed payment method handling

This commit is contained in:
jackiettran
2026-01-06 16:13:58 -05:00
parent ec84b8354e
commit 28c0b4976d
14 changed files with 1639 additions and 17 deletions

View File

@@ -51,7 +51,14 @@ class TemplateManager {
* @returns {Promise<void>}
*/
async loadEmailTemplates() {
const templatesDir = path.join(__dirname, "..", "..", "..", "templates", "emails");
const templatesDir = path.join(
__dirname,
"..",
"..",
"..",
"templates",
"emails"
);
// Critical templates that must load for the app to function
const criticalTemplates = [
@@ -95,6 +102,8 @@ class TemplateManager {
"forumItemRequestNotification.html",
"forumPostDeletionToAuthor.html",
"forumCommentDeletionToAuthor.html",
"paymentDeclinedToRenter.html",
"paymentMethodUpdatedToOwner.html",
];
const failedTemplates = [];
@@ -129,7 +138,9 @@ class TemplateManager {
if (missingCriticalTemplates.length > 0) {
const error = new Error(
`Critical email templates failed to load: ${missingCriticalTemplates.join(", ")}`
`Critical email templates failed to load: ${missingCriticalTemplates.join(
", "
)}`
);
error.missingTemplates = missingCriticalTemplates;
throw error;
@@ -138,7 +149,9 @@ class TemplateManager {
// Warn if non-critical templates failed
if (failedTemplates.length > 0) {
console.warn(
`⚠️ Non-critical templates failed to load: ${failedTemplates.join(", ")}`
`⚠️ Non-critical templates failed to load: ${failedTemplates.join(
", "
)}`
);
console.warn("These templates will use fallback versions");
}
@@ -483,6 +496,36 @@ class TemplateManager {
<p>Please review this feedback and take appropriate action if needed.</p>
`
),
paymentDeclinedToRenter: baseTemplate.replace(
"{{content}}",
`
<p>Hi {{renterFirstName}},</p>
<h2>Payment Issue with Your Rental Request</h2>
<p>The owner tried to approve your rental for <strong>{{itemName}}</strong>, but there was an issue processing your payment.</p>
<h3>What Happened</h3>
<p>{{declineReason}}</p>
<div class="info-box">
<p><strong>What You Can Do</strong></p>
<p>Please update your payment method so the owner can complete the approval of your rental request.</p>
</div>
<p>Once you update your payment method, the owner will be notified and can try to approve your rental again.</p>
`
),
paymentMethodUpdatedToOwner: baseTemplate.replace(
"{{content}}",
`
<p>Hi {{ownerFirstName}},</p>
<h2>Payment Method Updated</h2>
<p>The renter has updated their payment method for the rental of <strong>{{itemName}}</strong>.</p>
<div class="info-box">
<p><strong>Ready to Approve</strong></p>
<p>You can now try approving the rental request again. The renter's new payment method will be charged when you approve.</p>
</div>
<p style="text-align: center;"><a href="{{approvalUrl}}" class="button">Review & Approve Rental</a></p>
`
),
};
return (