How to Generate Receipts from Google Sheets Rows (Payment and Donation Receipts, 2026)
If you already log payments or donations in Google Sheets, you have everything a receipt needs: who paid, how much, when and for what. What's missing is the document. Instead of copying each row into a fresh Google Doc, you can keep one receipt template and generate a PDF for every row that is marked paid.
This guide covers simple payment receipts (for clients, students, members or customers) and donation acknowledgments for small nonprofits. It uses the same “one document per row” method as the invoices and certificates guide; the difference is that a receipt confirms money already received, so it should only be created once a payment is recorded.
Watch the 2-minute walkthrough on YouTube. Short on time? Watch the 50-second version.
Step 1: a payments sheet that can become receipts
Use one row per payment, with columns such as: Receipt #, Name, Email, Date paid, Amount, Method (card, cash, check, transfer), Description, Status, and empty Receipt Doc / Receipt PDF columns for links.
Give every receipt a unique number. If you don't have a scheme yet, ="R-2026-"&TEXT(ROW()-1,"0000") in Receipt # works, but it changes if you sort or delete rows. Once a receipt has been issued, paste the number as a value (copy, then Paste special › Values only) so it never changes.
Add display columns so the Doc gets clean text instead of raw numbers: =TEXT(E2,"$#,##0.00") for an Amount display column and =TEXT(D2,"MMMM d, yyyy") for a Date display column. Point the placeholders at those headers.
Step 2: a Google Docs receipt template
Create a Doc with your logo, business or organization name and contact details, a “Receipt” heading, and lines like these. Placeholders must match your column headers exactly, including spaces and capitals:
Receipt {{Receipt #}}
Date: {{Date display}}
Received from: {{Name}}
Amount: {{Amount display}}
Payment method: {{Method}}
For: {{Description}}
Thank you for your payment.
Donation receipts. For a charitable gift, the wording matters more than the layout. In the United States, the IRS explains what a written acknowledgment should contain (such as the amount of a cash gift and whether any goods or services were given in return) in Publication 1771. Put that wording in the template once, add a column such as Goods or services provided if you need it, and have your accountant check the template. Other countries have their own rules.
Copy the template ID (between /d/ and /edit in its URL) and the ID of a Drive folder for finished receipts (after /folders/).
Step 3: create a PDF for each paid row
In the sheet, open Extensions › Apps Script, paste the script below, fill in the two IDs, save, then reload the sheet. A Receipts menu appears; choose Create receipts for paid rows and approve the permissions the first time. Rows that already have a Receipt PDF link are skipped, so running it twice never makes duplicates.
/**
* Create a Google Doc + PDF receipt for each row whose Status is "Paid"
* and whose "Receipt PDF" cell is still empty.
* Template placeholders must match headers, e.g. {{Receipt #}}, {{Name}}, {{Amount display}}.
*/
const TEMPLATE_ID = 'PASTE_TEMPLATE_DOC_ID';
const FOLDER_ID = 'PASTE_OUTPUT_FOLDER_ID';
function onOpen() {
SpreadsheetApp.getUi().createMenu('Receipts')
.addItem('Create receipts for paid rows', 'createReceipts')
.addToUi();
}
function createReceipts() {
const sh = SpreadsheetApp.getActiveSheet();
const data = sh.getDataRange().getDisplayValues();
const head = data[0];
const statusCol = head.indexOf('Status');
const pdfCol = ensureCol_(sh, head, 'Receipt PDF');
const docCol = ensureCol_(sh, head, 'Receipt Doc');
const folder = DriveApp.getFolderById(FOLDER_ID);
for (let r = 1; r < data.length; r++) {
if (String(data[r][statusCol] || '').trim().toLowerCase() !== 'paid') continue;
if (sh.getRange(r + 1, pdfCol).getValue()) continue; // already issued
const rec = {};
head.forEach((h, i) => { if (h) rec[h] = data[r][i]; });
const name = 'Receipt-' + (rec['Receipt #'] || ('row-' + (r + 1)));
const copy = DriveApp.getFileById(TEMPLATE_ID).makeCopy(name, folder);
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
Object.keys(rec).forEach((h) => {
const escaped = h.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
body.replaceText('\\{\\{' + escaped + '\\}\\}', rec[h] || '');
});
doc.saveAndClose();
const pdf = folder.createFile(copy.getAs(MimeType.PDF).setName(name + '.pdf'));
sh.getRange(r + 1, docCol).setValue(copy.getUrl());
sh.getRange(r + 1, pdfCol).setValue(pdf.getUrl());
}
}
function ensureCol_(sh, head, name) {
let i = head.indexOf(name);
if (i === -1) {
i = head.length;
sh.getRange(1, i + 1).setValue(name);
head.push(name);
}
return i + 1;
}
Tips
- Receipts from a Google Form. If payments or pledges arrive through a Google Form, the responses already land in a sheet. Add the Status and link columns to the right of the form columns, and see generating a PDF from a Form response for the timing details.
- Fix the sheet, not the PDF. If a receipt is wrong, correct the row, delete the two links (and the old files), and run the menu again. Editing PDFs by hand is how numbers drift apart.
- Year-end summaries. For one annual statement per donor or client, build a summary tab with one row per person (for example with
SUMIFSon Name and year), then run the same script on that tab with its own template. - Sending. This script saves files and links; it doesn't email anyone. Attach the PDF from Drive when you reply, or add a separate step once you're happy with the output.
- Chasing unpaid invoices? That's the opposite job. See invoice payment reminders from Google Sheets.
- Execution time. Apps Script runs stop after six minutes. A big backlog may need more than one run; the empty-link check lets it pick up where it left off.
See SheetWeave
Related Google Sheets guides
- How to generate a PDF or Google Doc for each row in Google Sheets
- Best Autocrat alternatives for mail merge to PDF and Docs
- Make invoices or certificates from Google Sheets rows
- Create sales quotes or estimates from Google Sheets
- Generate receipts from Google Sheets rows
- Create purchase orders from Google Sheets
- Make packing slips from Google Sheets orders
- Generate a PDF certificate from a Google Form response
- Issue numbered training completion certificates with expiry dates
- Make a PDF progress report for each student
- Generate offer letters from a Google Sheets hiring tracker
- Email each row’s PDF as an attachment
- Automatic email reminders from a date column
- Contract renewal and expiration alerts from Google Sheets
- Track certificate of insurance (COI) expirations in Google Sheets
- Track employee license and certification expirations
- Track equipment and vehicle maintenance with reminders
- Track warranty expiration dates with reminders
- Birthday and work anniversary reminders from Google Sheets
- Rent due and lease renewal reminders from Google Sheets
- Send invoice payment reminders from Google Sheets
- Highlight overdue tasks and send email reminders
- Follow-up reminders for leads, clients and candidates
- Membership renewal reminders for clubs and associations
- SheetWeave vs Autocrat
- SheetWeave vs Document Studio
- SheetWeave vs RowDocs
Instructions refer to Google Sheets, Google Docs, Google Forms, Google Drive and Apps Script as they worked on November 10, 2026. Not affiliated with Google or any other vendor named here. Google Sheets, Google Docs, Google Forms, Google Slides and Google Drive are trademarks of Google LLC. Features change, so verify in your own account. Questions or corrections: hello@loomwise.app.