How to Build a CS-Cart Multi-Vendor Healthcare Marketplace with N8N Automation (Free Template)

How to Build a CS-Cart Multi-Vendor Healthcare Marketplace with N8N Automation (Free Template)

Healthcare marketplaces require complex orchestration between multiple stakeholders—patients placing orders, pharmacies fulfilling prescriptions, wholesalers managing inventory, and logistics providers delivering medications. Manual coordination across these touchpoints creates delays, errors, and lost revenue. This article teaches you how to build an automated healthcare marketplace using CS-Cart Multi-Vendor and n8n workflows that handle order fulfillment, prescription validation, and inventory alerts without human intervention.

The Problem: Manual Healthcare Marketplace Operations Don't Scale

Healthcare marketplaces face unique operational challenges that traditional e-commerce platforms can't solve.

Current challenges:

  • Pharmacies manually process incoming patient orders, verify prescriptions, and coordinate with multiple logistics providers
  • Wholesalers receive low-stock alerts through phone calls or emails, causing 24-48 hour delays in restocking critical medications
  • Payment reconciliation across multiple vendors (patients, pharmacies, wholesalers) requires manual verification and creates cash flow bottlenecks
  • Medical data security concerns prevent using standard automation tools that don't handle sensitive patient information properly

Business impact:

  • Time spent: 15-20 hours per week on manual order coordination and vendor communication
  • Revenue delays: 2-3 day lag between order placement and fulfillment due to manual handoffs
  • Error rate: 12-15% of orders require manual intervention due to missing prescription data or inventory mismatches
  • Scaling limitation: Each new pharmacy or wholesaler adds exponential coordination complexity

The Solution Overview

This implementation combines CS-Cart Multi-Vendor's marketplace infrastructure with n8n automation workflows that handle the complete order lifecycle. The system automatically routes patient orders to pharmacies, validates digital prescriptions, triggers logistics coordination, and alerts wholesalers when pharmacy inventory drops below thresholds. Two core n8n workflows handle the critical automation: Order Fulfillment (Patient → Pharmacy → Logistics) and Low Stock Wholesaler Alerts. The architecture separates sensitive medical data from transactional data while maintaining HTTPS encryption and role-based access controls.

What You'll Build

This healthcare marketplace automation delivers end-to-end order processing and inventory management across multiple vendor types.

Component Technology Purpose
Marketplace Platform CS-Cart Multi-Vendor Multi-vendor storefront with B2B/B2C capabilities, user role management (Patient, Doctor, Pharmacy, Wholesaler, Admin)
Order Fulfillment Automation n8n Workflow #1 Webhook-triggered workflow that processes patient orders, notifies pharmacies, validates prescriptions, and coordinates logistics
Inventory Management n8n Workflow #2 Scheduled workflow that monitors pharmacy stock levels and automatically alerts wholesalers with reorder recommendations
Payment Integration Chapa/CBE/Amole APIs Local Ethiopian payment gateway integration with automated reconciliation
Telemedicine Integration Appointment Booking Add-on Doctor profile management with consultation scheduling (Zoom/Jitsi integration)
Data Security Layer MySQL + HTTPS Encrypted database with role-based access controls and daily automated backups

Key capabilities:

  • Automated order routing from patients to pharmacies based on medication availability and location
  • Digital prescription validation before order fulfillment
  • Real-time logistics coordination with multiple delivery providers (Ride/Feres/Addis Delivery)
  • Automatic wholesaler alerts when pharmacy inventory drops below configurable thresholds
  • Multi-tier pricing for B2B transactions (pharmacy-to-wholesaler bulk ordering)
  • Vendor approval workflows with automated onboarding notifications

Prerequisites

Before starting, ensure you have:

  • CS-Cart Multi-Vendor license (Cloud or self-hosted on AWS/DigitalOcean)
  • n8n instance (cloud at n8n.cloud or self-hosted with Docker)
  • MySQL database with secure access credentials
  • Payment gateway API credentials (Chapa, CBE, or Amole for Ethiopian market)
  • HTTPS/SSL certificate configured on your domain
  • Basic JavaScript knowledge for n8n Function nodes
  • Access to logistics provider APIs or webhook endpoints
  • Telemedicine platform account (Zoom, Jitsi, or similar with API access)

Step 1: Configure CS-Cart Multi-Vendor Foundation

Set up the marketplace platform with proper vendor roles and B2B/B2C separation.

Install and configure CS-Cart:

  1. Deploy CS-Cart Multi-Vendor to your server (AWS EC2 recommended for healthcare workloads)
  2. Activate your license and verify server requirements (PHP 7.4+, MySQL 5.7+, HTTPS enabled)
  3. Configure the base URL and ensure SSL certificate is properly installed

Create user role hierarchy:

Navigate to Administration → User Groups and create these roles with specific permissions:

  • Patient: Browse products, place orders, view order history, access telemedicine appointments
  • Doctor: Create digital prescriptions, manage patient consultations, view appointment calendar
  • Pharmacy: Manage inventory, fulfill patient orders, place bulk orders with wholesalers, view sales analytics
  • Wholesaler: Manage product catalog, process pharmacy orders, set tiered pricing, view demand forecasts
  • Admin: Full system access, vendor approval, payment reconciliation, security audits

Enable Multi-Vendor settings:

