Spent
$0.00
0% of budget
Budget
Remaining
Days Left
Connect Google Sheets
Sync with your spreadsheet
Apple Pay
Transactions
Settings
Monthly Amount

1. In your Sheet: Extensions → Apps Script
2. Paste the script below → Deploy → New deployment → Web app
3. Execute as: Me · Who has access: Anyone
4. Copy the deployment URL and paste it below
function doGet(e) { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName('Transactions'); var action = e.parameter.action || 'add'; if (action === 'list') { var last = sheet.getLastRow(); if (last < 12) return out('[]', 'json'); var rows = sheet.getRange(12, 2, last - 11, 5).getValues(); var txs = []; rows.forEach(function(r) { var dateVal = r[0]; var dateStr = ''; try { var d = new Date(dateVal); if (!isNaN(d.getTime()) && d.getFullYear() > 2000) { dateStr = Utilities.formatDate(d, Session.getScriptTimeZone(), 'yyyy-MM-dd'); } } catch(ex) {} if (!dateStr) return; var amount = parseFloat(r[2]); if (isNaN(amount) || amount <= 0) return; if (String(r[1]) === 'PERIOD TOTAL') return; txs.push({ date: dateStr, merchant: String(r[1] || 'Unknown'), amount: amount, note: String(r[4] || '') }); }); return out(JSON.stringify(txs), 'json'); } if (action === 'delete') { var dDate = e.parameter.date, dMerchant = e.parameter.merchant, dAmount = parseFloat(e.parameter.amount); var last = sheet.getLastRow(); var rows = sheet.getRange(12, 2, last - 11, 4).getValues(); for (var i = 0; i < rows.length; i++) { var d = new Date(rows[i][0]); var ds = isNaN(d.getTime()) ? '' : Utilities.formatDate(d, Session.getScriptTimeZone(), 'yyyy-MM-dd'); if (ds === dDate && String(rows[i][1]) === dMerchant && Math.abs(parseFloat(rows[i][2]) - dAmount) < 0.01) { sheet.deleteRow(12 + i); return out('DELETED'); } } return out('NOT_FOUND'); } if (action === 'update') { var dDate = e.parameter.date, dMerchant = e.parameter.merchant, dAmount = parseFloat(e.parameter.amount); var newDate = e.parameter.newDate, newMerchant = e.parameter.newMerchant, newAmount = parseFloat(e.parameter.newAmount); var last = sheet.getLastRow(); var rows = sheet.getRange(12, 2, last - 11, 4).getValues(); for (var i = 0; i < rows.length; i++) { var d = new Date(rows[i][0]); var ds = isNaN(d.getTime()) ? '' : Utilities.formatDate(d, Session.getScriptTimeZone(), 'yyyy-MM-dd'); if (ds === dDate && String(rows[i][1]) === dMerchant && Math.abs(parseFloat(rows[i][2]) - dAmount) < 0.01) { var nd = new Date(newDate + 'T12:00:00'); sheet.getRange(12 + i, 2, 1, 3).setValues([[nd, newMerchant, newAmount]]); sheet.getRange(12 + i, 2).setNumberFormat('MMM D'); sheet.getRange(12 + i, 4).setNumberFormat('$#,##0.00'); return out('UPDATED'); } } return out('NOT_FOUND'); } var amount = parseFloat(e.parameter.amount); var note = e.parameter.note || 'Apple Pay'; if (isNaN(amount) || amount <= 0) return out('ERROR'); var today = new Date(); var last = sheet.getLastRow(); var col = sheet.getRange('C12:C' + last).getValues(); var ins = last + 1; for (var i = col.length - 1; i >= 0; i--) { if (col[i][0] === 'PERIOD TOTAL') { ins = 12 + i; break; } } sheet.insertRowBefore(ins); sheet.getRange(ins, 2, 1, 5).setValues([[today, note, amount, '', '']]); sheet.getRange(ins, 2).setNumberFormat('MMM D'); sheet.getRange(ins, 4).setNumberFormat('$#,##0.00'); return out('OK: $' + amount); } function out(s, t) { var m = t === 'json' ? ContentService.MimeType.JSON : ContentService.MimeType.TEXT; return ContentService.createTextOutput(s).setMimeType(m); }
Apps Script Web App URL

After deploying the Apps Script, create a Shortcut:
1. Ask for Input → Number → "Amount?"
2. Ask for Input → Text → "Note? (optional)"
3. URL → paste your Apps Script URL, add:
?action=add&amount=[Input]&note=[Input]
4. Get Contents of URL → Done
Add Transaction
Amount
Merchant
Date
Edit Transaction
Amount
Merchant
Date