๐Ÿ’ฐSplit Bill Calculator

Advanced split bill calculator with tip calculation, tax splitting, and receipt scanning. Split restaurant bills and group expenses fairly among friends with multiple calculation methods and detailed breakdowns.

๐Ÿค” What Is a Split Bill Calculator?

Think of a fair referee for restaurant checks - that's our Split Bill Calculator! It divides bills perfectly among friends, handles tips and taxes automatically, and ensures everyone pays their exact share. No more awkward math at the dinner table!

๐Ÿงพ Quick Bill Split

Perfect for restaurants where everyone pays equally

๐Ÿ’ณ Your split results will appear here

๐Ÿ“ Item-by-Item Split

Perfect for when different people ordered different items

๐Ÿ“ Detailed split results will appear here

๐Ÿ‘ฅ Group Expense Tracker

Track multiple expenses and see who owes what

๐Ÿ‘ฅ Group settlement results will appear here

๐Ÿ“‹ Sample Bill Scenarios

๐Ÿฝ๏ธ Restaurant Dinner
$125.50 โ€ข 4 people โ€ข 18% tip โ€ข $12.50 tax
โ˜• Coffee Shop
$32.80 โ€ข 3 people โ€ข 15% tip โ€ข $2.80 tax
๐Ÿ” Fast Food
$45.75 โ€ข 5 people โ€ข 10% tip โ€ข $4.15 tax
๐Ÿฅ‚ Fine Dining
$285.00 โ€ข 6 people โ€ข 20% tip โ€ข $25.65 tax
๐Ÿšš Food Delivery
$78.90 โ€ข 3 people โ€ข 18% tip โ€ข $7.12 tax
๐Ÿป Bar Tab
$156.40 โ€ข 7 people โ€ข 20% tip โ€ข $14.04 tax

๐Ÿ’ณ Split Breakdown

Subtotal per person: ${results.perPersonSubtotal.toFixed(2)}
Tax per person: ${results.perPersonTax.toFixed(2)}
Tip per person (${results.tipPercent}%): ${results.perPersonTip.toFixed(2)}
Each person pays: ${results.perPersonTotal.toFixed(2)}
`; } // Display detailed split results function displayDetailedResults(personTotals, subtotal, taxAmount, tipAmount, tipPercent) { const container = document.getElementById('detailedResultContainer'); const totalAmount = subtotal + taxAmount + tipAmount; container.innerHTML = `
${subtotal.toFixed(2)}
Items Subtotal
${tipAmount.toFixed(2)}
Total Tip (${tipPercent}%)
${totalAmount.toFixed(2)}
Grand Total
${Object.values(personTotals).map(person => `
${person.name}
${person.total.toFixed(2)}
Items: ${person.subtotal.toFixed(2)}
Tax: ${person.tax.toFixed(2)}
Tip: ${person.tip.toFixed(2)}
`).join('')}
`; } // Display group results function displayGroupResults(balances) { const container = document.getElementById('groupResultContainer'); // Separate who owes and who is owed const owedMoney = Object.values(balances).filter(p => p.balance > 0.01); const owesMoney = Object.values(balances).filter(p => p.balance < -0.01); container.innerHTML = `
${splitBillState.expenses.length}
Total Expenses
${splitBillState.expenses.reduce((sum, e) => sum + e.amount, 0).toFixed(2)}
Total Amount
${owedMoney.length + owesMoney.length}
People Involved

๐Ÿ’ฐ Should Receive

