fix: Route priority issue - /order was matched by /{id}

Problem:
POST /payments/gateways/order → 404 'gateway_not_found'

Root Cause:
WordPress REST API matches routes in registration order.
The /gateways/order route was registered AFTER /gateways/{id}.
So /gateways/order was being matched by /gateways/{id} where id='order'.
Then get_gateway('order') returned 'gateway_not_found'.

Solution:
Register specific routes BEFORE dynamic routes:
1. /gateways (list)
2. /gateways/order (specific - NEW POSITION)
3. /gateways/{id} (dynamic)
4. /gateways/{id}/toggle (dynamic with action)

Route Priority Rules:
 Specific routes first
 Dynamic routes last
 More specific before less specific

Before:
/gateways → OK
/gateways/{id} → Matches everything including 'order'
/gateways/{id}/toggle → OK (more specific than {id})
/gateways/order → Never reached!

After:
/gateways → OK
/gateways/order → Matches 'order' specifically
/gateways/{id} → Matches other IDs
/gateways/{id}/toggle → OK

Result:
 /gateways/order now works correctly
 Sorting saves to database
 No more 'gateway_not_found' error

Files Modified:
- PaymentsController.php: Moved /order route before /{id} routes
This commit is contained in:
dwindown
2025-11-06 14:05:18 +07:00
parent 52f7c1b99d
commit 40fb364035
2 changed files with 42 additions and 29 deletions

View File

@@ -117,18 +117,26 @@ export default function PaymentsPage() {
// Initialize order from saved order or gateways
React.useEffect(() => {
if (gateways.length > 0 && manualOrder.length === 0 && onlineOrder.length === 0) {
console.log('Initializing gateway order...');
console.log('All gateways:', gateways.map((g: PaymentGateway) => ({ id: g.id, type: g.type })));
console.log('Saved order:', savedOrder);
// Use saved order if available, otherwise use gateway order
if (savedOrder.manual.length > 0) {
console.log('Using saved manual order:', savedOrder.manual);
setManualOrder(savedOrder.manual);
} else {
const manual = gateways.filter((g: PaymentGateway) => g.type === 'manual').map((g: PaymentGateway) => g.id);
console.log('Using gateway manual order:', manual);
setManualOrder(manual);
}
if (savedOrder.online.length > 0) {
console.log('Using saved online order:', savedOrder.online);
setOnlineOrder(savedOrder.online);
} else {
const online = gateways.filter((g: PaymentGateway) => g.type === 'provider' || g.type === 'other').map((g: PaymentGateway) => g.id);
console.log('Using gateway online order:', online);
setOnlineOrder(online);
}
}
@@ -189,14 +197,16 @@ export default function PaymentsPage() {
// Save order to backend
try {
console.log('Saving manual order:', newOrder);
await api.post('/payments/gateways/order', {
category: 'manual',
order: newOrder,
});
toast.success('Payment methods reordered');
} catch (error) {
} catch (error: any) {
console.error('Failed to save order:', error);
toast.error('Failed to save order');
console.error('Error response:', error.response?.data);
toast.error(error.response?.data?.message || 'Failed to save order');
// Revert order on error
setManualOrder(manualOrder);
}
@@ -215,14 +225,16 @@ export default function PaymentsPage() {
// Save order to backend
try {
console.log('Saving online order:', newOrder);
await api.post('/payments/gateways/order', {
category: 'online',
order: newOrder,
});
toast.success('Payment methods reordered');
} catch (error) {
} catch (error: any) {
console.error('Failed to save order:', error);
toast.error('Failed to save order');
console.error('Error response:', error.response?.data);
toast.error(error.response?.data?.message || 'Failed to save order');
// Revert order on error
setOnlineOrder(onlineOrder);
}