ResellerFinance Module
The ResellerFinance module handles all financial operations for the reseller network, including wallets, COD collection, and settlement processing.
Overview
This module manages:
- Tenant Wallets - Per-tenant balance tracking with holds
- COD Collections - Track who collected cash on delivery
- Remittances - Money flow between tenants
- Settlement Processing - Automated and manual settlement
Wallet System
Wallet Structure
Each tenant has a wallet in the central database:
[
'id' => 'wallet-uuid',
'tenant_id' => 'tenant-uuid',
'balance' => 25000.00, // Current available balance
'pending_credits' => 5000.00, // Expected incoming (margins)
'pending_debits' => 3000.00, // On hold for remittance
'total_earned' => 150000.00, // Lifetime earnings
'total_paid_out' => 125000.00, // Lifetime payouts
'credit_limit' => 10000.00, // Allowed negative balance
'currency' => 'INR',
'last_settlement_at' => '2024-01-15T00:00:00Z',
]
Wallet Operations
use Modules\ResellerFinance\App\Models\TenantWallet;
$wallet = TenantWallet::getOrCreate($tenantId);
// Credit (add money)
$wallet->credit(
amount: 500.00,
description: 'Margin from order #ORD-2024-001',
refType: 'chain_order',
refId: 'order-uuid'
);
// Debit (remove money)
$wallet->debit(
amount: 4500.00,
description: 'COD remittance to Parent Wholesaler',
refType: 'remittance',
refId: 'remittance-uuid'
);
// Hold (reserve for future debit)
$wallet->hold(
amount: 4500.00,
description: 'COD remittance pending for order #ORD-2024-001',
refType: 'chain_order',
refId: 'order-uuid'
);
// Release (remove hold)
$wallet->release(
amount: 4500.00,
description: 'Remittance processed',
refType: 'remittance',
refId: 'remittance-uuid'
);
// Balance checks
$wallet->getAvailableBalance(); // balance - pending_debits
$wallet->getEffectiveBalance(); // balance + credit_limit
Dual COD Flow
Understanding the Flows
The platform supports two COD collection scenarios:
Flow A: Upstream (Super Admin Fulfills)
┌─────────────────────────────────────────────────────────────┐
│ Super Admin ships order via Delhivery │
│ Courier collects ₹155 COD from customer │
└─────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Delhivery remits ₹155 to Super Admin │
│ CodCollection created (flow_type: upstream) │
└─────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ CodSettlementService processes margins │
│ │
│ Super Admin: keeps ₹100 base + ₹20 margin = ₹120 │
│ Distributor: wallet credited ₹18 │
│ Sub-Reseller: wallet credited ₹17 │
└─────────────────────────────────────────────────────────────┘
Flow B: Downstream (Reseller Fulfills Locally)
┌─────────────────────────────────────────────────────────────┐
│ Sub-Reseller ships locally, collects ₹155 COD │
│ CodCollection created (flow_type: downstream) │
└─────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Sub-Reseller keeps their margin (₹17) │
│ Must remit ₹138 to Distributor │
│ CodRemittance created: Sub-Reseller → Distributor │
│ Hold placed on Sub-Reseller wallet │
└─────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Sub-Reseller processes remittance (pays Distributor) │
│ Wallet debited ₹138, hold released │
│ Distributor wallet credited ₹138 │
└─────────────────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Distributor keeps their margin (₹18) │
│ Must remit ₹120 to Super Admin │
│ Process continues up the chain... │
└─────────────────────────────────────────────────────────────┘
CodSettlementService
The core service handling all settlement logic:
use Modules\ResellerFinance\App\Services\CodSettlementService;
$service = app(CodSettlementService::class);
// Process a delivered order (called automatically)
$service->processDeliveredOrder($chainOrder);
// Process a specific remittance
$service->processRemittance($remittance);
// Get pending remittances for a tenant
$pending = $service->getPendingRemittances($tenant);
// Returns: ['to_pay' => [...], 'to_receive' => [...], 'total_owed' => X, 'total_receivable' => Y]
// Get settlement summary
$summary = $service->getSettlementSummary($tenant, 'month');
API Endpoints
Wallet
GET /api/v1/finance/wallet # Get wallet balance
GET /api/v1/finance/wallet/summary # Get period summary
GET /api/v1/finance/wallet/transactions # Transaction history
GET /api/v1/finance/wallet/transactions/export # Export CSV
GET /api/v1/finance/wallet/transactions/{id} # Single transaction
Settlements
GET /api/v1/finance/settlements/summary # Settlement summary
GET /api/v1/finance/settlements/pending # Pending remittances
GET /api/v1/finance/settlements/collections # COD collections
GET /api/v1/finance/settlements/remittances # Remittance history
POST /api/v1/finance/settlements/remittances/{id}/process # Pay remittance
POST /api/v1/finance/settlements/remittances/bulk-process # Bulk pay
Admin (Super Admin Only)
GET /api/v1/finance/admin/stats # Global settlement statistics
Example API Responses
Get Wallet
GET /api/v1/finance/wallet
Authorization: Bearer <token>
X-Tenant: reseller-uuid
{
"wallet": {
"id": "wallet-uuid",
"balance": 25000.00,
"available_balance": 22000.00,
"effective_balance": 35000.00,
"pending_credits": 5000.00,
"pending_debits": 3000.00,
"total_earned": 150000.00,
"total_paid_out": 125000.00,
"credit_limit": 10000.00,
"currency": "INR",
"last_settlement_at": "2024-01-15T00:00:00Z"
}
}
Get Pending Remittances
GET /api/v1/finance/settlements/pending
Authorization: Bearer <token>
X-Tenant: reseller-uuid
{
"to_pay": [
{
"id": "remittance-uuid-1",
"to_tenant": {
"id": "parent-uuid",
"name": "Distributor ABC"
},
"amount": 4500.00,
"breakdown": {
"type": "cod_remittance",
"your_margin": 500.00
},
"due_date": "2024-01-18T00:00:00Z",
"order_number": "ORD-2024-001",
"created_at": "2024-01-15T10:30:00Z"
}
],
"to_receive": [
{
"id": "remittance-uuid-2",
"from_tenant": {
"id": "sub-reseller-uuid",
"name": "Retail Store XYZ"
},
"amount": 6000.00,
"due_date": "2024-01-19T00:00:00Z",
"order_number": "ORD-2024-003",
"created_at": "2024-01-16T09:00:00Z"
}
],
"totals": {
"owed": 4500.00,
"receivable": 6000.00,
"net_position": 1500.00
}
}
Process Remittance
POST /api/v1/finance/settlements/remittances/remittance-uuid-1/process
Authorization: Bearer <token>
X-Tenant: reseller-uuid
{
"message": "Remittance processed successfully",
"remittance": {
"id": "remittance-uuid-1",
"status": "completed",
"completed_at": "2024-01-17T14:30:00Z",
"amount": 4500.00
},
"wallet": {
"new_balance": 17500.00,
"deducted": 4500.00
}
}
Get Wallet Summary
GET /api/v1/finance/wallet/summary?period=month
Authorization: Bearer <token>
X-Tenant: reseller-uuid
{
"period": "month",
"start_date": "2024-01-01T00:00:00Z",
"wallet": {
"balance": 25000.00,
"available_balance": 22000.00,
"pending_credits": 5000.00,
"pending_debits": 3000.00
},
"period_summary": {
"total_credits": 45000.00,
"total_debits": 32000.00,
"total_holds": 3000.00,
"total_releases": 2500.00,
"net_change": 13000.00,
"transaction_count": 87
},
"by_reference_type": {
"chain_order": {
"count": 45,
"total_credits": 35000.00,
"total_debits": 20000.00
},
"remittance": {
"count": 32,
"total_credits": 8000.00,
"total_debits": 10000.00
}
}
}
Transaction History
GET /api/v1/finance/wallet/transactions?type=credit&per_page=20
Authorization: Bearer <token>
X-Tenant: reseller-uuid
{
"transactions": [
{
"id": "txn-uuid-1",
"type": "credit",
"amount": 500.00,
"balance_after": 25500.00,
"reference_type": "chain_order",
"reference_id": "order-uuid",
"description": "Margin from order #ORD-2024-001",
"created_at": "2024-01-17T10:30:00Z"
},
{
"id": "txn-uuid-2",
"type": "credit",
"amount": 600.00,
"balance_after": 25000.00,
"reference_type": "chain_order",
"reference_id": "order-uuid-2",
"description": "Margin from order #ORD-2024-002",
"created_at": "2024-01-16T14:20:00Z"
}
],
"pagination": {
"current_page": 1,
"last_page": 5,
"per_page": 20,
"total": 87
}
}
Frontend Pages
Finance Dashboard
Route: /reseller-finance
Features:
- Wallet balance overview
- Pending settlements summary
- Net position indicator
- Quick links to detailed views
Wallet Details
Route: /reseller-finance/wallet
Features:
- Detailed balance breakdown
- Period-based summary (week/month/quarter/year)
- Transaction breakdown by type
- Lifetime statistics
Settlements
Route: /reseller-finance/settlements
Features:
- To Pay tab - Remittances you owe
- To Receive tab - Remittances owed to you
- History tab - Completed settlements
- Process individual or bulk remittances
- Overdue indicators
Transaction History
Route: /reseller-finance/transactions
Features:
- Full transaction log
- Filter by type (credit/debit/hold/release)
- Filter by reference type
- Search functionality
- Export to CSV
Database Schema
tenant_wallets
CREATE TABLE tenant_wallets (
id UUID PRIMARY KEY,
tenant_id VARCHAR(36) NOT NULL UNIQUE,
balance DECIMAL(14,2) DEFAULT 0,
pending_credits DECIMAL(14,2) DEFAULT 0,
pending_debits DECIMAL(14,2) DEFAULT 0,
total_earned DECIMAL(14,2) DEFAULT 0,
total_paid_out DECIMAL(14,2) DEFAULT 0,
credit_limit DECIMAL(14,2) DEFAULT 0,
currency VARCHAR(3) DEFAULT 'INR',
last_settlement_at TIMESTAMP,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
wallet_transactions
CREATE TABLE wallet_transactions (
id UUID PRIMARY KEY,
wallet_id UUID NOT NULL REFERENCES tenant_wallets(id),
type VARCHAR(20) NOT NULL, -- credit, debit, hold, release
amount DECIMAL(14,2) NOT NULL,
balance_after DECIMAL(14,2) NOT NULL,
reference_type VARCHAR(50),
reference_id VARCHAR(36),
description TEXT,
metadata JSONB DEFAULT '{}',
created_by VARCHAR(36),
created_at TIMESTAMP
);
CREATE INDEX idx_wallet_txn_wallet ON wallet_transactions(wallet_id);
CREATE INDEX idx_wallet_txn_type ON wallet_transactions(type);
CREATE INDEX idx_wallet_txn_ref ON wallet_transactions(reference_type, reference_id);
cod_collections
CREATE TABLE cod_collections (
id UUID PRIMARY KEY,
chain_order_id UUID NOT NULL REFERENCES chain_orders(id),
collected_by_tenant_id VARCHAR(36) NOT NULL,
collected_amount DECIMAL(14,2) NOT NULL,
collected_at TIMESTAMP NOT NULL,
flow_type VARCHAR(20) NOT NULL, -- upstream, downstream
status VARCHAR(20) DEFAULT 'pending',
settlement_batch_id UUID,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE INDEX idx_cod_tenant ON cod_collections(collected_by_tenant_id);
CREATE INDEX idx_cod_order ON cod_collections(chain_order_id);
cod_remittances
CREATE TABLE cod_remittances (
id UUID PRIMARY KEY,
cod_collection_id UUID NOT NULL REFERENCES cod_collections(id),
from_tenant_id VARCHAR(36) NOT NULL,
to_tenant_id VARCHAR(36) NOT NULL,
amount DECIMAL(14,2) NOT NULL,
breakdown JSONB DEFAULT '{}',
status VARCHAR(20) DEFAULT 'pending',
due_date TIMESTAMP,
completed_at TIMESTAMP,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE INDEX idx_remit_from ON cod_remittances(from_tenant_id);
CREATE INDEX idx_remit_to ON cod_remittances(to_tenant_id);
CREATE INDEX idx_remit_status ON cod_remittances(status);
Events
| Event | When Fired | Payload |
|---|---|---|
WalletCredited |
Money added to wallet | wallet, amount, transaction |
WalletDebited |
Money removed from wallet | wallet, amount, transaction |
CodCollected |
COD collected for order | collection, chain_order |
RemittanceCreated |
New remittance record | remittance |
RemittanceProcessed |
Remittance paid | remittance |
RemittanceOverdue |
Remittance past due date | remittance |
Permissions
| Permission | Description |
|---|---|
settlements.view |
View settlement history |
settlements.manage |
Process and manage settlements |
settlements.view_wallet |
View wallet balance and transactions |
settlements.manage_wallet |
Manage wallet operations |
Configuration
// config/resellerfinance.php
return [
'default_currency' => 'INR',
'remittance' => [
'default_due_days' => 3,
'reminder_days' => 1,
'auto_debit' => false,
],
'settlement' => [
'minimum_amount' => 100,
'batch_frequency' => 'weekly',
'weekly_day' => 1, // Monday
],
'credit' => [
'default_limit' => 0,
'max_limit' => 100000,
'allow_negative' => true,
],
'notifications' => [
'low_balance_threshold' => 1000,
'notify_overdue' => true,
'channels' => ['database'],
],
];
Best Practices
Managing Cash Flow
- Process remittances promptly - Avoid overdue penalties
- Monitor pending debits - Know your obligations
- Use credit wisely - Credit limit is for emergencies
- Regular reconciliation - Match with bank statements
For Super Admins
- Set appropriate credit limits - Based on reseller history
- Monitor overdue remittances - Follow up promptly
- Batch settlements - Process weekly for efficiency
- Review transaction logs - Detect anomalies early
Next Steps
- API Reference - Complete endpoint documentation
- Database Schema - All table definitions
- Architecture - Technical deep dive