Student Loan Refinancing Calculator

Step 1: Your Current Student Loan Details

Enter the combined details if you are considering refinancing multiple loans.

Step 2: Proposed New Refinanced Loan Details

Include any origination fees or other one-time costs for refinancing.

Step 3: Refinancing Comparison & Savings Summary

New Refinanced Loan Amortization Schedule

Month Payment Principal Interest Balance

Est. Total Future Payments: ${slrc_formatCurrency(totalFuturePaymentsCurrent)}

New Refinanced Loan

New Monthly Payment: ${slrc_formatCurrency(newMonthlyPayment)}

New Loan Term: ${newTermYears * 12} months (${newTermYears} years)

Total Interest Paid: ${slrc_formatCurrency(totalInterestNew)}

Upfront Refinancing Fees: ${slrc_formatCurrency(refiFees)}

Total Cost (Interest + Fees): ${slrc_formatCurrency(totalCostNewLoan)}

Refinancing Impact

Change in Monthly Payment: ${monthlyPaymentDifference > 0 ? `Save ${slrc_formatCurrency(monthlyPaymentDifference)}` : (monthlyPaymentDifference < 0 ? `Increase by ${slrc_formatCurrency(Math.abs(monthlyPaymentDifference))}` : 'No Change')} / month

Potential Lifetime Savings: ${lifetimeSavings > 0 ? `Save ${slrc_formatCurrency(lifetimeSavings)}` : (lifetimeSavings < 0 ? `Cost ${slrc_formatCurrency(Math.abs(lifetimeSavings))} more` : 'No Overall Savings')}

Breakeven Point for Fees: ${typeof breakevenMonths === 'number' ? `${breakevenMonths} months` : breakevenMonths}

