# easy-invoice/2.3.1/templates/payments/list.php

Easy Invoice – Invoice Generator, PDF Quotes &amp; Payments, version 2.3.1. 1,049 lines.

- Page: https://pluginprobe.com/plugins/easy-invoice/2.3.1/code/templates/payments/list.php
- Raw: https://pluginprobe.com/plugins/easy-invoice/2.3.1/raw/templates/payments/list.php
- Modified: 2026-05-21T08:29:24+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/easy-invoice/2.3.1/code/templates/payments/list.php#L10-L20`.

```php
<?php
/**
 * Payments List Template
 *
 * @package Easy_Invoice
 */

// Ensure we're in the correct namespace
namespace EasyInvoice\Templates\Payments;

// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}

use EasyInvoice\Models\Payment;
use EasyInvoice\Models\Invoice;


// Extract data passed from controller
$payments = $payments ?? [];
$current_view = $current_view ?? 'all';
$status_filter = $status_filter ?? '';
$status_filters = $status_filters ?? [];
$trash_count = $trash_count ?? 0;
$stats = $stats ?? [];
$current_page = $current_page ?? 1;
$per_page = $per_page ?? 20;
$total_payments = $total_payments ?? 0;
$total_pages = $total_pages ?? 1;

// Ensure all required stats keys exist with default values
$stats = array_merge([
    'total_payments' => 0,
    'total_amount' => 0,
    'completed_payments' => 0,
    'pending_payments' => 0,
    'failed_payments' => 0
], $stats);

// Initialize amounts_by_currency array
$amounts_by_currency = [];
// Calculate stats from the payments array
foreach ($payments as $payment) {
    $amount = floatval($payment->getAmount());
    $status = $payment->getStatus();
    
    $stats['total_amount'] += $amount;
    
    switch ($status) {
        case 'completed':
            $stats['completed_payments']++;
            break;
        case 'pending':
            $stats['pending_payments']++;
            break;
        case 'failed':
            $stats['failed_payments']++;
            break;
    }
    
    // Calculate currency breakdown
    $payment_currency = $payment->getCurrency();
    
    // If currency is empty or "global", get the actual currency that was used
    if (empty($payment_currency) || $payment_currency === 'global') {
        $actual_currency = get_post_meta($payment->getId(), '_currency', true);
        $payment_currency = !empty($actual_currency) ? $actual_currency : get_option('easy_invoice_currency_code', 'USD');
    }
    
    // If currency is still "global", use the global setting
    if ($payment_currency === 'global') {
        $payment_currency = get_option('easy_invoice_currency_code', 'USD');
}

    $payment_currency_symbol = $payment->getCurrencySymbol() ?: \EasyInvoice\Helpers\CurrencyHelper::getCurrencySymbol($payment_currency);
    
    // Normalize currency code to uppercase for consistent grouping
    $payment_currency = strtoupper($payment_currency);

    // Group amounts by currency
    if (!isset($amounts_by_currency[$payment_currency])) {
        $amounts_by_currency[$payment_currency] = [
            'amount' => 0,
            'symbol' => $payment_currency_symbol
        ];
}
    $amounts_by_currency[$payment_currency]['amount'] += $amount;
}

// Check for bulk action notifications
$notification = false;

if (isset($_GET['bulk_trashed']) && $_GET['bulk_trashed'] > 0) {
    $count = intval($_GET['bulk_trashed']);
    easy_invoice_display_notification('success', sprintf(_n('%s payment moved to trash.', '%s payments moved to trash.', $count, 'easy-invoice'), $count));
    $notification = true;
}

if (isset($_GET['bulk_restored']) && $_GET['bulk_restored'] > 0) {
    $count = intval($_GET['bulk_restored']);
    easy_invoice_display_notification('success', sprintf(_n('%s payment restored from trash.', '%s payments restored from trash.', $count, 'easy-invoice'), $count));
    $notification = true;
}

if (isset($_GET['bulk_deleted']) && $_GET['bulk_deleted'] > 0) {
    $count = intval($_GET['bulk_deleted']);
    easy_invoice_display_notification('success', sprintf(_n('%s payment permanently deleted.', '%s payments permanently deleted.', $count, 'easy-invoice'), $count));
    $notification = true;
}

if (isset($_GET['bulk_error'])) {
    $error = sanitize_text_field($_GET['bulk_error']);
    $error_message = 'An error occurred while processing the bulk action.';
    
    if ($error === 'no_selection') {
        $error_message = 'Please select at least one payment to perform this action.';
    } elseif ($error === 'invalid_action') {
        $error_message = 'Please select a valid bulk action.';
    }
    
    easy_invoice_display_notification('error', $error_message);
    $notification = true;
}

?>
<div class="p-8">
    <div class="ei-app-page-header bg-white border-b border-gray-200 px-6" style="margin-left: -2rem; margin-top: -2rem; margin-right: -2rem; padding-left: 2rem; padding-right: 2rem;">
        <div class="flex items-center justify-between">
            <div>
                <h1 class="text-2xl font-bold text-gray-900"><?php _e('Payments', 'easy-invoice'); ?></h1>
                <p class="mt-1 text-sm text-gray-500"><?php _e('Manage all payment records', 'easy-invoice'); ?></p>
            </div>
            <div class="flex items-center space-x-3">
                <?php
                // "Export All" is part of the bulk_operations addon
                // (Personal tier). See templates/invoices/listing.php
                // for the canonical three-state gate pattern.
                $ei_bulk_ops_loaded = \EasyInvoice\Addons\AddonManager::shouldLoad('bulk_operations');
                ?>
                <?php if ($ei_bulk_ops_loaded): ?>
                <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display:inline;">
                    <input type="hidden" name="action" value="easy_invoice_export_all_payments" />
                    <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce('easy_invoice_export_all_payments'); ?>" />
                    <button type="submit" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
                        <svg class="w-4 h-4 mr-2 text-indigo-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
                        </svg>
                        <?php _e('Export All', 'easy-invoice'); ?>
                    </button>
                </form>
                <?php elseif (!easy_invoice_has_pro()): ?>
                <button type="button" id="export-all-payments-btn" class="premium-export-btn inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors duration-200 relative">
                    <svg class="w-4 h-4 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
                    </svg>
                    <?php _e('Export All', 'easy-invoice'); ?>
                    <svg class="ml-2 w-5 h-5 text-purple-600 crown-icon" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path d="M12 8L15 13.2L18 10.5L17.3 14H6.7L6 10.5L9 13.2L12 8M12 4L8.5 10L3 5L5 16H19L21 5L15.5 10L12 4Z"/>
                    </svg>
                </button>
                <script>
                jQuery(document).ready(function($) {
                    $('#export-all-payments-btn').on('click', function(e) {
                        e.preventDefault();
                        if (typeof EasyInvoiceConfirmation !== 'undefined') {
                            EasyInvoiceConfirmation.showFeatureUpgrade('Export All Payments', 'Export all your payments to CSV, Excel, or PDF format for backup, analysis, or sharing with your team.');
                        } else {
                            EasyInvoiceToast.error('<?php echo esc_js(__('Exporting all payments is a premium feature. Upgrade to Easy Invoice Pro to unlock this feature.', 'easy-invoice')); ?>');
                        }
                    });
                });
                </script>
                <?php endif; ?>
                
                <a href="?page=easy-invoice-payment-new" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
                    <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
                    </svg>
                    <?php _e('Add New Payment', 'easy-invoice'); ?>
        </a>
            </div>
        </div>
    </div>

    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8 mt-8">
        <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
            <div class="flex items-center">
                <div class="rounded-full bg-indigo-100 p-3 mr-4">
                    <svg class="w-6 h-6 text-indigo-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
                    </svg>
                </div>
                <div>
                    <h3 class="text-sm font-medium text-gray-500">Total Payments</h3>
                    <p class="mt-1 text-2xl font-bold text-gray-900"><?php echo $stats['total_payments']; ?></p>
                </div>
            </div>
        </div>
        <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
            <div class="flex items-center">
                <div class="rounded-full bg-green-100 p-3 mr-4">
                    <svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                    </svg>
                </div>
                <div>
                    <h3 class="text-sm font-medium text-gray-500">Total Amount</h3>
                    <?php if (!empty($amounts_by_currency)): ?>
                        <div class="mt-1">
                            <?php foreach ($amounts_by_currency as $currency => $data): ?>
                                <p class="text-lg font-bold text-gray-900">
                                    <?php echo $data['symbol'] . number_format($data['amount'], 2); ?>
                                    <span class="text-sm font-normal text-gray-500"><?php echo strtoupper($currency ?? 'USD'); ?></span>
                                </p>
                            <?php endforeach; ?>
                        </div>
                    <?php else: ?>
                        <p class="mt-1 text-lg font-bold text-gray-900"><?php echo get_option('easy_invoice_currency_symbol', '$') . '0.00'; ?></p>
                    <?php endif; ?>
                </div>
            </div>
        </div>
        <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
            <div class="flex items-center">
                <div class="rounded-full bg-green-100 p-3 mr-4">
                    <svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                    </svg>
                </div>
                <div>
                    <h3 class="text-sm font-medium text-gray-500">Completed Payments</h3>
                    <p class="mt-1 text-2xl font-bold text-green-600"><?php echo $stats['completed_payments']; ?></p>
                </div>
            </div>
        </div>
        <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
            <div class="flex items-center">
                <div class="rounded-full bg-yellow-100 p-3 mr-4">
                    <svg class="w-6 h-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                    </svg>
                </div>
                <div>
                    <h3 class="text-sm font-medium text-gray-500">Pending Payments</h3>
                    <p class="mt-1 text-2xl font-bold text-yellow-600"><?php echo $stats['pending_payments']; ?></p>
                </div>
            </div>
        </div>
    </div>

    <?php if ($total_payments > 0): ?>
    <div class="mb-4">
        <div class="px-4 py-3 flex items-center justify-between">
            <div class="flex items-center space-x-2">
                <span class="text-sm text-gray-700">
                    Showing 
                    <span class="font-medium"><?php echo number_format((($current_page - 1) * $per_page) + 1); ?></span>
                    to 
                    <span class="font-medium"><?php echo number_format(min($current_page * $per_page, $total_payments)); ?></span>
                    of 
                    <span class="font-medium"><?php echo number_format($total_payments); ?></span>
                    results
                </span>
            </div>
            <?php if ($total_pages > 1): ?>
            <div class="flex items-center space-x-2">
                <span class="text-sm text-gray-500">Page <?php echo number_format($current_page); ?> of <?php echo number_format($total_pages); ?></span>
                <?php
                // Use WordPress's built-in pagination for top
                $top_pagination_args = array(
                    'base' => add_query_arg('paged', '%#%'),
                    'format' => '',
                    'current' => $current_page,
                    'total' => $total_pages,
                    'prev_text' => '‹ Previous',
                    'next_text' => 'Next ›',
                    'type' => 'array',
                    'end_size' => 1,
                    'mid_size' => 2,
                    'add_args' => array(
                        'page' => 'easy-invoice-payments',
                        'view' => $current_view,
                        'status' => $status_filter
                    )
                );
                
                $top_pagination_links = paginate_links($top_pagination_args);
                
                if ($top_pagination_links) {
                    echo '<div class="flex space-x-1">';
                    foreach ($top_pagination_links as $link) {
                        // Add null check to prevent passing null to easy_invoice_str_replace
                        if ($link === null) {
                            continue;
                        }
                        
                        // Convert WordPress pagination to our styling
                        $link = easy_invoice_str_replace('page-numbers', 'px-3 py-2 text-sm font-medium border border-gray-300 rounded-md', $link);
                        $link = easy_invoice_str_replace('current', 'bg-indigo-50 border-indigo-500 text-indigo-600', $link);
                        $link = easy_invoice_str_replace('prev', 'bg-white text-gray-500 hover:bg-gray-50', $link);
                        $link = easy_invoice_str_replace('next', 'bg-white text-gray-500 hover:bg-gray-50', $link);
                        $link = easy_invoice_str_replace('dots', 'bg-white text-gray-700', $link);
                        
                        // Add default styling for regular page numbers
                        if ($link && strpos($link, 'bg-indigo-50') === false && strpos($link, 'bg-white') === false) {
                            $link = easy_invoice_str_replace('border-gray-300', 'border-gray-300 bg-white text-gray-500 hover:bg-gray-50', $link);
                        }
                        
                        echo $link;
                    }
                    echo '</div>';
                }
                ?>
            </div>
            <?php endif; ?>
        </div>
    </div>
    <?php endif; ?>

    <div class="bg-white rounded-lg shadow mb-6 overflow-hidden">
        <div class="border-b border-gray-200 bg-gradient-to-r from-indigo-50 to-white">
            <nav class="flex">
                <?php 
                // View Tabs (All, Trash)
                $views = array(
                    'all' => 'All (' . $stats['total_payments'] . ')',
                    'trash' => 'Trash (' . $trash_count . ')'
                );
                
                foreach ($views as $view => $label) {
                    $is_current = $current_view === $view;
                    $status_param = !empty($status_filter) && $view === 'all' ? '&status=' . $status_filter : '';
                    $class = $is_current 
                        ? 'border-b-2 border-indigo-500 text-indigo-600 bg-white' 
                        : 'border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300';
                    ?>
                    <a href="?page=easy-invoice-payments&view=<?php echo $view . $status_param; ?>" 
                       class="flex items-center whitespace-nowrap py-4 px-6 font-medium text-sm transition-colors duration-200 <?php echo $class; ?>">
                        <?php echo $label; ?>
                    </a>
                <?php } ?>
            </nav>
        </div>
        </div>

    <div class="bg-white shadow overflow-hidden sm:rounded-lg">
        <div class="px-6 py-3 border-b border-gray-200 bg-gray-50">
            <div class="flex items-center justify-between">
                <div class="flex items-center space-x-4">
                    <form id="bulk-action-form" method="post" class="flex items-center gap-2">
                        <?php wp_nonce_field('easy_invoice_payment_bulk_action', 'easy_invoice_payment_bulk_nonce'); ?>
                        <input type="hidden" name="action" value="easy_invoice_payment_bulk_action">
                        
                        <select name="bulk_action" class="block w-full px-3 py-2 border border-gray-300 rounded-md leading-5 bg-white text-gray-700 placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
                            <option value="">Bulk Actions</option>
                            <?php if ($current_view === 'trash'): ?>
                                <option value="restore">Restore</option>
                                <option value="delete">Delete Permanently</option>
                            <?php else: ?>
                                <option value="trash">Move to Trash</option>
                                <option value="delete">Delete Permanently</option>
                            <?php endif; ?>
                        </select>

                        <button type="submit" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
                            Apply
                        </button>
                    </form>
                </div>
                <div class="text-sm text-gray-500">
                    <span id="selected-count">0</span> payments selected
                </div>
            </div>
        </div>

        <div class="ei-table-responsive">
        <table class="min-w-full divide-y divide-gray-200 ei-payments-table">
            <thead class="bg-gray-50">
                <tr>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                        <input type="checkbox" id="select-all-payments" class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
                    </th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="id">
                        <div class="flex items-center space-x-1">
                            <span>Payment ID</span>
                            <div class="sort-indicator">
                                <i class="fas fa-sort text-gray-400"></i>
                            </div>
                        </div>
                    </th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="invoice">
                        <div class="flex items-center space-x-1">
                            <span>Invoice</span>
                            <div class="sort-indicator">
                                <i class="fas fa-sort text-gray-400"></i>
                            </div>
                        </div>
                    </th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="amount">
                        <div class="flex items-center space-x-1">
                            <span>Amount</span>
                            <div class="sort-indicator">
                                <i class="fas fa-sort text-gray-400"></i>
                            </div>
                        </div>
                    </th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="method">
                        <div class="flex items-center space-x-1">
                            <span>Method</span>
                            <div class="sort-indicator">
                                <i class="fas fa-sort text-gray-400"></i>
                            </div>
                        </div>
                    </th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="status">
                        <div class="flex items-center space-x-1">
                            <span>Status</span>
                            <div class="sort-indicator">
                                <i class="fas fa-sort text-gray-400"></i>
                            </div>
                        </div>
                    </th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="date">
                        <div class="flex items-center space-x-1">
                            <span>Date</span>
                            <div class="sort-indicator">
                                <i class="fas fa-sort text-gray-400"></i>
                            </div>
                        </div>
                    </th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100 hidden sm:table-cell" data-sort="type">
                        <div class="flex items-center space-x-1">
                            <span>Type</span>
                            <div class="sort-indicator">
                                <i class="fas fa-sort text-gray-400"></i>
                            </div>
                        </div>
                    </th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                        Actions
                    </th>
                </tr>
            </thead>
            <tbody class="bg-white divide-y divide-gray-200">
                <?php if ($payments): ?>
                    <?php foreach ($payments as $payment): ?>
                        <?php 
                        // $payment is already a Payment object, no need to create new one
                        
                        // Get invoice information
                        $invoice_id = $payment->getInvoiceId();
                        
                        // Temporarily show all payments regardless of invoice
                        ?>
                        <tr>
                            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
                                <input type="checkbox" name="payment_ids[]" value="<?php echo $payment->getId(); ?>" form="bulk-action-form" class="payment-checkbox rounded border-gray-300 text-indigo-600 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
                            </td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
                                #<?php echo $payment->getId(); ?>
                            </td>
                            <td class="px-6 py-4 text-sm text-gray-500">
                                <?php if ($invoice_id): ?>
                                    <?php 
                                    $invoice_post = get_post($invoice_id);
                                    if ($invoice_post && $invoice_post->post_type === 'easy_invoice'): 
                                        $invoice = new \EasyInvoice\Models\Invoice($invoice_id);
                                    ?>
                                    <div>
                                        <a href="<?php echo get_permalink($invoice->getId()); ?>" class="text-indigo-600 hover:text-indigo-900 font-medium" target="_blank">
                                    <?php echo $invoice->getNumber(); ?>
                                </a>
                                        <div class="text-xs text-gray-400 mt-1">
                                            <?php echo esc_html($invoice->getTitle() ?: __('Untitled Invoice', 'easy-invoice')); ?>
                                        </div>
                                    </div>
                                    <?php else: ?>
                                    <span class="text-gray-400">
                                        <?php _e('Invoice not found', 'easy-invoice'); ?>
                                        <?php if (current_user_can('manage_options')): ?>
                                            <br><small class="text-xs text-gray-500">ID: <?php echo $invoice_id; ?> (Type: <?php echo $invoice_post ? $invoice_post->post_type : 'null'; ?>)</small>
                                        <?php endif; ?>
                                    </span>
                                    <?php endif; ?>
                                <?php else: ?>
                                    <span class="text-gray-400">
                                        <?php _e('No invoice ID', 'easy-invoice'); ?>
                                    </span>
                                <?php endif; ?>
                            </td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                                <?php echo $payment->getCurrencySymbol() . number_format($payment->getAmount(), 2); ?>
                            </td>
                            <td class="px-6 py-4 text-sm text-gray-500">
                                <?php 
                                // Get payment method label dynamically from registered gateways
                                $payment_method = $payment->getPaymentMethod();
                                $gateway_manager = \EasyInvoice\EasyInvoice::getInstance()->getGatewayManager();
                                $gateways = $gateway_manager->getGateways();
                                
                                // Try to get the gateway title from registered gateways
                                $method_label = ucfirst(easy_invoice_str_replace('_', ' ', $payment_method)); // Default fallback
                                
                                foreach ($gateways as $gateway) {
                                    if ($gateway->getName() === $payment_method) {
                                        $method_label = $gateway_manager->getGatewayDisplayName($gateway->getName());
                                        break;
                                    }
                                }
                                
                                // Special case for manual payments
                                if ($payment_method === 'manual') {
                                    $method_label = __('Manual', 'easy-invoice');
                                }
                                
                                echo esc_html($method_label);
                                ?>
                            </td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                                    <?php
                                $status = $payment->getStatus();
                                $status_class = '';
                                $status_text = '';
                                
                                switch ($status) {
                                        case 'completed':
                                        $status_class = 'bg-green-100 text-green-800';
                                        $status_text = __('Completed', 'easy-invoice');
                                            break;
                                        case 'pending':
                                        $status_class = 'bg-yellow-100 text-yellow-800';
                                        $status_text = __('Pending', 'easy-invoice');
                                            break;
                                        case 'failed':
                                        $status_class = 'bg-red-100 text-red-800';
                                        $status_text = __('Failed', 'easy-invoice');
                                            break;
                                        default:
                                        $status_class = 'bg-gray-100 text-gray-800';
                                        $status_text = ucfirst($status);
                                    }
                                ?>
                                <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium <?php echo $status_class; ?>">
                                    <?php echo $status_text; ?>
                                </span>
                            </td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                                <?php echo $payment->getPaymentDate() ? date('M j, Y', strtotime($payment->getPaymentDate())) : date('M j, Y', strtotime($payment->getPost()->post_date)); ?>
                            </td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 hidden sm:table-cell">
                                <?php echo ucfirst($payment->getPaymentType() ?: 'one-time'); ?>
                            </td>
                            <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
                                <div class="flex items-center space-x-2">
                                    <a href="?page=easy-invoice-payments&action=view&id=<?php echo $payment->getId(); ?>" class="text-indigo-600 hover:text-indigo-900">
                                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
                                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
                                        </svg>
                                    </a>
                                    <a href="?page=easy-invoice-payments&action=edit&id=<?php echo $payment->getId(); ?>" class="text-blue-600 hover:text-blue-900">
                                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
                                        </svg>
                                    </a>
                                    <?php if (in_array($status, ['pending', 'pending-bank', 'pending-cheque'])): ?>
                                    <button type="button" class="approve-payment-btn text-green-600 hover:text-green-900" 
                                            data-payment-id="<?php echo $payment->getId(); ?>"
                                            data-invoice-id="<?php echo $payment->getInvoiceId(); ?>"
                                            data-nonce="<?php echo wp_create_nonce('easy_invoice_approve_payment'); ?>">
                                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
                                        </svg>
                                    </button>
                                    <?php endif; ?>
                                    
                                    <?php 
                                    // Hook for additional payment actions (used by Pro plugin for receipts)
                                    do_action('easy_invoice_payment_row_actions', $payment, $status);
                                    ?>
                                </div>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                <?php else : ?>
                    <tr>
                        <td colspan="9" class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 text-center">
                            <?php _e('No payments found.', 'easy-invoice'); ?>
                        </td>
                    </tr>
                <?php endif; ?>
            </tbody>
        </table>
        </div>
    </div>

    <?php if ($total_payments > 0): ?>
    <div class="mt-4">
        <div class="px-4 py-3 flex items-center justify-between">
            <div class="flex items-center space-x-2">
                <span class="text-sm text-gray-700">
                    Showing 
                    <span class="font-medium"><?php echo number_format((($current_page - 1) * $per_page) + 1); ?></span>
                    to 
                    <span class="font-medium"><?php echo number_format(min($current_page * $per_page, $total_payments)); ?></span>
                    of 
                    <span class="font-medium"><?php echo number_format($total_payments); ?></span>
                    results
                </span>
            </div>
            <?php if ($total_pages > 1): ?>
            <div class="flex items-center space-x-2">
                <span class="text-sm text-gray-500">Page <?php echo number_format($current_page); ?> of <?php echo number_format($total_pages); ?></span>
                <?php
                // Use WordPress's built-in pagination for bottom
                $bottom_pagination_args = array(
                    'base' => add_query_arg('paged', '%#%'),
                    'format' => '',
                    'current' => $current_page,
                    'total' => $total_pages,
                    'prev_text' => '‹ Previous',
                    'next_text' => 'Next ›',
                    'type' => 'array',
                    'end_size' => 1,
                    'mid_size' => 2,
                    'add_args' => array(
                        'page' => 'easy-invoice-payments',
                        'view' => $current_view,
                        'status' => $status_filter
                    )
                );
                
                $bottom_pagination_links = paginate_links($bottom_pagination_args);
                
                if ($bottom_pagination_links) {
                    echo '<div class="flex space-x-1">';
                    foreach ($bottom_pagination_links as $link) {
                        // Add null check to prevent passing null to easy_invoice_str_replace
                        if ($link === null) {
                            continue;
                        }
                        
                        // Convert WordPress pagination to our styling
                        $link = easy_invoice_str_replace('page-numbers', 'px-3 py-2 text-sm font-medium border border-gray-300 rounded-md', $link);
                        $link = easy_invoice_str_replace('current', 'bg-indigo-50 border-indigo-500 text-indigo-600', $link);
                        $link = easy_invoice_str_replace('prev', 'bg-white text-gray-500 hover:bg-gray-50', $link);
                        $link = easy_invoice_str_replace('next', 'bg-white text-gray-500 hover:bg-gray-50', $link);
                        $link = easy_invoice_str_replace('dots', 'bg-white text-gray-700', $link);
                        
                        // Add default styling for regular page numbers
                        if ($link && strpos($link, 'bg-indigo-50') === false && strpos($link, 'bg-white') === false) {
                            $link = easy_invoice_str_replace('border-gray-300', 'border-gray-300 bg-white text-gray-500 hover:bg-gray-50', $link);
                        }
                        
                        echo $link;
                    }
                    echo '</div>';
                }
                ?>
            </div>
            <?php endif; ?>
        </div>
    </div>
    <?php endif; ?>
</div>

<div id="payment-approval-modal" class="fixed inset-0 z-50 overflow-y-auto hidden" aria-labelledby="modal-title" role="dialog" aria-modal="true">
    <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
        <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
        
        <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
            <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
                <div class="sm:flex sm:items-start">
                    <div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-green-100 sm:mx-0 sm:h-10 sm:w-10">
                        <svg class="h-6 w-6 text-green-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
                        </svg>
                    </div>
                    <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
                        <h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
                            <?php _e('Approve Payment', 'easy-invoice'); ?>
                        </h3>
                        <div class="mt-2">
                            <p class="text-sm text-gray-500">
                                <?php _e('You are about to approve this payment. This will mark the invoice as paid and update the payment records.', 'easy-invoice'); ?>
                            </p>
                            <div class="mt-4">
                                <label for="approval-notes" class="block text-sm font-medium text-gray-700">
                                    <?php _e('Notes (optional)', 'easy-invoice'); ?>
                                </label>
                                <textarea id="approval-notes" name="notes" rows="3" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" placeholder="<?php _e('Add any notes about this payment approval...', 'easy-invoice'); ?>"></textarea>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
                <button type="button" id="confirm-approve-btn" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 text-base font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:ml-3 sm:w-auto sm:text-sm">
                    <?php _e('Approve Payment', 'easy-invoice'); ?>
                </button>
                <button type="button" id="cancel-approve-btn" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
                    <?php _e('Cancel', 'easy-invoice'); ?>
                </button>
            </div>
        </div>
    </div>
</div>

<div id="payment-approve-notification" class="fixed top-0 right-0 m-4 hidden">
</div>

<style>
/* Add any additional custom styles here */
.ei-table-responsive{
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.ei-payments-table{
    width: 100%;
    min-width: 900px;
}
@media (max-width: 640px) {
    .ei-payments-table th,
    .ei-payments-table td{
        padding-left: 0.75rem !important;
        padding-right: 0.75rem !important;
    }
}
.payment-status {
    display: inline-block;
    padding: 3px 8px;
    border-radius: 3px;
    font-size: 12px;
    font-weight: 600;
}
.status-completed {
    background-color: #dff0d8;
    color: #3c763d;
}
.status-pending {
    background-color: #fcf8e3;
    color: #8a6d3b;
}
.status-failed {
    background-color: #f2dede;
    color: #a94442;
}
</style>

<script>
// Define ajaxurl for AJAX requests
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';

jQuery(document).ready(function($) {
    // Variables to store the current payment being approved
    let currentInvoiceId = null;
    let currentPaymentId = null;
    let currentNonce = null;
    
    // Handle Approve button click
    $('.approve-payment-btn').on('click', function(e) {
        e.preventDefault();
        
        // Store the data for the current payment
        currentInvoiceId = $(this).data('invoice-id');
        currentPaymentId = $(this).data('payment-id');
        currentNonce = $(this).data('nonce');
        
        // Show the approval modal
        $('#payment-approval-modal').removeClass('hidden');
    });
    
    // Handle Cancel button in modal
    $('#cancel-approve-btn').on('click', function() {
        // Hide the modal and reset the form
        $('#payment-approval-modal').addClass('hidden');
        $('#approval-notes').val('');
    });
    
    // Handle Confirm Approve button in modal
    $('#confirm-approve-btn').on('click', function() {
        // Get the notes from the textarea
        const notes = $('#approval-notes').val();
        
        // Disable the button to prevent double clicks
        $(this).prop('disabled', true).text('Processing...');
        
        // Make AJAX request to approve the payment
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'easy_invoice_approve_payment',
                invoice_id: currentInvoiceId,
                nonce: currentNonce,
                notes: notes
            },
            success: function(response) {
                // Hide the modal
                $('#payment-approval-modal').addClass('hidden');
                
                if (response.success) {
                    // Show success toast
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.success('Payment approved successfully.');
                    }
                    
                    // Refresh the page after a short delay
                    setTimeout(function() {
                        location.reload();
                    }, 1500);
                } else {
                    // Show error toast
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.error('Failed to approve payment.');
                    }
                    
                    // Re-enable the button
                    $('#confirm-approve-btn').prop('disabled', false).text('Approve Payment');
                }
            },
            error: function() {
                // Hide the modal
                $('#payment-approval-modal').addClass('hidden');
                
                // Show error toast
                if (typeof EasyInvoiceToast !== 'undefined') {
                    EasyInvoiceToast.error('Server error occurred. Please try again.');
                }
                
                // Re-enable the button
                $('#confirm-approve-btn').prop('disabled', false).text('Approve Payment');
            }
        });
    });
    

    
    // Close the modal if clicking outside of it
    $(window).on('click', function(e) {
        if ($(e.target).is('#payment-approval-modal')) {
            $('#payment-approval-modal').addClass('hidden');
            $('#approval-notes').val('');
        }
    });
    
    // Close the modal with Escape key
    $(document).on('keydown', function(e) {
        if (e.key === "Escape" && !$('#payment-approval-modal').hasClass('hidden')) {
            $('#payment-approval-modal').addClass('hidden');
            $('#approval-notes').val('');
        }
    });
    
    // Dismiss notification buttons
    $('.notification-dismiss').on('click', function() {
        $(this).closest('.rounded-md').remove();
    });
    
    // Payment Table Sorting and Filtering Functionality
    let currentSort = { column: '', direction: '' };
    
    // Initialize sorting and filtering
    function initSortingAndFiltering() {
        // Add click handlers to sortable headers
        $('th[data-sort]').on('click', function() {
            const column = $(this).data('sort');
            const currentDirection = currentSort.column === column ? currentSort.direction : 'desc';
            const newDirection = currentDirection === 'asc' ? 'desc' : 'asc';
            
            currentSort = { column: column, direction: newDirection };
            updateSortIndicator(column, newDirection);
            sortTable(column, newDirection);
        });
    }
    
    // Update sort indicator
    function updateSortIndicator(activeColumn, direction) {
        // Reset all indicators
        $('.sort-indicator i').removeClass('fa-sort-up fa-sort-down').addClass('fa-sort text-gray-400');
        
        // Set active indicator
        $(`th[data-sort="${activeColumn}"] .sort-indicator i`)
            .removeClass('fa-sort text-gray-400')
            .addClass(direction === 'asc' ? 'fa-sort-up text-indigo-600' : 'fa-sort-down text-indigo-600');
    }
    
    // Sort table function
    function sortTable(column, direction) {
        const tbody = $('tbody');
        const rows = tbody.find('tr').toArray();
        
        rows.sort(function(a, b) {
            let aValue, bValue;
            
            switch(column) {
                case 'id':
                    aValue = parseInt($(a).find('td:first-child').text().replace('#', ''));
                    bValue = parseInt($(b).find('td:first-child').text().replace('#', ''));
                    break;
                case 'invoice':
                    aValue = $(a).find('td:nth-child(2) a').text().toLowerCase();
                    bValue = $(b).find('td:nth-child(2) a').text().toLowerCase();
                    break;
                case 'amount':
                    aValue = parseFloat($(a).find('td:nth-child(3)').text().replace(/[^0-9.-]+/g, ''));
                    bValue = parseFloat($(b).find('td:nth-child(3)').text().replace(/[^0-9.-]+/g, ''));
                    break;
                case 'method':
                    aValue = $(a).find('td:nth-child(4)').text().toLowerCase();
                    bValue = $(b).find('td:nth-child(4)').text().toLowerCase();
                    break;
                case 'status':
                    aValue = $(a).find('td:nth-child(5) span').text().toLowerCase();
                    bValue = $(b).find('td:nth-child(5) span').text().toLowerCase();
                    break;
                case 'date':
                    aValue = new Date($(a).find('td:nth-child(6)').text());
                    bValue = new Date($(b).find('td:nth-child(6)').text());
                    break;
                case 'type':
                    aValue = $(a).find('td:nth-child(7)').text().toLowerCase();
                    bValue = $(b).find('td:nth-child(7)').text().toLowerCase();
                    break;
                default:
                    return 0;
            }
            
            if (direction === 'asc') {
                return aValue > bValue ? 1 : -1;
            } else {
                return aValue < bValue ? 1 : -1;
            }
        });
        
        // Reorder rows with animation
        tbody.find('tr').fadeOut(200, function() {
            tbody.empty();
            $.each(rows, function(index, row) {
                tbody.append(row);
            });
            tbody.find('tr').fadeIn(200);
        });
    }
    
    // Initialize sorting and filtering
    initSortingAndFiltering();
    
    // Payment Delete Functionality
    let selectedPayments = [];
    
    // Handle select all checkbox
    $('#select-all-payments').on('change', function() {
        const isChecked = $(this).is(':checked');
        $('.payment-checkbox').prop('checked', isChecked);
        
        if (isChecked) {
            selectedPayments = $('.payment-checkbox').map(function() {
                return $(this).val();
            }).get();
        } else {
            selectedPayments = [];
        }
        
        updateBulkActionButton();
    });
    
    // Handle individual checkboxes
    $(document).on('change', '.payment-checkbox', function() {
        const paymentId = $(this).val();
        const isChecked = $(this).is(':checked');
        
        if (isChecked) {
            if (!selectedPayments.includes(paymentId)) {
                selectedPayments.push(paymentId);
            }
        } else {
            selectedPayments = selectedPayments.filter(id => id !== paymentId);
        }
        
        // Update select all checkbox
        const totalCheckboxes = $('.payment-checkbox').length;
        const checkedCheckboxes = $('.payment-checkbox:checked').length;
        
        if (checkedCheckboxes === 0) {
            $('#select-all-payments').prop('checked', false).prop('indeterminate', false);
        } else if (checkedCheckboxes === totalCheckboxes) {
            $('#select-all-payments').prop('checked', true).prop('indeterminate', false);
        } else {
            $('#select-all-payments').prop('checked', false).prop('indeterminate', true);
        }
        
        updateBulkActionButton();
    });
    
    // Update bulk action button state
    function updateBulkActionButton() {
        const button = $('#bulk-action-form button[type="submit"]');
        const countSpan = $('#selected-count');
        
        if (selectedPayments.length > 0) {
            button.prop('disabled', false);
            countSpan.text(selectedPayments.length);
        } else {
            button.prop('disabled', true);
            countSpan.text('0');
        }
    }
    
    // Form submission validation for bulk actions
    $("#bulk-action-form").on("submit", function(e) {
        e.preventDefault();
        
        var bulkAction = $("select[name='bulk_action']").val();
        if (!bulkAction) {
            EasyInvoiceToast.error('Please select a bulk action.');
            return;
        }
        
        if (selectedPayments.length === 0) {
            EasyInvoiceToast.error('Please select at least one payment.');
            return;
        }
        
        // Confirm bulk actions
        if (bulkAction === 'trash') {
            EasyInvoiceConfirmation.confirmAction('trash', selectedPayments.length + ' payment(s)', function() {
                $("#bulk-action-form")[0].submit();
            });
            return;
        } else if (bulkAction === 'delete') {
            EasyInvoiceConfirmation.confirmAction('delete', selectedPayments.length + ' payment(s)', function() {
                $("#bulk-action-form")[0].submit();
            });
            return;
        } else if (bulkAction === 'restore') {
            EasyInvoiceConfirmation.confirmAction('restore', selectedPayments.length + ' payment(s)', function() {
                $("#bulk-action-form")[0].submit();
            });
            return;
        } else {
            $("#bulk-action-form")[0].submit();
        }
    });
});
</script>
```
