This workflow corresponds to n8n.io template #13829 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "qdsK4hpd4LVM1NoB",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "(Retail) Auto-Sync Transactions to Accounting Tools",
"tags": [],
"nodes": [
{
"id": "0625b8c1-aa39-44df-959f-4e652e70b392",
"name": "Shopify Order Events",
"type": "n8n-nodes-base.shopifyTrigger",
"position": [
176,
144
],
"parameters": {
"topic": "orders/create",
"authentication": "accessToken"
},
"typeVersion": 1
},
{
"id": "432ce392-47d6-4a21-bc58-77b19242b3ea",
"name": "WooCommerce Order Events",
"type": "n8n-nodes-base.wooCommerceTrigger",
"position": [
176,
320
],
"parameters": {
"event": "order.created"
},
"typeVersion": 1
},
{
"id": "4dc27308-6725-44ae-8e4d-26a750a48ad5",
"name": "Merge Platform Data",
"type": "n8n-nodes-base.merge",
"position": [
992,
240
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "2c82cdfb-f175-45c1-a3b3-e9bb3dcd79c6",
"name": "Format Transaction Data",
"type": "n8n-nodes-base.set",
"position": [
1216,
240
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "orderId",
"type": "string",
"value": "={{ $json.orderId }}"
},
{
"id": "id-2",
"name": "orderNumber",
"type": "string",
"value": "={{ $json.orderNumber }}"
},
{
"id": "id-3",
"name": "amount",
"type": "number",
"value": "={{ $json.totalAmount }}"
},
{
"id": "id-4",
"name": "subtotal",
"type": "number",
"value": "={{ $json.subtotal }}"
},
{
"id": "id-5",
"name": "tax",
"type": "number",
"value": "={{ $json.totalTax }}"
},
{
"id": "id-6",
"name": "currency",
"type": "string",
"value": "={{ $json.currency }}"
},
{
"id": "id-7",
"name": "customerEmail",
"type": "string",
"value": "={{ $json.customerEmail }}"
},
{
"id": "id-8",
"name": "customerName",
"type": "string",
"value": "={{ $json.customerName }}"
},
{
"id": "id-9",
"name": "source",
"type": "string",
"value": "={{ $json.sourceSystem }}"
},
{
"id": "id-10",
"name": "transactionType",
"type": "string",
"value": "={{ $json.transactionType }}"
},
{
"id": "id-11",
"name": "status",
"type": "string",
"value": "={{ $json.financialStatus }}"
},
{
"id": "id-12",
"name": "date",
"type": "string",
"value": "={{ $json.createdAt }}"
},
{
"id": "id-13",
"name": "description",
"type": "string",
"value": "={{ 'Order #' + $json.orderNumber + ' from ' + $json.sourceSystem }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "43368cd4-2fd7-4033-9d4b-20c43d9a2143",
"name": "Format Sale Entry",
"type": "n8n-nodes-base.set",
"position": [
2016,
176
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "TxnDate",
"type": "string",
"value": "={{ $json.date.split('T')[0] }}"
},
{
"id": "id-2",
"name": "CustomerRef",
"type": "object",
"value": "={{ { value: '1', name: $json.customerName } }}"
},
{
"id": "id-3",
"name": "Line",
"type": "array",
"value": "={{ JSON.stringify([{ Amount: $json.amount, DetailType: 'SalesItemLineDetail', SalesItemLineDetail: { ItemRef: { value: '1', name: 'Sales' }, Qty: 1, UnitPrice: $json.amount, TaxCodeRef: { value: 'TAX' } } }]) }}"
},
{
"id": "id-4",
"name": "TotalAmt",
"type": "number",
"value": "={{ $json.amount }}"
},
{
"id": "id-5",
"name": "PrivateNote",
"type": "string",
"value": "={{ $json.description + ' - Order ID: ' + $json.orderId }}"
},
{
"id": "id-6",
"name": "DocNumber",
"type": "string",
"value": "={{ $json.orderNumber }}"
},
{
"id": "id-7",
"name": "CurrencyRef",
"type": "object",
"value": "={{ { value: $json.currency } }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ed1edb0c-6b5e-43b7-a41f-960db674a722",
"name": "Format Refund Entry",
"type": "n8n-nodes-base.set",
"position": [
2016,
320
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "TxnDate",
"type": "string",
"value": "={{ $json.date.split('T')[0] }}"
},
{
"id": "id-2",
"name": "CustomerRef",
"type": "object",
"value": "={{ { value: '1', name: $json.customerName } }}"
},
{
"id": "id-3",
"name": "Line",
"type": "array",
"value": "={{ JSON.stringify([{ Amount: Math.abs($json.amount), DetailType: 'SalesItemLineDetail', SalesItemLineDetail: { ItemRef: { value: '1', name: 'Refund' }, Qty: 1, UnitPrice: Math.abs($json.amount) } }]) }}"
},
{
"id": "id-4",
"name": "TotalAmt",
"type": "number",
"value": "={{ Math.abs($json.amount) }}"
},
{
"id": "id-5",
"name": "PrivateNote",
"type": "string",
"value": "={{ 'Refund - ' + $json.description + ' - Order ID: ' + $json.orderId }}"
},
{
"id": "id-6",
"name": "DocNumber",
"type": "string",
"value": "={{ 'REF-' + $json.orderNumber }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "fb63da36-e07b-4e9f-a089-38de69e29432",
"name": "Log to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
2464,
256
],
"parameters": {
"columns": {
"value": {},
"schema": [
{
"id": "TxnDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "TxnDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "CustomerRef",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "CustomerRef",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Line",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Line",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "TotalAmt",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "TotalAmt",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "PrivateNote",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "PrivateNote",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "DocNumber",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "DocNumber",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "CurrencyRef",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "CurrencyRef",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet3"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "{sheetId}",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/{sheetId}=drivesdk",
"cachedResultName": "Price_Changes_Log"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "c9c81ef1-c594-47e7-b1ae-eaef11f5c19f",
"name": "Check Transaction Type",
"type": "n8n-nodes-base.if",
"position": [
1424,
240
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "2c25b7a6-47d5-4f8b-a5c3-19a920de834e",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.transactionType }}",
"rightValue": "sale"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "3719b8e9-1394-470b-95ee-38800e5a9865",
"name": "Shopify Configuration",
"type": "n8n-nodes-base.set",
"position": [
432,
144
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "orderId",
"type": "number",
"value": "={{ $json.id }}"
},
{
"id": "id-2",
"name": "orderNumber",
"type": "string",
"value": "={{ $json.order_number }}"
},
{
"id": "id-3",
"name": "totalAmount",
"type": "number",
"value": "={{ $json.current_total_price }}"
},
{
"id": "id-4",
"name": "subtotal",
"type": "number",
"value": "={{ $json.current_subtotal_price }}"
},
{
"id": "id-5",
"name": "totalTax",
"type": "number",
"value": "={{ $json.current_total_tax }}"
},
{
"id": "id-6",
"name": "currency",
"type": "string",
"value": "={{ $json.currency }}"
},
{
"id": "id-7",
"name": "customerEmail",
"type": "string",
"value": "={{ $json.customer.email || 'N/A' }}"
},
{
"id": "id-8",
"name": "customerName",
"type": "string",
"value": "={{ $json.customer.first_name + ' ' + $json.customer.last_name }}"
},
{
"id": "id-9",
"name": "financialStatus",
"type": "string",
"value": "={{ $json.financial_status }}"
},
{
"id": "id-10",
"name": "sourceSystem",
"type": "string",
"value": "shopify"
},
{
"id": "id-11",
"name": "transactionType",
"type": "string",
"value": "sale"
},
{
"id": "id-12",
"name": "createdAt",
"type": "string",
"value": "={{ $json.created_at }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a0bb07c1-d143-4651-9e72-5f56c07a9d19",
"name": "WooCommerce Configuration",
"type": "n8n-nodes-base.set",
"position": [
432,
320
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "orderId",
"type": "number",
"value": "={{ $json.id }}"
},
{
"id": "id-2",
"name": "orderNumber",
"type": "string",
"value": "={{ $json.number }}"
},
{
"id": "id-3",
"name": "totalAmount",
"type": "number",
"value": "={{ $json.total }}"
},
{
"id": "id-4",
"name": "subtotal",
"type": "number",
"value": "={{ $json.subtotal || '0' }}"
},
{
"id": "id-5",
"name": "totalTax",
"type": "number",
"value": "={{ $json.total_tax }}"
},
{
"id": "id-6",
"name": "currency",
"type": "string",
"value": "={{ $json.currency }}"
},
{
"id": "id-7",
"name": "customerEmail",
"type": "string",
"value": "={{ $json.billing.email || 'N/A' }}"
},
{
"id": "id-8",
"name": "customerName",
"type": "string",
"value": "={{ $json.billing.first_name + ' ' + $json.billing.last_name }}"
},
{
"id": "id-9",
"name": "financialStatus",
"type": "string",
"value": "={{ $json.status }}"
},
{
"id": "id-10",
"name": "sourceSystem",
"type": "string",
"value": "woocommerce"
},
{
"id": "id-11",
"name": "transactionType",
"type": "string",
"value": "sale"
},
{
"id": "id-12",
"name": "createdAt",
"type": "string",
"value": "={{ $json.date_created }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "d43057a0-4775-46db-ad17-5559cac3c269",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
-704,
-448
],
"parameters": {
"width": 544,
"height": 992,
"content": "# How It Works\nThis workflow serves as an automated Retail Transaction Sync system, capturing sales and refund data from multiple e-commerce platforms to maintain a centralized financial ledger. It is initiated by Shopify and WooCommerce webhooks whenever a new order is created. The system normalizes disparate data formats from both platforms into a unified structure, evaluates whether the transaction is a sale or a refund, and automatically formats the data for accounting purposes before logging it into a Google Sheets database.\n\n# Setup Steps\n## Webhook Trigger\nConfigure your Shopify and WooCommerce admin panels to send \"Order Created\" notifications to the workflow's respective trigger URLs to ensure the workflow runs instantly whenever a customer completes a purchase.\n\n## Connect Accounts\nShopify: Provide an Access Token with required order permissions to the \"Shopify Order Events\" node.\nWooCommerce: Use API credentials to authenticate the \"WooCommerce Order Events\" node.\nGoogle Sheets: Set up Google OAuth2 credentials to allow the \"Log to Google Sheets\" node to write transaction data to your spreadsheet.\n\n## Configure Parameters\nStorage Nodes: Verify the Google Sheets Document ID and Sheet Name (e.g., \"Sheet3\") in the \"Log to Google Sheets\" node to ensure data is routed to your specific tracking table.\n\nData Mapping: Review the Shopify Configuration and WooCommerce Configuration nodes to ensure fields like total amount, currency, and customer details align with your store's structure.\n\n## Update Notifications\nTransaction Logging: Confirm that the Google Sheets account used has the necessary permissions to write to the target spreadsheet.\n\nVerify Headers: Ensure the column headers in your Google Sheet (e.g., TxnDate, CustomerRef, TotalAmt) match the keys defined in the \"Format Sale Entry\" and \"Format Refund Entry\" nodes."
},
"typeVersion": 1
},
{
"id": "f5ad9d00-e81f-4423-a451-d9d56941a9c5",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
-96
],
"parameters": {
"color": 7,
"width": 816,
"height": 640,
"content": "## Webhook Trigger and Set Configuration\nThe Shopify and WooCommerce Order Events nodes serve as the workflow's entry points, listening for orders/create and order.created webhooks to capture transaction data the moment a customer completes a purchase. Subsequent Shopify and WooCommerce Configuration nodes then normalize these native JSON payloads\u2014mapping platform-specific fields like current_total_price or status to a unified internal schema\u2014ensuring all order data is standardized for consistent downstream logging and analysis.\n"
},
"typeVersion": 1
},
{
"id": "129e1e95-dcde-408e-b75e-3a3490cd728e",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
880,
-96
],
"parameters": {
"color": 7,
"width": 816,
"height": 640,
"content": "## Merge, Format & Route Transaction Data \nThe Merge Platform Data node consolidates incoming streams from different e-commerce sources into a single workflow path. The subsequent Format Transaction Data node then maps various platform attributes\u2014such as totalAmount, customerEmail, and sourceSystem\u2014into a unified schema, ensuring all downstream operations receive consistent data structures regardless of the origin.\n\nThe final Check Transaction Type node acts as a router, evaluating the transactionType field to distinguish between \"sale\" and other entries. This allows the workflow to dynamically direct the formatted data to the appropriate accounting logic for processing sales or refunds.\n"
},
"typeVersion": 1
},
{
"id": "ecb03981-ba4e-4a7b-93e4-b0180ec55840",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1776,
-96
],
"parameters": {
"color": 7,
"width": 1088,
"height": 640,
"content": "## Transaction Formatting & Accounting Sync \nThe Format Sale and Format Refund Entry nodes prepare the normalized data for accounting by structuring it into financial records. They calculate absolute values for amounts, generate transaction dates, and create detailed line items (e.g., \"Sales\" or \"Refund\" tags) and private notes containing the original Order ID for audit tracking.\n\nThe final Log to Google Sheets node records these formatted entries into a centralized spreadsheet. By utilizing an \"append or update\" operation, it ensures that every transaction\u2014whether a new sale or a processed refund\u2014is accurately captured in the master ledger with all relevant metadata like customer names, currency, and document numbers.\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "3be8f1a2-40bb-453e-9eae-c995b48b3b64",
"connections": {
"Format Sale Entry": {
"main": [
[
{
"node": "Log to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Format Refund Entry": {
"main": [
[
{
"node": "Log to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Merge Platform Data": {
"main": [
[
{
"node": "Format Transaction Data",
"type": "main",
"index": 0
}
]
]
},
"Shopify Order Events": {
"main": [
[
{
"node": "Shopify Configuration",
"type": "main",
"index": 0
}
]
]
},
"Shopify Configuration": {
"main": [
[
{
"node": "Merge Platform Data",
"type": "main",
"index": 0
}
]
]
},
"Check Transaction Type": {
"main": [
[
{
"node": "Format Sale Entry",
"type": "main",
"index": 0
}
],
[
{
"node": "Format Refund Entry",
"type": "main",
"index": 0
}
]
]
},
"Format Transaction Data": {
"main": [
[
{
"node": "Check Transaction Type",
"type": "main",
"index": 0
}
]
]
},
"WooCommerce Order Events": {
"main": [
[
{
"node": "WooCommerce Configuration",
"type": "main",
"index": 0
}
]
]
},
"WooCommerce Configuration": {
"main": [
[
{
"node": "Merge Platform Data",
"type": "main",
"index": 1
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automates the collection and standardization of sales data from Shopify and WooCommerce into a centralized Google Sheets ledger. It triggers on new orders, normalizes disparate platform data, distinguishes between sales and refunds, and formats the information for…
Source: https://n8n.io/workflows/13829/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates the synchronization of product prices across Shopify and WooCommerce platforms to ensure retail consistency. It triggers when a price change is detected in either system, appli
This n8n workflow automatically sends WhatsApp notifications to customers when their Shopify orders are fulfilled. It extracts order details, validates customer phone numbers for WhatsApp compatibilit
This workflow is designed for online store owners, customer-success teams, and marketing operators who want to automatically verify customers' WhatsApp numbers and deliver order updates or invoice lin
This n8n workflow listens for order cancellations in Shopify, extracts relevant customer and order data, checks if the customer’s phone number is registered on WhatsApp via the Rapiwa API, and sends a
The workflow triggers on a new checkout event from Shopify and extracts all relevant cart data. It filters carts based on value and age to isolate qualified abandoned checkouts. For each qualified car