Creating Modules

Auto Commerce uses a modular, plugin-based architecture that allows you to add custom integrations and functionality without modifying core code.

Overview

Modules in Auto Commerce are:

  • Self-contained: Each module is a complete package with its own code, migrations, routes
  • Pluggable: Enable/disable modules per tenant without affecting others
  • Event-driven: Communicate with core and other modules via events
  • Contract-based: Implement standard interfaces for consistency

Module Types

Store Integrations

Connect to e-commerce platforms (Shopify, WooCommerce, etc.)

Interface: StoreProviderContract

Shipping Providers

Integrate with logistics companies (Delhivery, Shiprocket, etc.)

Interface: ShippingProviderContract

Communication Channels

Add messaging platforms (WhatsApp, SMS, Email, etc.)

Interface: ChannelProviderContract

Payment Gateways

Connect payment processors (Razorpay, Cashfree, etc.)

Interface: PaymentProviderContract

AI Services

Integrate AI capabilities (OpenAI, Claude, etc.)

Interface: AIProviderContract

Custom Functionality

Add any custom features or integrations

No specific interface required

Quick Start

1. Generate Module

php artisan module:make CustomIntegration

This creates:

modules/CustomIntegration/
├── Config/
│   └── config.php
├── Database/
│   └── Migrations/
├── Entities/
├── Http/
│   ├── Controllers/
│   └── routes.php
├── Providers/
│   └── CustomIntegrationServiceProvider.php
├── Resources/
│   └── views/
├── Services/
└── module.json

2. Define Module Manifest

Edit module.json:

{
  "name": "CustomIntegration",
  "alias": "custom-integration",
  "description": "Integration with CustomService",
  "version": "1.0.0",
  "type": "custom",
  "requires": [],
  "provides": [],
  "settings_schema": {
    "api_key": {
      "type": "string",
      "required": true,
      "encrypted": true,
      "label": "API Key"
    },
    "api_url": {
      "type": "string",
      "required": true,
      "label": "API URL",
      "default": "https://api.customservice.com"
    }
  }
}

3. Create Module Service

namespace Modules\CustomIntegration\Services;

class CustomIntegrationService
{
    protected $apiKey;
    protected $apiUrl;

    public function __construct()
    {
        $this->apiKey = $this->getSetting('api_key');
        $this->apiUrl = $this->getSetting('api_url');
    }

    protected function getSetting($key)
    {
        return ModuleManager::getSetting('custom-integration', $key);
    }

    public function sendData($data)
    {
        // Your integration logic
        $response = Http::withHeaders([
            'Authorization' => 'Bearer ' . $this->apiKey
        ])->post($this->apiUrl . '/endpoint', $data);

        return $response->json();
    }
}

4. Listen to Events

Register event listeners in your ServiceProvider:

namespace Modules\CustomIntegration\Providers;

use Illuminate\Support\ServiceProvider;
use App\Core\Events\OrderCreated;
use Modules\CustomIntegration\Listeners\HandleOrderCreated;

class CustomIntegrationServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Register event listeners
        Event::listen(OrderCreated::class, HandleOrderCreated::class);
    }
}

Create the listener:

namespace Modules\CustomIntegration\Listeners;

use App\Core\Events\OrderCreated;
use Modules\CustomIntegration\Services\CustomIntegrationService;

class HandleOrderCreated
{
    public function handle(OrderCreated $event)
    {
        $order = $event->order;

        // Send order to custom service
        $service = app(CustomIntegrationService::class);
        $service->sendData([
            'order_id' => $order->id,
            'total' => $order->total,
            'customer' => $order->customer->email
        ]);
    }
}

5. Add HTTP Routes

In Http/routes.php:

Route::group([
    'prefix' => 'integrations/custom',
    'middleware' => ['auth:api', 'tenant']
], function () {
    Route::post('/connect', 'CustomIntegrationController@connect');
    Route::post('/sync', 'CustomIntegrationController@sync');
    Route::get('/status', 'CustomIntegrationController@status');
});

6. Create Database Tables

php artisan module:make-migration create_custom_integrations_table CustomIntegration

Edit the migration:

Schema::create('custom_integrations', function (Blueprint $table) {
    $table->id();
    $table->foreignId('tenant_id')->constrained();
    $table->string('external_id')->nullable();
    $table->json('settings')->nullable();
    $table->boolean('is_active')->default(true);
    $table->timestamps();

    $table->index(['tenant_id', 'external_id']);
});

Run migration:

php artisan module:migrate CustomIntegration

Module Activation

For Development

php artisan module:enable CustomIntegration

For Tenants

// In your controller or service
ModuleManager::enable('custom-integration', $tenant);

Setting Configuration

ModuleManager::setSetting('custom-integration', $tenant, [
    'api_key' => 'your-api-key',
    'api_url' => 'https://api.customservice.com'
]);

Testing Your Module

Unit Tests

namespace Modules\CustomIntegration\Tests\Unit;

use Tests\TestCase;
use Modules\CustomIntegration\Services\CustomIntegrationService;

class CustomIntegrationServiceTest extends TestCase
{
    public function test_can_send_data()
    {
        $service = app(CustomIntegrationService::class);

        $result = $service->sendData([
            'test' => 'data'
        ]);

        $this->assertArrayHasKey('status', $result);
    }
}

Feature Tests

public function test_order_syncs_to_custom_service()
{
    // Enable module for test tenant
    ModuleManager::enable('custom-integration', $this->tenant);

    // Create order
    $order = Order::factory()->create();

    // Assert custom service was called
    // (use mocking or API mock server)
}

Publishing Your Module

1. Add Documentation

Create README.md:

# Custom Integration Module

Integration with CustomService for Auto Commerce.

## Installation

1. Enable the module
2. Configure API credentials
3. Test connection

## Configuration

- API Key: Your CustomService API key
- API URL: CustomService API endpoint

2. Version Your Module

Update module.json:

{
  "version": "1.0.0",
  "changelog": {
    "1.0.0": "Initial release"
  }
}

3. Share on GitHub

Make your module available to others:

git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/yourusername/autocom-custom-integration.git
git push -u origin main

Best Practices

  1. Follow naming conventions: Use StudlyCase for module names
  2. Implement contracts: Use standard interfaces where applicable
  3. Handle errors gracefully: Don't break core functionality if module fails
  4. Log important events: Use Laravel's logging for debugging
  5. Test thoroughly: Write tests for critical functionality
  6. Document everything: Clear README and inline comments
  7. Version carefully: Follow semantic versioning
  8. Respect tenant isolation: Always check tenant context

Next Steps