From bdb47d9d7a228d0b05e67be10c17fcfa9e68fb70 Mon Sep 17 00:00:00 2001 From: Aljaz Ceru Date: Tue, 27 May 2025 17:51:50 +0200 Subject: [PATCH] changes --- breez-woocommerce.php | 105 ++++++++++++++++++----- class-wc-gateway-breez.php | 86 ++++++++++--------- includes/admin/breez-settings.php | 11 +-- includes/class-breez-api-client.php | 101 ++++++++++++++++------ includes/class-breez-webhook-handler.php | 14 +-- templates/payment-instructions.php | 40 ++++++--- 6 files changed, 243 insertions(+), 114 deletions(-) diff --git a/breez-woocommerce.php b/breez-woocommerce.php index 1351222..4b2a975 100755 --- a/breez-woocommerce.php +++ b/breez-woocommerce.php @@ -1,7 +1,7 @@ log('Direct payment status check endpoint called', 'debug'); $invoice_id = $request->get_param('invoice_id'); + if (empty($invoice_id)) { + $logger->log('No invoice ID provided', 'error'); + return new WP_REST_Response(array( + 'success' => false, + 'message' => 'Invoice ID is required' + ), 400); + } + $logger->log("Checking payment status for invoice ID: $invoice_id", 'debug'); + // Initialize DB manager to get payment details + $db_manager = new Breez_DB_Manager(); + $payment = $db_manager->get_payment_by_invoice($invoice_id); + + if (!$payment) { + $logger->log("No payment found for invoice ID: $invoice_id", 'error'); + return new WP_REST_Response(array( + 'success' => false, + 'message' => 'Payment not found', + 'status' => 'UNKNOWN' + ), 404); + } + // Initialize API client - directly fetch gateway settings $gateway_settings = get_option('woocommerce_breez_settings'); $api_url = isset($gateway_settings['api_url']) ? $gateway_settings['api_url'] : ''; @@ -279,11 +300,36 @@ function breez_wc_check_payment_status_by_invoice_endpoint($request) { $client = new Breez_API_Client($api_url, $api_key); $payment_status = $client->check_payment_status($invoice_id); $logger->log("Payment status for invoice ID $invoice_id: " . print_r($payment_status, true), 'debug'); + + // Update payment status in database if it has changed + if ($payment_status['status'] !== $payment['status']) { + $db_manager->update_payment_status($payment['order_id'], $payment_status['status']); + + // Get the order + $order = wc_get_order($payment['order_id']); + if ($order) { + // Update order status if needed + if ($payment_status['status'] === 'SUCCEEDED' && $order->get_status() === 'pending') { + $order->payment_complete($invoice_id); + $order->add_order_note(__('Payment confirmed via Breez API.', 'breez-woocommerce')); + $order->save(); + $logger->log("Order #{$payment['order_id']} marked as complete", 'info'); + } else if ($payment_status['status'] === 'FAILED' && $order->get_status() === 'pending') { + $order->update_status('failed', __('Payment failed or expired.', 'breez-woocommerce')); + $logger->log("Order #{$payment['order_id']} marked as failed", 'info'); + } + } + } return new WP_REST_Response(array( 'success' => true, 'status' => $payment_status['status'], - 'data' => $payment_status + 'data' => array_merge($payment_status, array( + 'order_id' => $payment['order_id'], + 'payment_method' => $payment['metadata']['payment_method'], + 'amount_sat' => $payment['metadata']['amount_sat'], + 'expires_at' => $payment['metadata']['expires_at'] + )) ), 200); } catch (Exception $e) { @@ -415,30 +461,47 @@ function breez_wc_check_pending_payments() { /** * Plugin activation hook */ -function breez_wc_activate() { - // Include required files before using them - require_once BREEZ_WC_PLUGIN_DIR . 'includes/class-breez-logger.php'; - require_once BREEZ_WC_PLUGIN_DIR . 'includes/class-breez-db-manager.php'; +function breez_wc_activate($network_wide = false) { + // Include all required files before using them + $required_files = array( + 'includes/class-breez-logger.php', + 'includes/class-breez-api-client.php', + 'includes/class-breez-db-manager.php', + 'includes/class-breez-payment-handler.php', + 'includes/class-breez-webhook-handler.php' + ); - // Initialize logger + foreach ($required_files as $file) { + $full_path = BREEZ_WC_PLUGIN_DIR . $file; + if (file_exists($full_path)) { + require_once $full_path; + } + } + + // Initialize logger first $logger = new Breez_Logger(true); $logger->log('Plugin activation started', 'info'); - // Initialize DB manager - $db_manager = new Breez_DB_Manager(); - - // Force drop and recreate the payments table with new schema - $logger->log('Forcing table recreation to update schema', 'info'); - $db_manager->recreate_table(); - - // Create required directories - $upload_dir = wp_upload_dir(); - $breez_dir = $upload_dir['basedir'] . '/breez-wc'; - if (!file_exists($breez_dir)) { - wp_mkdir_p($breez_dir); + // Make sure the DB Manager class exists before using it + if (class_exists('Breez_DB_Manager')) { + // Initialize DB manager + $db_manager = new Breez_DB_Manager(); + + // Force drop and recreate the payments table with new schema + $logger->log('Installing database tables', 'info'); + $db_manager->install_tables(); + + // Create required directories + $upload_dir = wp_upload_dir(); + $breez_dir = $upload_dir['basedir'] . '/breez-wc'; + if (!file_exists($breez_dir)) { + wp_mkdir_p($breez_dir); + } + + $logger->log('Plugin activation completed', 'info'); + } else { + $logger->log('ERROR: Unable to initialize DB manager - class not found', 'error'); } - - $logger->log('Plugin activation completed', 'info'); } register_activation_hook(__FILE__, 'breez_wc_activate'); diff --git a/class-wc-gateway-breez.php b/class-wc-gateway-breez.php index 15fe8e1..5020e54 100644 --- a/class-wc-gateway-breez.php +++ b/class-wc-gateway-breez.php @@ -56,7 +56,7 @@ class WC_Gateway_Breez extends WC_Payment_Gateway { $this->id = 'breez'; $this->icon = apply_filters('woocommerce_breez_icon', ''); $this->has_fields = false; - $this->method_title = __('Lightning Payments', 'breez-woocommerce'); + $this->method_title = __('Pay with Lightning', 'breez-woocommerce'); $this->method_description = __('', 'breez-woocommerce'); $this->supports = array( 'products', @@ -96,13 +96,8 @@ class WC_Gateway_Breez extends WC_Payment_Gateway { $this->logger->log('API Key: ' . ($this->api_key ? 'SET' : 'MISSING'), 'error'); add_action('admin_notices', array($this, 'admin_api_notice')); } - - // Check webhook secret - $webhook_secret = $this->get_option('webhook_secret'); - if ($this->enabled === 'yes' && empty($webhook_secret)) { - $this->logger->log('Webhook secret not configured', 'warning'); - add_action('admin_notices', array($this, 'admin_webhook_secret_notice')); - } + + // Initialize client, DB manager, payment handler try { @@ -176,15 +171,6 @@ class WC_Gateway_Breez extends WC_Payment_Gateway { '

