__('Error de seguridad. Por favor recarga la pagina.', 'roi-theme') ], 403); return; } // 2. Rate limiting (1 suscripcion por IP cada 60 segundos) if (!$this->checkRateLimit()) { wp_send_json_error([ 'message' => __('Por favor espera un momento antes de intentar de nuevo.', 'roi-theme') ], 429); return; } // 3. Validar y sanitizar campos $email = sanitize_email($_POST['email'] ?? ''); $name = sanitize_text_field($_POST['name'] ?? ''); $whatsapp = sanitize_text_field($_POST['whatsapp'] ?? ''); if (empty($email) || !is_email($email)) { wp_send_json_error([ 'message' => __('Por favor ingresa un email valido.', 'roi-theme') ], 422); return; } // 4. Obtener configuracion del componente $settings = $this->settingsRepository->getComponentSettings(self::COMPONENT_NAME); if (empty($settings)) { wp_send_json_error([ 'message' => __('Error de configuracion. Contacta al administrador.', 'roi-theme') ], 500); return; } $newsletter = $settings['newsletter'] ?? []; $webhookUrl = $newsletter['newsletter_webhook_url'] ?? ''; $successMsg = $newsletter['newsletter_success_message'] ?? __('Gracias por suscribirte!', 'roi-theme'); $errorMsg = $newsletter['newsletter_error_message'] ?? __('Error al suscribirse. Intenta de nuevo.', 'roi-theme'); if (empty($webhookUrl)) { // Si no hay webhook, simular exito para UX pero loguear warning error_log('ROI Theme Newsletter: No webhook URL configured'); wp_send_json_success([ 'message' => $successMsg ]); return; } // 5. Preparar payload $payload = [ 'email' => $email, 'name' => $name, 'whatsapp' => $whatsapp, 'source' => 'newsletter-footer', 'pageUrl' => sanitize_url($_POST['pageUrl'] ?? ''), 'pageTitle' => sanitize_text_field($_POST['pageTitle'] ?? ''), 'timestamp' => current_time('c'), 'timezone' => wp_timezone_string(), 'siteName' => get_bloginfo('name'), 'siteUrl' => home_url(), ]; // Debug: Log payload enviado error_log('ROI Theme Newsletter: Enviando a webhook - ' . wp_json_encode($payload)); // 6. Enviar a webhook $result = $this->sendToWebhook($webhookUrl, $payload); if ($result['success']) { wp_send_json_success([ 'message' => $successMsg ]); } else { error_log('ROI Theme Newsletter webhook error: ' . $result['error']); wp_send_json_error([ 'message' => $errorMsg ], 500); } } /** * Enviar datos al webhook */ private function sendToWebhook(string $url, array $payload): array { error_log('ROI Theme Newsletter: Webhook URL - ' . $url); $response = wp_remote_post($url, [ 'timeout' => 30, 'headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', ], 'body' => wp_json_encode($payload), ]); if (is_wp_error($response)) { error_log('ROI Theme Newsletter: WP Error - ' . $response->get_error_message()); return [ 'success' => false, 'error' => $response->get_error_message() ]; } $statusCode = wp_remote_retrieve_response_code($response); $responseBody = wp_remote_retrieve_body($response); error_log('ROI Theme Newsletter: Response Code - ' . $statusCode); error_log('ROI Theme Newsletter: Response Body - ' . $responseBody); if ($statusCode >= 200 && $statusCode < 300) { return ['success' => true, 'error' => '']; } return [ 'success' => false, 'error' => sprintf('HTTP %d: %s', $statusCode, wp_remote_retrieve_response_message($response)) ]; } /** * Rate limiting por IP */ private function checkRateLimit(): bool { $ip = $this->getClientIP(); $transientKey = 'roi_newsletter_' . md5($ip); $lastSubmit = get_transient($transientKey); if ($lastSubmit !== false) { return false; } set_transient($transientKey, time(), 60); return true; } /** * Obtener IP del cliente */ private function getClientIP(): string { $ip = ''; if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = sanitize_text_field($_SERVER['HTTP_CLIENT_IP']); } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = sanitize_text_field(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]); } elseif (!empty($_SERVER['REMOTE_ADDR'])) { $ip = sanitize_text_field($_SERVER['REMOTE_ADDR']); } return $ip; } }