저의 워크플로우 23
이것은Invoice Processing, Multimodal AI분야의자동화 워크플로우로, 46개의 노드를 포함합니다.주로 If, Code, Merge, Stripe, Airtable 등의 노드를 사용하며. 전 주기 인보이스 자동화: Airtable, QuickBooks, Stripe
- •Stripe API Key
- •Airtable API Key
- •대상 API의 인증 정보가 필요할 수 있음
{
"id": "wnHdgRqker2FalaJ",
"meta": {
"instanceId": "1a54c41d9050a8f1fa6f74ca858828ad9fb97b9fafa3e9760e576171c531a787"
},
"name": "My workflow 23",
"tags": [],
"nodes": [
{
"id": "989dcbdc-5d15-45df-bb0e-db6049c537e2",
"name": "Airtable 트리거",
"type": "n8n-nodes-base.airtableTrigger",
"position": [
60,
1780
],
"parameters": {
"baseId": {
"__rl": true,
"mode": "id",
"value": "{YOUR_AIRTABLE_BASE_ID}"
},
"tableId": {
"__rl": true,
"mode": "id",
"value": "{YOUR_AIRTABLE_TABLE_ID}"
},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerField": "Created",
"authentication": "airtableTokenApi",
"additionalFields": {}
},
"typeVersion": 1
},
{
"id": "45863a72-e832-448e-88e6-edb6ee1c8908",
"name": "IF - 상태 확인",
"type": "n8n-nodes-base.if",
"position": [
1580,
1580
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.Status }}",
"value2": "Approved for Invoicing"
}
]
}
},
"typeVersion": 1
},
{
"id": "43c615f1-777f-43da-8274-2b9ecce18aa0",
"name": "IF - 고객 존재 여부?",
"type": "n8n-nodes-base.if",
"position": [
3020,
1340
],
"parameters": {
"conditions": {
"number": [
{
"value1": "={{ $json.Id ?? \"\" }}",
"operation": "isEmpty"
}
]
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "2cb49f5e-08f7-46ea-afab-217e98908a14",
"mode": "append",
"name": "QBO 고객 병합",
"type": "n8n-nodes-base.merge",
"position": [
4320,
1540
],
"parameters": {},
"typeVersion": 1
},
{
"id": "60920472-77b6-4243-89b0-f162f6e900d9",
"name": "Stripe - 고객 찾기",
"type": "n8n-nodes-base.stripe",
"position": [
5800,
1020
],
"parameters": {
"resource": "customer",
"customerId": "={{ $('Search records').item.json['Stripe Customer ID'] || \"\"}}"
},
"typeVersion": 1
},
{
"id": "bd0adf89-499a-40ee-9e37-648ae0aad30d",
"name": "IF - Stripe 고객 존재 여부?",
"type": "n8n-nodes-base.if",
"position": [
7220,
1160
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.DisplayName }}",
"operation": "isNotEmpty"
}
]
}
},
"typeVersion": 1
},
{
"id": "ea27b7d1-4e6e-4620-b402-b0b8e0db436d",
"name": "Stripe - 고객 생성",
"type": "n8n-nodes-base.stripe",
"position": [
7960,
980
],
"parameters": {
"name": "={{ $json.DisplayName }}",
"resource": "customer",
"operation": "create",
"additionalFields": {
"email": "={{ $json.PrimaryEmailAddr.Address }}"
}
},
"typeVersion": 1
},
{
"id": "901e1828-f5e5-4801-83a0-53fce11f4ea0",
"mode": "append",
"name": "Stripe 고객 병합",
"type": "n8n-nodes-base.merge",
"position": [
8520,
1380
],
"parameters": {},
"typeVersion": 1
},
{
"id": "4c99441c-1f72-49d6-b421-62e3c2c72b28",
"name": "QuickBooks - 고객 찾기",
"type": "n8n-nodes-base.quickbooks",
"position": [
2360,
1160
],
"parameters": {
"limit": 500,
"filters": {
"query": "=WHERE DisplayName = '{{ $json['Client Name'] }}'\n\n"
},
"operation": "getAll"
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "497c8d82-1916-4ac6-acd2-7fdc561d3919",
"name": "청구서 생성",
"type": "n8n-nodes-base.quickbooks",
"position": [
13120,
1420
],
"parameters": {
"Line": [
{
"Qty": "={{ $('Update Quickbooks and Stripe Customer Ids').item.json.fields.Quantity }}",
"Amount": "={{ $json.Amount }}",
"itemId": "={{ $json.Id }}",
"DetailType": "SalesItemLineDetail",
"Description": "={{ $json.Description }}"
}
],
"resource": "invoice",
"operation": "create",
"CustomerRef": "={{ $('Update Quickbooks and Stripe Customer Ids').item.json.fields['QuickBooks Customer ID'] }}",
"additionalFields": {}
},
"typeVersion": 1
},
{
"id": "b1330d78-6e36-4296-98b0-0312804e955d",
"name": "고객 생성",
"type": "n8n-nodes-base.quickbooks",
"position": [
3680,
1100
],
"parameters": {
"operation": "create",
"displayName": "={{ $('IF - Status Check').item.json['Client Name'] }}",
"additionalFields": {
"PrimaryEmailAddr": "={{ $('IF - Status Check').item.json['Client Email'] }}"
}
},
"typeVersion": 1
},
{
"id": "8b371200-572e-4995-b7d7-d496751342f4",
"name": "기록 검색",
"type": "n8n-nodes-base.airtable",
"position": [
800,
1360
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "{YOUR_AIRTABLE_BASE_ID}",
"cachedResultUrl": "https://airtable.com/{YOUR_AIRTABLE_BASE_ID}",
"cachedResultName": "{YOUR_AIRTABLE_BASE_NAME}"
},
"table": {
"__rl": true,
"mode": "list",
"value": "{YOUR_AIRTABLE_TABLE_ID}",
"cachedResultUrl": "https://airtable.com/{YOUR_AIRTABLE_BASE_ID}/{YOUR_AIRTABLE_TABLE_ID}",
"cachedResultName": "{YOUR_AIRTABLE_TABLE_NAME}"
},
"options": {},
"operation": "search"
},
"typeVersion": 2.1
},
{
"id": "d56e433c-447b-406f-8467-a8c5de082d5b",
"name": "스티커 메모",
"type": "n8n-nodes-base.stickyNote",
"position": [
-100,
1920
],
"parameters": {
"color": 3,
"width": 500,
"height": 300,
"content": "### Step 1: Airtable Trigger 🚦📋\n\nThis node triggers the workflow whenever there is a change in the **Created** column, effectively activating when new data is added.\n\nWhy this step is important:\n\n- ⏰ Automatically starts the workflow on new entries.\n- 📈 Monitors real-time changes for timely processing.\n- 🔄 Ensures your automation responds instantly to new Airtable data.\n\nIt’s the step that keeps your workflow synced with your Airtable updates. 🔔✨\n"
},
"typeVersion": 1
},
{
"id": "44f16735-21cb-4a35-bb97-45bf8ec79469",
"name": "스티커 메모1",
"type": "n8n-nodes-base.stickyNote",
"position": [
620,
1040
],
"parameters": {
"width": 460,
"height": 300,
"content": "### Step 2: Airtable Search Records 🔍📋\n\nThis node searches and retrieves all records from a specific Airtable table.\n\nWhy this step is important:\n\n- 🔎 Gathers complete data from the table for processing.\n- 📊 Enables further filtering, updating, or analysis within the workflow.\n- 🗂️ Provides a snapshot of all relevant records at once.\n\nIt’s the step that collects your data foundation for the automation ahead. 🧱✨\n"
},
"typeVersion": 1
},
{
"id": "430acba9-f9ad-424f-888e-a239968e9bbf",
"name": "스티커 메모2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1360,
1220
],
"parameters": {
"color": 5,
"width": 500,
"height": 300,
"content": "### Step 3: Status Check (If Node) ✅❌\n\nThis node checks whether the **Status** field is set to **'Approved for Invoicing'**.\n\n- **True:** Continues with the workflow.\n- **False:** Gracefully exits the workflow.\n\nWhy this step is important:\n\n- ✔️ Ensures only approved records proceed for invoicing.\n- 🛑 Prevents processing of draft or already invoiced data.\n- 🔄 Maintains workflow efficiency and accuracy."
},
"typeVersion": 1
},
{
"id": "5d2740d4-c4fc-4290-914c-bcbff9202b1c",
"name": "스티커 메모3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2200,
2080
],
"parameters": {
"color": 3,
"width": 520,
"height": 300,
"content": "### Graceful Exit (No-Op Node) 🛑✨\n\nThis **No Operation** node acts as a graceful exit point for items whose status is **not** 'Approved for Invoicing'.\n\nWhy this step is important:\n\n- 🛡️ Prevents further processing of unapproved records.\n- 🔄 Ensures the workflow ends cleanly without errors.\n- 🧹 Keeps workflow logic clear and organized.\n\nIt’s the safe landing spot that quietly ends the flow when no action is needed. 🚪✅\n"
},
"typeVersion": 1
},
{
"id": "12d6c762-e245-4203-b91d-a03ad0c39c5a",
"name": "워크플로우 종료",
"type": "n8n-nodes-base.noOp",
"position": [
2400,
1920
],
"parameters": {},
"typeVersion": 1
},
{
"id": "d3de759a-8382-4127-867f-84afbc9fb1b6",
"name": "스티커 메모4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2180,
800
],
"parameters": {
"color": 4,
"width": 460,
"height": 320,
"content": "### Step 4: Find Customer in QuickBooks 🔍👤\n\nThis node uses the **Find Customer** operation to search for a customer in QuickBooks based on the **Display Name** parameter.\n\nWhy this step is important:\n\n- 🔎 Quickly locates existing customers by their display name.\n- ✅ Helps avoid duplicate customer records.\n- 📋 Ensures accurate linking of invoices and estimates to the right customer.\n\nIt’s the step that verifies customer existence to maintain clean and organized data. 🧹✨\n"
},
"typeVersion": 1
},
{
"id": "2aa200ff-342e-4a9b-b46d-956dc31ea3e1",
"name": "스티커 메모5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2820,
1480
],
"parameters": {
"color": 6,
"width": 580,
"height": 340,
"content": "### Step 5: Customer Existence Check (If Node) ❓✅❌\n\nThis node checks whether a customer exists in QuickBooks.\n\n- **False:** Customer exists; workflow continues without creating a new customer.\n- **True:** Customer does **not** exist; triggers creation of a new customer before continuing.\n\nWhy this step is important:\n\n- 🔄 Directs the workflow to create a customer only when needed.\n- 🛡️ Prevents duplicate customer entries.\n- ⚙️ Ensures smooth, logical progression of the automation.\n\nIt’s the decision point that manages customer creation intelligently. 🔀✨\n"
},
"typeVersion": 1
},
{
"id": "054ac6a9-7198-49d3-8005-8291e2b99de1",
"name": "스티커 메모6",
"type": "n8n-nodes-base.stickyNote",
"position": [
3480,
780
],
"parameters": {
"color": 4,
"width": 480,
"height": 300,
"content": "Create Customer in QuickBooks ➕👤\n\nThis node uses the **Create Customer** operation to add a new customer to QuickBooks using details from Airtable.\n\nWhy this step is important:\n\n- 🆕 Adds new customers automatically when they don’t exist.\n- 📥 Keeps your QuickBooks customer database current and accurate.\n- 🔗 Links customer records to subsequent invoices or estimates.\n\nIt’s the step that fills gaps in your customer list, ensuring seamless data flow. ✍️✨\n"
},
"typeVersion": 1
},
{
"id": "e656e242-fcd7-4f4b-b8c7-1093e6873c9d",
"name": "스티커 메모7",
"type": "n8n-nodes-base.stickyNote",
"position": [
4160,
1180
],
"parameters": {
"width": 500,
"height": 300,
"content": "### Step 6: Merge Customer Data Node 🔗📊\n\nThis node merges data from existing customers with newly created customer records.\n\nWhy this step is important:\n\n- 🔄 Combines customer information into a single dataset.\n- 📋 Ensures continuity and completeness of customer details.\n- ⚙️ Prepares unified data for downstream workflow steps.\n\nIt’s the step that brings together all customer data for seamless processing. 🤝✨\n"
},
"typeVersion": 1
},
{
"id": "43640cbe-d8c0-4d46-a8be-71ed26deaf88",
"name": "IF - Stripe 고객 ID",
"type": "n8n-nodes-base.if",
"position": [
5100,
1180
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0e0b7c72-589a-4d76-9201-cbc4cfdc9c70",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $('Search records').item.json['Stripe Customer ID'] }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e7fd405d-2dca-453d-ad16-086d855393e0",
"name": "스티커 메모8",
"type": "n8n-nodes-base.stickyNote",
"position": [
4840,
800
],
"parameters": {
"color": 3,
"width": 600,
"height": 340,
"content": "### Step 7: Stripe Customer ID Check (If Node) 🔍💳\n\nThis node checks whether the **Stripe Customer ID** already exists for users in Airtable.\n\n- **True:** Stripe Customer ID exists; proceeds to find the customer.\n- **False:** Stripe Customer ID does not exist; continues with the workflow to create or update as needed.\n\nWhy this step is important:\n\n- ✅ Prevents duplicate Stripe customer entries.\n- 🔄 Directs the workflow along the correct path based on Stripe data.\n- ⚙️ Maintains data integrity across systems.\n\nIt’s the decision point that manages Stripe customer handling efficiently. 🔀✨\n"
},
"typeVersion": 1
},
{
"id": "d8810872-3110-450d-a87e-a68c6acec976",
"name": "스티커 메모9",
"type": "n8n-nodes-base.stickyNote",
"position": [
5540,
680
],
"parameters": {
"color": 5,
"width": 580,
"height": 300,
"content": "Find Customer in Stripe 🔍💳\n\nThis node uses the **Find Customer** operation to search for a customer in Stripe based on the **Stripe Customer ID**.\n\nWhy this step is important:\n\n- 🔎 Quickly locates the customer record in Stripe.\n- ✅ Ensures accurate synchronization between your systems.\n- 📋 Prevents duplicate customer creation in Stripe.\n\nIt’s the step that verifies Stripe customer existence to maintain clean and consistent billing data. 🧹✨\n"
},
"typeVersion": 1
},
{
"id": "0af13885-0000-48a4-9a1a-5ca0695d4329",
"name": "Stripe 고객 병합",
"type": "n8n-nodes-base.merge",
"position": [
6320,
1460
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "66ce007d-361a-44d1-b397-c8bf354bc62a",
"name": "스티커 메모10",
"type": "n8n-nodes-base.stickyNote",
"position": [
6180,
1620
],
"parameters": {
"color": 6,
"width": 480,
"height": 300,
"content": "### Step 8: Merge Stripe Customer Data Node 🔗💳\n\nThis node merges data from the **If Node** decision with the newly retrieved customer data from the **Stripe - Find Customer** node.\n\nWhy this step is important:\n\n- 🔄 Combines decision results with fresh customer information.\n- 📊 Ensures unified data for further processing in the workflow.\n- ⚙️ Maintains data consistency across Stripe and Airtable.\n\nIt’s the step that integrates conditional logic with actual customer details for smooth automation. 🤝✨\n"
},
"typeVersion": 1
},
{
"id": "642cf14a-238f-4525-bc6c-a4d88ad2ff25",
"name": "스티커 메모11",
"type": "n8n-nodes-base.stickyNote",
"position": [
7020,
780
],
"parameters": {
"color": 3,
"width": 540,
"height": 340,
"content": "### Step 9: Stripe Customer Existence Check (If Node) 🔍✅❌\n\nThis node checks whether a Stripe customer exists based on the **name**.\n\n- **True:** Customer does **not** exist; proceeds to create a new customer.\n- **False:** Customer exists; continues with the workflow without creating.\n\nWhy this step is important:\n\n- ✅ Prevents duplicate Stripe customer creation.\n- 🔄 Directs workflow to create customers only when necessary.\n- ⚙️ Ensures clean and accurate Stripe customer data.\n\nIt’s the decision gate that manages Stripe customer creation smartly. 🔀✨\n"
},
"typeVersion": 1
},
{
"id": "fe468b60-5f78-4a61-9262-a0c24e2054e8",
"name": "스티커 메모12",
"type": "n8n-nodes-base.stickyNote",
"position": [
7740,
640
],
"parameters": {
"width": 500,
"height": 320,
"content": "Create Customer in Stripe ➕💳\n\nThis node uses the **Create Customer** operation to add a new customer in Stripe using the **name** and **email address** from Airtable.\n\nWhy this step is important:\n\n- 🆕 Automatically adds new customers to Stripe when they don’t exist.\n- 📧 Uses accurate customer details from Airtable for Stripe records.\n- 🔗 Ensures Stripe customer data is up-to-date and linked correctly.\n\nIt’s the step that expands your Stripe customer base seamlessly from Airtable data. ✍️✨\n"
},
"typeVersion": 1
},
{
"id": "84f2c126-13e0-4999-95ed-c62155473934",
"name": "스티커 메모13",
"type": "n8n-nodes-base.stickyNote",
"position": [
8320,
1540
],
"parameters": {
"color": 5,
"width": 520,
"height": 300,
"content": "### Step 10: Merge New Stripe Customer Data Node 🔗💳\n\nThis node merges data from the previous **If Node** with the newly created Stripe customer data.\n\nWhy this step is important:\n\n- 🔄 Combines decision results with fresh customer creation data.\n- 📊 Provides a unified dataset for downstream processing.\n- ⚙️ Ensures consistency and completeness of customer information.\n\nIt’s the step that integrates newly created Stripe customer details seamlessly into the workflow. 🤝✨\n"
},
"typeVersion": 1
},
{
"id": "d72208de-119a-4cc7-8f41-c04e8534fdf5",
"name": "이메일로 기록 검색",
"type": "n8n-nodes-base.airtable",
"position": [
9260,
1080
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "{YOUR_AIRTABLE_BASE_ID}",
"cachedResultUrl": "https://airtable.com/{YOUR_AIRTABLE_BASE_ID}",
"cachedResultName": "{YOUR_AIRTABLE_BASE_NAME}"
},
"table": {
"__rl": true,
"mode": "list",
"value": "{YOUR_AIRTABLE_TABLE_ID}",
"cachedResultUrl": "https://airtable.com/{YOUR_AIRTABLE_BASE_ID}/{YOUR_AIRTABLE_TABLE_ID}",
"cachedResultName": "{YOUR_AIRTABLE_TABLE_NAME}"
},
"options": {},
"operation": "search",
"filterByFormula": "={Client Email} = \"{{ $json.email }}\""
},
"typeVersion": 2.1,
"alwaysOutputData": true
},
{
"id": "0dc8e7c1-e027-4641-9618-357f72d67039",
"name": "스티커 메모14",
"type": "n8n-nodes-base.stickyNote",
"position": [
9060,
760
],
"parameters": {
"color": 6,
"width": 480,
"height": 300,
"content": "### Step 11: Search Records in Airtable 🔍📋\n\nThis node searches for complete records in the Airtable table based on the **email address** from the previous merge node.\n\nWhy this step is important:\n\n- 🔎 Retrieves full user data linked to the email.\n- 📊 Ensures accurate and updated information for the workflow.\n- ⚙️ Enables precise matching and further processing.\n\nIt’s the step that pulls detailed Airtable records to keep your automation data-rich and reliable. 📚✨\n"
},
"typeVersion": 1
},
{
"id": "62d46511-8cf8-4160-a242-bea2e4e81086",
"name": "QuickBooks 및 Stripe 고객 ID 업데이트",
"type": "n8n-nodes-base.airtable",
"position": [
9980,
1400
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "{YOUR_AIRTABLE_BASE_ID}",
"cachedResultUrl": "https://airtable.com/{YOUR_AIRTABLE_BASE_ID}",
"cachedResultName": "{YOUR_AIRTABLE_BASE_NAME}"
},
"table": {
"__rl": true,
"mode": "list",
"value": "{YOUR_AIRTABLE_TABLE_ID}",
"cachedResultUrl": "https://airtable.com/{YOUR_AIRTABLE_BASE_ID}/{YOUR_AIRTABLE_TABLE_ID}",
"cachedResultName": "{YOUR_AIRTABLE_TABLE_NAME}"
},
"columns": {
"value": {
"id": "={{ $json.id }}",
"Stripe Customer ID": "={{ $('Merge Stripe Customer').item.json.id }}",
"QuickBooks Customer ID": "={{ $('Merge QBO Customer').item.json.Id }}"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "id",
"defaultMatch": true
},
{
"id": "Deal Name",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Deal Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Name",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Client Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Email",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Client Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "options",
"display": true,
"options": [
{
"name": "Approved for Invoicing",
"value": "Approved for Invoicing"
},
{
"name": "Draft",
"value": "Draft"
},
{
"name": "Invoiced",
"value": "Invoiced"
}
],
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Line Items JSON",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Line Items JSON",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "QuickBooks Customer ID",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "QuickBooks Customer ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Stripe Customer ID",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Stripe Customer ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Stripe Payment Link",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Stripe Payment Link",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "QuickBooks Invoice #",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "QuickBooks Invoice #",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update"
},
"typeVersion": 2.1
},
{
"id": "5cbaa7bd-1ef6-49d8-8b61-fef3f2d3090c",
"name": "스티커 메모15",
"type": "n8n-nodes-base.stickyNote",
"position": [
9780,
1580
],
"parameters": {
"width": 520,
"height": 300,
"content": "### Step 12: Update Records in Airtable ✏️🔄\n\nThis node updates the Airtable records to add or modify the **QuickBooks Customer ID** and **Stripe Customer ID** for the corresponding users.\n\nWhy this step is important:\n\n- 🆕 Keeps Airtable data synchronized with QuickBooks and Stripe.\n- 🔗 Ensures accurate linking of customer IDs across platforms.\n- 🔄 Maintains data integrity for future workflows and reports.\n\nIt’s the step that closes the loop by updating your source data with key customer identifiers. ✅✨\n"
},
"typeVersion": 1
},
{
"id": "cdd5c85d-1168-4b4e-ab95-b17132f0bd10",
"name": "결제 링크 생성",
"type": "n8n-nodes-base.httpRequest",
"position": [
10700,
1080
],
"parameters": {
"url": "https://api.stripe.com/v1/payment_links",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "form-urlencoded",
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "line_items[0][price]",
"value": "={{ $json.fields['Stripe Price Id'] }}"
},
{
"name": "line_items[0][quantity]",
"value": "={{ $json.fields.Quantity }}"
}
]
},
"nodeCredentialType": "stripeApi"
},
"typeVersion": 4.2
},
{
"id": "86d2ad6f-2501-4885-9f61-40563bcd132a",
"name": "스티커 메모16",
"type": "n8n-nodes-base.stickyNote",
"position": [
10500,
760
],
"parameters": {
"color": 3,
"width": 520,
"height": 300,
"content": "### Step 13: Generate Stripe Payment Link (HTTP Request) 🔗💳\n\nThis node sends a **POST** HTTP request with the **Stripe Price ID** and **quantity** from Airtable to generate a ready-to-pay link.\n\nWhy this step is important:\n\n- 🛒 Creates a payment link dynamically based on order details.\n- 🔗 Enables easy and secure customer checkout.\n- ⚡ Automates payment initiation directly from your data.\n\nIt’s the step that turns order info into a clickable payment link, simplifying the checkout process. 🔥✨\n"
},
"typeVersion": 1
},
{
"id": "cce1f3fd-3731-41ea-8b6c-b1b6872f571c",
"name": "모든 QuickBook 제품 가져오기",
"type": "n8n-nodes-base.httpRequest",
"position": [
11440,
1400
],
"parameters": {
"url": "https://quickbooks.api.intuit.com/v3/company/{YOUR_QUICKBOOKS_COMPANY_ID}/query?query=SELECT%20*%20FROM%20Item",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "quickBooksOAuth2Api"
},
"typeVersion": 4.2
},
{
"id": "e4819fee-6591-45cf-b9e7-000ec6ba07e4",
"name": "스티커 메모17",
"type": "n8n-nodes-base.stickyNote",
"position": [
11240,
1580
],
"parameters": {
"width": 540,
"height": 280,
"content": "### Step 14: Fetch All Products from QuickBooks (HTTP Request) 📦🔍\n\nThis node sends an HTTP request to retrieve all products from QuickBooks.\n\nWhy this step is important:\n\n- 📋 Gathers the full product catalog for reference or processing.\n- 🔄 Keeps your workflow updated with the latest product information.\n- ⚙️ Enables product data integration across your automation.\n\nIt’s the step that pulls your product inventory into the workflow for seamless management. 📦✨\n"
},
"typeVersion": 1
},
{
"id": "29e7df5d-6b99-44a4-8493-d3c2aec66353",
"name": "스티커 메모18",
"type": "n8n-nodes-base.stickyNote",
"position": [
12060,
760
],
"parameters": {
"color": 6,
"width": 540,
"height": 300,
"content": "### Step 15: Filter Products by Airtable Data (Code Node) ⚙️🔍\n\nThis node runs custom code to filter and return only the product details that exist in Airtable.\n\nWhy this step is important:\n\n- 🎯 Narrows down the product list to relevant items.\n- 🔄 Improves workflow efficiency by processing only necessary data.\n- 📋 Ensures accuracy by matching QuickBooks products with Airtable records.\n\nIt’s the step that refines your product data for targeted automation. 🧹✨\n"
},
"typeVersion": 1
},
{
"id": "b6e2c9d4-502b-44e6-b907-8eab05c7561e",
"name": "필터링 및 제품 세부 정보 반환",
"type": "n8n-nodes-base.code",
"position": [
12260,
1100
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const airtableProductName = $('Update Quickbooks and Stripe Customer Ids').item.json.fields['Quickbooks Product Name'];\nconst quantity = $('Update Quickbooks and Stripe Customer Ids').item.json.fields.Quantity;\n\nconst quickBooksProducts = $json.QueryResponse.Item;\n\nconst matchingProduct = quickBooksProducts.find(product => product.Name === airtableProductName);\n\nif (matchingProduct) {\n const unitPrice = matchingProduct.UnitPrice || 0;\n const amount = unitPrice * (quantity || 0);\n\n return {\n json: {\n Id: matchingProduct.Id,\n Description: matchingProduct.Description,\n Amount: amount,\n }\n };\n} else {\n return {\n json: {\n Id: null,\n Description: null,\n Amount: 0,\n }\n };\n}\n"
},
"typeVersion": 2
},
{
"id": "4e309a57-bebd-4a0e-871f-1f66e7119099",
"name": "스티커 메모19",
"type": "n8n-nodes-base.stickyNote",
"position": [
12960,
1620
],
"parameters": {
"color": 4,
"width": 480,
"height": 300,
"content": "### Step 16: Create Invoice in QuickBooks 🧾✨\n\nThis node uses the **Create Invoice** operation to generate an invoice in QuickBooks based on data from previous nodes.\n\nWhy this step is important:\n\n- 📄 Converts collected data into a formal invoice.\n- 🔗 Links invoices to the correct customers and products.\n- ⚡ Automates billing and record-keeping processes.\n\nIt’s the step that issues the official invoice, completing the sales cycle. ✅✨\n"
},
"typeVersion": 1
},
{
"id": "52c262a3-df12-47a4-bc8a-73eaaea82ec8",
"name": "Stripe 결제 링크 및 QuickBooks 청구서 번호 업데이트",
"type": "n8n-nodes-base.airtable",
"position": [
13840,
1100
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "{YOUR_AIRTABLE_BASE_ID}",
"cachedResultUrl": "https://airtable.com/{YOUR_AIRTABLE_BASE_ID}",
"cachedResultName": "{YOUR_AIRTABLE_BASE_NAME}"
},
"table": {
"__rl": true,
"mode": "list",
"value": "{YOUR_AIRTABLE_TABLE_ID}",
"cachedResultUrl": "https://airtable.com/{YOUR_AIRTABLE_BASE_ID}/{YOUR_AIRTABLE_TABLE_ID}",
"cachedResultName": "{YOUR_AIRTABLE_TABLE_NAME}"
},
"columns": {
"value": {
"id": "={{ $('Update Quickbooks and Stripe Customer Ids').item.json.id }}",
"Status": "Invoiced",
"Stripe Payment Link": "={{ $('Generate Payment Links').item.json.url }}",
"QuickBooks Invoice #": "=INV-{{ $json.DocNumber }}"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "id",
"defaultMatch": true
},
{
"id": "Deal Name",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Deal Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Name",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Client Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Email",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Client Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "options",
"display": true,
"options": [
{
"name": "Approved for Invoicing",
"value": "Approved for Invoicing"
},
{
"name": "Draft",
"value": "Draft"
},
{
"name": "Invoiced",
"value": "Invoiced"
}
],
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Line Items JSON",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Line Items JSON",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "QuickBooks Customer ID",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "QuickBooks Customer ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Stripe Customer ID",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Stripe Customer ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Stripe Payment Link",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Stripe Payment Link",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "QuickBooks Invoice #",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "QuickBooks Invoice #",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Stripe Price Id",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Stripe Price Id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Quantity",
"type": "number",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Quantity",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Quickbooks Product Name",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Quickbooks Product Name",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update"
},
"typeVersion": 2.1
},
{
"id": "cba338d9-dbad-4cf8-becc-609892ba96dc",
"name": "스티커 메모20",
"type": "n8n-nodes-base.stickyNote",
"position": [
13640,
740
],
"parameters": {
"color": 5,
"width": 480,
"height": 320,
"content": "### Step 17: Update Airtable Records ✏️🔄\n\nThis node updates Airtable records with the newly created **Stripe Payment Link** and **QuickBooks Invoice #**.\n\nWhy this step is important:\n\n- 🔗 Keeps Airtable synchronized with payment and invoice details.\n- 📋 Provides easy access to transaction information within Airtable.\n- ⚡ Enhances tracking and reporting accuracy.\n\nIt’s the step that ensures your source data reflects the latest billing status. 📈✨\n"
},
"typeVersion": 1
},
{
"id": "e8125d20-5e72-443c-82ca-9f444ff91e1d",
"name": "워크플로우 완료",
"type": "n8n-nodes-base.noOp",
"position": [
14660,
1420
],
"parameters": {},
"typeVersion": 1
},
{
"id": "b3e74b53-f2e4-4c37-adb0-008766c0c21e",
"name": "스티커 메모21",
"type": "n8n-nodes-base.stickyNote",
"position": [
14500,
1560
],
"parameters": {
"color": 4,
"width": 500,
"height": 300,
"content": "### Step 18: Workflow Completion (No-Op Node) ✅🎉\n\nThis **No Operation** node marks the successful completion of the entire workflow.\n\nWhy this step is important:\n\n- 🎯 Signifies a clean and error-free end to the process.\n- 🛡️ Prevents unintended actions after workflow completion.\n- 🔄 Helps maintain clear workflow structure and readability.\n\nIt’s the final step that confirms your automation ran smoothly from start to finish. 🎬✨\n"
},
"typeVersion": 1
},
{
"id": "75b2998f-2369-425a-b88b-f8e7383861f1",
"name": "스티커 메모22",
"type": "n8n-nodes-base.stickyNote",
"position": [
-60,
40
],
"parameters": {
"color": 3,
"width": 620,
"height": 680,
"content": "### Prerequisites ⚙️🔗\n\n#### AIRTABLE\n- Create and connect your Airtable account using a **Personal Access Token**.\n- Create a table with the following columns:\n - **Deal Name** - Short representation of each record.\n - **Client Name** - Name of the client/customer.\n - **Client Email** - Email of the client/customer.\n - **Status** - Status of the deal (Draft, Approved for Invoicing, Invoiced).\n - **QuickBooks Customer ID** - ID of the client in QuickBooks.\n - **Stripe Customer ID** - ID of the client in Stripe.\n - **Stripe Payment Link** - Payment link from Stripe.\n - **QuickBooks Invoice #** - Invoice number from QuickBooks.\n - **Stripe Price Id** - Price ID of the product selected by the client in Stripe.\n - **Quantity** - Quantity of the product selected by the client.\n - **QuickBooks Product Name** - Name of the product from QuickBooks.\n - **Created** - Created timestamp.\n\n- Select the base and table in the **Airtable Trigger** node.\n- Connect and select the same base and table in all required Airtable nodes.\n\n#### QUICKBOOKS\n- Create and connect credentials using **OAuth2 authorization** in QuickBooks.\n- Use the same credentials across all QuickBooks nodes.\n- Add your company ID in the URL in the **Get all Quickbook products** node\n\n#### STRIPE\n- Generate and connect your Stripe account using the **Secret Key**.\n- Use these credentials in all required Stripe nodes.\n"
},
"typeVersion": 1
},
{
"id": "d88adcf9-9557-4759-9638-bfdd2f6e00b8",
"name": "스티커 메모23",
"type": "n8n-nodes-base.stickyNote",
"position": [
14500,
900
],
"parameters": {
"width": 360,
"height": 300,
"content": "### Get in Touch\n\nPlease feel free to reachout to us, if you need any help in settin up this workflow.\n\nWe can also help customize workflow pet the use-case. \n\nReach out us at: getstarted@intuz.com\n\nWebsite: https://www.intuz.com/\n\n"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "e10a1c5b-b5c4-4861-a1b7-8cf52907b464",
"connections": {
"8b371200-572e-4995-b7d7-d496751342f4": {
"main": [
[
{
"node": "45863a72-e832-448e-88e6-edb6ee1c8908",
"type": "main",
"index": 0
}
]
]
},
"989dcbdc-5d15-45df-bb0e-db6049c537e2": {
"main": [
[
{
"node": "8b371200-572e-4995-b7d7-d496751342f4",
"type": "main",
"index": 0
}
]
]
},
"b1330d78-6e36-4296-98b0-0312804e955d": {
"main": [
[
{
"node": "2cb49f5e-08f7-46ea-afab-217e98908a14",
"type": "main",
"index": 0
}
]
]
},
"497c8d82-1916-4ac6-acd2-7fdc561d3919": {
"main": [
[
{
"node": "52c262a3-df12-47a4-bc8a-73eaaea82ec8",
"type": "main",
"index": 0
}
]
]
},
"45863a72-e832-448e-88e6-edb6ee1c8908": {
"main": [
[
{
"node": "4c99441c-1f72-49d6-b421-62e3c2c72b28",
"type": "main",
"index": 0
}
],
[
{
"node": "12d6c762-e245-4203-b91d-a03ad0c39c5a",
"type": "main",
"index": 0
}
]
]
},
"2cb49f5e-08f7-46ea-afab-217e98908a14": {
"main": [
[
{
"node": "43640cbe-d8c0-4d46-a8be-71ed26deaf88",
"type": "main",
"index": 0
}
]
]
},
"43c615f1-777f-43da-8274-2b9ecce18aa0": {
"main": [
[
{
"node": "b1330d78-6e36-4296-98b0-0312804e955d",
"type": "main",
"index": 0
}
],
[
{
"node": "2cb49f5e-08f7-46ea-afab-217e98908a14",
"type": "main",
"index": 1
}
]
]
},
"0af13885-0000-48a4-9a1a-5ca0695d4329": {
"main": [
[
{
"node": "bd0adf89-499a-40ee-9e37-648ae0aad30d",
"type": "main",
"index": 0
}
]
]
},
"cdd5c85d-1168-4b4e-ab95-b17132f0bd10": {
"main": [
[
{
"node": "cce1f3fd-3731-41ea-8b6c-b1b6872f571c",
"type": "main",
"index": 0
}
]
]
},
"60920472-77b6-4243-89b0-f162f6e900d9": {
"main": [
[
{
"node": "0af13885-0000-48a4-9a1a-5ca0695d4329",
"type": "main",
"index": 1
}
]
]
},
"43640cbe-d8c0-4d46-a8be-71ed26deaf88": {
"main": [
[
{
"node": "60920472-77b6-4243-89b0-f162f6e900d9",
"type": "main",
"index": 0
}
],
[
{
"node": "0af13885-0000-48a4-9a1a-5ca0695d4329",
"type": "main",
"index": 0
}
]
]
},
"d72208de-119a-4cc7-8f41-c04e8534fdf5": {
"main": [
[
{
"node": "62d46511-8cf8-4160-a242-bea2e4e81086",
"type": "main",
"index": 0
}
]
]
},
"ea27b7d1-4e6e-4620-b402-b0b8e0db436d": {
"main": [
[
{
"node": "0af13885-0000-48a4-9a1a-5ca0695d4329",
"type": "main",
"index": 0
}
]
]
},
"cce1f3fd-3731-41ea-8b6c-b1b6872f571c": {
"main": [
[
{
"node": "b6e2c9d4-502b-44e6-b907-8eab05c7561e",
"type": "main",
"index": 0
}
]
]
},
"4c99441c-1f72-49d6-b421-62e3c2c72b28": {
"main": [
[
{
"node": "43c615f1-777f-43da-8274-2b9ecce18aa0",
"type": "main",
"index": 0
}
]
]
},
"bd0adf89-499a-40ee-9e37-648ae0aad30d": {
"main": [
[
{
"node": "ea27b7d1-4e6e-4620-b402-b0b8e0db436d",
"type": "main",
"index": 0
}
],
[
{
"node": "0af13885-0000-48a4-9a1a-5ca0695d4329",
"type": "main",
"index": 1
}
]
]
},
"b6e2c9d4-502b-44e6-b907-8eab05c7561e": {
"main": [
[
{
"node": "497c8d82-1916-4ac6-acd2-7fdc561d3919",
"type": "main",
"index": 0
}
]
]
},
"62d46511-8cf8-4160-a242-bea2e4e81086": {
"main": [
[
{
"node": "cdd5c85d-1168-4b4e-ab95-b17132f0bd10",
"type": "main",
"index": 0
}
]
]
},
"52c262a3-df12-47a4-bc8a-73eaaea82ec8": {
"main": [
[
{
"node": "e8125d20-5e72-443c-82ca-9f444ff91e1d",
"type": "main",
"index": 0
}
]
]
}
}
}이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
고급 - 청구서 처리, 멀티모달 AI
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
Intuz
@intuzWorkflow automation can help automate your routine activities and help saves $$$, as well as hours of time. As a boutique tech consulting company, Intuz help businesses with custom AI/ML, AI Workflow Automations, and software development. Automate your business workflow for: Sales Marketing Accounting Finance Operations E-Commerce Customer Support Admin & Backoffice Logistics & Supply Chain
이 워크플로우 공유