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

  1. Process remittances promptly - Avoid overdue penalties
  2. Monitor pending debits - Know your obligations
  3. Use credit wisely - Credit limit is for emergencies
  4. Regular reconciliation - Match with bank statements

For Super Admins

  1. Set appropriate credit limits - Based on reseller history
  2. Monitor overdue remittances - Follow up promptly
  3. Batch settlements - Process weekly for efficiency
  4. Review transaction logs - Detect anomalies early

Next Steps