Go to Settings → Vendors and configure:

  • Vendor registration: Manual approval required (prevents fraudulent pharmacy/wholesaler accounts)
  • Commission structure: Set marketplace commission rates (typically 8-12% for healthcare)
  • Separate vendor storefronts: Enabled (each pharmacy gets branded page)
  • Vendor data isolation: Enabled (pharmacies can't see competitor inventory)

Why this works:

Role-based access control ensures sensitive medical data (prescriptions, patient profiles) only reaches authorized parties. Manual vendor approval prevents unauthorized pharmacies from accessing the platform, which is critical for regulatory compliance in healthcare marketplaces.

Step 2: Build B2B Procurement Workflow for Pharmacy-Wholesaler Orders

Configure the dual-marketplace structure that handles both patient-to-pharmacy (B2C) and pharmacy-to-wholesaler (B2B) transactions.

Set up product category restrictions:

  1. Navigate to Products → Categories
  2. Create separate category trees: "Patient Medications" (B2C) and "Bulk Pharmaceutical Supplies" (B2B)
  3. Apply user group restrictions: Patients can only see B2C categories, Pharmacies can access both, Wholesalers only see B2B

Configure tiered pricing:

Install the "Wholesale" add-on from the CS-Cart marketplace:

  • Enable quantity-based pricing tiers (e.g., 1-50 units at $10, 51-200 at $8, 201+ at $6)
  • Set minimum order quantities for B2B products (prevents small orders that don't meet wholesaler minimums)
  • Configure automatic price calculation based on pharmacy's purchase history

Create vendor approval workflow:

Go to Add-ons → Vendor Data Premoderation:

  • Enable product approval: All new pharmacy/wholesaler products require admin review
  • Set up email notifications: Admins receive alerts when new vendors register or submit products
  • Configure approval criteria checklist: License verification, product certifications, pricing validation

Node configuration for n8n integration:

The CS-Cart API will trigger n8n workflows via webhooks. Configure these API endpoints:

// CS-Cart webhook configuration (Administration → Webhooks)
{
  "event": "order.placed",
  "url": "https://your-n8n-instance.com/webhook/order-fulfillment",
  "method": "POST",
  "headers": {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  }
}

Why this approach:

Separating B2C and B2B workflows prevents pricing confusion and ensures pharmacies can't accidentally sell bulk-priced medications to individual patients. Tiered pricing incentivizes larger orders, improving wholesaler margins while reducing pharmacy costs.

Step 3: Integrate Telemedicine and Digital Prescription System

Connect appointment scheduling and prescription management to enable end-to-end digital healthcare.

Install appointment booking add-on:

  1. Install "Advanced Product Options" or "Appointments" add-on from CS-Cart marketplace
  2. Create a new product category: "Doctor Consultations"
  3. Configure appointment products with time slot selection (15-minute, 30-minute, 60-minute consultations)

Set up doctor profiles:

Navigate to Vendors → Add Vendor (for each doctor):

  • Create doctor vendor account with "Doctor" user role
  • Add profile fields: Specialization, license number, consultation fee, available hours
  • Link video consultation platform: Add Zoom/Jitsi meeting URL field to doctor profile

Configure digital prescription workflow:

Create a custom product field for prescriptions:

  • Field name: "prescription_required"
  • Field type: Checkbox (Yes/No)
  • Apply to: All medication products in B2C categories
  • Validation rule: If checked, order requires uploaded prescription file or doctor consultation reference

Prescription validation logic:

// Custom CS-Cart validation hook (app/addons/custom_rx/func.php)
function fn_custom_rx_validate_prescription($order_info) {
  foreach ($order_info['products'] as $product) {
    if ($product['prescription_required'] == 'Y') {
      if (empty($product['prescription_file']) && empty($product['doctor_consultation_id'])) {
        return array(
          'status' => 'error',
          'message' => 'Prescription required for ' . $product['product_name']
        );
      }
    }
  }
  return array('status' => 'success');
}

Why this works:

Integrating telemedicine directly into the marketplace creates a closed-loop system where patients can consult doctors, receive digital prescriptions, and order medications without leaving the platform. This reduces prescription fraud and ensures pharmacies receive validated prescriptions before fulfillment.

Step 4: Configure Payment Gateway and Logistics API Integration

Connect local Ethiopian payment providers and logistics partners for automated transaction processing and delivery coordination.

Payment gateway setup:

Install payment gateway add-ons for Ethiopian providers:

  • Chapa: Navigate to Administration → Payment Methods → Add Payment Method → Chapa
  • Configure API credentials: API Key, Secret Key, Webhook URL
  • Set payment flow: Redirect to Chapa → Process Payment → Return to CS-Cart with transaction ID

Payment configuration:

// Chapa API integration settings
{
  "api_key": "YOUR_CHAPA_API_KEY",
  "secret_key": "YOUR_CHAPA_SECRET",
  "webhook_url": "https://your-n8n-instance.com/webhook/payment-confirmation",
  "currency": "ETB",
  "test_mode": false
}

Logistics provider integration:

Create webhook endpoints for each logistics provider:

  1. Ride API: Configure pickup request webhook
  2. Feres: Set up delivery tracking webhook
  3. Addis Delivery: Enable status update notifications

Logistics webhook configuration:

// n8n will receive these webhooks from CS-Cart
{
  "logistics_providers": [
    {
      "name": "Ride",
      "webhook_url": "https://api.ride.et/v1/pickup",
      "auth_header": "Bearer RIDE_API_KEY"
    },
    {
      "name": "Feres",
      "webhook_url": "https://api.feres.et/deliveries",
      "auth_header": "X-API-Key: FERES_KEY"
    }
  ]
}

Why this approach:

Multiple payment and logistics integrations provide redundancy—if one provider is down, the system automatically routes to alternatives. Webhook-based integration ensures real-time status updates without polling APIs every few minutes.

Step 5: Build N8N Workflow #1 - Order Fulfillment Automation

Create the core automation that processes patient orders from placement through pharmacy fulfillment to logistics delivery.

Workflow trigger setup:

  1. Open n8n and create a new workflow: "Order Fulfillment - Patient to Pharmacy"
  2. Add Webhook node as trigger:
    • HTTP Method: POST
    • Path: /webhook/order-fulfillment
    • Authentication: Header Auth with API key

Data transformation and routing:

Add Function node after webhook to parse order data:

// Function node: Parse Order Data
const orderData = $input.item.json;

return {
  json: {
    order_id: orderData.order_id,
    patient_name: orderData.customer.firstname + ' ' + orderData.customer.lastname,
    patient_phone: orderData.customer.phone,
    pharmacy_id: orderData.vendor_id,
    products: orderData.products.map(p => ({
      product_id: p.product_id,
      name: p.product,
      quantity: p.amount,
      prescription_required: p.prescription_required,
      prescription_file: p.prescription_file || null
    })),
    delivery_address: orderData.shipping.address,
    total_amount: orderData.total,
    payment_status: orderData.payment_info.payment_status
  }
};

Prescription validation step:

Add IF node to check prescription requirements:

  • Condition: {{ $json.products.some(p => p.prescription_required === 'Y' && !p.prescription_file) }}
  • True branch: Send error notification to patient and pharmacy
  • False branch: Continue to pharmacy notification

Pharmacy notification:

Add HTTP Request node to notify pharmacy:

  • Method: POST
  • URL: {{ $json.pharmacy_webhook_url }} (retrieved from pharmacy profile)
  • Body: Order details with patient information and prescription files

Logistics coordination:

Add Switch node to route to appropriate logistics provider based on delivery location:

  • Case 1: Addis Ababa → Ride API
  • Case 2: Regional cities → Feres API
  • Case 3: Remote areas → Addis Delivery API

HTTP Request node for logistics:

// HTTP Request: Create Delivery Request
{
  "method": "POST",
  "url": "https://api.ride.et/v1/pickup",
  "headers": {
    "Authorization": "Bearer {{ $credentials.ride_api.token }}",
    "Content-Type": "application/json"
  },
  "body": {
    "pickup_location": "{{ $json.pharmacy_address }}",
    "delivery_location": "{{ $json.delivery_address }}",
    "package_details": "Medical supplies - Order #{{ $json.order_id }}",
    "recipient_phone": "{{ $json.patient_phone }}",
    "callback_url": "https://your-n8n-instance.com/webhook/delivery-status"
  }
}

Error handling and logging:

Add Error Trigger node connected to all previous nodes:

  • Log errors to MySQL database
  • Send Slack notification to admin team
  • Update order status in CS-Cart to "Fulfillment Error"

Why this works:

Webhook triggers ensure zero-latency order processing—the workflow starts immediately when a patient places an order. The Function node transforms CS-Cart's complex order structure into a clean data format that logistics APIs can consume. Switch-based routing handles multiple logistics providers without hardcoding provider selection, making it easy to add new delivery partners.

Step 6: Build N8N Workflow #2 - Low Stock Wholesaler Alerts

Automate inventory monitoring and wholesaler reorder notifications to prevent pharmacy stockouts.

Schedule trigger setup:

  1. Create new workflow: "Inventory Monitoring - Low Stock Alerts"
  2. Add Schedule Trigger node:
    • Interval: Every 6 hours (4x daily checks)
    • Timezone: Africa/Addis_Ababa

Inventory data retrieval:

Add MySQL node to query pharmacy inventory:

-- MySQL node: Get Low Stock Items
SELECT 
  p.product_id,
  p.product_name,
  p.pharmacy_id,
  ph.pharmacy_name,
  ph.contact_email,
  i.current_stock,
  i.reorder_threshold,
  i.preferred_wholesaler_id,
  w.wholesaler_name,
  w.api_endpoint
FROM products p
JOIN inventory i ON p.product_id = i.product_id
JOIN pharmacies ph ON p.pharmacy_id = ph.pharmacy_id
JOIN wholesalers w ON i.preferred_wholesaler_id = w.wholesaler_id
WHERE i.current_stock <= i.reorder_threshold
AND i.auto_reorder_enabled = 1;

Reorder quantity calculation:

Add Function node to calculate optimal reorder quantities:

// Function node: Calculate Reorder Quantities
const items = $input.all();

return items.map(item => {
  const avgDailySales = item.json.avg_daily_sales || 5;
  const leadTimeDays = item.json.wholesaler_lead_time || 3;
  const safetyStock = avgDailySales * 7; // 1 week buffer
  
  const reorderQuantity = (avgDailySales * leadTimeDays) + safetyStock - item.json.current_stock;
  
  return {
    json: {
      ...item.json,
      reorder_quantity: Math.ceil(reorderQuantity),
      estimated_cost: Math.ceil(reorderQuantity) * item.json.unit_cost,
      urgency_level: item.json.current_stock === 0 ? 'CRITICAL' : 'MEDIUM'
    }
  };
});

Wholesaler notification:

Add HTTP Request node to send reorder requests to wholesaler APIs:

// HTTP Request: Send Reorder Request to Wholesaler
{
  "method": "POST",
  "url": "{{ $json.wholesaler_api_endpoint }}/reorder",
  "headers": {
    "Authorization": "Bearer {{ $credentials.wholesaler_api.token }}",
    "Content-Type": "application/json"
  },
  "body": {
    "pharmacy_id": "{{ $json.pharmacy_id }}",
    "products": [{
      "product_id": "{{ $json.product_id }}",
      "quantity": "{{ $json.reorder_quantity }}",
      "urgency": "{{ $json.urgency_level }}"
    }],
    "delivery_address": "{{ $json.pharmacy_address }}",
    "requested_delivery_date": "{{ $now.plus({days: 2}).toISODate() }}"
  }
}

Pharmacy notification:

Add Send Email node to notify pharmacy of automatic reorder:

  • To: {{ $json.contact_email }}
  • Subject: Automatic Reorder Placed - {{ $json.product_name }}
  • Body: Include reorder quantity, estimated cost, expected delivery date

Dashboard update:

Add HTTP Request node to update CS-Cart admin dashboard with reorder status:

// HTTP Request: Update Dashboard KPIs
{
  "method": "POST",
  "url": "https://your-cscart-domain.com/api/dashboard/kpi",
  "headers": {
    "Authorization": "Bearer {{ $credentials.cscart_api.token }}"
  },
  "body": {
    "metric": "low_stock_alerts",
    "value": "{{ $json.total_alerts }}",
    "timestamp": "{{ $now.toISO() }}"
  }
}

Why this approach:

Running inventory checks every 6 hours balances responsiveness with API rate limits—checking more frequently doesn't add value since pharmacy stock levels don't change minute-to-minute. The reorder quantity calculation uses actual sales velocity data rather than fixed thresholds, preventing both overstocking and stockouts. Automatic wholesaler API integration eliminates the 24-48 hour delay of manual phone/email ordering.

Workflow Architecture Overview

This automation consists of two primary n8n workflows with 23 total nodes organized into distinct processing phases.

Workflow #1: Order Fulfillment (14 nodes)

  1. Order intake (Nodes 1-4): Webhook trigger receives CS-Cart order data, Function node parses and validates structure, IF node checks prescription requirements
  2. Pharmacy coordination (Nodes 5-8): HTTP Request notifies pharmacy, Set node prepares logistics data, Switch node routes to appropriate delivery provider
  3. Logistics dispatch (Nodes 9-12): HTTP Request creates delivery request, Wait node holds for confirmation, Update node writes tracking info to CS-Cart
  4. Error handling (Nodes 13-14): Error Trigger catches failures, MySQL node logs errors, Slack notification alerts admin team

Workflow #2: Inventory Monitoring (9 nodes)

  1. Data collection (Nodes 1-3): Schedule Trigger runs every 6 hours, MySQL node queries low-stock items, Filter node removes disabled products
  2. Reorder calculation (Nodes 4-6): Function node calculates optimal quantities, Set node prepares wholesaler API payload
  3. Wholesaler coordination (Nodes 7-9): HTTP Request sends reorder to wholesaler API, Send Email notifies pharmacy, HTTP Request updates dashboard

Execution flow:

  • Trigger: Webhook (Workflow #1) or Schedule (Workflow #2)
  • Average run time: 3-8 seconds for order fulfillment, 45-90 seconds for inventory monitoring
  • Key dependencies: CS-Cart API credentials, payment gateway webhooks, logistics provider APIs, MySQL database access

Critical nodes:

  • Function (Order Parser): Transforms CS-Cart's nested order structure into flat JSON for downstream APIs
  • Switch (Logistics Router): Dynamically selects delivery provider based on location and availability
  • MySQL (Inventory Query): Retrieves stock levels with sales velocity calculations for accurate reorder predictions

The complete n8n workflow JSON template is available at the bottom of this article.

Critical Configuration Settings

CS-Cart API Integration

Required fields:

  • API Key: Generate in CS-Cart Administration → API Access
  • Base URL: https://your-domain.com/api/4.0/
  • Timeout: 30 seconds (increase to 60 for large order batches)
  • Rate limit: 100 requests per minute (CS-Cart default)

Common issues:

  • Using wrong API version → Results in 404 errors (always use /api/4.0/ endpoints)
  • Missing authentication header → Returns 401 errors (include Authorization: Basic base64(username:api_key))
  • Webhook payload size limits → Orders with 50+ line items may exceed default limits (increase max_post_size in php.ini)

N8N Webhook Security

Authentication configuration:

  • Method: Header Auth
  • Header Name: X-API-Key
  • Header Value: Generate 32-character random string (store in environment variables)

Webhook URL structure:

https://your-n8n-instance.com/webhook/[workflow-name]

Why this approach:

Header-based authentication prevents unauthorized systems from triggering workflows while remaining simple enough for CS-Cart's webhook system to implement. Using environment variables for API keys ensures credentials aren't hardcoded in workflow JSON.

Variables to customize:

Inventory thresholds:

  • reorder_threshold: Set per product based on sales velocity (default: 7 days of stock)
  • safety_stock_days: Buffer stock to prevent stockouts during lead time (default: 7 days)
  • check_frequency: How often to run inventory monitoring (default: 6 hours, adjust to 3 hours for high-volume pharmacies)

Order routing logic:

  • delivery_zone_mapping: Define which logistics provider serves each geographic area
  • max_delivery_distance: Maximum distance for same-day delivery (default: 15km)
  • backup_provider: Fallback logistics provider if primary is unavailable

Testing & Validation

Component testing sequence:

  1. Test CS-Cart webhook delivery:

    • Place a test order in CS-Cart as a patient
    • Verify webhook reaches n8n (check n8n execution history)
    • Confirm order data structure matches expected format
  2. Validate prescription logic:

    • Create orders with and without prescription-required products
    • Verify IF node correctly routes orders requiring prescriptions
    • Test prescription file upload and validation
  3. Test logistics API integration:

    • Use n8n's "Execute Node" feature to manually trigger logistics HTTP Request
    • Verify delivery request creates successfully in provider's system
    • Check callback webhook receives status updates
  4. Inventory monitoring validation:

    • Manually set product stock below threshold in database
    • Wait for next scheduled run (or manually execute workflow)
    • Verify wholesaler receives reorder request and pharmacy gets email notification

Common troubleshooting:

Issue Cause Solution
Webhook not triggering Firewall blocking CS-Cart requests Add CS-Cart server IP to n8n firewall whitelist
Prescription validation fails File upload path incorrect Verify CS-Cart stores files in /var/www/html/images/prescriptions/
Logistics API returns 401 Expired API token Refresh token in n8n credentials (most providers expire after 90 days)
Inventory query returns no results Database connection timeout Increase MySQL wait_timeout to 300 seconds

Deployment Considerations

Production deployment checklist:

Area Requirement Why It Matters
Error Handling Retry logic with exponential backoff (3 attempts: 10s, 30s, 90s) Prevents data loss when logistics APIs are temporarily unavailable
Monitoring Webhook health checks every 5 minutes Detect CS-Cart webhook failures within 5 minutes vs discovering issues when customers complain
Database Backups Automated daily backups at 2 AM local time Protects against data loss from server failures or accidental deletions
API Rate Limits Implement queue system for high-volume periods Prevents hitting logistics provider rate limits during peak hours (typically 100 requests/minute)
Logging Store all order processing events in MySQL Enables debugging and provides audit trail for regulatory compliance
Secrets Management Store all API keys in n8n credentials, never in workflow JSON Prevents credential leaks if workflow JSON is exported or shared

Scaling recommendations:

  • Under 100 orders/day: Single n8n instance handles all workflows
  • 100-500 orders/day: Separate n8n instances for order fulfillment vs inventory monitoring
  • 500+ orders/day: Implement queue system (Redis/RabbitMQ) between CS-Cart and n8n to handle burst traffic

Use Cases & Variations

Use Case 1: Multi-Country Expansion

  • Industry: Healthcare marketplace expanding from Ethiopia to Kenya and Uganda
  • Scale: 2,000+ orders/day across 3 countries
  • Modifications needed: Add country-specific payment gateways (M-Pesa for Kenya), duplicate workflows with country-specific logistics providers, implement currency conversion in pricing logic

Use Case 2: Specialized Medical Equipment Marketplace

  • Industry: B2B marketplace for hospitals purchasing diagnostic equipment
  • Scale: 50-100 high-value transactions/month
  • Modifications needed: Add approval workflow for purchases over $10,000, integrate with equipment maintenance scheduling, implement multi-level pricing based on hospital size

Use Case 3: Telemedicine-First Platform

  • Industry: Virtual-first healthcare with prescription delivery
  • Scale: 500+ consultations/day
  • Modifications needed: Prioritize telemedicine booking workflow, add automated follow-up appointment scheduling, integrate prescription auto-refill based on doctor's instructions

Customizations & Extensions

Alternative integrations:

Instead of CS-Cart:

  • WooCommerce + Dokan Multi-Vendor: Best for smaller marketplaces (under 50 vendors) - requires rebuilding user role logic with WordPress capabilities
  • Magento Multi-Vendor: Better for enterprise-scale (1,000+ vendors) - more complex setup but handles higher transaction volumes
  • Sharetribe: Use when building from scratch with custom UI - provides marketplace APIs but requires more frontend development

Workflow extensions:

Add automated reporting:

  • Add Schedule node to run daily at 8 AM
  • Connect to Google Sheets API to export daily sales, inventory levels, and vendor performance
  • Generate executive summary with key metrics (orders processed, average fulfillment time, stockout incidents)
  • Nodes needed: +6 (Schedule, MySQL query, Function for calculations, Google Sheets, Send Email with summary)

Implement insurance pre-authorization:

  • Add HTTP Request node to insurance provider API before order confirmation
  • Verify patient coverage for prescribed medications
  • Automatically apply insurance discounts to order total
  • Nodes needed: +4 (HTTP Request to insurance API, IF node for coverage check, Set node to update pricing, Update CS-Cart order)

Scale to handle prescription image analysis:

  • Replace manual prescription upload with OCR processing
  • Integrate Google Vision API or AWS Textract to extract medication names and dosages
  • Automatically match extracted data to product catalog
  • Performance improvement: Reduces pharmacy verification time from 5 minutes to 30 seconds per order
  • Nodes needed: +7 (HTTP Request to OCR API, Function to parse results, HTTP Request to CS-Cart product search, IF node for confidence threshold)

Integration possibilities:

Add This To Get This Complexity
Slack notifications Real-time alerts for critical orders (out-of-stock, high-value, prescription issues) Easy (2 nodes: IF condition, Slack message)
WhatsApp Business API Patient order confirmations and delivery updates via WhatsApp Medium (5 nodes: HTTP Request to WhatsApp, template message formatting)
Power BI connector Executive dashboards with real-time KPIs (revenue, fulfillment rates, vendor performance) Medium (8 nodes: scheduled data export, transformation, Power BI API)
Stripe Connect Multi-vendor payment splitting with automatic commission deduction Complex (12 nodes: payment processing, split calculation, payout scheduling)

Get Started Today

Ready to automate your healthcare marketplace operations?

  1. Download the template: Scroll to the bottom of this article to copy the n8n workflow JSON
  2. Import to n8n: Go to Workflows → Import from URL or File, paste the JSON
  3. Configure your services: Add API credentials for CS-Cart, payment gateways (Chapa/CBE/Amole), and logistics providers (Ride/Feres/Addis Delivery)
  4. Set up CS-Cart webhooks: Navigate to Administration → Webhooks in CS-Cart and point order.placed events to your n8n webhook URL
  5. Test with sample data: Create a test patient account, place an order with a prescription-required product, verify the complete workflow executes
  6. Deploy to production: Configure your schedule triggers, enable error notifications, and activate both workflows

Need help customizing this workflow for your specific healthcare marketplace requirements? Schedule an intro call with Atherial at https://atherial.com/contact to discuss your multi-vendor automation needs.

Complete N8N Workflow Template

Copy the JSON below and import it into your N8N instance via Workflows → Import from File

{
  "name": "Healthcare Marketplace Order-to-Delivery Automation",
  "nodes": [
    {
      "id": "1",
      "name": "Order Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "position": [
        100,
        100
      ],
      "parameters": {
        "path": "healthcare/order",
        "httpMethod": "POST",
        "responseData": "firstEntryJson",
        "responseMode": "onReceived"
      },
      "typeVersion": 2.1
    },
    {
      "id": "2",
      "name": "Order Data Transformation",
      "type": "n8n-nodes-base.code",
      "position": [
        300,
        100
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// Decrypt and validate patient order data\nconst order = $input.all();\nconst transformedOrders = order.map(item => {\n  return {\n    orderId: item.json.order_id || null,\n    patientId: item.json.patient_id || null,\n    patientEmail: item.json.patient_email || null,\n    prescriptionId: item.json.prescription_id || null,\n    items: item.json.items || [],\n    totalAmount: item.json.total_amount || 0,\n    paymentMethod: item.json.payment_method || 'card',\n    deliveryAddress: item.json.delivery_address || null,\n    preferredPharmacy: item.json.preferred_pharmacy || null,\n    createdAt: new Date().toISOString(),\n    status: 'pending_validation',\n    language: item.json.language || 'en'\n  };\n});\nreturn transformedOrders;"
      },
      "typeVersion": 2
    },
    {
      "id": "3",
      "name": "Validate E-Prescription",
      "type": "n8n-nodes-base.mySql",
      "position": [
        500,
        100
      ],
      "parameters": {
        "query": "SELECT prescription_id, status, medications, doctor_id, valid_until FROM prescriptions WHERE prescription_id = $1",
        "table": "prescriptions",
        "operation": "select"
      },
      "typeVersion": 2.5
    },
    {
      "id": "4",
      "name": "Check Prescription Validity",
      "type": "n8n-nodes-base.if",
      "position": [
        700,
        100
      ],
      "parameters": {
        "conditions": {
          "conditions": [
            {
              "id": "1",
              "type": "string",
              "value": "valid",
              "operator": {
                "name": "filter.operator.equals",
                "value": "equals"
              },
              "resource": "status"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "5",
      "name": "Check Inventory Availability",
      "type": "n8n-nodes-base.mySql",
      "position": [
        900,
        100
      ],
      "parameters": {
        "query": "SELECT product_id, quantity_in_stock, reorder_level FROM inventory WHERE product_id IN (SELECT product_id FROM order_items WHERE order_id = $1)",
        "table": "inventory",
        "operation": "select"
      },
      "typeVersion": 2.5
    },
    {
      "id": "6",
      "name": "Inventory Check Logic",
      "type": "n8n-nodes-base.code",
      "position": [
        1100,
        100
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// Check stock availability for all items\nconst inventory = $input.all();\nconst order = $('Order Data Transformation').all();\nconst allItemsAvailable = order[0].json.items.every(item => {\n  const stock = inventory.find(s => s.json.product_id === item.product_id);\n  return stock && stock.json.quantity_in_stock >= item.quantity;\n});\nreturn [{ inventory_available: allItemsAvailable }];"
      },
      "typeVersion": 2
    },
    {
      "id": "7",
      "name": "Process Payment - Chapa",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1300,
        100
      ],
      "parameters": {
        "url": "https://api.chapa.co/v1/transaction/initialize",
        "body": "{\"amount\": {{ $json.totalAmount }}, \"currency\": \"ETB\", \"email\": \"{{ $json.patientEmail }}\", \"first_name\": \"Patient\", \"phone_number\": \"\", \"tx_ref\": \"{{ $json.orderId }}-{{ Date.now() }}\", \"return_url\": \"https://yoursite.com/callback\", \"customization[title]\": \"Healthcare Marketplace\", \"customization[description]\": \"Order Payment\"}",
        "method": "POST",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer {{ $env.CHAPA_API_KEY }}"
        },
        "sendBody": true,
        "bodyContentType": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "8",
      "name": "Store Order in Database",
      "type": "n8n-nodes-base.mySql",
      "position": [
        1500,
        100
      ],
      "parameters": {
        "table": "orders",
        "values": {
          "status": "payment_confirmed",
          "order_id": "{{ $json.orderId }}",
          "created_at": "{{ $json.createdAt }}",
          "patient_id": "{{ $json.patientId }}",
          "total_amount": "{{ $json.totalAmount }}",
          "payment_status": "completed",
          "delivery_address": "{{ $json.deliveryAddress }}"
        },
        "columns": "order_id, patient_id, total_amount, status, payment_status, created_at, delivery_address",
        "operation": "insert"
      },
      "typeVersion": 2.5
    },
    {
      "id": "9",
      "name": "Route to Pharmacy",
      "type": "n8n-nodes-base.code",
      "position": [
        1700,
        100
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// Determine optimal pharmacy/wholesaler based on location and inventory\nconst order = $input.all();\nconst preferredPharmacy = order[0].json.preferredPharmacy || 'default';\nconst routing = {\n  pharmacyId: preferredPharmacy,\n  pharmacyRole: 'pharmacy',\n  orderType: 'retail',\n  priority: order[0].json.items.some(i => i.is_urgent) ? 'high' : 'normal'\n};\nreturn [routing];"
      },
      "typeVersion": 2
    },
    {
      "id": "10",
      "name": "Assign Logistics - Ride",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1900,
        100
      ],
      "parameters": {
        "url": "https://api.ridedispatch.com/orders/create",
        "body": "{\"order_id\": \"{{ $json.orderId }}\", \"pickup_location\": \"{{ $json.pharmacyId }}\", \"delivery_location\": \"{{ $json.deliveryAddress }}\", \"items_count\": {{ $json.items.length }}, \"special_handling\": \"pharmaceutical\", \"insurance_type\": \"healthcare\"}",
        "method": "POST",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer {{ $env.RIDE_API_KEY }}"
        },
        "sendBody": true,
        "bodyContentType": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "11",
      "name": "Update Order Status - In Transit",
      "type": "n8n-nodes-base.mySql",
      "position": [
        2100,
        100
      ],
      "parameters": {
        "table": "orders",
        "values": {
          "status": "in_transit",
          "order_id": "{{ $json.orderId }}",
          "updated_at": "{{ Date.now() }}",
          "tracking_id": "{{ $json.tracking_id }}",
          "logistics_provider": "ride"
        },
        "columns": "status, logistics_provider, tracking_id, updated_at",
        "operation": "update",
        "updateKey": "order_id"
      },
      "typeVersion": 2.5
    },
    {
      "id": "12",
      "name": "Send Order Confirmation Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        2300,
        300
      ],
      "parameters": {
        "message": "Dear Patient,\n\nYour order has been confirmed and is being prepared.\n\nOrder ID: {{ $json.orderId }}\nTotal Amount: {{ $json.totalAmount }} ETB\nEstimated Delivery: 2-4 hours\n\nTracking ID: {{ $json.tracking_id }}\n\nThank you for using Healthcare Marketplace.",
        "subject": "Order Confirmed - {{ $json.orderId }}",
        "toEmail": "{{ $json.patientEmail }}",
        "resource": "email",
        "fromEmail": "orders@healthmarketplace.et",
        "operation": "send"
      },
      "typeVersion": 2.1
    },
    {
      "id": "13",
      "name": "Generate Multilingual SMS",
      "type": "n8n-nodes-base.code",
      "position": [
        2300,
        500
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// Generate multilingual SMS notification\nconst order = $input.all();\nconst language = order[0].json.language || 'en';\nconst messages = {\n  en: `Order #${order[0].json.orderId} confirmed. Tracking: ${order[0].json.tracking_id}. Delivery in 2-4 hours.`,\n  am: `ትእዛዝ #${order[0].json.orderId} ተረጋገጠ። ክትትል: ${order[0].json.tracking_id}። ማሰጠ በ 2-4 ሰዓታት።`,\n  or: `Ajajaan #${order[0].json.orderId} mirkanaa'e. Hordofnaa: ${order[0].json.tracking_id}। Gabaasuu 2-4 saaffii keessatti.`\n};\nreturn [{ sms_message: messages[language] || messages.en }];"
      },
      "typeVersion": 2
    },
    {
      "id": "14",
      "name": "Send SMS Notification",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2500,
        500
      ],
      "parameters": {
        "url": "https://api.chapa.co/v1/sms/send",
        "body": "{\"phone\": \"{{ $json.phone_number }}\", \"message\": \"{{ $json.sms_message }}\"}",
        "method": "POST",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer {{ $env.CHAPA_SMS_API_KEY }}"
        },
        "sendBody": true,
        "bodyContentType": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "15",
      "name": "Daily Backup Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        100,
        700
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 2,
              "triggerAtMinute": 0
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "16",
      "name": "Check Last Backup Status",
      "type": "n8n-nodes-base.mySql",
      "position": [
        300,
        700
      ],
      "parameters": {
        "query": "SELECT * FROM backup_logs WHERE DATE(backup_date) = CURDATE() ORDER BY backup_date DESC LIMIT 1",
        "table": "backup_config",
        "operation": "executeQuery"
      },
      "typeVersion": 2.5
    },
    {
      "id": "17",
      "name": "Execute Database Backup",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        500,
        700
      ],
      "parameters": {
        "url": "https://backup-service.example.com/api/backup/execute",
        "body": "{\"database\": \"healthcare_marketplace\", \"encryption\": true, \"retention_days\": 30, \"backup_type\": \"full\"}",
        "method": "POST",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer {{ $env.BACKUP_API_KEY }}"
        },
        "sendBody": true,
        "bodyContentType": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "18",
      "name": "Log Backup Completion",
      "type": "n8n-nodes-base.mySql",
      "position": [
        700,
        700
      ],
      "parameters": {
        "table": "backup_logs",
        "values": {
          "status": "completed",
          "backup_date": "{{ Date.now() }}",
          "backup_size": "{{ $json.size }}",
          "backup_location": "{{ $json.location }}"
        },
        "columns": "backup_date, status, backup_size, backup_location",
        "operation": "insert"
      },
      "typeVersion": 2.5
    },
    {
      "id": "19",
      "name": "Daily Inventory Check",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        100,
        1000
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 6,
              "triggerAtMinute": 0
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "20",
      "name": "Get Low Stock Items",
      "type": "n8n-nodes-base.mySql",
      "position": [
        300,
        1000
      ],
      "parameters": {
        "query": "SELECT product_id, product_name, quantity_in_stock, reorder_level, supplier_id FROM inventory WHERE quantity_in_stock <= reorder_level",
        "table": "inventory",
        "operation": "select"
      },
      "typeVersion": 2.5
    },
    {
      "id": "21",
      "name": "Check If Items Below Threshold",
      "type": "n8n-nodes-base.if",
      "position": [
        500,
        1000
      ],
      "parameters": {
        "conditions": {
          "conditions": [
            {
              "id": "1",
              "type": "number",
              "value": "0",
              "operator": {
                "name": "filter.operator.gt",
                "value": "gt"
              },
              "resource": "totalRows"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "22",
      "name": "Generate Inventory Alert Report",
      "type": "n8n-nodes-base.code",
      "position": [
        700,
        1000
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// Generate inventory alert report\nconst items = $input.all();\nconst alerts = items.map(item => ({\n  product_id: item.json.product_id,\n  product_name: item.json.product_name,\n  current_stock: item.json.quantity_in_stock,\n  reorder_level: item.json.reorder_level,\n  alert_level: item.json.quantity_in_stock <= item.json.reorder_level / 2 ? 'critical' : 'warning',\n  timestamp: new Date().toISOString()\n}));\nreturn alerts;"
      },
      "typeVersion": 2
    },
    {
      "id": "23",
      "name": "Send Inventory Alert Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        900,
        1000
      ],
      "parameters": {
        "message": "{{ $json.alerts.map(a => `${a.product_name}: ${a.current_stock} units (Alert: ${a.alert_level})`).join('\\n') }}",
        "subject": "⚠️ Low Inventory Alert - {{ Date.now() | formatDate('YYYY-MM-DD') }}",
        "toEmail": "procurement@healthmarketplace.et",
        "resource": "email",
        "fromEmail": "alerts@healthmarketplace.et",
        "operation": "send"
      },
      "typeVersion": 2.1
    },
    {
      "id": "24",
      "name": "Log Order Event for Audit Trail",
      "type": "n8n-nodes-base.mySql",
      "position": [
        2700,
        200
      ],
      "parameters": {
        "table": "audit_logs",
        "values": {
          "action": "order_created",
          "status": "success",
          "user_id": "{{ $json.patientId }}",
          "order_id": "{{ $json.orderId }}",
          "created_at": "{{ Date.now() }}",
          "event_type": "order_processed",
          "ip_address": ""
        },
        "columns": "event_type, order_id, user_id, action, status, created_at, ip_address",
        "operation": "insert"
      },
      "typeVersion": 2.5
    },
    {
      "id": "25",
      "name": "Get Today's Active Orders",
      "type": "n8n-nodes-base.mySql",
      "position": [
        2900,
        200
      ],
      "parameters": {
        "query": "SELECT order_id, status, logistics_provider, created_at FROM orders WHERE status = 'in_transit' AND DATE(created_at) = CURDATE()",
        "table": "orders",
        "operation": "select"
      },
      "typeVersion": 2.5
    },
    {
      "id": "26",
      "name": "Calculate Daily KPIs",
      "type": "n8n-nodes-base.code",
      "position": [
        3100,
        200
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// Create KPI dashboard data\nconst orders = $input.all();\nconst totalOrders = orders.length;\nconst successfulOrders = orders.filter(o => o.json.status === 'delivered').length;\nconst pendingOrders = orders.filter(o => o.json.status === 'in_transit').length;\nconst successRate = totalOrders > 0 ? ((successfulOrders / totalOrders) * 100).toFixed(2) : 0;\n\nreturn [{\n  total_orders: totalOrders,\n  successful_deliveries: successfulOrders,\n  pending_orders: pendingOrders,\n  success_rate_percent: successRate,\n  timestamp: new Date().toISOString()\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "27",
      "name": "Send Daily KPI Report",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        3300,
        200
      ],
      "parameters": {
        "message": "Daily Performance Report:\\n\\nTotal Orders: {{ $json.total_orders }}\\nSuccessful Deliveries: {{ $json.successful_deliveries }}\\nPending Orders: {{ $json.pending_orders }}\\nSuccess Rate: {{ $json.success_rate_percent }}%\\n\\nTimestamp: {{ $json.timestamp }}",
        "subject": "Daily KPI Report - {{ Date.now() | formatDate('YYYY-MM-DD') }}",
        "toEmail": "management@healthmarketplace.et",
        "resource": "email",
        "fromEmail": "dashboard@healthmarketplace.et",
        "operation": "send"
      },
      "typeVersion": 2.1
    },
    {
      "id": "28",
      "name": "Send Prescription Validation Error",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        900,
        300
      ],
      "parameters": {
        "message": "Your order could not be processed due to prescription validation failure. Please contact your doctor or pharmacist.",
        "subject": "Invalid Prescription - Order {{ $json.orderId }}",
        "toEmail": "{{ $json.patientEmail }}",
        "resource": "email",
        "fromEmail": "system@healthmarketplace.et",
        "operation": "send"
      },
      "typeVersion": 2.1
    },
    {
      "id": "29",
      "name": "Log Prescription Error",
      "type": "n8n-nodes-base.mySql",
      "position": [
        1100,
        300
      ],
      "parameters": {
        "table": "order_errors",
        "values": {
          "order_id": "{{ $json.orderId }}",
          "created_at": "{{ Date.now() }}",
          "error_type": "prescription_invalid",
          "error_message": "Prescription validation failed"
        },
        "columns": "order_id, error_type, error_message, created_at",
        "operation": "insert"
      },
      "typeVersion": 2.5
    },
    {
      "id": "30",
      "name": "Send Out of Stock Notification",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1300,
        300
      ],
      "parameters": {
        "message": "One or more items in your order are currently out of stock. We will notify you when they become available.",
        "subject": "Out of Stock - Order {{ $json.orderId }}",
        "toEmail": "{{ $json.patientEmail }}",
        "resource": "email",
        "fromEmail": "system@healthmarketplace.et",
        "operation": "send"
      },
      "typeVersion": 2.1
    },
    {
      "id": "31",
      "name": "Log Inventory Error",
      "type": "n8n-nodes-base.mySql",
      "position": [
        1500,
        300
      ],
      "parameters": {
        "table": "order_errors",
        "values": {
          "order_id": "{{ $json.orderId }}",
          "created_at": "{{ Date.now() }}",
          "error_type": "inventory_unavailable",
          "error_message": "One or more items out of stock"
        },
        "columns": "order_id, error_type, error_message, created_at",
        "operation": "insert"
      },
      "typeVersion": 2.5
    }
  ],
  "connections": {
    "Route to Pharmacy": {
      "main": [
        [
          {
            "node": "Assign Logistics - Ride",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Low Stock Items": {
      "main": [
        [
          {
            "node": "Check If Items Below Threshold",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Daily KPIs": {
      "main": [
        [
          {
            "node": "Send Daily KPI Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Backup Schedule": {
      "main": [
        [
          {
            "node": "Check Last Backup Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Inventory Check": {
      "main": [
        [
          {
            "node": "Get Low Stock Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Inventory Check Logic": {
      "main": [
        [
          {
            "node": "Process Payment - Chapa",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Out of Stock Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Order Webhook Trigger": {
      "main": [
        [
          {
            "node": "Order Data Transformation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send SMS Notification": {
      "main": [
        [
          {
            "node": "Log Order Event for Audit Trail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assign Logistics - Ride": {
      "main": [
        [
          {
            "node": "Update Order Status - In Transit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Database Backup": {
      "main": [
        [
          {
            "node": "Log Backup Completion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Payment - Chapa": {
      "main": [
        [
          {
            "node": "Store Order in Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store Order in Database": {
      "main": [
        [
          {
            "node": "Route to Pharmacy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate E-Prescription": {
      "main": [
        [
          {
            "node": "Check Prescription Validity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Last Backup Status": {
      "main": [
        [
          {
            "node": "Execute Database Backup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Multilingual SMS": {
      "main": [
        [
          {
            "node": "Send SMS Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Today's Active Orders": {
      "main": [
        [
          {
            "node": "Calculate Daily KPIs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Order Data Transformation": {
      "main": [
        [
          {
            "node": "Validate E-Prescription",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Prescription Validity": {
      "main": [
        [
          {
            "node": "Check Inventory Availability",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Prescription Validation Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Inventory Availability": {
      "main": [
        [
          {
            "node": "Inventory Check Logic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Order Confirmation Email": {
      "main": [
        [
          {
            "node": "Generate Multilingual SMS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Items Below Threshold": {
      "main": [
        [
          {
            "node": "Generate Inventory Alert Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Out of Stock Notification": {
      "main": [
        [
          {
            "node": "Log Inventory Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Inventory Alert Report": {
      "main": [
        [
          {
            "node": "Send Inventory Alert Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Order Event for Audit Trail": {
      "main": [
        [
          {
            "node": "Get Today's Active Orders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Order Status - In Transit": {
      "main": [
        [
          {
            "node": "Send Order Confirmation Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Prescription Validation Error": {
      "main": [
        [
          {
            "node": "Log Prescription Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}