const EmailClient = require("../core/EmailClient"); const TemplateManager = require("../core/TemplateManager"); /** * PaymentEmailService handles payment-related emails * This service is responsible for: * - Sending payment declined notifications to renters * - Sending payment method updated notifications to owners */ class PaymentEmailService { constructor() { this.emailClient = new EmailClient(); this.templateManager = new TemplateManager(); this.initialized = false; } /** * Initialize the payment email service * @returns {Promise} */ async initialize() { if (this.initialized) return; await Promise.all([ this.emailClient.initialize(), this.templateManager.initialize(), ]); this.initialized = true; console.log("Payment Email Service initialized successfully"); } /** * Send payment declined notification to renter * @param {string} renterEmail - Renter's email address * @param {Object} params - Email parameters * @param {string} params.renterFirstName - Renter's first name * @param {string} params.itemName - Item name * @param {string} params.declineReason - User-friendly decline reason * @param {string} params.rentalId - Rental ID * @param {string} params.updatePaymentUrl - URL to update payment method * @returns {Promise<{success: boolean, messageId?: string, error?: string}>} */ async sendPaymentDeclinedNotification(renterEmail, params) { if (!this.initialized) { await this.initialize(); } try { const { renterFirstName, itemName, declineReason, updatePaymentUrl, } = params; const variables = { renterFirstName: renterFirstName || "there", itemName: itemName || "the item", declineReason: declineReason || "Your payment could not be processed.", updatePaymentUrl: updatePaymentUrl, }; const htmlContent = await this.templateManager.renderTemplate( "paymentDeclinedToRenter", variables ); return await this.emailClient.sendEmail( renterEmail, `Action Required: Payment Issue - ${itemName || "Your Rental"}`, htmlContent ); } catch (error) { console.error("Failed to send payment declined notification:", error); return { success: false, error: error.message }; } } /** * Send payment method updated notification to owner * @param {string} ownerEmail - Owner's email address * @param {Object} params - Email parameters * @param {string} params.ownerFirstName - Owner's first name * @param {string} params.itemName - Item name * @param {string} params.rentalId - Rental ID * @param {string} params.approvalUrl - URL to approve the rental * @returns {Promise<{success: boolean, messageId?: string, error?: string}>} */ async sendPaymentMethodUpdatedNotification(ownerEmail, params) { if (!this.initialized) { await this.initialize(); } try { const { ownerFirstName, itemName, approvalUrl } = params; const variables = { ownerFirstName: ownerFirstName || "there", itemName: itemName || "the item", approvalUrl: approvalUrl, }; const htmlContent = await this.templateManager.renderTemplate( "paymentMethodUpdatedToOwner", variables ); return await this.emailClient.sendEmail( ownerEmail, `Payment Method Updated - ${itemName || "Your Item"}`, htmlContent ); } catch (error) { console.error("Failed to send payment method updated notification:", error); return { success: false, error: error.message }; } } /** * Send payout failed notification to owner * @param {string} ownerEmail - Owner's email address * @param {Object} params - Email parameters * @param {string} params.ownerName - Owner's name * @param {number} params.payoutAmount - Payout amount in dollars * @param {string} params.failureMessage - User-friendly failure message * @param {string} params.actionRequired - Action the owner needs to take * @param {string} params.failureCode - The Stripe failure code * @param {boolean} params.requiresBankUpdate - Whether bank account update is needed * @param {string} params.payoutSettingsUrl - URL to payout settings * @returns {Promise<{success: boolean, messageId?: string, error?: string}>} */ async sendPayoutFailedNotification(ownerEmail, params) { if (!this.initialized) { await this.initialize(); } try { const { ownerName, payoutAmount, failureMessage, actionRequired, failureCode, requiresBankUpdate, payoutSettingsUrl, } = params; const variables = { ownerName: ownerName || "there", payoutAmount: payoutAmount?.toFixed(2) || "0.00", failureMessage: failureMessage || "There was an issue with your payout.", actionRequired: actionRequired || "Please check your bank account details.", failureCode: failureCode || "unknown", requiresBankUpdate: requiresBankUpdate || false, payoutSettingsUrl: payoutSettingsUrl || process.env.FRONTEND_URL + "/settings/payouts", }; const htmlContent = await this.templateManager.renderTemplate( "payoutFailedToOwner", variables ); return await this.emailClient.sendEmail( ownerEmail, "Action Required: Payout Issue - Village Share", htmlContent ); } catch (error) { console.error("Failed to send payout failed notification:", error); return { success: false, error: error.message }; } } } module.exports = PaymentEmailService;