'; } - /** - * Display admin notice for missing webhook secret - */ - public function admin_webhook_secret_notice() { - echo '

' . - __('Breez Payment Gateway: Please configure a webhook secret in the gateway settings to secure your webhook endpoint.', 'breez-woocommerce') . - '

'; - } - /** * Display admin notice for API initialization error */ @@ -520,30 +506,52 @@ class WC_Gateway_Breez extends WC_Payment_Gateway { $this->logger->log("Payment for order #$order_id confirmed via API check", 'debug'); } - // Load the payment instructions template - $template_path = BREEZ_WC_PLUGIN_DIR . 'templates/payment-instructions.php'; - $this->logger->log("Loading template from: $template_path", 'debug'); - - if (!file_exists($template_path)) { - $this->logger->log("Template file not found!", 'error'); - return; + // Only show payment instructions when order is still pending + // and payment status is not SUCCEEDED or WAITING_CONFIRMATION + if ($order->get_status() === 'pending' && + $api_payment_status !== 'SUCCEEDED' && + $api_payment_status !== 'WAITING_CONFIRMATION') { + + // Load the payment instructions template + $template_path = BREEZ_WC_PLUGIN_DIR . 'templates/payment-instructions.php'; + $this->logger->log("Loading payment instructions template from: $template_path", 'debug'); + + if (!file_exists($template_path)) { + $this->logger->log("Template file not found!", 'error'); + return; + } + + // Load the payment instructions template + wc_get_template( + 'payment-instructions.php', + array( + 'order' => $order, + 'invoice_id' => $invoice_id, + 'payment_method' => $payment_method, + 'expiry' => $expiry, + 'current_time' => $current_time, + 'payment_status' => 'PENDING' // Force pending status to show payment instructions + ), + '', + BREEZ_WC_PLUGIN_DIR . 'templates/' + ); + } else { + // Payment is already complete, show success message + wc_get_template( + 'payment-instructions.php', + array( + 'order' => $order, + 'invoice_id' => $invoice_id, + 'payment_method' => $payment_method, + 'expiry' => $expiry, + 'current_time' => $current_time, + 'payment_status' => 'SUCCEEDED' // Force succeeded status to show success message + ), + '', + BREEZ_WC_PLUGIN_DIR . 'templates/' + ); } - // Load the payment instructions template - wc_get_template( - 'payment-instructions.php', - array( - 'order' => $order, - 'invoice_id' => $invoice_id, - 'payment_method' => $payment_method, - 'expiry' => $expiry, - 'current_time' => $current_time, - 'payment_status' => $api_payment_status - ), - '', - BREEZ_WC_PLUGIN_DIR . 'templates/' - ); - $this->logger->log("Template loaded successfully for order #$order_id", 'debug'); } diff --git a/includes/admin/breez-settings.php b/includes/admin/breez-settings.php index d1d44cf..e6ad4ee 100644 --- a/includes/admin/breez-settings.php +++ b/includes/admin/breez-settings.php @@ -40,7 +40,7 @@ return array( 'api_settings' => array( 'title' => __('API Settings', 'breez-woocommerce'), 'type' => 'title', - 'description' => __('Enter your Breez API credentials below.', 'breez-woocommerce'), + 'description' => __('Enter your Breez API credentials below. The API key will be used for both API authentication and webhook validation.', 'breez-woocommerce'), ), 'api_url' => array( 'title' => __('API URL', 'breez-woocommerce'), @@ -52,14 +52,7 @@ return array( 'api_key' => array( 'title' => __('API Key', 'breez-woocommerce'), 'type' => 'password', - 'description' => __('Enter your Breez API key.', 'breez-woocommerce'), - 'default' => '', - 'desc_tip' => true, - ), - 'webhook_secret' => array( - 'title' => __('Webhook Secret', 'breez-woocommerce'), - 'type' => 'password', - 'description' => __('Enter a secret key that will be used to validate webhook requests. This should be a random string of at least 32 characters.', 'breez-woocommerce'), + 'description' => __('Enter your Breez API key. This key will be used for both API authentication and webhook validation.', 'breez-woocommerce'), 'default' => '', 'desc_tip' => true, ), diff --git a/includes/class-breez-api-client.php b/includes/class-breez-api-client.php index f443b4a..a9b1001 100644 --- a/includes/class-breez-api-client.php +++ b/includes/class-breez-api-client.php @@ -113,56 +113,101 @@ class Breez_API_Client { */ public function check_payment_status($invoice_id) { try { - $response = $this->request('GET', "/check_payment_status/{$invoice_id}"); + $url = $this->api_url . "/check_payment_status/{$invoice_id}?source=woocommerce"; - if (!$response) { - throw new Exception('Failed to check payment status'); + $response = wp_remote_get($url, array( + 'headers' => array( + 'Content-Type' => 'application/json', + 'x-api-key' => $this->api_key + ), + 'timeout' => 30 + )); + + if (is_wp_error($response)) { + throw new Exception($response->get_error_message()); + } + + $body = wp_remote_retrieve_body($response); + $data = json_decode($body, true); + + if (!$data) { + throw new Exception('Invalid response from API'); } // Log the raw API response for debugging $this->logger->log('Payment status check response', 'debug', array( 'invoice_id' => $invoice_id, - 'response' => $response + 'response' => $data )); - // If the payment is not found, return pending instead of throwing an error - if ($response['status'] === 'UNKNOWN') { + // If the payment is not found, return pending with full details + if ($data['status'] === 'UNKNOWN') { return array( 'status' => 'PENDING', 'destination' => $invoice_id, - 'sdk_status' => 'UNKNOWN' + 'sdk_status' => 'UNKNOWN', + 'amount_sat' => 0, + 'fees_sat' => 0, + 'payment_type' => 'UNKNOWN', + 'timestamp' => time(), + 'payment_hash' => null, + 'tx_id' => null, + 'swap_id' => null, + 'source' => 'woocommerce', + 'error' => null, + 'description' => null, + 'metadata' => array(), + 'exchange_rate' => null, + 'fiat_amount' => null, + 'fiat_currency' => null ); } - // Build response with all available details - keep original SDK status - $result = array( - 'status' => $response['status'], // Keep original SDK status (SUCCEEDED, WAITING_CONFIRMATION, etc) - 'sdk_status' => $response['status'], - 'destination' => $invoice_id, - 'amount_sat' => $response['amount_sat'] ?? null, - 'fees_sat' => $response['fees_sat'] ?? null, - 'timestamp' => $response['timestamp'] ?? null, - 'error' => $response['error'] ?? null + // Extract payment details from response + $payment_details = $data['payment_details'] ?? array(); + + // Return comprehensive payment status information + return array( + 'status' => $data['status'], + 'sdk_status' => $payment_details['sdk_status'] ?? $data['status'], + 'destination' => $payment_details['destination'] ?? $invoice_id, + 'amount_sat' => $payment_details['amount_sat'] ?? 0, + 'fees_sat' => $payment_details['fees_sat'] ?? 0, + 'payment_type' => $payment_details['payment_type'] ?? 'UNKNOWN', + 'timestamp' => $payment_details['timestamp'] ?? time(), + 'payment_hash' => $payment_details['payment_hash'] ?? null, + 'tx_id' => $payment_details['tx_id'] ?? null, + 'swap_id' => $payment_details['swap_id'] ?? null, + 'source' => $payment_details['source'] ?? 'woocommerce', + 'error' => $payment_details['error'] ?? null, + 'description' => $payment_details['description'] ?? null, + 'metadata' => $payment_details['metadata'] ?? array(), + 'exchange_rate' => $payment_details['exchange_rate'] ?? null, + 'fiat_amount' => $payment_details['fiat_amount'] ?? null, + 'fiat_currency' => $payment_details['fiat_currency'] ?? null ); - // Include payment details if available - if (isset($response['payment_details'])) { - $result['payment_details'] = $response['payment_details']; - } - - // Add human-readable status description - $result['status_description'] = $this->get_status_description($response['status']); - - return $result; - } catch (Exception $e) { $this->logger->log('Payment status check error: ' . $e->getMessage(), 'error'); - // Return pending status instead of throwing an error + // Return pending status with error information return array( 'status' => 'PENDING', 'sdk_status' => 'UNKNOWN', 'destination' => $invoice_id, - 'error' => $e->getMessage() + 'amount_sat' => 0, + 'fees_sat' => 0, + 'payment_type' => 'UNKNOWN', + 'timestamp' => time(), + 'payment_hash' => null, + 'tx_id' => null, + 'swap_id' => null, + 'source' => 'woocommerce', + 'error' => $e->getMessage(), + 'description' => null, + 'metadata' => array(), + 'exchange_rate' => null, + 'fiat_amount' => null, + 'fiat_currency' => null ); } } diff --git a/includes/class-breez-webhook-handler.php b/includes/class-breez-webhook-handler.php index 4f8ef90..daf6dd9 100644 --- a/includes/class-breez-webhook-handler.php +++ b/includes/class-breez-webhook-handler.php @@ -41,13 +41,13 @@ class Breez_Webhook_Handler { self::init_logger(); try { - // Get the webhook secret from settings + // Get the API key from settings $settings = get_option('woocommerce_breez_settings', array()); - $webhook_secret = isset($settings['webhook_secret']) ? $settings['webhook_secret'] : ''; + $api_key = isset($settings['api_key']) ? $settings['api_key'] : ''; - if (empty($webhook_secret)) { - self::$logger->log('Webhook validation failed: No webhook secret configured', 'error'); - return new WP_Error('invalid_webhook', 'No webhook secret configured', array('status' => 401)); + if (empty($api_key)) { + self::$logger->log('Webhook validation failed: No API key configured', 'error'); + return new WP_Error('invalid_webhook', 'No API key configured', array('status' => 401)); } // Get headers @@ -83,9 +83,9 @@ class Breez_Webhook_Handler { return new WP_Error('invalid_webhook', 'Nonce already used', array('status' => 401)); } - // Calculate expected signature + // Calculate expected signature using API key instead of webhook secret $payload = $timestamp . $nonce . $body; - $expected_signature = hash_hmac('sha256', $payload, $webhook_secret); + $expected_signature = hash_hmac('sha256', $payload, $api_key); // Verify signature if (!hash_equals($expected_signature, $signature)) { diff --git a/templates/payment-instructions.php b/templates/payment-instructions.php index c9eb348..2b58a4f 100644 --- a/templates/payment-instructions.php +++ b/templates/payment-instructions.php @@ -147,19 +147,27 @@ var invoiceId = ''; var orderId = 'get_id()); ?>'; function checkPaymentStatus() { + console.log('Checking payment status for invoice:', invoiceId); fetch('/wp-json/breez-wc/v1/check-payment-status/' + invoiceId, { headers: { 'Accept': 'application/json' } }) - .then(response => response.json()) + .then(response => { + console.log('Response status:', response.status); + return response.json(); + }) .then(data => { + console.log('Payment status data:', data); var paymentData = data.data || data; + console.log('Processed payment data:', paymentData); var statusContainer = document.getElementById('breez-payment-status'); - - if (!statusContainer) return; - + if (!statusContainer) { + console.log('Status container not found'); + return; + } if (paymentData.status === 'SUCCEEDED' || paymentData.status === 'WAITING_CONFIRMATION') { + console.log('Payment successful, updating UI'); clearInterval(statusCheckInterval); statusContainer.innerHTML = `
@@ -168,8 +176,13 @@ function checkPaymentStatus() {
`; // Reload page after successful payment - setTimeout(() => window.location.reload(), 2000); + console.log('Scheduling page reload'); + setTimeout(() => { + console.log('Reloading page'); + window.location.reload(); + }, 2000); } else if (paymentData.status === 'FAILED') { + console.log('Payment failed, updating UI'); clearInterval(statusCheckInterval); statusContainer.innerHTML = `
@@ -178,7 +191,7 @@ function checkPaymentStatus() {
`; } else { - // For PENDING or any other status + console.log('Payment pending, updating UI'); statusContainer.innerHTML = `

@@ -187,15 +200,22 @@ function checkPaymentStatus() { `; } }) - .catch(error => console.error('Error checking payment status:', error)); + .catch(error => { + console.error('Error checking payment status:', error); + // Try to get more detailed error information + if (error.response) { + console.error('Error response:', error.response); + } + }); } +// Initial check +console.log('Starting payment status checks'); +checkPaymentStatus(); + // Check payment status every 5 seconds var statusCheckInterval = setInterval(checkPaymentStatus, 5000); -// Initial check -checkPaymentStatus(); - // Copy invoice functionality var copyButton = document.querySelector('.breez-copy-button'); if (copyButton) {