PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.3
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.3
2.4.3 2.4.4 2.4.2 2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 All 60 releases
← All changes | templates/payments/list.php +163 -144 2.1.19 → 2.4.3 View file →
@@ -37,63 +37,26 @@
37 37 'pending_payments' => 0,
38 38 'failed_payments' => 0
39 39 ], $stats);
40 40
41 -// Initialize amounts_by_currency array
42 -$amounts_by_currency = [];
43 -// Calculate stats from the payments array
44 -foreach ($payments as $payment) {
45 - $amount = floatval($payment->getAmount());
46 - $status = $payment->getStatus();
47 -
48 - $stats['total_amount'] += $amount;
49 -
50 - switch ($status) {
51 - case 'completed':
52 - $stats['completed_payments']++;
53 - break;
54 - case 'pending':
55 - $stats['pending_payments']++;
56 - break;
57 - case 'failed':
58 - $stats['failed_payments']++;
59 - break;
60 - }
61 -
62 - // Calculate currency breakdown
63 - $payment_currency = $payment->getCurrency();
64 -
65 - // If currency is empty or "global", get the actual currency that was used
66 - if (empty($payment_currency) || $payment_currency === 'global') {
67 - $actual_currency = get_post_meta($payment->getId(), '_currency', true);
68 - $payment_currency = !empty($actual_currency) ? $actual_currency : get_option('easy_invoice_currency_code', 'USD');
69 - }
70 -
71 - // If currency is still "global", use the global setting
72 - if ($payment_currency === 'global') {
73 - $payment_currency = get_option('easy_invoice_currency_code', 'USD');
41 +// Site-wide figures come from the controller (one query each); the page's own
42 +// twenty rows used to be added on top of them, which inflated "Completed" and
43 +// "Awaiting confirmation" and made "Total amount" the page's sum.
44 +$amounts_by_currency = $amounts_by_currency ?? [];
45 +if (empty($amounts_by_currency) && !empty($stats['total_amount'])) {
46 + $ei_code = strtoupper((string) get_option('easy_invoice_currency_code', 'USD'));
47 + $amounts_by_currency[$ei_code] = [
48 + 'amount' => (float) $stats['total_amount'],
49 + 'symbol' => \EasyInvoice\Helpers\CurrencyHelper::getCurrencySymbol($ei_code),
50 + ];
74 51 }
75 52
76 - $payment_currency_symbol = $payment->getCurrencySymbol() ?: \EasyInvoice\Helpers\CurrencyHelper::getCurrencySymbol($payment_currency);
77 -
78 - // Normalize currency code to uppercase for consistent grouping
79 - $payment_currency = strtoupper($payment_currency);
80 -
81 - // Group amounts by currency
82 - if (!isset($amounts_by_currency[$payment_currency])) {
83 - $amounts_by_currency[$payment_currency] = [
84 - 'amount' => 0,
85 - 'symbol' => $payment_currency_symbol
86 - ];
87 -}
88 - $amounts_by_currency[$payment_currency]['amount'] += $amount;
89 -}
90 -
91 53 // Check for bulk action notifications
92 54 $notification = false;
93 55
94 56 if (isset($_GET['bulk_trashed']) && $_GET['bulk_trashed'] > 0) {
95 57 $count = intval($_GET['bulk_trashed']);
58 + /* translators: %s: number of items. */
96 59 easy_invoice_display_notification('success', sprintf(_n('%s payment moved to trash.', '%s payments moved to trash.', $count, 'easy-invoice'), $count));
97 60 $notification = true;
98 61 }
99 62
@@ -98,8 +61,9 @@
98 61 }
99 62
100 63 if (isset($_GET['bulk_restored']) && $_GET['bulk_restored'] > 0) {
101 64 $count = intval($_GET['bulk_restored']);
65 + /* translators: %s: number of items. */
102 66 easy_invoice_display_notification('success', sprintf(_n('%s payment restored from trash.', '%s payments restored from trash.', $count, 'easy-invoice'), $count));
103 67 $notification = true;
104 68 }
105 69
@@ -104,8 +68,9 @@
104 68 }
105 69
106 70 if (isset($_GET['bulk_deleted']) && $_GET['bulk_deleted'] > 0) {
107 71 $count = intval($_GET['bulk_deleted']);
72 + /* translators: %s: number of items. */
108 73 easy_invoice_display_notification('success', sprintf(_n('%s payment permanently deleted.', '%s payments permanently deleted.', $count, 'easy-invoice'), $count));
109 74 $notification = true;
110 75 }
111 76
@@ -124,22 +89,38 @@
124 89 }
125 90
126 91 ?>
127 92 <div class="p-8">
128 - <!-- Header with Actions -->
129 93 <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;">
130 94 <div class="flex items-center justify-between">
131 95 <div>
132 - <h1 class="text-2xl font-bold text-gray-900"><?php _e('Payments', 'easy-invoice'); ?></h1>
133 - <p class="mt-1 text-sm text-gray-500"><?php _e('Manage all payment records', 'easy-invoice'); ?></p>
96 + <h1 class="text-2xl font-bold text-gray-900"><?php esc_html_e('Payments', 'easy-invoice'); ?></h1>
97 + <p class="mt-1 text-sm text-gray-500"><?php esc_html_e('Manage all payment records', 'easy-invoice'); ?></p>
134 98 </div>
135 99 <div class="flex items-center space-x-3">
136 - <?php if (!easy_invoice_has_pro()): ?>
100 + <?php
101 + // "Export All" is part of the bulk_operations addon
102 + // (Personal tier). See templates/invoices/listing.php
103 + // for the canonical three-state gate pattern.
104 + $ei_bulk_ops_loaded = \EasyInvoice\Addons\AddonManager::shouldLoad('bulk_operations');
105 + ?>
106 + <?php if ($ei_bulk_ops_loaded): ?>
107 + <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display:inline;">
108 + <input type="hidden" name="action" value="easy_invoice_export_all_payments" />
109 + <input type="hidden" name="_wpnonce" value="<?php echo esc_attr(wp_create_nonce('easy_invoice_export_all_payments')); ?>" />
110 + <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">
111 + <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">
112 + <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>
113 + </svg>
114 + <?php esc_html_e('Export All', 'easy-invoice'); ?>
115 + </button>
116 + </form>
117 + <?php elseif (!easy_invoice_has_pro()): ?>
137 118 <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">
138 119 <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">
139 120 <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>
140 121 </svg>
141 - <?php _e('Export All', 'easy-invoice'); ?>
122 + <?php esc_html_e('Export All', 'easy-invoice'); ?>
142 123 <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">
143 124 <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"/>
144 125 </svg>
145 126 </button>
@@ -146,42 +127,30 @@
146 127 <script>
147 128 jQuery(document).ready(function($) {
148 129 $('#export-all-payments-btn').on('click', function(e) {
149 130 e.preventDefault();
150 - // Show premium popup using the proper confirmation modal
151 131 if (typeof EasyInvoiceConfirmation !== 'undefined') {
152 132 EasyInvoiceConfirmation.showFeatureUpgrade('Export All Payments', 'Export all your payments to CSV, Excel, or PDF format for backup, analysis, or sharing with your team.');
153 133 } else {
154 - // Fallback to toast if confirmation modal is not available
155 134 EasyInvoiceToast.error('<?php echo esc_js(__('Exporting all payments is a premium feature. Upgrade to Easy Invoice Pro to unlock this feature.', 'easy-invoice')); ?>');
156 135 }
157 136 });
158 137 });
159 138 </script>
160 - <?php else: ?>
161 - <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display:inline;">
162 - <input type="hidden" name="action" value="easy_invoice_export_all_payments" />
163 - <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce('easy_invoice_export_all_payments'); ?>" />
164 - <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">
165 - <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">
166 - <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>
167 - </svg>
168 - <?php _e('Export All', 'easy-invoice'); ?>
169 - </button>
170 - </form>
171 139 <?php endif; ?>
172 140
173 - <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">
141 + <?php if (easy_invoice_user_can('ei_record_payment')) : ?>
142 +<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">
174 143 <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
175 144 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
176 145 </svg>
177 - <?php _e('Add New Payment', 'easy-invoice'); ?>
146 + <?php esc_html_e('Add New Payment', 'easy-invoice'); ?>
178 147 </a>
148 +<?php endif; ?>
179 149 </div>
180 150 </div>
181 151 </div>
182 152
183 - <!-- Stats Cards -->
184 153 <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8 mt-8">
185 154 <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
186 155 <div class="flex items-center">
187 156 <div class="rounded-full bg-indigo-100 p-3 mr-4">
@@ -189,10 +158,10 @@
189 158 <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>
190 159 </svg>
191 160 </div>
192 161 <div>
193 - <h3 class="text-sm font-medium text-gray-500">Total Payments</h3>
194 - <p class="mt-1 text-2xl font-bold text-gray-900"><?php echo $stats['total_payments']; ?></p>
162 + <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e('Total Payments', 'easy-invoice'); ?></h3>
163 + <p class="mt-1 text-2xl font-bold text-gray-900"><?php echo esc_html($stats['total_payments']); ?></p>
195 164 </div>
196 165 </div>
197 166 </div>
198 167 <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
@@ -202,20 +171,20 @@
202 171 <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>
203 172 </svg>
204 173 </div>
205 174 <div>
206 - <h3 class="text-sm font-medium text-gray-500">Total Amount</h3>
175 + <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e('Total Amount', 'easy-invoice'); ?></h3>
207 176 <?php if (!empty($amounts_by_currency)): ?>
208 177 <div class="mt-1">
209 178 <?php foreach ($amounts_by_currency as $currency => $data): ?>
210 179 <p class="text-lg font-bold text-gray-900">
211 - <?php echo $data['symbol'] . number_format($data['amount'], 2); ?>
212 - <span class="text-sm font-normal text-gray-500"><?php echo strtoupper($currency ?? 'USD'); ?></span>
180 + <?php echo esc_html($data['symbol'] . number_format($data['amount'], 2)); ?>
181 + <span class="text-sm font-normal text-gray-500"><?php echo esc_html(strtoupper($currency ?? 'USD')); ?></span>
213 182 </p>
214 183 <?php endforeach; ?>
215 184 </div>
216 185 <?php else: ?>
217 - <p class="mt-1 text-lg font-bold text-gray-900"><?php echo get_option('easy_invoice_currency_symbol', '$') . '0.00'; ?></p>
186 + <p class="mt-1 text-lg font-bold text-gray-900"><?php echo esc_html(get_option('easy_invoice_currency_symbol', '$') . '0.00'); ?></p>
218 187 <?php endif; ?>
219 188 </div>
220 189 </div>
221 190 </div>
@@ -226,10 +195,10 @@
226 195 <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>
227 196 </svg>
228 197 </div>
229 198 <div>
230 - <h3 class="text-sm font-medium text-gray-500">Completed Payments</h3>
231 - <p class="mt-1 text-2xl font-bold text-green-600"><?php echo $stats['completed_payments']; ?></p>
199 + <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e('Completed Payments', 'easy-invoice'); ?></h3>
200 + <p class="mt-1 text-2xl font-bold text-green-600"><?php echo esc_html($stats['completed_payments']); ?></p>
232 201 </div>
233 202 </div>
234 203 </div>
235 204 <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
@@ -239,16 +208,15 @@
239 208 <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>
240 209 </svg>
241 210 </div>
242 211 <div>
243 - <h3 class="text-sm font-medium text-gray-500">Pending Payments</h3>
244 - <p class="mt-1 text-2xl font-bold text-yellow-600"><?php echo $stats['pending_payments']; ?></p>
212 + <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e('Pending Payments', 'easy-invoice'); ?></h3>
213 + <p class="mt-1 text-2xl font-bold text-yellow-600"><?php echo esc_html($stats['pending_payments']); ?></p>
245 214 </div>
246 215 </div>
247 216 </div>
248 217 </div>
249 218
250 - <!-- Top Pagination -->
251 219 <?php if ($total_payments > 0): ?>
252 220 <div class="mb-4">
253 221 <div class="px-4 py-3 flex items-center justify-between">
254 222 <div class="flex items-center space-x-2">
@@ -305,9 +273,9 @@
305 273 if ($link && strpos($link, 'bg-indigo-50') === false && strpos($link, 'bg-white') === false) {
306 274 $link = easy_invoice_str_replace('border-gray-300', 'border-gray-300 bg-white text-gray-500 hover:bg-gray-50', $link);
307 275 }
308 276
309 - echo $link;
277 + echo wp_kses_post($link);
310 278 }
311 279 echo '</div>';
312 280 }
313 281 ?>
@@ -316,11 +284,9 @@
316 284 </div>
317 285 </div>
318 286 <?php endif; ?>
319 287
320 - <!-- Tabs with more modern styling -->
321 288 <div class="bg-white rounded-lg shadow mb-6 overflow-hidden">
322 - <!-- Tabs with more modern styling -->
323 289 <div class="border-b border-gray-200 bg-gradient-to-r from-indigo-50 to-white">
324 290 <nav class="flex">
325 291 <?php
326 292 // View Tabs (All, Trash)
@@ -335,11 +301,11 @@
335 301 $class = $is_current
336 302 ? 'border-b-2 border-indigo-500 text-indigo-600 bg-white'
337 303 : 'border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300';
338 304 ?>
339 - <a href="?page=easy-invoice-payments&view=<?php echo $view . $status_param; ?>"
340 - class="flex items-center whitespace-nowrap py-4 px-6 font-medium text-sm transition-colors duration-200 <?php echo $class; ?>">
341 - <?php echo $label; ?>
305 + <a href="?page=easy-invoice-payments&view=<?php echo esc_attr($view . $status_param); ?>"
306 + class="flex items-center whitespace-nowrap py-4 px-6 font-medium text-sm transition-colors duration-200 <?php echo esc_attr($class); ?>">
307 + <?php echo esc_html($label); ?>
342 308 </a>
343 309 <?php } ?>
344 310 </nav>
345 311 </div>
@@ -344,11 +310,9 @@
344 310 </nav>
345 311 </div>
346 312 </div>
347 313
348 - <!-- Payments Table -->
349 314 <div class="bg-white shadow overflow-hidden sm:rounded-lg">
350 - <!-- Bulk Actions -->
351 315 <div class="px-6 py-3 border-b border-gray-200 bg-gray-50">
352 316 <div class="flex items-center justify-between">
353 317 <div class="flex items-center space-x-4">
354 318 <form id="bulk-action-form" method="post" class="flex items-center gap-2">
@@ -354,16 +318,16 @@
354 318 <form id="bulk-action-form" method="post" class="flex items-center gap-2">
355 319 <?php wp_nonce_field('easy_invoice_payment_bulk_action', 'easy_invoice_payment_bulk_nonce'); ?>
356 320 <input type="hidden" name="action" value="easy_invoice_payment_bulk_action">
357 321
358 - <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">
359 - <option value="">Bulk Actions</option>
322 + <select name="bulk_action" aria-label="Bulk action for selected payments" 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">
323 + <option value=""><?php esc_html_e('Bulk Actions', 'easy-invoice'); ?></option>
360 324 <?php if ($current_view === 'trash'): ?>
361 - <option value="restore">Restore</option>
362 - <option value="delete">Delete Permanently</option>
325 + <option value="restore"><?php esc_html_e('Restore', 'easy-invoice'); ?></option>
326 + <option value="delete"><?php esc_html_e('Delete Permanently', 'easy-invoice'); ?></option>
363 327 <?php else: ?>
364 - <option value="trash">Move to Trash</option>
365 - <option value="delete">Delete Permanently</option>
328 + <option value="trash"><?php esc_html_e('Move to Trash', 'easy-invoice'); ?></option>
329 + <option value="delete"><?php esc_html_e('Delete Permanently', 'easy-invoice'); ?></option>
366 330 <?php endif; ?>
367 331 </select>
368 332
369 333 <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">
@@ -381,13 +345,13 @@
381 345 <table class="min-w-full divide-y divide-gray-200 ei-payments-table">
382 346 <thead class="bg-gray-50">
383 347 <tr>
384 348 <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
385 - <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">
349 + <input type="checkbox" id="select-all-payments" aria-label="Select all payments on this page" class="rounded border-gray-300 text-indigo-600 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
386 350 </th>
387 351 <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">
388 352 <div class="flex items-center space-x-1">
389 - <span>Payment ID</span>
353 + <span><?php esc_html_e('Payment ID', 'easy-invoice'); ?></span>
390 354 <div class="sort-indicator">
391 355 <i class="fas fa-sort text-gray-400"></i>
392 356 </div>
393 357 </div>
@@ -393,9 +357,9 @@
393 357 </div>
394 358 </th>
395 359 <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">
396 360 <div class="flex items-center space-x-1">
397 - <span>Invoice</span>
361 + <span><?php esc_html_e('Invoice', 'easy-invoice'); ?></span>
398 362 <div class="sort-indicator">
399 363 <i class="fas fa-sort text-gray-400"></i>
400 364 </div>
401 365 </div>
@@ -401,9 +365,9 @@
401 365 </div>
402 366 </th>
403 367 <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">
404 368 <div class="flex items-center space-x-1">
405 - <span>Amount</span>
369 + <span><?php esc_html_e('Amount', 'easy-invoice'); ?></span>
406 370 <div class="sort-indicator">
407 371 <i class="fas fa-sort text-gray-400"></i>
408 372 </div>
409 373 </div>
@@ -409,9 +373,9 @@
409 373 </div>
410 374 </th>
411 375 <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">
412 376 <div class="flex items-center space-x-1">
413 - <span>Method</span>
377 + <span><?php esc_html_e('Method', 'easy-invoice'); ?></span>
414 378 <div class="sort-indicator">
415 379 <i class="fas fa-sort text-gray-400"></i>
416 380 </div>
417 381 </div>
@@ -417,9 +381,9 @@
417 381 </div>
418 382 </th>
419 383 <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">
420 384 <div class="flex items-center space-x-1">
421 - <span>Status</span>
385 + <span><?php esc_html_e('Status', 'easy-invoice'); ?></span>
422 386 <div class="sort-indicator">
423 387 <i class="fas fa-sort text-gray-400"></i>
424 388 </div>
425 389 </div>
@@ -425,9 +389,9 @@
425 389 </div>
426 390 </th>
427 391 <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">
428 392 <div class="flex items-center space-x-1">
429 - <span>Date</span>
393 + <span><?php esc_html_e('Date', 'easy-invoice'); ?></span>
430 394 <div class="sort-indicator">
431 395 <i class="fas fa-sort text-gray-400"></i>
432 396 </div>
433 397 </div>
@@ -433,9 +397,9 @@
433 397 </div>
434 398 </th>
435 399 <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">
436 400 <div class="flex items-center space-x-1">
437 - <span>Type</span>
401 + <span><?php esc_html_e('Type', 'easy-invoice'); ?></span>
438 402 <div class="sort-indicator">
439 403 <i class="fas fa-sort text-gray-400"></i>
440 404 </div>
441 405 </div>
@@ -457,12 +421,12 @@
457 421 // Temporarily show all payments regardless of invoice
458 422 ?>
459 423 <tr>
460 424 <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
461 - <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">
425 + <input type="checkbox" name="payment_ids[]" value="<?php echo (int) $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">
462 426 </td>
463 427 <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
464 - #<?php echo $payment->getId(); ?>
428 + #<?php echo (int) $payment->getId(); ?>
465 429 </td>
466 430 <td class="px-6 py-4 text-sm text-gray-500">
467 431 <?php if ($invoice_id): ?>
468 432 <?php
@@ -470,10 +434,10 @@
470 434 if ($invoice_post && $invoice_post->post_type === 'easy_invoice'):
471 435 $invoice = new \EasyInvoice\Models\Invoice($invoice_id);
472 436 ?>
473 437 <div>
474 - <a href="<?php echo get_permalink($invoice->getId()); ?>" class="text-indigo-600 hover:text-indigo-900 font-medium" target="_blank">
475 - <?php echo $invoice->getNumber(); ?>
438 + <a href="<?php echo esc_url(get_permalink($invoice->getId())); ?>" class="text-indigo-600 hover:text-indigo-900 font-medium" target="_blank">
439 + <?php echo esc_html($invoice->getNumber()); ?>
476 440 </a>
477 441 <div class="text-xs text-gray-400 mt-1">
478 442 <?php echo esc_html($invoice->getTitle() ?: __('Untitled Invoice', 'easy-invoice')); ?>
479 443 </div>
@@ -479,22 +443,22 @@
479 443 </div>
480 444 </div>
481 445 <?php else: ?>
482 446 <span class="text-gray-400">
483 - <?php _e('Invoice not found', 'easy-invoice'); ?>
447 + <?php esc_html_e('Invoice not found', 'easy-invoice'); ?>
484 448 <?php if (current_user_can('manage_options')): ?>
485 - <br><small class="text-xs text-gray-500">ID: <?php echo $invoice_id; ?> (Type: <?php echo $invoice_post ? $invoice_post->post_type : 'null'; ?>)</small>
449 + <br><small class="text-xs text-gray-500">ID: <?php echo (int) $invoice_id; ?> (Type: <?php echo esc_html($invoice_post ? $invoice_post->post_type : 'null'); ?>)</small>
486 450 <?php endif; ?>
487 451 </span>
488 452 <?php endif; ?>
489 453 <?php else: ?>
490 454 <span class="text-gray-400">
491 - <?php _e('No invoice ID', 'easy-invoice'); ?>
455 + <?php esc_html_e('No invoice ID', 'easy-invoice'); ?>
492 456 </span>
493 457 <?php endif; ?>
494 458 </td>
495 459 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
496 - <?php echo $payment->getCurrencySymbol() . number_format($payment->getAmount(), 2); ?>
460 + <?php echo esc_html($payment->getCurrencySymbol() . number_format((float) $payment->getAmount(), 2)); ?>
497 461 </td>
498 462 <td class="px-6 py-4 text-sm text-gray-500">
499 463 <?php
500 464 // Get payment method label dynamically from registered gateways
@@ -517,8 +481,16 @@
517 481 $method_label = __('Manual', 'easy-invoice');
518 482 }
519 483
520 484 echo esc_html($method_label);
485 + $ei_reference = (string) get_post_meta((int) $payment->getId(), \EasyInvoice\Services\OfflinePayments::META_REFERENCE, true);
486 + if ('' !== $ei_reference) :
487 + /* translators: %s: reference the client gave. */
488 + echo '<span class="block text-xs text-gray-400" title="' . esc_attr__('Reference given by the client', 'easy-invoice') . '">' . esc_html(sprintf(__('Ref: %s', 'easy-invoice'), $ei_reference)) . '</span>';
489 + endif;
490 + if (\EasyInvoice\Services\OfflinePayments::hasProof((int) $payment->getId())) :
491 + echo '<a class="inline-flex items-center gap-1 mt-1 text-xs font-medium text-indigo-600 hover:text-indigo-900" target="_blank" rel="noopener" href="' . esc_url(\EasyInvoice\Services\OfflinePayments::proofUrl((int) $payment->getId())) . '"><svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"></path></svg>' . esc_html__('View receipt', 'easy-invoice') . '</a>';
492 + endif;
521 493 ?>
522 494 </td>
523 495 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
524 496 <?php
@@ -531,11 +503,18 @@
531 503 $status_class = 'bg-green-100 text-green-800';
532 504 $status_text = __('Completed', 'easy-invoice');
533 505 break;
534 506 case 'pending':
507 + case 'pending-bank':
508 + case 'pending-cheque':
509 + case 'pending_verification':
535 510 $status_class = 'bg-yellow-100 text-yellow-800';
536 - $status_text = __('Pending', 'easy-invoice');
511 + $status_text = __('Awaiting confirmation', 'easy-invoice');
537 512 break;
513 + case 'rejected':
514 + $status_class = 'bg-gray-200 text-gray-700';
515 + $status_text = __('Rejected', 'easy-invoice');
516 + break;
538 517 case 'failed':
539 518 $status_class = 'bg-red-100 text-red-800';
540 519 $status_text = __('Failed', 'easy-invoice');
541 520 break;
@@ -543,40 +522,49 @@
543 522 $status_class = 'bg-gray-100 text-gray-800';
544 523 $status_text = ucfirst($status);
545 524 }
546 525 ?>
547 - <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium <?php echo $status_class; ?>">
548 - <?php echo $status_text; ?>
526 + <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium <?php echo esc_attr($status_class); ?>">
527 + <?php echo esc_html($status_text); ?>
549 528 </span>
550 529 </td>
551 530 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
552 - <?php echo $payment->getPaymentDate() ? date('M j, Y', strtotime($payment->getPaymentDate())) : date('M j, Y', strtotime($payment->getPost()->post_date)); ?>
531 + <?php echo esc_html($payment->getPaymentDate() ? gmdate('M j, Y', strtotime($payment->getPaymentDate())) : gmdate('M j, Y', strtotime((string) get_post_field('post_date', $payment->getId())) ?: time())); ?>
553 532 </td>
554 533 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 hidden sm:table-cell">
555 - <?php echo ucfirst($payment->getPaymentType() ?: 'one-time'); ?>
534 + <?php echo esc_html(ucfirst($payment->getPaymentType() ?: 'one-time')); ?>
556 535 </td>
557 536 <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
558 537 <div class="flex items-center space-x-2">
559 - <a href="?page=easy-invoice-payments&action=view&id=<?php echo $payment->getId(); ?>" class="text-indigo-600 hover:text-indigo-900">
538 + <a href="?page=easy-invoice-payments&action=view&id=<?php echo (int) $payment->getId(); ?>" class="text-indigo-600 hover:text-indigo-900">
560 539 <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
561 540 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
562 541 <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>
563 542 </svg>
564 543 </a>
565 - <a href="?page=easy-invoice-payments&action=edit&id=<?php echo $payment->getId(); ?>" class="text-blue-600 hover:text-blue-900">
544 + <a href="?page=easy-invoice-payments&action=edit&id=<?php echo (int) $payment->getId(); ?>" class="text-blue-600 hover:text-blue-900">
566 545 <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
567 546 <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>
568 547 </svg>
569 548 </a>
570 - <?php if (in_array($status, ['pending', 'pending-bank', 'pending-cheque'])): ?>
571 - <button type="button" class="approve-payment-btn text-green-600 hover:text-green-900"
572 - data-payment-id="<?php echo $payment->getId(); ?>"
573 - data-invoice-id="<?php echo $payment->getInvoiceId(); ?>"
574 - data-nonce="<?php echo wp_create_nonce('easy_invoice_approve_payment'); ?>">
549 + <?php if (in_array($status, \EasyInvoice\Services\OfflinePayments::pendingStatuses(), true)): ?>
550 + <button type="button" class="approve-payment-btn text-green-600 hover:text-green-900" title="<?php esc_attr_e('Confirm this payment', 'easy-invoice'); ?>"
551 + data-payment-id="<?php echo (int) $payment->getId(); ?>"
552 + data-invoice-id="<?php echo esc_attr($payment->getInvoiceId()); ?>"
553 + data-nonce="<?php echo esc_attr(wp_create_nonce('easy_invoice_approve_payment')); ?>">
575 554 <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
576 555 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
577 556 </svg>
557 + <span class="sr-only"><?php esc_html_e('Confirm', 'easy-invoice'); ?></span>
578 558 </button>
559 + <button type="button" class="reject-payment-btn text-red-600 hover:text-red-900" title="<?php esc_attr_e('Reject this payment', 'easy-invoice'); ?>"
560 + data-payment-id="<?php echo (int) $payment->getId(); ?>"
561 + data-nonce="<?php echo esc_attr(wp_create_nonce('easy_invoice_approve_payment')); ?>">
562 + <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
563 + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
564 + </svg>
565 + <span class="sr-only"><?php esc_html_e('Reject', 'easy-invoice'); ?></span>
566 + </button>
579 567 <?php endif; ?>
580 568
581 569 <?php
582 570 // Hook for additional payment actions (used by Pro plugin for receipts)
@@ -587,10 +575,25 @@
587 575 </tr>
588 576 <?php endforeach; ?>
589 577 <?php else : ?>
590 578 <tr>
591 - <td colspan="9" class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 text-center">
592 - <?php _e('No payments found.', 'easy-invoice'); ?>
579 + <?php
580 + // Was a bare "No payments found." with no way forward. Every
581 + // other empty state in the plugin offers the next action, so
582 + // this one now points at Add New Payment too.
583 + //
584 + // `whitespace-nowrap` also had to go: it is meant for table
585 + // cells holding short values, and on a 9-column empty row it
586 + // stopped the message wrapping.
587 + $ei_add_payment_link = '<a href="' . esc_url(admin_url('admin.php?page=easy-invoice-payment-new')) . '" class="text-indigo-600 hover:text-indigo-900">'
588 + . esc_html__('Record your first payment', 'easy-invoice')
589 + . '</a>';
590 + ?>
591 + <td colspan="9" class="px-6 py-4 text-sm text-gray-500 text-center">
592 + <?php
593 + /* translators: %s: link reading "Record your first payment". */
594 + printf(esc_html__('No payments found. %s.', 'easy-invoice'), wp_kses_post($ei_add_payment_link));
595 + ?>
593 596 </td>
594 597 </tr>
595 598 <?php endif; ?>
596 599 </tbody>
@@ -597,9 +600,8 @@
597 600 </table>
598 601 </div>
599 602 </div>
600 603
601 - <!-- Bottom Pagination -->
602 604 <?php if ($total_payments > 0): ?>
603 605 <div class="mt-4">
604 606 <div class="px-4 py-3 flex items-center justify-between">
605 607 <div class="flex items-center space-x-2">
@@ -656,9 +658,9 @@
656 658 if ($link && strpos($link, 'bg-indigo-50') === false && strpos($link, 'bg-white') === false) {
657 659 $link = easy_invoice_str_replace('border-gray-300', 'border-gray-300 bg-white text-gray-500 hover:bg-gray-50', $link);
658 660 }
659 661
660 - echo $link;
662 + echo wp_kses_post($link);
661 663 }
662 664 echo '</div>';
663 665 }
664 666 ?>
@@ -668,15 +670,12 @@
668 670 </div>
669 671 <?php endif; ?>
670 672 </div>
671 673
672 -<!-- Approval Modal -->
673 674 <div id="payment-approval-modal" class="fixed inset-0 z-50 overflow-y-auto hidden" aria-labelledby="modal-title" role="dialog" aria-modal="true">
674 675 <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
675 - <!-- Background overlay -->
676 676 <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
677 677
678 - <!-- Modal panel -->
679 678 <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">
680 679 <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
681 680 <div class="sm:flex sm:items-start">
682 681 <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">
@@ -685,19 +684,19 @@
685 684 </svg>
686 685 </div>
687 686 <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
688 687 <h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
689 - <?php _e('Approve Payment', 'easy-invoice'); ?>
688 + <?php esc_html_e('Approve Payment', 'easy-invoice'); ?>
690 689 </h3>
691 690 <div class="mt-2">
692 691 <p class="text-sm text-gray-500">
693 - <?php _e('You are about to approve this payment. This will mark the invoice as paid and update the payment records.', 'easy-invoice'); ?>
692 + <span data-ei-mode-text="approve"><?php esc_html_e('Confirm that this payment arrived. The payment is marked completed and the invoice becomes Paid when its balance is covered, or Partially paid otherwise.', 'easy-invoice'); ?></span><span data-ei-mode-text="reject" hidden><?php esc_html_e('Reject this submission. The record is kept for the audit trail, nothing counts toward the balance, and the invoice keeps its status.', 'easy-invoice'); ?></span>
694 693 </p>
695 694 <div class="mt-4">
696 695 <label for="approval-notes" class="block text-sm font-medium text-gray-700">
697 - <?php _e('Notes (optional)', 'easy-invoice'); ?>
696 + <?php esc_html_e('Notes (optional)', 'easy-invoice'); ?>
698 697 </label>
699 - <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>
698 + <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 echo esc_js(__('Add any notes about this payment approval...', 'easy-invoice')); ?>"></textarea>
700 699 </div>
701 700 </div>
702 701 </div>
703 702 </div>
@@ -703,12 +702,12 @@
703 702 </div>
704 703 </div>
705 704 <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
706 705 <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">
707 - <?php _e('Approve Payment', 'easy-invoice'); ?>
706 + <span data-ei-mode-text="approve"><?php esc_html_e('Confirm payment', 'easy-invoice'); ?></span><span data-ei-mode-text="reject" hidden><?php esc_html_e('Reject payment', 'easy-invoice'); ?></span>
708 707 </button>
709 708 <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">
710 - <?php _e('Cancel', 'easy-invoice'); ?>
709 + <?php esc_html_e('Cancel', 'easy-invoice'); ?>
711 710 </button>
712 711 </div>
713 712 </div>
714 713 </div>
@@ -713,11 +712,9 @@
713 712 </div>
714 713 </div>
715 714 </div>
716 715
717 -<!-- Notification area for AJAX responses -->
718 716 <div id="payment-approve-notification" class="fixed top-0 right-0 m-4 hidden">
719 - <!-- Content will be injected via JavaScript -->
720 717 </div>
721 718
722 719 <style>
723 720 /* Add any additional custom styles here */
@@ -760,9 +757,9 @@
760 757 </style>
761 758
762 759 <script>
763 760 // Define ajaxurl for AJAX requests
764 -var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
761 +var ajaxurl = '<?php echo esc_url(admin_url('admin-ajax.php')); ?>';
765 762
766 763 jQuery(document).ready(function($) {
767 764 // Variables to store the current payment being approved
768 765 let currentInvoiceId = null;
@@ -776,13 +773,33 @@
776 773 // Store the data for the current payment
777 774 currentInvoiceId = $(this).data('invoice-id');
778 775 currentPaymentId = $(this).data('payment-id');
779 776 currentNonce = $(this).data('nonce');
777 + currentMode = 'approve';
778 + setModalMode('approve');
780 779
781 780 // Show the approval modal
782 781 $('#payment-approval-modal').removeClass('hidden');
783 782 });
784 783
784 + // Reject uses the same dialog with different copy and a different endpoint.
785 + var currentMode = 'approve';
786 + function setModalMode(mode) {
787 + $('#payment-approval-modal [data-ei-mode-text]').each(function() {
788 + $(this).prop('hidden', $(this).data('ei-mode-text') !== mode);
789 + });
790 + $('#confirm-approve-btn').toggleClass('bg-red-600 hover:bg-red-700', mode === 'reject').toggleClass('bg-green-600 hover:bg-green-700', mode !== 'reject');
791 + }
792 + $('.reject-payment-btn').on('click', function(e) {
793 + e.preventDefault();
794 + currentInvoiceId = null;
795 + currentPaymentId = $(this).data('payment-id');
796 + currentNonce = $(this).data('nonce');
797 + currentMode = 'reject';
798 + setModalMode('reject');
799 + $('#payment-approval-modal').removeClass('hidden');
800 + });
801 +
785 802 // Handle Cancel button in modal
786 803 $('#cancel-approve-btn').on('click', function() {
787 804 // Hide the modal and reset the form
788 805 $('#payment-approval-modal').addClass('hidden');
@@ -794,9 +811,9 @@
794 811 // Get the notes from the textarea
795 812 const notes = $('#approval-notes').val();
796 813
797 814 // Disable the button to prevent double clicks
798 - $(this).prop('disabled', true).text('Processing...');
815 + $(this).prop('disabled', true);
799 816
800 817 // Make AJAX request to approve the payment
801 818 $.ajax({
802 819 url: ajaxurl,
@@ -801,10 +818,11 @@
801 818 $.ajax({
802 819 url: ajaxurl,
803 820 type: 'POST',
804 821 data: {
805 - action: 'easy_invoice_approve_payment',
822 + action: currentMode === 'reject' ? 'easy_invoice_reject_payment' : 'easy_invoice_approve_payment',
806 823 invoice_id: currentInvoiceId,
824 + payment_id: currentPaymentId,
807 825 nonce: currentNonce,
808 826 notes: notes
809 827 },
810 828 success: function(response) {
@@ -810,12 +828,13 @@
810 828 success: function(response) {
811 829 // Hide the modal
812 830 $('#payment-approval-modal').addClass('hidden');
813 831
832 + var toast = response && response.data && response.data.toast ? response.data.toast.message : '';
814 833 if (response.success) {
815 834 // Show success toast
816 835 if (typeof EasyInvoiceToast !== 'undefined') {
817 - EasyInvoiceToast.success('Payment approved successfully.');
836 + EasyInvoiceToast.success(toast || (currentMode === 'reject' ? 'Payment rejected.' : 'Payment confirmed.'));
818 837 }
819 838
820 839 // Refresh the page after a short delay
821 840 setTimeout(function() {
@@ -823,13 +842,13 @@
823 842 }, 1500);
824 843 } else {
825 844 // Show error toast
826 845 if (typeof EasyInvoiceToast !== 'undefined') {
827 - EasyInvoiceToast.error('Failed to approve payment.');
846 + EasyInvoiceToast.error(toast || 'The payment could not be updated.');
828 847 }
829 848
830 849 // Re-enable the button
831 - $('#confirm-approve-btn').prop('disabled', false).text('Approve Payment');
850 + $('#confirm-approve-btn').prop('disabled', false); setModalMode(currentMode);
832 851 }
833 852 },
834 853 error: function() {
835 854 // Hide the modal
@@ -840,9 +859,9 @@
840 859 EasyInvoiceToast.error('Server error occurred. Please try again.');
841 860 }
842 861
843 862 // Re-enable the button
844 - $('#confirm-approve-btn').prop('disabled', false).text('Approve Payment');
863 + $('#confirm-approve-btn').prop('disabled', false); setModalMode(currentMode);
845 864 }
846 865 });
847 866 });
848 867