When a customer completes checkout, Shopify can fire an orders/paid webhook — a JSON payload containing the order ID, line items, customer details, totals, discounts, and fulfilment status — to any URL you configure in Settings → Notifications → Webhooks. Everything downstream depends on that one event.
There are two free ways to turn that payload into rows in a spreadsheet:
Route 1 — Make.com (no code)
A Webhooks module receives the payload, a Google Sheets Add a Row module writes it. This is the fastest route to something working, and it's what the rest of this guide builds on — see the actual scenario structure below.
Route 2 — Google Apps Script (zero external tools)
A Web App deployed from inside the Sheet itself, listening for the same webhook via doPost(e). No Make.com account needed, but subject to Apps Script's own execution limits — covered in full in why Apps Script hits quota walls at volume.
function doPost(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Orders');
var data = JSON.parse(e.postData.contents);
data.line_items.forEach(function(item) {
sheet.appendRow([
data.id,
data.created_at,
data.email,
item.sku,
item.title,
item.quantity,
item.price,
data.total_price,
data.fulfillment_status || 'unfulfilled'
]);
});
return ContentService.createTextOutput('SUCCESS').setMimeType(ContentService.MimeType.TEXT);
} Note the forEach over line_items — a three-item order should produce three rows, one per SKU, not one row per order. Most CSV export apps flatten this into a single row per order and lose per-product detail. Either free route above beats a $29–$99/month export app on cost; which one you pick depends on volume and whether you want a Make.com account in the loop at all.