Docs/Creating Modules
Module Development

Creating Your First Module

Learn how to build custom modules for AutoCom.

Quick Start

Create a new module in 3 steps:

  1. 1

    Create the module directory

    mkdir -p modules/MyModule/{backend,frontend}
  2. 2

    Create the module manifest

    # modules/MyModule/module.json
    {
      "name": "MyModule",
      "alias": "my-module",
      "displayName": "My Custom Module",
      "version": "1.0.0",
      "type": "custom",
      "priority": 50,
      "enabled": true,
      "backend": {
        "namespace": "Modules\\MyModule",
        "providers": [
          "Modules\\MyModule\\MyModuleServiceProvider"
        ]
      }
    }
  3. 3

    Create the service provider

    # modules/MyModule/backend/MyModuleServiceProvider.php
    <?php
    
    namespace Modules\MyModule;
    
    use Illuminate\Support\ServiceProvider;
    
    class MyModuleServiceProvider extends ServiceProvider
    {
        public function register(): void
        {
            // Register bindings
        }
    
        public function boot(): void
        {
            $this->loadRoutesFrom(__DIR__.'/routes/api.php');
            $this->loadMigrationsFrom(__DIR__.'/Database/Migrations');
        }
    }

Module Manifest (module.json)

Every module requires a module.json file at its root:

{
  "name": "ShippingDelhivery",
  "alias": "shipping-delhivery",
  "displayName": "Delhivery Shipping",
  "description": "Integration with Delhivery courier services",
  "version": "1.0.0",
  "type": "shipping",
  "priority": 20,
  "enabled": true,
  "isCore": false,
  "requires": ["orders"],
  "backend": {
    "namespace": "Modules\\ShippingDelhivery",
    "providers": [
      "Modules\\ShippingDelhivery\\ShippingDelhiveryServiceProvider"
    ]
  },
  "frontend": {
    "exports": ["components", "hooks", "types"]
  },
  "settings_schema": {
    "api_key": {
      "type": "string",
      "required": true,
      "encrypted": true,
      "label": "API Key"
    },
    "warehouse_id": {
      "type": "string",
      "required": true,
      "label": "Warehouse ID"
    }
  }
}

Manifest Fields

namePascalCase module identifier
aliasURL-friendly identifier (kebab-case)
typecore | store | shipping | channel | payment | ai | custom
priorityLoad order (lower = earlier). Core modules use 10-15.
requiresArray of module aliases this depends on
settings_schemaConfiguration fields for tenant settings

Module Types

coreCore Modules

Products, Customers, Orders. Cannot be disabled.

storeStore Integrations

Shopify, WooCommerce. Implement StoreProviderContract.

shippingShipping Carriers

Delhivery, Shiprocket. Implement ShippingProviderContract.

channelCommunication Channels

WhatsApp, SMS, Email. Implement ChannelProviderContract.

Implementing Contracts

Integration modules must implement the appropriate contract:

<?php

namespace Modules\ShippingDelhivery\Services;

use Modules\Core\Contracts\ShippingProviderContract;

class DelhiveryService implements ShippingProviderContract
{
    public function createShipment(array $data): array
    {
        // Create shipment with Delhivery API
        return [
            'awb' => 'AWB123456',
            'tracking_url' => 'https://...',
        ];
    }

    public function trackShipment(string $awb): array
    {
        // Get tracking info
    }

    public function cancelShipment(string $awb): bool
    {
        // Cancel shipment
    }

    public function generateLabel(string $awb): string
    {
        // Return PDF URL or base64
    }
}

Listening to Events

Modules can listen to core events to react to system changes:

# In your ServiceProvider boot() method:

use Modules\Core\Events\OrderCreated;
use Modules\Core\Events\OrderStatusChanged;

Event::listen(OrderCreated::class, function ($event) {
    // React to new orders
    $order = $event->order;
    // Maybe sync to external system, send notification, etc.
});

Event::listen(OrderStatusChanged::class, function ($event) {
    $order = $event->order;
    $oldStatus = $event->oldStatus;
    $newStatus = $event->newStatus;

    if ($newStatus === 'shipped') {
        // Send shipping notification
    }
});