ResellerOrders Module
The ResellerOrders module handles order flow through the reseller chain, including forwarding, acceptance, fulfillment, and status propagation.
Overview
This module manages:
- Chain Orders - Orders that flow through the reseller hierarchy
- Order Forwarding - Moving orders up the chain to fulfillment
- Status Propagation - Syncing status across all levels
- Fulfillment Tracking - Who ships and how
Order Flow
Complete Order Lifecycle
┌─────────────────────────────────────────────────────────────┐
│ 1. CUSTOMER PLACES ORDER │
│ Customer buys on Sub-Reseller's Shopify store │
└─────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. ORDER SYNCED TO AUTOCOM │
│ Shopify webhook → Sub-Reseller's tenant database │
│ Status: pending_forward │
└─────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. CHAIN ORDER CREATED │
│ OrderForwardingService creates ChainOrder │
│ Visible to all tenants in the chain │
└─────────────────────────────┬───────────────────────────────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ 4A. FORWARD UP CHAIN │ │ 4B. FULFILL LOCALLY │
│ Order moves to parent │ │ Reseller ships direct │
│ Status: forwarded │ │ Status: processing │
└───────────┬─────────────┘ └───────────┬─────────────┘
│ │
▼ │
┌─────────────────────────┐ │
│ 5. ACCEPTED BY PARENT │ │
│ Parent claims order │ │
│ Status: accepted │ │
└───────────┬─────────────┘ │
│ │
▼ │
┌─────────────────────────┐ │
│ 6. FULFILLMENT │ │
│ Fulfiller ships order │◄────────────────┘
│ Status: shipped │
└───────────┬─────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 7. DELIVERED │
│ Courier confirms delivery │
│ Status: delivered │
│ → Triggers COD settlement flow │
└─────────────────────────────────────────────────────────────┘
Chain Order Model
Status Flow
pending_forward → forwarded → accepted → processing → shipped → delivered
↘ ↗
→ cancelled / returned ←
Status Definitions
| Status | Description |
|---|---|
pending_forward |
New order, awaiting forwarding decision |
forwarded |
Sent to parent tenant |
accepted |
Parent accepted responsibility |
processing |
Being prepared for shipment |
shipped |
Handed to courier |
out_for_delivery |
With delivery agent |
delivered |
Successfully delivered |
cancelled |
Order cancelled |
returned |
Returned by customer |
rto |
Return to origin (failed delivery) |
ChainOrder Structure
[
'id' => 'chain-order-uuid',
// Origin info (where order was placed)
'origin_tenant_id' => 'sub-reseller-uuid',
'origin_order_id' => 'local-order-uuid',
'origin_order_number' => 'ORD-2024-001',
// Current handler
'current_tenant_id' => 'distributor-uuid',
'current_order_id' => 'distributor-local-order-uuid',
// Fulfiller (who will ship)
'fulfiller_tenant_id' => 'super-admin-uuid',
'fulfiller_order_id' => 'super-admin-local-order-uuid',
// Chain info
'chain_path' => ['super-admin', 'distributor', 'sub-reseller'],
'chain_depth' => 3,
'chain_status' => 'shipped',
// Pricing
'origin_total' => 155.00, // Customer paid
'fulfiller_total' => 100.00, // Fulfiller's cost
'cod_amount' => 155.00,
'margin_breakdown' => [/* see architecture docs */],
// Customer info
'customer_name' => 'John Doe',
'customer_phone' => '+919876543210',
'shipping_address' => '123 Main St',
'shipping_city' => 'Mumbai',
'shipping_state' => 'Maharashtra',
'shipping_pincode' => '400001',
// Payment
'payment_method' => 'cod',
'payment_status' => 'pending',
// Shipping
'tracking_number' => 'DEL123456789',
'carrier' => 'delhivery',
'shipped_at' => '2024-01-15T10:30:00Z',
'delivered_at' => null,
]
Services
OrderForwardingService
Handles order creation and forwarding:
use Modules\ResellerOrders\App\Services\OrderForwardingService;
$service = app(OrderForwardingService::class);
// Create a new chain order
$chainOrder = $service->createChainOrder(
originTenant: $subReseller,
localOrderId: 'local-order-uuid',
orderData: [
'order_number' => 'ORD-2024-001',
'total' => 155.00,
'items' => [...],
'customer' => [...],
'shipping_address' => [...],
'payment_method' => 'cod',
]
);
// Forward to parent
$chainOrder = $service->forwardOrder($chainOrder, $subReseller);
// Parent accepts
$chainOrder = $service->acceptOrder($chainOrder, $distributor);
// Someone claims for fulfillment
$chainOrder = $service->claimForFulfillment($chainOrder, $superAdmin);
StatusPropagationService
Syncs status across the chain:
use Modules\ResellerOrders\App\Services\StatusPropagationService;
$service = app(StatusPropagationService::class);
// Mark as shipped
$chainOrder = $service->markShipped(
chainOrder: $chainOrder,
fulfiller: $superAdmin,
trackingNumber: 'DEL123456789',
carrier: 'delhivery',
userId: $user->id
);
// Mark as delivered (triggers COD settlement)
$chainOrder = $service->markDelivered($chainOrder, $user->id);
// Cancel order
$chainOrder = $service->cancelOrder(
chainOrder: $chainOrder,
reason: 'Customer requested cancellation',
userId: $user->id
);
API Endpoints
List Orders
GET /api/v1/chain-orders
GET /api/v1/chain-orders/incoming # From sub-resellers
GET /api/v1/chain-orders/forwarded # Sent to parent
GET /api/v1/chain-orders/fulfillment # To be fulfilled
Order Details
GET /api/v1/chain-orders/{id}
GET /api/v1/chain-orders/{id}/timeline
Order Actions
POST /api/v1/chain-orders/{id}/forward
POST /api/v1/chain-orders/{id}/accept
POST /api/v1/chain-orders/{id}/ship
POST /api/v1/chain-orders/{id}/deliver
POST /api/v1/chain-orders/{id}/cancel
Statistics
GET /api/v1/chain-orders/stats
Example API Responses
List Incoming Orders
GET /api/v1/chain-orders/incoming
Authorization: Bearer <token>
X-Tenant: distributor-uuid
{
"orders": [
{
"id": "chain-order-uuid",
"origin_order_number": "ORD-2024-001",
"from_tenant": {
"id": "sub-reseller-uuid",
"name": "Retail Store ABC"
},
"customer_name": "John Doe",
"shipping_city": "Mumbai",
"total_at_your_cost": 120.00,
"origin_total": 155.00,
"your_margin": 18.00,
"payment_method": "cod",
"status": "pending_forward",
"created_at": "2024-01-15T09:00:00Z"
}
],
"stats": {
"pending": 5,
"accepted": 12,
"shipped": 45
},
"pagination": {
"current_page": 1,
"total": 62
}
}
Get Order Details
GET /api/v1/chain-orders/chain-order-uuid
Authorization: Bearer <token>
X-Tenant: distributor-uuid
{
"order": {
"id": "chain-order-uuid",
"origin_order_number": "ORD-2024-001",
"chain_status": "shipped",
"chain_path": [
{
"tenant_id": "super-admin-uuid",
"tenant_name": "Super Admin",
"role": "fulfiller",
"cost": 100.00
},
{
"tenant_id": "distributor-uuid",
"tenant_name": "Distributor ABC",
"role": "current",
"cost": 120.00,
"margin": 18.00
},
{
"tenant_id": "sub-reseller-uuid",
"tenant_name": "Retail Store XYZ",
"role": "origin",
"cost": 138.00,
"margin": 17.00
}
],
"customer": {
"name": "John Doe",
"phone": "+919876543210",
"email": "john@example.com"
},
"shipping_address": {
"line1": "123 Main Street",
"city": "Mumbai",
"state": "Maharashtra",
"pincode": "400001"
},
"items": [
{
"product_id": "prod-uuid",
"name": "Premium Widget",
"quantity": 2,
"price_at_origin": 77.50,
"price_at_your_cost": 60.00
}
],
"pricing": {
"origin_total": 155.00,
"your_cost": 120.00,
"your_margin": 18.00,
"cod_amount": 155.00
},
"shipping": {
"carrier": "delhivery",
"tracking_number": "DEL123456789",
"shipped_at": "2024-01-15T10:30:00Z",
"estimated_delivery": "2024-01-18"
},
"payment": {
"method": "cod",
"status": "pending"
}
}
}
Get Order Timeline
GET /api/v1/chain-orders/chain-order-uuid/timeline
{
"timeline": [
{
"id": "history-1",
"status": "pending_forward",
"previous_status": null,
"changed_by_tenant": "Retail Store XYZ",
"changed_by_user": "store_admin@example.com",
"notes": "Order received from Shopify",
"created_at": "2024-01-15T09:00:00Z"
},
{
"id": "history-2",
"status": "forwarded",
"previous_status": "pending_forward",
"changed_by_tenant": "Retail Store XYZ",
"notes": "Forwarded to parent for fulfillment",
"created_at": "2024-01-15T09:05:00Z"
},
{
"id": "history-3",
"status": "accepted",
"previous_status": "forwarded",
"changed_by_tenant": "Distributor ABC",
"notes": "Order accepted",
"created_at": "2024-01-15T09:30:00Z"
},
{
"id": "history-4",
"status": "shipped",
"previous_status": "accepted",
"changed_by_tenant": "Super Admin",
"metadata": {
"tracking_number": "DEL123456789",
"carrier": "delhivery"
},
"created_at": "2024-01-15T10:30:00Z"
}
]
}
Ship Order
POST /api/v1/chain-orders/chain-order-uuid/ship
Authorization: Bearer <token>
X-Tenant: super-admin-uuid
Content-Type: application/json
{
"tracking_number": "DEL123456789",
"carrier": "delhivery"
}
{
"message": "Order marked as shipped",
"order": {
"id": "chain-order-uuid",
"chain_status": "shipped",
"tracking_number": "DEL123456789",
"carrier": "delhivery",
"shipped_at": "2024-01-15T10:30:00Z"
}
}
Frontend Pages
Chain Orders Dashboard
Route: /reseller-orders
Features:
- Overview of all chain orders
- Status breakdown chart
- Quick filters
- Recent activity feed
Incoming Orders
Route: /reseller-orders/incoming
Features:
- Orders from sub-resellers
- Accept/forward actions
- Bulk operations
- Filter by status, date, sub-reseller
Forwarded Orders
Route: /reseller-orders/forwarded
Features:
- Orders you've sent up the chain
- Track fulfillment progress
- Settlement status
Fulfillment Queue
Route: /reseller-orders/fulfillment
Features:
- Orders you need to ship
- Generate shipping labels
- Bulk ship functionality
- Print packing slips
Database Schema
chain_orders
CREATE TABLE chain_orders (
id UUID PRIMARY KEY,
-- Origin
origin_tenant_id VARCHAR(36) NOT NULL,
origin_order_id VARCHAR(36),
origin_order_number VARCHAR(100),
-- Current handler
current_tenant_id VARCHAR(36) NOT NULL,
current_order_id VARCHAR(36),
-- Fulfiller
fulfiller_tenant_id VARCHAR(36),
fulfiller_order_id VARCHAR(36),
-- Chain info
chain_path JSONB NOT NULL DEFAULT '[]',
chain_depth INTEGER DEFAULT 1,
chain_status VARCHAR(30) DEFAULT 'pending_forward',
-- Pricing
origin_total DECIMAL(14,2) NOT NULL,
fulfiller_total DECIMAL(14,2),
cod_amount DECIMAL(14,2),
margin_breakdown JSONB DEFAULT '[]',
-- Customer
customer_name VARCHAR(255),
customer_phone VARCHAR(20),
customer_email VARCHAR(255),
-- Shipping
shipping_address TEXT,
shipping_city VARCHAR(100),
shipping_state VARCHAR(100),
shipping_pincode VARCHAR(10),
shipping_country VARCHAR(50) DEFAULT 'India',
-- Payment
payment_method VARCHAR(20) DEFAULT 'cod',
payment_status VARCHAR(20) DEFAULT 'pending',
-- Tracking
tracking_number VARCHAR(100),
carrier VARCHAR(50),
shipped_at TIMESTAMP,
delivered_at TIMESTAMP,
-- Items
items JSONB DEFAULT '[]',
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE INDEX idx_chain_orders_origin ON chain_orders(origin_tenant_id);
CREATE INDEX idx_chain_orders_current ON chain_orders(current_tenant_id);
CREATE INDEX idx_chain_orders_fulfiller ON chain_orders(fulfiller_tenant_id);
CREATE INDEX idx_chain_orders_status ON chain_orders(chain_status);
chain_order_status_history
CREATE TABLE chain_order_status_history (
id UUID PRIMARY KEY,
chain_order_id UUID NOT NULL REFERENCES chain_orders(id),
status VARCHAR(30) NOT NULL,
previous_status VARCHAR(30),
changed_by_tenant_id VARCHAR(36),
changed_by_user_id VARCHAR(36),
notes TEXT,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMP
);
CREATE INDEX idx_status_history_order ON chain_order_status_history(chain_order_id);
Events
| Event | When Fired | Payload |
|---|---|---|
ChainOrderCreated |
New chain order | order, origin_tenant |
ChainOrderForwarded |
Order forwarded up | order, from_tenant, to_tenant |
ChainOrderAccepted |
Order accepted | order, accepting_tenant |
ChainOrderStatusChanged |
Any status change | order, old_status, new_status |
ChainOrderShipped |
Order shipped | order, tracking, carrier |
ChainOrderDelivered |
Order delivered | order (triggers settlement) |
Permissions
| Permission | Description |
|---|---|
chain_orders.view |
View orders in the reseller chain |
chain_orders.accept |
Accept incoming orders |
chain_orders.fulfill |
Mark orders as shipped/delivered |
chain_orders.forward |
Forward orders up the chain |
chain_orders.cancel |
Cancel orders |
Configuration
// config/reseller-orders.php
return [
// Auto-forward orders to parent
'auto_forward' => false,
// Auto-accept incoming orders
'auto_accept' => false,
// Default fulfiller (null = manual selection)
'default_fulfiller' => null,
// Days to accept before auto-escalation
'accept_deadline_days' => 1,
// Notify on new incoming orders
'notify_incoming' => true,
// Supported carriers
'carriers' => ['delhivery', 'shiprocket', 'bluedart', 'manual'],
];
Best Practices
Order Processing
- Process quickly - Set up notifications for incoming orders
- Communicate status - Each status change is visible to all chain members
- Accurate tracking - Enter tracking numbers promptly
- Handle exceptions - Use cancellation/return flows appropriately
Fulfillment Strategy
- Centralized fulfillment - Most efficient for COD handling
- Local fulfillment - Faster delivery but complex settlements
- Hybrid approach - Different strategies by region/product
Next Steps
- ResellerFinance Module - COD settlements
- API Reference - Complete endpoints
- Database Schema - All tables