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
- Follow naming conventions: Use StudlyCase for module names
- Implement contracts: Use standard interfaces where applicable
- Handle errors gracefully: Don't break core functionality if module fails
- Log important events: Use Laravel's logging for debugging
- Test thoroughly: Write tests for critical functionality
- Document everything: Clear README and inline comments
- Version carefully: Follow semantic versioning
- Respect tenant isolation: Always check tenant context
Next Steps
- Module Structure - Detailed directory structure
- Backend Development - Deep dive into backend code
- Frontend Development - Add UI components