diff --git a/database_updates.php b/database_updates.php index dab71d07..c8bfe440 100644 --- a/database_updates.php +++ b/database_updates.php @@ -3675,10 +3675,10 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.0'"); } - if (CURRENT_DATABASE_VERSION == '2.2.0') { - mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_quote_id` INT(11) NOT NULL DEFAULT 0 AFTER `ticket_asset_id`"); - mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.1'"); - } + if (CURRENT_DATABASE_VERSION == '2.2.0') { + mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_quote_id` INT(11) NOT NULL DEFAULT 0 AFTER `ticket_asset_id`"); + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.1'"); + } if (CURRENT_DATABASE_VERSION == '2.2.1') { mysqli_query($mysqli, "CREATE TABLE `ai_providers` ( @@ -3691,16 +3691,21 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { PRIMARY KEY (`ai_provider_id`) )"); - mysqli_query($mysqli, "CREATE TABLE `ai_models` ( - `ai_model_id` INT(11) NOT NULL AUTO_INCREMENT, - `ai_model_name` VARCHAR(200) NOT NULL, - `ai_model_prompt` TEXT DEFAULT NULL, - `ai_model_use_case` VARCHAR(200) DEFAULT NULL, - `ai_model_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `ai_model_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, - `ai_model_ai_provider_id` INT(11) NOT NULL, - PRIMARY KEY (`ai_model_id`) - )"); + mysqli_query($mysqli, " + CREATE TABLE `ai_models` ( + `ai_model_id` INT(11) NOT NULL AUTO_INCREMENT, + `ai_model_name` VARCHAR(200) NOT NULL, + `ai_model_prompt` TEXT DEFAULT NULL, + `ai_model_use_case` VARCHAR(200) DEFAULT NULL, + `ai_model_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `ai_model_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, + `ai_model_ai_provider_id` INT(11) NOT NULL, + PRIMARY KEY (`ai_model_id`), + FOREIGN KEY (`ai_model_ai_provider_id`) + REFERENCES `ai_providers`(`ai_provider_id`) + ON DELETE CASCADE + ) + "); mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.2'"); } @@ -3710,7 +3715,6 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { `payment_method_id` INT(11) NOT NULL AUTO_INCREMENT, `payment_method_name` VARCHAR(200) NOT NULL, `payment_method_description` VARCHAR(250) DEFAULT NULL, - `payment_method_provider_id` INT(11) DEFAULT 0, `payment_method_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `payment_method_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`payment_method_id`) @@ -3736,16 +3740,31 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { mysqli_query($mysqli, "CREATE TABLE `client_saved_payment_methods` ( `saved_payment_id` INT(11) NOT NULL AUTO_INCREMENT, - `saved_payment_provider_client` VARCHAR(200) NOT NULL, `saved_payment_provider_method` VARCHAR(200) NOT NULL, - `saved_payment_details` VARCHAR(200) DEFAULT NULL, + `saved_payment_description` VARCHAR(200) DEFAULT NULL, `saved_payment_client_id` INT(11) NOT NULL, `saved_payment_provider_id` INT(11) NOT NULL, `saved_payment_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `saved_payment_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`saved_payment_id`) + PRIMARY KEY (`saved_payment_id`), + FOREIGN KEY (`saved_payment_client_id`) REFERENCES clients(`client_id`) ON DELETE CASCADE, + FOREIGN KEY (`saved_payment_provider_id`) REFERENCES payment_providers(`payment_provider_id`) ON DELETE CASCADE )"); + mysqli_query($mysqli, "CREATE TABLE `client_payment_provider` ( + `client_id` INT(11) NOT NULL, + `payment_provider_id` INT(11) NOT NULL, + `payment_provider_client` VARCHAR(200) NOT NULL, + `client_payment_provider_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`client_id`, `payment_provider_id`), + FOREIGN KEY (`client_id`) REFERENCES clients(`client_id`) ON DELETE CASCADE, + FOREIGN KEY (`payment_provider_id`) REFERENCES payment_providers(`payment_provider_id`) ON DELETE CASCADE + )"); + + mysqli_query($mysqli, "ALTER TABLE `recurring_payments` ADD `recurring_payment_saved_payment_id` INT(11) DEFAULT NULL AFTER `recurring_payment_recurring_invoice_id`"); + + mysqli_query($mysqli, "ALTER TABLE `recurring_payments` ADD CONSTRAINT `fk_recurring_saved_payment` FOREIGN KEY (`recurring_payment_saved_payment_id`) REFERENCES `client_saved_payment_methods`(`saved_payment_id`) ON DELETE CASCADE"); + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '2.2.3'"); } diff --git a/db.sql b/db.sql index 9985423c..82716e33 100644 --- a/db.sql +++ b/db.sql @@ -53,7 +53,9 @@ CREATE TABLE `ai_models` ( `ai_model_created_at` datetime NOT NULL DEFAULT current_timestamp(), `ai_model_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), `ai_model_ai_provider_id` int(11) NOT NULL, - PRIMARY KEY (`ai_model_id`) + PRIMARY KEY (`ai_model_id`), + KEY `ai_model_ai_provider_id` (`ai_model_ai_provider_id`), + CONSTRAINT `ai_models_ibfk_1` FOREIGN KEY (`ai_model_ai_provider_id`) REFERENCES `ai_providers` (`ai_provider_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -486,26 +488,6 @@ CREATE TABLE `certificates` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; --- --- Table structure for table `cient_saved_payment_methods` --- - -DROP TABLE IF EXISTS `cient_saved_payment_methods`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `cient_saved_payment_methods` ( - `saved_payment_id` int(11) NOT NULL AUTO_INCREMENT, - `saved_payment_provider_client` varchar(200) NOT NULL, - `saved_payment_provider_method` varchar(200) NOT NULL, - `saved_payment_details` varchar(200) DEFAULT NULL, - `saved_payment_client_id` int(11) NOT NULL, - `saved_payment_provider_id` int(11) NOT NULL, - `saved_payment_created_at` datetime NOT NULL DEFAULT current_timestamp(), - `saved_payment_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), - PRIMARY KEY (`saved_payment_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - -- -- Table structure for table `client_notes` -- @@ -528,6 +510,48 @@ CREATE TABLE `client_notes` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `client_payment_provider` +-- + +DROP TABLE IF EXISTS `client_payment_provider`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `client_payment_provider` ( + `client_id` int(11) NOT NULL, + `payment_provider_id` int(11) NOT NULL, + `payment_provider_client` varchar(200) NOT NULL, + `client_payment_provider_created_at` datetime NOT NULL DEFAULT current_timestamp(), + PRIMARY KEY (`client_id`,`payment_provider_id`), + KEY `payment_provider_id` (`payment_provider_id`), + CONSTRAINT `client_payment_provider_ibfk_1` FOREIGN KEY (`client_id`) REFERENCES `clients` (`client_id`) ON DELETE CASCADE, + CONSTRAINT `client_payment_provider_ibfk_2` FOREIGN KEY (`payment_provider_id`) REFERENCES `payment_providers` (`payment_provider_id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `client_saved_payment_methods` +-- + +DROP TABLE IF EXISTS `client_saved_payment_methods`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `client_saved_payment_methods` ( + `saved_payment_id` int(11) NOT NULL AUTO_INCREMENT, + `saved_payment_provider_method` varchar(200) NOT NULL, + `saved_payment_description` varchar(200) DEFAULT NULL, + `saved_payment_client_id` int(11) NOT NULL, + `saved_payment_provider_id` int(11) NOT NULL, + `saved_payment_created_at` datetime NOT NULL DEFAULT current_timestamp(), + `saved_payment_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), + PRIMARY KEY (`saved_payment_id`), + KEY `saved_payment_client_id` (`saved_payment_client_id`), + KEY `saved_payment_provider_id` (`saved_payment_provider_id`), + CONSTRAINT `client_saved_payment_methods_ibfk_1` FOREIGN KEY (`saved_payment_client_id`) REFERENCES `clients` (`client_id`) ON DELETE CASCADE, + CONSTRAINT `client_saved_payment_methods_ibfk_2` FOREIGN KEY (`saved_payment_provider_id`) REFERENCES `payment_providers` (`payment_provider_id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `client_stripe` -- @@ -1331,7 +1355,6 @@ CREATE TABLE `payment_methods` ( `payment_method_id` int(11) NOT NULL AUTO_INCREMENT, `payment_method_name` varchar(200) NOT NULL, `payment_method_description` varchar(250) DEFAULT NULL, - `payment_method_provider_id` int(11) DEFAULT 0, `payment_method_created_at` datetime NOT NULL DEFAULT current_timestamp(), `payment_method_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), PRIMARY KEY (`payment_method_id`) @@ -1661,7 +1684,10 @@ CREATE TABLE `recurring_payments` ( `recurring_payment_account_id` int(11) NOT NULL, `recurring_payment_recurring_expense_id` int(11) NOT NULL DEFAULT 0, `recurring_payment_recurring_invoice_id` int(11) NOT NULL, - PRIMARY KEY (`recurring_payment_id`) + `recurring_payment_saved_payment_id` int(11) DEFAULT NULL, + PRIMARY KEY (`recurring_payment_id`), + KEY `fk_recurring_saved_payment` (`recurring_payment_saved_payment_id`), + CONSTRAINT `fk_recurring_saved_payment` FOREIGN KEY (`recurring_payment_saved_payment_id`) REFERENCES `client_saved_payment_methods` (`saved_payment_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -2692,4 +2718,4 @@ CREATE TABLE `vendors` ( /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2025-07-07 16:36:58 +-- Dump completed on 2025-07-08 14:06:43 diff --git a/post/admin/admin_saved_payment_method.php b/post/admin/admin_saved_payment_method.php index e697b1f2..42871b0c 100644 --- a/post/admin/admin_saved_payment_method.php +++ b/post/admin/admin_saved_payment_method.php @@ -5,66 +5,65 @@ defined('FROM_POST_HANDLER') || die("Direct file access is not allowed"); if (isset($_GET['delete_saved_payment'])) { validateCSRFToken($_GET['csrf_token']); - if (!$config_stripe_enable) { - $_SESSION['alert_message'] = "Stripe not enabled"; - header("Location: " . $_SERVER["HTTP_REFERER"]); - exit(); - } + $saved_payment_id = intval($_GET['delete_saved_payment']); - $client_id = intval($_GET['client_id']); - $payment_method = sanitizeInput($_GET['pm']); + $sql = mysqli_query($mysqli, " + SELECT + client_saved_payment_methods.saved_payment_id, + client_saved_payment_methods.saved_payment_client_id, + client_saved_payment_methods.saved_payment_provider_id, + client_saved_payment_methods.saved_payment_provider_method, + client_saved_payment_methods.saved_payment_description, + client_payment_provider.payment_provider_client, + payment_providers.payment_provider_name, + payment_providers.payment_provider_private_key + FROM client_saved_payment_methods + LEFT JOIN client_payment_provider + ON client_payment_provider.client_id = client_saved_payment_methods.saved_payment_client_id + AND client_payment_provider.payment_provider_id = client_saved_payment_methods.saved_payment_provider_id + LEFT JOIN payment_providers + ON payment_providers.payment_provider_id = client_saved_payment_methods.saved_payment_provider_id + WHERE client_saved_payment_methods.saved_payment_id = $saved_payment_id" + ); - try { - // Initialize stripe - require_once 'plugins/stripe-php/init.php'; - $stripe = new \Stripe\StripeClient($config_stripe_secret); + $row = mysqli_fetch_array($sql); + $client_id = intval($row['saved_payment_client_id']); + $provider_id = intval($row['saved_payment_provider_id']); + $payment_provider_name = nullable_htmlentities($row['payment_provider_name']); + $saved_payment_description = nullable_htmlentities($row['saved_payment_description']); + $provider_client = nullable_htmlentities($row['payment_provider_client']); + $payment_method = $row['saved_payment_provider_method']; - // Detach PM - $stripe->paymentMethods->detach($payment_method, []); + $private_key = $row['payment_provider_private_key']; + + // Seperate logic for each Payment Provider + if ($payment_provider_name == 'Stripe') { + + try { + // Initialize stripe + require_once 'plugins/stripe-php/init.php'; + $stripe = new \Stripe\StripeClient($private_key); + + // Detach PM + $stripe->paymentMethods->detach($payment_method, []); + + } catch (Exception $e) { + $error = $e->getMessage(); + error_log("Stripe payment error - encountered exception when removing payment method info for $payment_method: $error"); + logApp("Stripe", "error", "Exception removing payment method for $payment_method: $error"); + } - } catch (Exception $e) { - $error = $e->getMessage(); - error_log("Stripe payment error - encountered exception when removing payment method info for $payment_method: $error"); - logApp("Stripe", "error", "Exception removing payment method for $payment_method: $error"); } // Remove payment method from ITFlow - mysqli_query($mysqli, "UPDATE client_stripe SET stripe_pm = NULL WHERE client_id = $client_id LIMIT 1"); + mysqli_query($mysqli, "DELETE FROM client_saved_payment_methods WHERE saved_payment_id = $saved_payment_id"); - // Remove Auto Pay on recurring invoices that are stripe - $sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id"); - - while ($row = mysqli_fetch_array($sql_recurring_invoices)) { - $recurring_invoice_id = intval($row['recurring_invoice_id']); - mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id"); - } + // Remove All Associted Auto Payment Methods on recurring invoices + mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_saved_payment_id = $saved_payment_id"); // Logging & Redirect - logAction("Stripe", "Update", "$session_name deleted saved Stripe payment method (PM: $payment_method)", $client_id); - $_SESSION['alert_message'] = "Payment method removed"; + logAction("Payment Provider", "Update", "$session_name deleted saved payment method $saved_payment_description (PM: $payment_method)", $client_id); + $_SESSION['alert_message'] = "Payment method $saved_payment_description removed"; header("Location: " . $_SERVER["HTTP_REFERER"]); } - -if (isset($_GET['stripe_reset_customer'])) { - validateCSRFToken($_GET['csrf_token']); - - $client_id = intval($_GET['client_id']); - - // Delete the customer id and payment method id stored in ITFlow, allowing the client to set these up again - mysqli_query($mysqli, "DELETE FROM client_stripe WHERE client_id = $client_id"); - - // Remove Auto Pay on recurring invoices that are stripe - $sql_recurring_invoices = mysqli_query($mysqli, "SELECT recurring_invoice_id FROM recurring_invoices WHERE recurring_invoice_client_id = $client_id"); - - while ($row = mysqli_fetch_array($sql_recurring_invoices)) { - $recurring_invoice_id = intval($row['recurring_invoice_id']); - mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe' AND recurring_payment_recurring_invoice_id = $recurring_invoice_id"); - } - - // Logging - logAction("Stripe", "Delete", "$session_name reset Stripe settings for client", $client_id); - - $_SESSION['alert_message'] = "Reset client Stripe settings"; - header("Location: " . $_SERVER["HTTP_REFERER"]); -} \ No newline at end of file