namespace, '/' . $this->rest_base . '/gateways', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_gateways'], 'permission_callback' => [$this, 'check_permission'], ], 'schema' => [$this, 'get_gateways_schema'], ]); // POST /woonoow/v1/payments/gateways/order // IMPORTANT: Register this BEFORE the dynamic {id} routes to avoid conflicts register_rest_route($this->namespace, '/' . $this->rest_base . '/gateways/order', [ [ 'methods' => WP_REST_Server::EDITABLE, 'callback' => [$this, 'save_gateway_order'], 'permission_callback' => [$this, 'check_permission'], 'args' => [ 'category' => [ 'description' => 'Gateway category (manual or online)', 'type' => 'string', 'required' => true, 'enum' => ['manual', 'online'], ], 'order' => [ 'description' => 'Array of gateway IDs in desired order', 'type' => 'array', 'required' => true, 'items' => [ 'type' => 'string', ], ], ], ], ]); // GET /woonoow/v1/payments/gateways/{id} register_rest_route($this->namespace, '/' . $this->rest_base . '/gateways/(?P[a-zA-Z0-9_-]+)', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_gateway'], 'permission_callback' => [$this, 'check_permission'], 'args' => [ 'id' => [ 'description' => 'Gateway ID', 'type' => 'string', 'required' => true, ], ], ], ]); // POST /woonoow/v1/payments/gateways/{id} register_rest_route($this->namespace, '/' . $this->rest_base . '/gateways/(?P[a-zA-Z0-9_-]+)', [ [ 'methods' => WP_REST_Server::EDITABLE, 'callback' => [$this, 'save_gateway'], 'permission_callback' => [$this, 'check_permission'], 'args' => [ 'id' => [ 'description' => 'Gateway ID', 'type' => 'string', 'required' => true, ], ], ], ]); // POST /woonoow/v1/payments/gateways/{id}/toggle register_rest_route($this->namespace, '/' . $this->rest_base . '/gateways/(?P[a-zA-Z0-9_-]+)/toggle', [ [ 'methods' => WP_REST_Server::EDITABLE, 'callback' => [$this, 'toggle_gateway'], 'permission_callback' => [$this, 'check_permission'], 'args' => [ 'id' => [ 'description' => 'Gateway ID', 'type' => 'string', 'required' => true, ], 'enabled' => [ 'description' => 'Enable or disable gateway', 'type' => 'boolean', 'required' => true, ], ], ], ]); } /** * Get all payment gateways * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object or error */ public function get_gateways(WP_REST_Request $request) { try { $gateways = PaymentGatewaysProvider::get_gateways(); // Get saved order $manual_order = get_option('woonoow_payment_gateway_order_manual', []); $online_order = get_option('woonoow_payment_gateway_order_online', []); $response = rest_ensure_response([ 'gateways' => $gateways, 'order' => [ 'manual' => $manual_order, 'online' => $online_order, ], ]); // Cache for 5 minutes $response->header('Cache-Control', 'max-age=300'); return $response; } catch (\Exception $e) { return new WP_Error( 'get_gateways_failed', $e->getMessage(), ['status' => 500] ); } } /** * Get single payment gateway * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object or error */ public function get_gateway(WP_REST_Request $request) { $gateway_id = $request->get_param('id'); try { $gateway = PaymentGatewaysProvider::get_gateway($gateway_id); if ($gateway === null) { return new WP_Error( 'gateway_not_found', sprintf('Gateway "%s" not found', $gateway_id), ['status' => 404] ); } $response = rest_ensure_response($gateway); // Cache for 5 minutes $response->header('Cache-Control', 'max-age=300'); return $response; } catch (\Exception $e) { return new WP_Error( 'get_gateway_failed', $e->getMessage(), ['status' => 500] ); } } /** * Save gateway settings * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object or error */ public function save_gateway(WP_REST_Request $request) { $gateway_id = $request->get_param('id'); $settings = $request->get_json_params(); if (empty($settings)) { return new WP_Error( 'missing_settings', 'No settings provided', ['status' => 400] ); } try { // Debug: Log what we're saving error_log(sprintf('[WooNooW] Saving gateway %s settings: %s', $gateway_id, json_encode($settings))); $result = PaymentGatewaysProvider::save_gateway_settings($gateway_id, $settings); if (is_wp_error($result)) { error_log(sprintf('[WooNooW] Save failed: %s', $result->get_error_message())); return $result; } // Clear cache before fetching updated gateway wp_cache_flush(); // Return updated gateway data (fresh from DB) $gateway = PaymentGatewaysProvider::get_gateway($gateway_id); // Debug: Log success error_log(sprintf('[WooNooW] Gateway %s settings saved successfully', $gateway_id)); return rest_ensure_response([ 'success' => true, 'message' => 'Gateway settings saved successfully', 'gateway' => $gateway, ]); } catch (\Exception $e) { error_log(sprintf('[WooNooW] Save exception: %s', $e->getMessage())); return new WP_Error( 'save_gateway_failed', $e->getMessage(), ['status' => 500] ); } } /** * Toggle gateway enabled status * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object or error */ public function toggle_gateway(WP_REST_Request $request) { $gateway_id = $request->get_param('id'); $enabled = $request->get_param('enabled'); // Convert to boolean (handles both bool and string "true"/"false") $enabled = filter_var($enabled, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); if ($enabled === null) { return new WP_Error( 'invalid_enabled_value', 'The "enabled" parameter must be a boolean', ['status' => 400] ); } try { // Debug: Log what we're trying to do error_log(sprintf('[WooNooW] Toggling gateway %s to %s', $gateway_id, $enabled ? 'enabled' : 'disabled')); $result = PaymentGatewaysProvider::toggle_gateway($gateway_id, $enabled); if (is_wp_error($result)) { error_log(sprintf('[WooNooW] Toggle failed: %s', $result->get_error_message())); return $result; } // Clear cache before fetching updated gateway wp_cache_flush(); // Return updated gateway data (fresh from DB) $gateway = PaymentGatewaysProvider::get_gateway($gateway_id); // Debug: Log what we got back error_log(sprintf('[WooNooW] Gateway %s after toggle: enabled=%s', $gateway_id, $gateway['enabled'] ? 'true' : 'false')); return rest_ensure_response([ 'success' => true, 'message' => $enabled ? 'Gateway enabled' : 'Gateway disabled', 'gateway' => $gateway, ]); } catch (\Exception $e) { error_log(sprintf('[WooNooW] Toggle exception: %s', $e->getMessage())); return new WP_Error( 'toggle_gateway_failed', $e->getMessage(), ['status' => 500] ); } } /** * Save gateway order * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object or error */ public function save_gateway_order(WP_REST_Request $request) { $category = $request->get_param('category'); $order = $request->get_param('order'); // Validate category if (!in_array($category, ['manual', 'online'], true)) { return new WP_Error( 'invalid_category', 'Category must be either "manual" or "online"', ['status' => 400] ); } // Validate order is array if (!is_array($order)) { return new WP_Error( 'invalid_order', 'Order must be an array of gateway IDs', ['status' => 400] ); } // Save to WordPress options $option_key = 'woonoow_payment_gateway_order_' . $category; update_option($option_key, $order, false); error_log(sprintf('[WooNooW] Saved %s gateway order: %s', $category, implode(', ', $order))); return rest_ensure_response([ 'success' => true, 'message' => 'Gateway order saved successfully', 'category' => $category, 'order' => $order, ]); } /** * Check permission * * @return bool True if user has permission */ public function check_permission() { return current_user_can('manage_woocommerce'); } /** * Get gateways collection schema * * @return array Schema */ public function get_gateways_schema() { return [ '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'payment-gateways', 'type' => 'array', 'items' => [ 'type' => 'object', 'properties' => [ 'id' => [ 'description' => 'Gateway ID', 'type' => 'string', ], 'title' => [ 'description' => 'Gateway title', 'type' => 'string', ], 'description' => [ 'description' => 'Gateway description', 'type' => 'string', ], 'enabled' => [ 'description' => 'Whether gateway is enabled', 'type' => 'boolean', ], 'type' => [ 'description' => 'Gateway type', 'type' => 'string', 'enum' => ['manual', 'provider', 'other'], ], ], ], ]; } }