`; // Populate New Loan Amortization Table const amortTableBody = document.querySelector('#slrc-new-loan-amortization-table tbody'); amortTableBody.innerHTML = ''; slrc_comparisonDataForPdf.newLoanAmortization.forEach(row => { const tr = amortTableBody.insertRow(); tr.insertCell().textContent = row.month; tr.insertCell().textContent = slrc_formatCurrency(row.payment); tr.insertCell().textContent = slrc_formatCurrency(row.principal); tr.insertCell().textContent = slrc_formatCurrency(row.interest); tr.insertCell().textContent = slrc_formatCurrency(row.balance); }); slrc_navigateToTab(2); // Go to results tab } function slrc_generatePDF() { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('PDF generation library (jsPDF) is not loaded.'); return; } const JSPDF_CONSTRUCTOR = window.jspdf.jsPDF; const tempDoc = new JSPDF_CONSTRUCTOR(); if (typeof tempDoc.autoTable !== 'function') { alert('jsPDF AutoTable plugin is not loaded.'); return; } if (Object.keys(slrc_comparisonDataForPdf).length === 0) { alert('Please compare loans first to generate a PDF.'); return; } const doc = new JSPDF_CONSTRUCTOR({ orientation: 'p' }); const data = slrc_comparisonDataForPdf; let yPos = 15; const pageMargin = 15; const pageWidth = doc.internal.pageSize.getWidth(); const usableWidth = pageWidth - (2 * pageMargin); const primaryColor = [74, 144, 226]; // #4a90e2 const headingColor = [59, 124, 184]; // #3b7cb8 const textColor = [44, 62, 80]; // #2c3e50 const savingsGreen = [92, 184, 92]; // #5cb85c const costRed = [217, 83, 79]; // #d9534f function addMainHeader(text) { doc.setFontSize(16); doc.setTextColor(headingColor[0], headingColor[1], headingColor[2]); doc.text(text, pageWidth / 2, yPos, { align: 'center' }); yPos += 12; } function addSectionHeader(text) { if (yPos > doc.internal.pageSize.getHeight() - 30) { doc.addPage(); yPos = pageMargin; } doc.setFontSize(12); doc.setFont(undefined, 'bold'); doc.setTextColor(primaryColor[0], primaryColor[1], primaryColor[2]); doc.text(text, pageMargin, yPos); yPos += 8; doc.setFont(undefined, 'normal'); } function addWarning(textLines) { if (yPos > doc.internal.pageSize.getHeight() - (textLines.length * 5) - 15) { doc.addPage(); yPos = pageMargin; } doc.setFontSize(9); doc.setTextColor(costRed[0], costRed[1], costRed[2]); // Red for warning doc.setFillColor(252,248,227); // Light yellow background #fcf8e3 const textHeight = (textLines.length * 4) + (textLines.length > 1 ? (textLines.length-1)*1.5 : 0) + 8; // Approximate height doc.rect(pageMargin - 2, yPos - 3, usableWidth + 4, textHeight, 'F'); doc.text("Important: Refinancing Federal Loans", pageMargin, yPos); yPos +=5; textLines.forEach(line => { doc.text("• " + line, pageMargin + 3, yPos); yPos += 4.5; }); yPos += 5; // Spacing after warning doc.setTextColor(textColor[0], textColor[1], textColor[2]); // Reset color } addMainHeader("Student Loan Refinancing Comparison"); // Federal Loan Warning if applicable if (data.currentLoanType === 'federal' || data.currentLoanType === 'mix') { const warningLines = [ "Refinancing federal loans into a private loan means permanent loss of federal benefits:", " - Income-Driven Repayment (IDR) plans (SAVE, PAYE, etc.)", " - Public Service Loan Forgiveness (PSLF) & other federal forgiveness.", " - Federal deferment and forbearance options.", " - Potential future federal relief measures." , "Carefully consider if savings outweigh losing these protections." ]; addWarning(warningLines); } // Inputs Summary addSectionHeader("Your Inputs:"); const inputsForPdf = [ ["Total Current Loan Balance:", slrc_formatCurrency(data.currentBalance)], ["Current Avg. Interest Rate:", `${data.currentAnnualRate.toFixed(2)}%`], ["Current Total Monthly Payment:", slrc_formatCurrency(data.currentMonthlyPayment)], ["Type of Current Loans:", data.currentLoanType.charAt(0).toUpperCase() + data.currentLoanType.slice(1)], ["New Refinanced Interest Rate:", `${data.newAnnualRate.toFixed(2)}%`], ["New Refinanced Loan Term:", `${data.newTermYears} years`], ["Upfront Refinancing Fees:", slrc_formatCurrency(data.refiFees)], ]; doc.autoTable({ startY: yPos, body: inputsForPdf, theme: 'grid', styles: { fontSize: 9, cellPadding: 2 }, headStyles: {fillColor: primaryColor}, // Not using head explicitly here columnStyles: { 0: { fontStyle: 'bold' } }, didDrawPage: function (hookData){ yPos = hookData.cursor.y ? hookData.cursor.y +10 : pageMargin; } }); yPos = doc.lastAutoTable.finalY ? doc.lastAutoTable.finalY + 10 : yPos; // Comparison Summary if (yPos > doc.internal.pageSize.getHeight() - 80) { doc.addPage(); yPos = pageMargin; } addSectionHeader("Refinancing Comparison Summary:"); const comparisonForPdf = [ ["Metric", "Current Loan (Estimate)", "New Refinanced Loan"], ["Monthly Payment", slrc_formatCurrency(data.currentMonthlyPayment), slrc_formatCurrency(data.newMonthlyPayment)], ["Remaining Term", `${data.remainingPaymentsCurrent} months (~${data.remainingTermYearsCurrent.toFixed(1)} yrs)`, `${data.newTermYears * 12} months (${data.newTermYears} yrs)`], ["Total Future Interest Paid", slrc_formatCurrency(data.totalFutureInterestCurrent), slrc_formatCurrency(data.totalInterestNew)], ["Total Future Payments", slrc_formatCurrency(data.currentMonthlyPayment * data.remainingPaymentsCurrent), slrc_formatCurrency(data.newMonthlyPayment * data.newTermYears * 12)], ["Upfront Fees", "N/A", slrc_formatCurrency(data.refiFees)], ["Total Cost (Future Interest + Fees)", slrc_formatCurrency(data.totalFutureInterestCurrent), slrc_formatCurrency(data.totalCostNewLoan)], ]; doc.autoTable({ startY: yPos, head: [comparisonForPdf[0]], // Use first row as head body: comparisonForPdf.slice(1), theme: 'striped', headStyles: { fillColor: primaryColor, textColor: [255,255,255], fontStyle: 'bold' }, styles: { fontSize: 8, cellPadding: 2 }, didDrawPage: function (hookData){ yPos = hookData.cursor.y ? hookData.cursor.y +10 : pageMargin; } }); yPos = doc.lastAutoTable.finalY ? doc.lastAutoTable.finalY + 10 : yPos; // Savings Details if (yPos > doc.internal.pageSize.getHeight() - 40) { doc.addPage(); yPos = pageMargin; } addSectionHeader("Overall Impact:"); let mpdText = data.monthlyPaymentDifference > 0 ? `Save ${slrc_formatCurrency(data.monthlyPaymentDifference)} / month` : data.monthlyPaymentDifference < 0 ? `Increase by ${slrc_formatCurrency(Math.abs(data.monthlyPaymentDifference))} / month` : 'No Change / month'; let lsText = data.lifetimeSavings > 0 ? `Save ${slrc_formatCurrency(data.lifetimeSavings)}` : data.lifetimeSavings < 0 ? `Cost ${slrc_formatCurrency(Math.abs(data.lifetimeSavings))} more` : 'No Overall Savings/Cost Change'; const impactData = [ ["Change in Monthly Payment:", mpdText], ["Potential Lifetime Savings:", lsText], ["Breakeven Point for Fees:", typeof data.breakevenMonths === 'number' ? `${data.breakevenMonths} months` : data.breakevenMonths] ]; doc.autoTable({ startY: yPos, body: impactData, theme: 'plain', styles: { fontSize: 9, cellPadding: 2 }, columnStyles: { 0: { fontStyle: 'bold'} }, didParseCell: function(hookData){ if(hookData.row.index === 0) hookData.cell.styles.textColor = data.monthlyPaymentDifference > 0 ? savingsGreen : (data.monthlyPaymentDifference < 0 ? costRed : textColor); if(hookData.row.index === 1) hookData.cell.styles.textColor = data.lifetimeSavings > 0 ? savingsGreen : (data.lifetimeSavings < 0 ? costRed : textColor); }, didDrawPage: function (hookData){ yPos = hookData.cursor.y ? hookData.cursor.y +10 : pageMargin; } }); yPos = doc.lastAutoTable.finalY ? doc.lastAutoTable.finalY + 10 : yPos; // New Loan Amortization Schedule (if space allows or new page) if (data.newLoanAmortization && data.newLoanAmortization.length > 0) { if (yPos > doc.internal.pageSize.getHeight() - 50) { doc.addPage(); yPos = pageMargin; } // Check space addSectionHeader("New Refinanced Loan Amortization Schedule:"); const amortBody = data.newLoanAmortization.map(row => [ row.month, slrc_formatCurrency(row.payment), slrc_formatCurrency(row.principal), slrc_formatCurrency(row.interest), slrc_formatCurrency(row.balance) ]); doc.autoTable({ startY: yPos, head: [['Month', 'Payment', 'Principal', 'Interest', 'Balance']], body: amortBody, theme: 'striped', headStyles: { fillColor: primaryColor, textColor: [255,255,255] }, styles: { fontSize: 7, cellPadding: 1.5, halign: 'right' }, columnStyles: { 0: { halign: 'center' } }, didDrawPage: function (hookData){ yPos = hookData.cursor.y ? hookData.cursor.y +10 : pageMargin; } }); } doc.save("Student_Loan_Refinancing_Comparison.pdf"); }
Scroll to Top