${owedMoney.map(person => `
${person.name} +${person.balance.toFixed(2)}
`).join('') || '
No one is owed money
'}

๐Ÿ’ธ Should Pay

${owesMoney.map(person => `
${person.name} ${Math.abs(person.balance).toFixed(2)}
`).join('') || '
Everyone is settled up
'}
`; } // ========== SAMPLE SCENARIOS ========== // Use sample scenarios function useSample(sampleType) { const samples = { 'restaurant': { billTotal: 125.50, numPeople: 4, taxAmount: 12.50, tipPercent: 18 }, 'coffee': { billTotal: 32.80, numPeople: 3, taxAmount: 2.80, tipPercent: 15 }, 'fastfood': { billTotal: 45.75, numPeople: 5, taxAmount: 4.15, tipPercent: 10 }, 'finedining': { billTotal: 285.00, numPeople: 6, taxAmount: 25.65, tipPercent: 20 }, 'delivery': { billTotal: 78.90, numPeople: 3, taxAmount: 7.12, tipPercent: 18 }, 'bar': { billTotal: 156.40, numPeople: 7, taxAmount: 14.04, tipPercent: 20 } }; const sample = samples[sampleType]; if (!sample) return; // Fill in the form document.getElementById('billTotal').value = sample.billTotal; document.getElementById('numPeople').value = sample.numPeople; document.getElementById('taxAmount').value = sample.taxAmount; document.getElementById('tipPercent').value = sample.tipPercent; // Switch to simple tab if not already there if (splitBillState.currentTab !== 'simple') { switchTab('simple'); } // Smooth scroll to calculate button document.getElementById('calculateBtn').scrollIntoView({ behavior: 'smooth', block: 'center' }); // Highlight button const btn = document.getElementById('calculateBtn'); btn.style.animation = 'pulse 0.5s ease-in-out'; setTimeout(() => btn.style.animation = '', 500); // Track sample usage trackEvent('sample_used', { sample_type: sampleType }); } // ========== UTILITY FUNCTIONS ========== // Validate simple inputs function validateSimpleInputs(billTotal, numPeople, taxAmount, tipPercent) { clearErrors(); let isValid = true; if (billTotal <= 0) { showError('billTotalError', 'Bill total must be greater than 0'); isValid = false; } if (numPeople < 1 || numPeople > 50) { showError('numPeopleError', 'Number of people must be between 1 and 50'); isValid = false; } if (taxAmount < 0 || taxAmount > billTotal) { showError('taxAmountError', 'Tax amount cannot exceed bill total'); isValid = false; } if (tipPercent < 0 || tipPercent > 50) { showError('tipPercentError', 'Tip percent must be between 0% and 50%'); isValid = false; } return isValid; } // Copy bill results function copyBillResults(type) { let text = ''; if (type === 'simple' && splitBillState.lastCalculation) { const calc = splitBillState.lastCalculation.data; text = `Bill Split Results: โ€ข Bill Total: ${calc.billTotal.toFixed(2)} โ€ข Number of People: ${calc.numPeople} โ€ข Tax: ${calc.taxAmount.toFixed(2)} โ€ข Tip: ${calc.tipAmount.toFixed(2)} โ€ข Grand Total: ${calc.totalWithTip.toFixed(2)} โ€ข Each Person Pays: ${calc.perPersonTotal.toFixed(2)} Calculated with WIA Pin Code Split Bill Calculator`; } else { text = 'Bill split results copied to clipboard'; } copyToClipboard(text); } // Copy to clipboard function copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { showNotification('Copied to clipboard!', 'success'); }).catch(() => { const textArea = document.createElement('textarea'); textArea.value = text; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); showNotification('Copied to clipboard!', 'success'); }); } // Show error function showError(elementId, message) { const errorElement = document.getElementById(elementId); if (errorElement) { errorElement.textContent = message; } } // Clear errors function clearErrors() { document.querySelectorAll('.error').forEach(el => el.textContent = ''); } // Show notification toast function showNotification(message, type = 'success') { const toast = document.createElement('div'); toast.className = `toast ${type}`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.remove(); }, 3000); } // Show OTA section (dynamic) function showOTA() { const otaContainer = document.getElementById('otaContainer'); if (otaContainer && (otaContainer.style.display === 'none' || !otaContainer.style.display)) { otaContainer.style.display = 'block'; setTimeout(() => { const otaHeader = document.querySelector('.ota-header h3'); if (otaHeader) { otaHeader.style.animation = 'pulse 1s ease-in-out'; } }, 100); } } // Analytics tracking function trackEvent(eventName, data = {}) { if (typeof gtag !== 'undefined') { gtag('event', eventName, { 'event_category': TOOL_CONFIG.category, 'event_label': TOOL_CONFIG.name, ...data }); } } // ========== AI ASSISTANT FUNCTIONS ========== function openAIModal() { const modal = document.getElementById('aiModal'); if(modal) modal.classList.add('show'); if (aiModalState.apiKey && aiModalState.currentView === 'gemini') { showGeminiChat(); } else { showAISelector(); } updateAPIKeyStatus(); } function closeAIModal() { const modal = document.getElementById('aiModal'); if(modal) modal.classList.remove('show'); setTimeout(() => { aiModalState.currentView = 'selector'; showAISelector(); }, 300); } function showAISelector() { document.getElementById('aiModalTitle').textContent = 'Choose Your AI Assistant'; document.getElementById('aiSelector').style.display = 'flex'; document.getElementById('geminiChat').style.display = 'none'; document.getElementById('apiKeySetup').style.display = 'none'; aiModalState.currentView = 'selector'; } function showGeminiChat() { document.getElementById('aiModalTitle').innerHTML = 'โœจ Gemini AI Assistant'; document.getElementById('aiSelector').style.display = 'none'; document.getElementById('geminiChat').style.display = 'flex'; document.getElementById('apiKeySetup').style.display = 'none'; aiModalState.currentView = 'gemini'; const chatMessages = document.getElementById('chatMessages'); if (!chatMessages.innerHTML.trim()) { addMessage('assistant', `Hello! I can help you with: โ€ข How to split restaurant bills fairly โ€ข Tipping etiquette and customs around the world โ€ข Group dining and expense sharing strategies โ€ข Calculating complex bill divisions โ€ข Handling different payment methods What bill splitting question do you have?`); } } function showAPIKeySetup() { document.getElementById('aiModalTitle').textContent = 'Setup Gemini API'; document.getElementById('aiSelector').style.display = 'none'; document.getElementById('geminiChat').style.display = 'none'; document.getElementById('apiKeySetup').style.display = 'block'; aiModalState.currentView = 'setup'; } function selectAI(aiType) { switch(aiType) { case 'chatgpt': const toolContext = `I need help with splitting bills and restaurant expenses. I'm using a Split Bill Calculator tool that can handle simple splits, item-by-item divisions, and group expense tracking. Please help me understand bill splitting etiquette, tipping customs, and fair expense sharing strategies.`; const chatUrl = `https://chat.openai.com/?q=${encodeURIComponent(toolContext)}`; window.open(chatUrl, '_blank'); closeAIModal(); trackEvent('ai_selection', { ai_type: 'chatgpt' }); break; case 'claude': const claudeContext = `I need help with bill splitting and group dining expenses. I'm using a Split Bill Calculator tool for restaurant bills, item-by-item calculations, and group expense tracking. Please help me understand fair bill splitting methods, tipping guidelines, and group dining etiquette.`; const claudeUrl = `https://claude.ai/chat?q=${encodeURIComponent(claudeContext)}`; window.open(claudeUrl, '_blank'); closeAIModal(); trackEvent('ai_selection', { ai_type: 'claude' }); break; case 'gemini': if (!aiModalState.apiKey) { showAPIKeySetup(); } else { showGeminiChat(); } trackEvent('ai_selection', { ai_type: 'gemini' }); break; } } function saveGeminiApiKey() { const apiKey = document.getElementById('geminiApiKeyInput').value.trim(); if (apiKey) { localStorage.setItem('geminiApiKey', apiKey); aiModalState.apiKey = apiKey; showGeminiChat(); updateAPIKeyStatus(); } else { alert('Please enter a valid API key'); } } function updateAPIKeyStatus() { const statusEl = document.getElementById('apiKeyStatus'); if (aiModalState.apiKey) { statusEl.innerHTML = 'Change API Key'; } else { statusEl.textContent = 'No API key set'; } } function addMessage(type, content) { const chatMessages = document.getElementById('chatMessages'); const messageDiv = document.createElement('div'); messageDiv.className = `message ${type}`; if (type === 'user') { messageDiv.innerHTML = `You: ${content}`; } else { messageDiv.innerHTML = `โœจ Gemini:
${content.replace(/\n/g, '
')}`; } chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } async function sendToGemini() { const input = document.getElementById('geminiInput'); const message = input.value.trim(); if (!message) return; addMessage('user', message); input.value = ''; const loadingMsg = document.createElement('div'); loadingMsg.className = 'message assistant'; loadingMsg.innerHTML = 'โœจ Gemini:
Thinking...'; loadingMsg.id = 'loading-message'; document.getElementById('chatMessages').appendChild(loadingMsg); try { const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${aiModalState.apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ contents: [{ parts: [{ text: `Context: User is using a Split Bill Calculator tool on WIA Pin Code platform. The tool can split restaurant bills, calculate tips, divide expenses item-by-item, and track group expenses. WIA Pin Code is a universal address system for countries without postal codes. Split Bill Calculator features: - Simple bill splitting with tip calculation - Item-by-item division for detailed splits - Group expense tracking and settlement - Multiple calculation methods and tax handling User question: ${message} Please provide helpful advice about bill splitting, tipping etiquette, group dining, and expense sharing while noting this is general guidance.` }] }], generationConfig: { temperature: 0.7, maxOutputTokens: 1000 } }) }); const data = await response.json(); document.getElementById('loading-message').remove(); if (data.candidates && data.candidates[0] && data.candidates[0].content) { const reply = data.candidates[0].content.parts[0].text; addMessage('assistant', reply); } else { addMessage('assistant', 'Sorry, I could not generate a response. Please try again.'); } } catch (error) { document.getElementById('loading-message')?.remove(); if (error.message.includes('API key')) { addMessage('error', 'Invalid API key. Please check your API key and try again.'); showAPIKeySetup(); } else { addMessage('error', 'Failed to connect to Gemini. Please check your internet connection and try again.'); } } } // ========== EVENT LISTENERS ========== document.addEventListener('DOMContentLoaded', function() { // Enter key support for inputs ['billTotal', 'numPeople', 'taxAmount', 'tipPercent'].forEach(id => { const element = document.getElementById(id); if (element) { element.addEventListener('keypress', function(e) { if (e.key === 'Enter') { calculateSimpleSplit(); } }); element.addEventListener('input', clearErrors); } }); // Enter key for person name const personNameInput = document.getElementById('personName'); if (personNameInput) { personNameInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') { addPerson(); } }); } // Enter key for item inputs const itemNameInput = document.getElementById('itemName'); const itemPriceInput = document.getElementById('itemPrice'); if (itemNameInput && itemPriceInput) { [itemNameInput, itemPriceInput].forEach(input => { input.addEventListener('keypress', function(e) { if (e.key === 'Enter') { addItem(); } }); }); } document.getElementById('aiBtn').addEventListener('click', openAIModal); document.getElementById('aiModal').addEventListener('click', function(e) { if (e.target === this) { closeAIModal(); } }); document.addEventListener('keydown', function(e) { if (e.key === 'Enter') { const geminiInput = document.getElementById('geminiInput'); if (document.activeElement === geminiInput) { sendToGemini(); } } if (e.key === 'Escape') { closeAIModal(); } }); updateAPIKeyStatus(); updateCurrentYear(); updateToolCount(); }); // ========== DYNAMIC TOOL COUNT ========== async function updateToolCount() { try { const response = await fetch('/api/tool-count.php'); const data = await response.json(); document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${data.count}+ free online tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${data.count}+ ${suffix}`; }); } catch (error) { const fallbackCount = 333; document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${fallbackCount}+ free online tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${fallbackCount}+ ${suffix}`; }); console.log('Tool count API not available, using current count:', fallbackCount); } } function updateCurrentYear() { const currentYear = new Date().getFullYear(); document.querySelectorAll('.current-year').forEach(el => { el.textContent = currentYear; }); } // ========== ANALYTICS ========== window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXX'); trackEvent('page_view', { tool: TOOL_CONFIG.name, category: TOOL_CONFIG.category });