{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "46e661c8-a327-49d0-87e0-1f04332719eb",
      "name": "Webhook Trigger - Invoice Created",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -976,
        160
      ],
      "parameters": {
        "path": "225363a4-5e45-46b5-aefe-8ca0a4fa27b2",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 1.1
    },
    {
      "id": "46877753-f483-4723-b94c-ef44eb4d4ec4",
      "name": "Webhook - Payment Received",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -848,
        624
      ],
      "parameters": {
        "path": "1f435bd2-cbfe-4c4d-9cbd-cc3bf4f8e10a",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 1.1
    },
    {
      "id": "fc186c16-7e9b-4a82-be6d-f80cdbc5970b",
      "name": "Xero - Create Invoice",
      "type": "n8n-nodes-base.xero",
      "position": [
        -752,
        160
      ],
      "parameters": {
        "type": "ACCREC",
        "contactId": "Your_Contact_ID",
        "lineItemsUi": {
          "lineItemsValues": [
            {
              "taxType": "OUTPUT",
              "itemCode": "=",
              "quantity": "={{ $json.body.lineItems[0].quantity }}",
              "taxAmount": "={{ $json.body.totalAmount * 0.007 }}",
              "lineAmount": "={{ $json.body.totalAmount }}",
              "unitAmount": "={{ $json.body.lineItems[0].unitAmount }}",
              "accountCode": "200",
              "description": "={{ $json.body.lineItems[0].description }}"
            }
          ]
        },
        "organizationId": "a5917db9-07f1-40dc-b5f6-c55b39730d0f",
        "additionalFields": {
          "status": "AUTHORISED",
          "dueDate": "={{ $json.body.dueDate }}",
          "reference": "={{ $json.body.reference }}",
          "invoiceNumber": "={{ $json.body.invoiceNumber }}"
        }
      },
      "credentials": {
        "xeroOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "28cd7036-ad73-4808-9358-d286a30aa713",
      "name": "IF - Invoice Created Successfully",
      "type": "n8n-nodes-base.if",
      "position": [
        -528,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-1",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.Status }}",
              "rightValue": "AUTHORISED"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "3defccf8-8d1e-4090-a66e-a42ec8ebfd0c",
      "name": "Google Calendar - Create Due Date Event",
      "type": "n8n-nodes-base.googleCalendar",
      "position": [
        -80,
        64
      ],
      "parameters": {
        "end": "={{ $json[\"Due Date\"] }}T10:00:00",
        "start": "={{ $json[\"Due Date\"] }}T09:00:00",
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "user@example.com",
          "cachedResultName": "user@example.com"
        },
        "additionalFields": {
          "sendUpdates": "all"
        }
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "91bec07f-240b-4a65-a99e-84e3c4a5a6fd",
      "name": "WhatsApp - Send Invoice Confirmation",
      "type": "n8n-nodes-base.twilio",
      "position": [
        144,
        64
      ],
      "parameters": {
        "to": "Recipient_number",
        "from": "Your_number",
        "message": "=Hello {{ $('IF - Invoice Created Successfully').item.json.Contact.Name }},\n\nYour invoice #{{ $('IF - Invoice Created Successfully').item.json.InvoiceNumber }} for {{  $('IF - Invoice Created Successfully').item.json.Total }} has been created.\n\n\ud83d\udcc4 Due Date: {{ $('IF - Invoice Created Successfully').item.json.DueDateString }}\n\ud83d\udcb3 Amount: {{ $('IF - Invoice Created Successfully').item.json.Total }}\n\nPlease ensure payment is made by the due date.\n\nThank you!",
        "options": {},
        "toWhatsapp": true
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "dc9f2c38-1ea9-4023-aaac-83e1fe0d576b",
      "name": "Respond to Webhook - Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        368,
        64
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ { \"success\": true, \"message\": \"Invoice created and notifications sent\", \"invoiceId\": $json.invoiceId } }}"
      },
      "typeVersion": 1
    },
    {
      "id": "80970a52-22ab-45a2-b12a-09787ab1b3a4",
      "name": "Respond to Webhook - Error",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -304,
        256
      ],
      "parameters": {
        "options": {
          "responseCode": 500
        },
        "respondWith": "json",
        "responseBody": "={{ { \"success\": false, \"message\": \"Invoice creation failed\", \"error\": $json.error } }}"
      },
      "typeVersion": 1
    },
    {
      "id": "66eec00c-c906-4ce7-af0d-663627a35026",
      "name": "Google Calendar - Remove Due Date Event",
      "type": "n8n-nodes-base.googleCalendar",
      "position": [
        48,
        624
      ],
      "parameters": {
        "eventId": "={{ $json.calendarEventId }}",
        "options": {},
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "user@example.com",
          "cachedResultName": "user@example.com"
        },
        "operation": "delete"
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d590ac64-9726-4281-b623-d0c3f067000e",
      "name": "Respond to Webhook - Payment",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        272,
        624
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ { \"success\": true, \"message\": \"Payment processed successfully\" } }}"
      },
      "typeVersion": 1
    },
    {
      "id": "5a9bef7d-00d0-4445-838d-22c4b775709d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1120,
        -32
      ],
      "parameters": {
        "color": 7,
        "width": 1712,
        "height": 480,
        "content": "## 1. Create invoice, send notification and log"
      },
      "typeVersion": 1
    },
    {
      "id": "ae217e1c-558d-478e-b306-2d7018c6e191",
      "name": "Xero - Update Invoice to Paid1",
      "type": "n8n-nodes-base.xero",
      "position": [
        -432,
        624
      ],
      "parameters": {
        "invoiceId": "={{ $json.body.invoiceId }}",
        "operation": "update",
        "updateFields": {},
        "organizationId": "a5917db9-07f1-40dc-b5f6-c55b39730d0f"
      },
      "credentials": {
        "xeroOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "bfbf6c28-9698-44f7-83ea-136decf182b7",
      "name": "WhatsApp - Send Invoice Confirmation1",
      "type": "n8n-nodes-base.twilio",
      "position": [
        -192,
        624
      ],
      "parameters": {
        "to": "Recipient_number",
        "from": "Your_number",
        "message": "=Hello {{ $json.clientName }},\n\n\u2705 Payment Received!\n\nWe have received your payment of {{ $json.paymentAmount }} for Invoice #{{ $json.invoiceNumber }}.\n\n\ud83c\udf89 Thank you for your prompt payment!\n\nTransaction ID: {{ $json.transactionId }}",
        "options": {},
        "toWhatsapp": true
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d6f9e06a-b35e-4491-8144-9f25742d3c61",
      "name": "Add Invoice Record",
      "type": "n8n-nodes-base.postgres",
      "notes": "Optional: Enable if using PostgreSQL for logging",
      "position": [
        -288,
        64
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "invoice_logs",
          "cachedResultName": "invoice_logs"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "id": 0,
            "Amount": "={{ $json.AmountDue }}",
            "Status": "={{ $json.Contact.ContactStatus }}",
            "Due Date": "={{ $json.Date }}",
            "timestamp": "={{ $json.DateString }}",
            "invoice_id": "={{ $json.InvoiceID }}",
            "Client Name": "={{ $json.Contact.Name }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "number",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Client Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Amount",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Due Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Due Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "invoice_id",
              "type": "string",
              "display": true,
              "required": true,
              "displayName": "invoice_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Created Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Created Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Reminders Sent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Payment Reminders Sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Reminder Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Last Reminder Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Payment Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Client Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Phone",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Client Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "91b4f81e-35dd-42ee-892b-129e1aad06dd",
      "name": "PostgreSQL - Update Payment Status",
      "type": "n8n-nodes-base.postgres",
      "notes": "Optional: Enable if using PostgreSQL for logging",
      "position": [
        -640,
        624
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "invoice_logs",
          "cachedResultName": "invoice_logs"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "id": 0,
            "invoice_id": "{{ $json.body.invoiceId }}",
            "Payment Date": "={{ $json.body.paymentDate }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "number",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Client Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Amount",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Due Date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Due Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "invoice_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": true,
              "displayName": "invoice_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Created Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Created Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Reminders Sent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Payment Reminders Sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Reminder Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Last Reminder Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Payment Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Client Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Phone",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Client Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id",
            "invoice_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update"
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "92e31fcd-2448-46bd-8691-6d080d3ea60d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1024,
        496
      ],
      "parameters": {
        "color": 7,
        "width": 1552,
        "height": 336,
        "content": "## 2. Check and update payments, send notification and cancel event"
      },
      "typeVersion": 1
    },
    {
      "id": "090248e1-88ab-4977-b046-6065a3e683c9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1728,
        -32
      ],
      "parameters": {
        "width": 480,
        "height": 624,
        "content": "## Xero Invoice and Payment Automation Using n8n, PostgreSQL, and WhatsApp\n\n## How it works\n- **Webhook Trigger nodes** call the data from the source\n- **Xero nodes** are used to create and update invoices\n- **If node** to verify if invoice is successfully created\n- **PostgreSQL nodes serve as a database to log invoice records and update\n- Google Calendar nodes** are to log and modify the calendar event\n- **Twilio nodes** are to send WhatsApp notifications\n- **Respond webhook nodes** to send webhook responses\n\n## Setup\n1. Go to [xero](https://www.xero.com/), create an App, get details and add to credentials, then match\n2. Go to [Supabase](https://supabase.com/), create a table with the required details, connect and add to PostgreSQL credentials. P.S. This is not a mistake\n3. Enable Google Calendar from [Google Cloud console](https://console.cloud.google.com/) and connect to credentials\n4. Go to [Twilio](https://www.twilio.com/en-us) and connect to n8n credential. Get your WhatsApp number there, too\n5. Match the webhook to the payment data source and match the data in the nodes"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Add Invoice Record": {
      "main": [
        [
          {
            "node": "Google Calendar - Create Due Date Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Xero - Create Invoice": {
      "main": [
        [
          {
            "node": "IF - Invoice Created Successfully",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook - Payment Received": {
      "main": [
        [
          {
            "node": "PostgreSQL - Update Payment Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Xero - Update Invoice to Paid1": {
      "main": [
        [
          {
            "node": "WhatsApp - Send Invoice Confirmation1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF - Invoice Created Successfully": {
      "main": [
        [
          {
            "node": "Add Invoice Record",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond to Webhook - Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook Trigger - Invoice Created": {
      "main": [
        [
          {
            "node": "Xero - Create Invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PostgreSQL - Update Payment Status": {
      "main": [
        [
          {
            "node": "Xero - Update Invoice to Paid1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WhatsApp - Send Invoice Confirmation": {
      "main": [
        [
          {
            "node": "Respond to Webhook - Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WhatsApp - Send Invoice Confirmation1": {
      "main": [
        [
          {
            "node": "Google Calendar - Remove Due Date Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Calendar - Create Due Date Event": {
      "main": [
        [
          {
            "node": "WhatsApp - Send Invoice Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Calendar - Remove Due Date Event": {
      "main": [
        [
          {
            "node": "Respond to Webhook - Payment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}