Module Development
Backend Development
Building Laravel backend code for AutoCom modules.
Service Provider
The service provider is the entry point for your module's backend:
<?php
namespace Modules\ShippingDelhivery;
use Illuminate\Support\ServiceProvider;
use Modules\Core\Contracts\ShippingProviderContract;
use Modules\ShippingDelhivery\App\Services\DelhiveryService;
class ShippingDelhiveryServiceProvider extends ServiceProvider
{
public function register(): void
{
// Register config
$this->mergeConfigFrom(__DIR__.'/Config/config.php', 'delhivery');
// Bind service to contract
$this->app->bind(ShippingProviderContract::class, DelhiveryService::class);
}
public function boot(): void
{
// Load routes
$this->loadRoutesFrom(__DIR__.'/routes/api.php');
// Load migrations
$this->loadMigrationsFrom(__DIR__.'/Database/Migrations');
// Publish config (optional)
$this->publishes([
__DIR__.'/Config/config.php' => config_path('delhivery.php'),
], 'delhivery-config');
}
}Defining Routes
# modules/ShippingDelhivery/backend/routes/api.php
<?php
use Illuminate\Support\Facades\Route;
use Modules\ShippingDelhivery\App\Http\Controllers\DelhiveryController;
use Modules\ShippingDelhivery\App\Http\Controllers\DelhiveryWebhookController;
Route::middleware(['api', 'auth:api'])
->prefix('api/v1/shipping/delhivery')
->group(function () {
Route::post('/shipments', [DelhiveryController::class, 'createShipment']);
Route::get('/shipments/{awb}/track', [DelhiveryController::class, 'track']);
Route::get('/shipments/{awb}/label', [DelhiveryController::class, 'downloadLabel']);
Route::post('/shipments/{awb}/cancel', [DelhiveryController::class, 'cancel']);
});
// Webhook endpoint (no auth required)
Route::prefix('api/webhooks')
->group(function () {
Route::post('/delhivery', [DelhiveryWebhookController::class, 'handle']);
});Controllers
<?php
namespace Modules\ShippingDelhivery\App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Modules\ShippingDelhivery\App\Http\Requests\CreateShipmentRequest;
use Modules\ShippingDelhivery\App\Services\DelhiveryService;
class DelhiveryController extends Controller
{
public function __construct(
private DelhiveryService $delhivery
) {}
public function createShipment(CreateShipmentRequest $request): JsonResponse
{
$shipment = $this->delhivery->createShipment(
$request->validated()
);
return response()->json([
'data' => $shipment,
'message' => 'Shipment created successfully',
], 201);
}
public function track(string $awb): JsonResponse
{
$tracking = $this->delhivery->trackShipment($awb);
return response()->json(['data' => $tracking]);
}
}Form Requests
<?php
namespace Modules\ShippingDelhivery\App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateShipmentRequest extends FormRequest
{
public function authorize(): bool
{
return true; // Auth handled by middleware
}
public function rules(): array
{
return [
'order_id' => ['required', 'uuid', 'exists:orders,id'],
'weight_kg' => ['required', 'numeric', 'min:0.1', 'max:50'],
'dimensions' => ['nullable', 'array'],
'dimensions.length' => ['nullable', 'numeric'],
'dimensions.width' => ['nullable', 'numeric'],
'dimensions.height' => ['nullable', 'numeric'],
'pickup_date' => ['nullable', 'date', 'after:today'],
'is_cod' => ['boolean'],
'cod_amount' => ['required_if:is_cod,true', 'numeric', 'min:0'],
];
}
}Working with Core Models
Use the Core module's Eloquent models in your services:
use Modules\Core\Models\Order;
use Modules\Core\Models\Product;
use Modules\Core\Models\Customer;
// Query orders
$orders = Order::where('status', 'ready_to_ship')
->whereNull('shipment_id')
->with(['customer', 'shippingAddress', 'items'])
->get();
// Access relationships
$order->customer->full_name;
$order->shippingAddress->city;
$order->items->sum('total');
// Update with metadata
$order->setMetadata('delhivery_awb', $awb);
$order->setMetadata('shipped_at', now());
$order->save();Dispatching Events
use Modules\Core\Events\ShipmentCreated;
use Modules\Core\Events\ShipmentStatusChanged;
// When shipment is created
event(new ShipmentCreated($shipment));
// When status changes (from webhook)
event(new ShipmentStatusChanged(
shipment: $shipment,
oldStatus: 'in_transit',
newStatus: 'delivered'
));Background Jobs
<?php
namespace Modules\ShippingDelhivery\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Modules\ShippingDelhivery\App\Services\DelhiveryService;
class SyncTrackingStatus implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable;
public function __construct(
public string $awb
) {}
public function handle(DelhiveryService $delhivery): void
{
$tracking = $delhivery->trackShipment($this->awb);
// Update shipment status
// Dispatch events if status changed
}
}
// Dispatch the job
SyncTrackingStatus::dispatch($awb)->onQueue('tracking');