false, 'ERROR' => 'missing_params', 'MESSAGE' => 'UserID is required.']); } try { // Get ledger entries (most recent first) $qLedger = queryTimed(" SELECT ID, TaskID, GrossEarningsCents, ActivationWithheldCents, NetTransferCents, Status, CreatedAt FROM WorkPayoutLedgers WHERE UserID = ? ORDER BY CreatedAt DESC LIMIT 100 ", [$userID]); // Get totals $qTotals = queryOne(" SELECT COALESCE(SUM(GrossEarningsCents), 0) AS TotalGrossCents, COALESCE(SUM(ActivationWithheldCents), 0) AS TotalWithheldCents, COALESCE(SUM(CASE WHEN Status = 'transferred' THEN NetTransferCents ELSE 0 END), 0) AS TotalTransferredCents FROM WorkPayoutLedgers WHERE UserID = ? ", [$userID]); $ledgerEntries = []; foreach ($qLedger as $row) { $ledgerEntries[] = [ 'ID' => (int) $row['ID'], 'TaskID' => (int) $row['TaskID'], 'GrossEarningsCents' => (int) $row['GrossEarningsCents'], 'ActivationWithheldCents' => (int) $row['ActivationWithheldCents'], 'NetTransferCents' => (int) $row['NetTransferCents'], 'Status' => $row['Status'], 'CreatedAt' => toISO8601($row['CreatedAt']), ]; } jsonResponse([ 'OK' => true, 'LEDGER' => $ledgerEntries, 'TOTALS' => [ 'TotalGrossCents' => (int) ($qTotals['TotalGrossCents'] ?? 0), 'TotalWithheldCents' => (int) ($qTotals['TotalWithheldCents'] ?? 0), 'TotalTransferredCents' => (int) ($qTotals['TotalTransferredCents'] ?? 0), ], ]); } catch (Exception $e) { jsonResponse(['OK' => false, 'ERROR' => $e->getMessage()]); }