{
  "name": "Sync paid Shopify orders, products, and customers to Odoo",
  "tags": [],
  "nodes": [
    {
      "id": "3323c4e6-acbb-415f-9f93-1289606644da",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -816,
        -112
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Sync paid Shopify orders, products, and customers to Odoo\n\n### How it works\n\nThis workflow listens for paid Shopify order events, validates the incoming payload, then synchronizes the related customer, products, and order lines into Odoo. It searches for existing Odoo customers and products, creates missing records, aggregates the Shopify line items, and builds a corresponding Odoo sale order. After a successful sync it notifies Sales-Ops in Slack and sends a Gmail confirmation, while failures are routed to a centralized Slack error notification path.\n\n### Setup steps\n\n- Configure the Shopify Trigger with the correct Shopify credentials, store, and paid-order event/topic.\n- Configure Odoo credentials and confirm the customer, product, and sale order models/fields match the mappings used in the Odoo and Set nodes.\n- Configure Slack credentials and select the Sales-Ops success channel and the sync-error alert channel.\n- Configure Gmail credentials and update the confirmation email recipient, subject, and body templates.\n- Review the validation conditions and field mappings for Shopify order IDs, customer email/name, SKU, quantity, and Odoo record IDs before activating the workflow.\n\n### Customization\n\nAdjust the product and customer matching logic, such as matching products by SKU or barcode and customers by email or external Shopify ID. You can also customize Slack messages, email templates, Odoo sale order defaults, taxes, pricelists, warehouses, and payment terms."
      },
      "typeVersion": 1
    },
    {
      "id": "258e4568-5720-4908-9044-eea9a9b14d4a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -256,
        336
      ],
      "parameters": {
        "color": 7,
        "width": 512,
        "height": 336,
        "content": "## Receive and validate order\n\nStarts the workflow from a Shopify paid-order event and checks whether the payload is suitable for synchronization before branching into customer, product, or error handling paths."
      },
      "typeVersion": 1
    },
    {
      "id": "36c6084a-425a-476c-a2d7-52c764c6eb3d",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 768,
        "height": 304,
        "content": "## Lookup order products\n\nSplits Shopify order line items into individual records, searches for matching products in Odoo, and decides whether each product already exists."
      },
      "typeVersion": 1
    },
    {
      "id": "48a46cc3-5f3c-4cab-83d3-431e37375349",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1264,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 624,
        "content": "## Map or create products\n\nHandles the product resolution branch by mapping existing Odoo products or creating missing products, then standardizing product IDs, names, SKUs, and quantities for order-line construction."
      },
      "typeVersion": 1
    },
    {
      "id": "0df50c24-35bc-4c90-975f-e358e90cb333",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1856,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 240,
        "height": 368,
        "content": "## Aggregate product lines\n\nCollects the mapped product line data back into a single order-lines structure that can be merged with the customer data."
      },
      "typeVersion": 1
    },
    {
      "id": "b14728a4-ee9e-402f-acc1-b6dc1112a647",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        624
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 320,
        "content": "## Lookup order customer\n\nSearches Odoo for the Shopify customer and determines whether an existing customer record can be reused or a new one must be created."
      },
      "typeVersion": 1
    },
    {
      "id": "92ec98d5-fd80-4d5f-81c2-f1ac0e419964",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        544
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 560,
        "content": "## Map or create customer\n\nMaps an existing customer or creates a new Odoo customer, then prepares a normalized customer payload with the Odoo customer ID, name, and email."
      },
      "typeVersion": 1
    },
    {
      "id": "6e651f17-4d4c-442b-9cab-fe583b72a752",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        384
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 304,
        "content": "## Create Odoo sale order\n\nMerges the customer information with the aggregated product lines and creates the final sale order in Odoo."
      },
      "typeVersion": 1
    },
    {
      "id": "d008f84c-d3fe-4890-a6fa-0fc380fc87a7",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2752,
        352
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 320,
        "content": "## Send success notifications\n\nSends a successful sync notification to the Sales-Ops Slack channel and follows up with a Gmail confirmation email."
      },
      "typeVersion": 1
    },
    {
      "id": "c9059fd7-9d85-4e36-838c-052a95dc91db",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2464,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 336,
        "content": "## Handle sync errors\n\nCentralized error path that formats sync failure details and notifies the appropriate Slack channel when validation, Odoo operations, Slack, or Gmail steps fail."
      },
      "typeVersion": 1
    },
    {
      "id": "3d01c0ec-d79e-4e85-8895-215236afef15",
      "name": "When Shopify Order Created",
      "type": "n8n-nodes-base.shopifyTrigger",
      "position": [
        -208,
        512
      ],
      "parameters": {
        "topic": "orders/paid"
      },
      "typeVersion": 1
    },
    {
      "id": "88e5b997-3c29-4083-b898-ff12351935cc",
      "name": "If Order Payload Valid",
      "type": "n8n-nodes-base.if",
      "position": [
        112,
        512
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3be01a7c-0d2e-4d36-821c-c8a1990fe488",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ Array.isArray($json.line_items) && $json.line_items.length > 0 }}",
              "rightValue": ""
            },
            {
              "id": "d2e8eafb-c041-4e80-b211-ab44cf1a8f79",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ !!($json.customer && $json.customer.email) }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "7ee71af4-947d-418b-b898-9aba60940219",
      "name": "Split Line Items",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        432,
        208
      ],
      "parameters": {
        "include": "selectedOtherFields",
        "options": {},
        "fieldToSplitOut": "line_items",
        "fieldsToInclude": "customer,email,shipping_address,billing_address,order_number,currency,financial_status,note,created_at"
      },
      "typeVersion": 1
    },
    {
      "id": "4f1ba33b-f382-4d08-a8ee-e93af49f7821",
      "name": "Find Product in Odoo",
      "type": "n8n-nodes-base.odoo",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        704,
        208
      ],
      "parameters": {
        "limit": 1,
        "options": {
          "fieldsList": "id,default_code,list_price,name"
        },
        "resource": "custom",
        "authentication": "odooApi",
        "customResource": {
          "__rl": true,
          "mode": "id",
          "value": "product.product",
          "cachedResultName": "product.product"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2,
      "alwaysOutputData": true,
      "waitBetweenTries": 5000
    },
    {
      "id": "a643b13f-c7a4-4dff-99e5-f260e8f8ee22",
      "name": "If Product Exists in Odoo",
      "type": "n8n-nodes-base.if",
      "position": [
        1008,
        208
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "5522c9d3-cbf1-422c-bbed-4f15607cb7f1",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ !!$json.default_code }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "acb21e05-e8ca-4e98-ab38-5ac61430318e",
      "name": "Set Existing Product Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1312,
        64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b1fbcf86-5ada-4040-8dc2-89677e9dedc8",
              "name": "odoo_product_id",
              "type": "number",
              "value": "={{ $json.id }}"
            },
            {
              "id": "c78e534a-e41c-43bf-bcd2-d750ee7d5a29",
              "name": "product_name",
              "type": "string",
              "value": "={{ $json.name }}"
            },
            {
              "id": "e229b64b-a580-4214-95c0-62f4a834c0ef",
              "name": "sku",
              "type": "string",
              "value": "={{ $('Split Line Items').item.json.sku }}"
            },
            {
              "id": "d1bc3d48-9ac0-4ee8-93e2-b25522ae7fe6",
              "name": "quantity",
              "type": "number",
              "value": "={{ $('Split Line Items').item.json.quantity }}"
            },
            {
              "id": "c0ac2604-369f-4a01-b03d-bc58cb725fe1",
              "name": "unit_price",
              "type": "number",
              "value": "={{ $('Split Line Items').item.json.price }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "2c31149c-2981-4ad8-b843-c8f000e178b3",
      "name": "Add Product to Odoo",
      "type": "n8n-nodes-base.odoo",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        1312,
        352
      ],
      "parameters": {
        "resource": "custom",
        "operation": "create",
        "fieldsToSend": {
          "value": {
            "name": "={{ $('Split Line Items').item.json.title }}",
            "list_price": "={{ $('Split Line Items').item.json.price }}",
            "default_code": "={{ $('Split Line Items').item.json.sku }}"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "authentication": "odooApi",
        "customResource": {
          "__rl": true,
          "mode": "id",
          "value": "product.product",
          "cachedResultName": "product.product"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2,
      "waitBetweenTries": 5000
    },
    {
      "id": "b7e6a1e5-d015-4e39-9ea7-25ece4bccb99",
      "name": "Set New Product Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1600,
        352
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "abc5b967-f13d-4ca9-b36b-990d6183f8e2",
              "name": "odoo_product_id",
              "type": "number",
              "value": "={{ $json.id }}"
            },
            {
              "id": "9ac7c56c-a3c5-41b3-af2f-0706f8e0e4c3",
              "name": "product_name",
              "type": "string",
              "value": "={{ $('Split Line Items').item.json.title }}"
            },
            {
              "id": "08a50d49-d7ea-46e1-a3bd-cb801f7b1bfa",
              "name": "sku",
              "type": "string",
              "value": "={{ $('Split Line Items').item.json.sku }}"
            },
            {
              "id": "0612a014-872b-4128-8c4f-d603ccd10307",
              "name": "quantity",
              "type": "number",
              "value": "={{ $('Split Line Items').item.json.quantity }}"
            },
            {
              "id": "f6ae891f-597e-4bd8-a00a-f0708eadcf65",
              "name": "unit_price",
              "type": "number",
              "value": "={{ $('Split Line Items').item.json.price }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "80e5c221-3dcd-4be3-b86a-a13279e6a0bf",
      "name": "Aggregate Product Lines",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1904,
        208
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "lines"
      },
      "typeVersion": 1
    },
    {
      "id": "3561a4f7-573f-4478-a39f-1439839c58c5",
      "name": "Find Customer in Odoo",
      "type": "n8n-nodes-base.odoo",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        432,
        784
      ],
      "parameters": {
        "limit": 1,
        "filters": {
          "filter": [
            {
              "value": "={{ $json.customer.email }}",
              "fieldName": "email"
            }
          ]
        },
        "options": {
          "fieldsList": [
            "id",
            "name",
            "email",
            "phone"
          ]
        },
        "authentication": "odooApi"
      },
      "retryOnFail": true,
      "typeVersion": 2,
      "alwaysOutputData": true,
      "waitBetweenTries": 5000
    },
    {
      "id": "0f2bf709-f4e8-4bb1-ae03-b956d00c7ac3",
      "name": "If Customer Exists in Odoo",
      "type": "n8n-nodes-base.if",
      "position": [
        704,
        784
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "6ee5f0ec-43ae-4d54-a7a7-119d8fb23a16",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ !!$json.email }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "3955de12-4e28-43b4-9f49-2c833858c378",
      "name": "Set Existing Customer Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1008,
        704
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b93cc0a9-5170-4434-a6dd-7bafe7ee0ae9",
              "name": "customer_odoo_id",
              "type": "number",
              "value": "={{ $json.id }}"
            },
            {
              "id": "8ca9b2f1-478e-49b0-b3cf-d8f8616acffa",
              "name": "customer_name",
              "type": "string",
              "value": "={{ $json.name }}"
            },
            {
              "id": "49d37a3c-4a35-462d-9387-a3082fe35ef0",
              "name": "customer_email",
              "type": "string",
              "value": "={{ $json.email }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "47b7cc7d-26c3-4abb-9066-03141a2fbec1",
      "name": "Add Customer to Odoo",
      "type": "n8n-nodes-base.odoo",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        1008,
        944
      ],
      "parameters": {
        "operation": "create",
        "fieldsToSend": {
          "value": {
            "zip": "={{ $('If Order Payload Valid').item.json.shipping_address ? $('If Order Payload Valid').item.json.shipping_address.zip : '' }}",
            "city": "={{ $('If Order Payload Valid').item.json.shipping_address ? $('If Order Payload Valid').item.json.shipping_address.city : '' }}",
            "name": "={{ $('If Order Payload Valid').item.json.customer.first_name + ' ' + $('If Order Payload Valid').item.json.customer.last_name }}",
            "email": "={{ $('If Order Payload Valid').item.json.customer.email }}",
            "phone": "={{ $('If Order Payload Valid').item.json.customer.phone || ($('If Order Payload Valid').item.json.shipping_address ? $('If Order Payload Valid').item.json.shipping_address.phone : '') || '' }}",
            "street": "={{ $('If Order Payload Valid').item.json.shipping_address ? $('If Order Payload Valid').item.json.shipping_address.address1 : '' }}"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "authentication": "odooApi"
      },
      "retryOnFail": true,
      "typeVersion": 2,
      "waitBetweenTries": 5000
    },
    {
      "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5e1",
      "name": "Set New Customer Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1312,
        944
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5e2",
              "name": "customer_odoo_id",
              "type": "number",
              "value": "={{ $json.id }}"
            },
            {
              "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5e3",
              "name": "customer_name",
              "type": "string",
              "value": "={{ $('If Order Payload Valid').item.json.customer.first_name }} {{ $('If Order Payload Valid').item.json.customer.last_name }}"
            },
            {
              "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5e4",
              "name": "customer_email",
              "type": "string",
              "value": "={{ $('If Order Payload Valid').item.json.customer.email }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5e5",
      "name": "Merge Customer and Products",
      "type": "n8n-nodes-base.merge",
      "position": [
        2208,
        512
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5e6",
      "name": "Create Sales Order in Odoo",
      "type": "n8n-nodes-base.odoo",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        2512,
        512
      ],
      "parameters": {
        "resource": "custom",
        "operation": "create",
        "fieldsToSend": {
          "value": {
            "order_line": "={{ $json.lines.map(l => [0, 0, { product_id: l.odoo_product_id, product_uom_qty: l.quantity, price_unit: l.unit_price }]) }}",
            "partner_id": "={{ $json.customer_odoo_id }}",
            "client_order_ref": "={{ $('If Order Payload Valid').item.json.name }}"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "authentication": "odooApi",
        "customResource": {
          "__rl": true,
          "mode": "id",
          "value": "sale.order",
          "cachedResultName": "sale.order"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2,
      "waitBetweenTries": 5000
    },
    {
      "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5e7",
      "name": "Send Slack Notification (Sales)",
      "type": "n8n-nodes-base.slack",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        2800,
        512
      ],
      "parameters": {
        "text": "=\u2705 *Shopify \u2192 Odoo Sync*\nOrder `{{ $('If Order Payload Valid').item.json.name }}` synced successfully.\nCustomer: {{ $('Merge Customer and Products').item.json.customer_name }} ({{ $('Merge Customer and Products').item.json.customer_email }})\nLine items: {{ $('Merge Customer and Products').item.json.lines.length }}\nOdoo Sale Order ID: {{ $json.id }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C+1234567890",
          "cachedResultName": "#sales-ops"
        },
        "otherOptions": {}
      },
      "retryOnFail": true,
      "typeVersion": 2.5,
      "waitBetweenTries": 5000
    },
    {
      "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5e8",
      "name": "Send Order Confirmation Email",
      "type": "n8n-nodes-base.gmail",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        3104,
        512
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=<p>Order <strong>{{ $('If Order Payload Valid').item.json.name }}</strong> from Shopify has been synced to Odoo as Sale Order ID {{ $('Create Sales Order in Odoo').item.json.id }}.</p><p>Customer: {{ $('Merge Customer and Products').item.json.customer_name }} ({{ $('Merge Customer and Products').item.json.customer_email }})<br/>Line items: {{ $('Merge Customer and Products').item.json.lines.length }}</p>",
        "options": {},
        "subject": "=Shopify Order {{ $('If Order Payload Valid').item.json.name }} synced to Odoo"
      },
      "retryOnFail": true,
      "typeVersion": 2.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5e9",
      "name": "Record Synchronization Error",
      "type": "n8n-nodes-base.set",
      "position": [
        2512,
        992
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5f1",
              "name": "error_message",
              "type": "string",
              "value": "={{ $json.error?.message ?? 'Malformed Shopify order payload: missing line_items or customer.email' }}"
            },
            {
              "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5f2",
              "name": "failed_node",
              "type": "string",
              "value": "={{ $json.error?.node?.name ?? 'Validate Order Payload' }}"
            },
            {
              "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5f3",
              "name": "order_reference",
              "type": "string",
              "value": "={{ $('When Shopify Order Created').item.json.name ?? $('When Shopify Order Created').item.json.order_number ?? 'unknown' }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a1a1a1a1-b2b2-4c3c-8d4d-e5e5e5e5e5f4",
      "name": "Alert Sync Error on Slack",
      "type": "n8n-nodes-base.slack",
      "maxTries": 2,
      "position": [
        2800,
        992
      ],
      "parameters": {
        "text": "=\u274c *Shopify \u2192 Odoo sync issue*\nOrder: {{ $json.order_reference }}\nFailed at: {{ $json.failed_node }}\nError: {{ $json.error_message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C+1234567890",
          "cachedResultName": "#sales-ops-alerts"
        },
        "otherOptions": {}
      },
      "retryOnFail": true,
      "typeVersion": 2.5,
      "waitBetweenTries": 5000
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "saveExecutionProgress": true,
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "all"
  },
  "nodeGroups": [],
  "connections": {
    "Split Line Items": {
      "main": [
        [
          {
            "node": "Find Product in Odoo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Product to Odoo": {
      "main": [
        [
          {
            "node": "Set New Product Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Record Synchronization Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Customer to Odoo": {
      "main": [
        [
          {
            "node": "Set New Customer Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Record Synchronization Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Product in Odoo": {
      "main": [
        [
          {
            "node": "If Product Exists in Odoo",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Record Synchronization Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Customer in Odoo": {
      "main": [
        [
          {
            "node": "If Customer Exists in Odoo",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Record Synchronization Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Order Payload Valid": {
      "main": [
        [
          {
            "node": "Find Customer in Odoo",
            "type": "main",
            "index": 0
          },
          {
            "node": "Split Line Items",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Record Synchronization Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set New Product Fields": {
      "main": [
        [
          {
            "node": "Aggregate Product Lines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Product Lines": {
      "main": [
        [
          {
            "node": "Merge Customer and Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set New Customer Fields": {
      "main": [
        [
          {
            "node": "Merge Customer and Products",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "If Product Exists in Odoo": {
      "main": [
        [
          {
            "node": "Set Existing Product Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Add Product to Odoo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Sales Order in Odoo": {
      "main": [
        [
          {
            "node": "Send Slack Notification (Sales)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Record Synchronization Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Customer Exists in Odoo": {
      "main": [
        [
          {
            "node": "Set Existing Customer Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Add Customer to Odoo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Shopify Order Created": {
      "main": [
        [
          {
            "node": "If Order Payload Valid",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Customer and Products": {
      "main": [
        [
          {
            "node": "Create Sales Order in Odoo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Existing Product Fields": {
      "main": [
        [
          {
            "node": "Aggregate Product Lines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Record Synchronization Error": {
      "main": [
        [
          {
            "node": "Alert Sync Error on Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Existing Customer Fields": {
      "main": [
        [
          {
            "node": "Merge Customer and Products",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Send Order Confirmation Email": {
      "main": [
        [],
        [
          {
            "node": "Record Synchronization Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Slack Notification (Sales)": {
      "main": [
        [
          {
            "node": "Send Order Confirmation Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Record Synchronization Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}