From 549868e3bf5f7d3f7ae51c9f6a41e39cd271ceb5 Mon Sep 17 00:00:00 2001 From: wrongecho Date: Tue, 10 Sep 2024 20:26:16 +0100 Subject: [PATCH] Stripe - Client pays removal - Complete removal of client paying Stripe fees feature - Add PHP error logging to the Stripe payment process --- database_updates.php | 12 ++- database_version.php | 2 +- db.sql | 1 - get_settings.php | 1 - guest_ajax.php | 8 -- guest_pay_invoice_stripe.php | 74 +++----------- guest_view_invoice.php | 13 +-- post/invoice.php | 3 + post/setting.php | 3 +- settings_online_payment.php | 185 ++++++++++++++++------------------- 10 files changed, 114 insertions(+), 188 deletions(-) diff --git a/database_updates.php b/database_updates.php index 7041c1f7..a6eab3c7 100644 --- a/database_updates.php +++ b/database_updates.php @@ -2159,10 +2159,16 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.4.8'"); } - // if (CURRENT_DATABASE_VERSION == '1.4.8') { - // // Insert queries here required to update to DB version 1.4.9 + if (CURRENT_DATABASE_VERSION == '1.4.8') { + mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_stripe_client_pays_fees`"); + + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.4.9'"); + } + + // if (CURRENT_DATABASE_VERSION == '1.4.9') { + // // Insert queries here required to update to DB version 1.5.0 // // Then, update the database to the next sequential version - // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.4.9'"); + // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.5.0'"); // } } else { diff --git a/database_version.php b/database_version.php index 7ff2cbea..91793152 100644 --- a/database_version.php +++ b/database_version.php @@ -5,4 +5,4 @@ * It is used in conjunction with database_updates.php */ -DEFINE("LATEST_DATABASE_VERSION", "1.4.8"); +DEFINE("LATEST_DATABASE_VERSION", "1.4.9"); diff --git a/db.sql b/db.sql index a2f90caf..cd8d9b2b 100644 --- a/db.sql +++ b/db.sql @@ -1513,7 +1513,6 @@ CREATE TABLE `settings` ( `config_ai_url` varchar(250) DEFAULT NULL, `config_ai_api_key` varchar(250) DEFAULT NULL, `config_stripe_flat_fee` decimal(15,2) NOT NULL DEFAULT 0.30, - `config_stripe_client_pays_fees` tinyint(1) NOT NULL DEFAULT 0, `config_azure_client_id` varchar(200) DEFAULT NULL, `config_azure_client_secret` varchar(200) DEFAULT NULL, `config_module_enable_itdoc` tinyint(1) NOT NULL DEFAULT 1, diff --git a/get_settings.php b/get_settings.php index 46902edd..eda76869 100644 --- a/get_settings.php +++ b/get_settings.php @@ -94,7 +94,6 @@ $config_stripe_expense_vendor = intval($row['config_stripe_expense_vendor']); $config_stripe_expense_category = intval($row['config_stripe_expense_category']); $config_stripe_percentage_fee = floatval($row['config_stripe_percentage_fee']); $config_stripe_flat_fee = floatval($row['config_stripe_flat_fee']); -$config_stripe_client_pays_fees = intval($row['config_stripe_client_pays_fees']); // AI Provider Details $config_ai_enable = intval($row['config_ai_enable']); diff --git a/guest_ajax.php b/guest_ajax.php index 58e3133c..cec4ecc7 100644 --- a/guest_ajax.php +++ b/guest_ajax.php @@ -58,7 +58,6 @@ if (isset($_GET['stripe_create_pi'])) { $config_sql = mysqli_query($mysqli, "SELECT * FROM settings WHERE company_id = 1"); $config_row = mysqli_fetch_array($config_sql); - $config_stripe_client_pays_fees = intval($config_row['config_stripe_client_pays_fees']); $config_stripe_percentage_fee = floatval($config_row['config_stripe_percentage_fee']); $config_stripe_flat_fee = floatval($config_row['config_stripe_flat_fee']); @@ -68,15 +67,8 @@ if (isset($_GET['stripe_create_pi'])) { $amount_paid = floatval($row['amount_paid']); $balance_to_pay = $invoice_amount - $amount_paid; - // Check config to see if client pays fees is enabled - if ($config_stripe_client_pays_fees == 1) { - // Calculate the amount to charge the client - $balance_to_pay = ($balance_to_pay + $config_stripe_flat_fee) / (1 - $config_stripe_percentage_fee); - } - $balance_to_pay = round($balance_to_pay, 2); - if (intval($balance_to_pay) == 0) { exit("No balance outstanding"); } diff --git a/guest_pay_invoice_stripe.php b/guest_pay_invoice_stripe.php index 43c2b24a..9072519d 100644 --- a/guest_pay_invoice_stripe.php +++ b/guest_pay_invoice_stripe.php @@ -10,10 +10,10 @@ function log_to_console($message) { } // Define wording -DEFINE("WORDING_PAYMENT_FAILED", "

There was an error verifying your payment. Please contact us for more information.

"); +DEFINE("WORDING_PAYMENT_FAILED", "

There was an error verifying your payment. Please contact us for more information before attempting payment again.

"); // Setup Stripe -$stripe_vars = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_stripe_enable, config_stripe_publishable, config_stripe_secret, config_stripe_account, config_stripe_expense_vendor, config_stripe_expense_category, config_stripe_percentage_fee, config_stripe_flat_fee, config_stripe_client_pays_fees FROM settings WHERE company_id = 1")); +$stripe_vars = mysqli_fetch_array(mysqli_query($mysqli, "SELECT config_stripe_enable, config_stripe_publishable, config_stripe_secret, config_stripe_account, config_stripe_expense_vendor, config_stripe_expense_category, config_stripe_percentage_fee, config_stripe_flat_fee FROM settings WHERE company_id = 1")); $config_stripe_enable = intval($stripe_vars['config_stripe_enable']); $config_stripe_publishable = nullable_htmlentities($stripe_vars['config_stripe_publishable']); $config_stripe_secret = nullable_htmlentities($stripe_vars['config_stripe_secret']); @@ -22,13 +22,12 @@ $config_stripe_expense_vendor = intval($stripe_vars['config_stripe_expense_vendo $config_stripe_expense_category = intval($stripe_vars['config_stripe_expense_category']); $config_stripe_percentage_fee = floatval($stripe_vars['config_stripe_percentage_fee']); $config_stripe_flat_fee = floatval($stripe_vars['config_stripe_flat_fee']); -$config_stripe_client_pays_fees = intval($stripe_vars['config_stripe_client_pays_fees']); // Check Stripe is configured if ($config_stripe_enable == 0 || $config_stripe_account == 0 || empty($config_stripe_publishable) || empty($config_stripe_secret)) { echo "

Stripe payments not enabled/configured

"; require_once 'guest_footer.php'; - + error_log("Stripe payment error - disabled. Check payments are enabled, Expense account is set, Stripe publishable and secret keys are configured."); exit(); } @@ -56,7 +55,7 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent if (!$sql || mysqli_num_rows($sql) !== 1) { echo "

Oops, something went wrong! Please ensure you have the correct URL and have not already paid this invoice.

"; require_once 'guest_footer.php'; - + error_log("Stripe payment error - Invoice with ID $invoice_id is unknown/not eligible to be paid."); exit(); } @@ -84,16 +83,6 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent $amount_paid = floatval($row['amount_paid']); $balance_to_pay = $invoice_amount - $amount_paid; - if ($config_stripe_client_pays_fees == 1) { - $balance_before_fees = $balance_to_pay; - // See here for passing costs on to client https://support.stripe.com/questions/passing-the-stripe-fee-on-to-customers - // Calculate the amount to charge the client - $balance_to_pay = ($balance_to_pay + $config_stripe_flat_fee) / (1 - $config_stripe_percentage_fee); - // Calculate the fee amount - $gateway_fee = round($balance_to_pay - $balance_before_fees, 2); - - } - //Round balance to pay to 2 decimal places $balance_to_pay = round($balance_to_pay, 2); @@ -143,14 +132,6 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent - - - - Gateway Fees - - - - @@ -215,12 +196,14 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent $pi_obj = \Stripe\PaymentIntent::retrieve($pi_id); if ($pi_obj->client_secret !== $pi_cs) { + error_log("Stripe payment error - Payment intent ID/Secret mismatch for $pi_id"); exit(WORDING_PAYMENT_FAILED); } elseif ($pi_obj->status !== "succeeded") { exit(WORDING_PAYMENT_FAILED); } elseif ($pi_obj->amount !== $pi_obj->amount_received) { // The invoice wasn't paid in full // this should be flagged for manual review as would indicate something weird happening + error_log("Stripe payment error - payment amount does not match amount paid for $pi_id"); exit(WORDING_PAYMENT_FAILED); } @@ -245,6 +228,7 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent LIMIT 1" ); if (!$invoice_sql || mysqli_num_rows($invoice_sql) !== 1) { + error_log("Stripe payment error - Invoice with ID $invoice_id is unknown/not eligible to be paid. PI $pi_id"); exit(WORDING_PAYMENT_FAILED); } @@ -277,24 +261,8 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent $amount_paid_previously = $row['amount_paid']; $balance_to_pay = $invoice_amount - $amount_paid_previously; - // Check config to see if client pays fees is enabled or if should expense it - if ($config_stripe_client_pays_fees == 1) { - $balance_before_fees = $balance_to_pay; - // See here for passing costs on to client https://support.stripe.com/questions/passing-the-stripe-fee-on-to-customers - // Calculate the amount to charge the client - $balance_to_pay = ($balance_to_pay + $config_stripe_flat_fee) / (1 - $config_stripe_percentage_fee); - // Calculate the fee amount - $gateway_fee = round($balance_to_pay - $balance_before_fees, 2); - - // Add as line item to client Invoice - mysqli_query($mysqli,"INSERT INTO invoice_items SET item_name = 'Gateway Fees', item_description = 'Payment Gateway Fees', item_quantity = 1, item_price = $gateway_fee, item_subtotal = $gateway_fee, item_total = $gateway_fee, item_order = 999, item_invoice_id = $invoice_id"); - // Update the Amount on the invoice to include the gateway fee - $new_invoice_amount = $invoice_amount + $gateway_fee; - mysqli_query($mysqli,"UPDATE invoices SET invoice_amount = $new_invoice_amount WHERE invoice_id = $invoice_id"); - } - - // Check to see if Expense Fields are configured and client pays fee is off then create expense - if ($config_stripe_client_pays_fees == 0 && $config_stripe_expense_vendor > 0 && $config_stripe_expense_category > 0) { + // Check to see if Expense Fields are configured to create Stripe payment expense + if ($config_stripe_expense_vendor > 0 && $config_stripe_expense_category > 0) { // Calculate gateway expense fee $gateway_fee = round($balance_to_pay * $config_stripe_percentage_fee + $config_stripe_flat_fee, 2); @@ -307,7 +275,8 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent // Sanity check that the amount paid is exactly the invoice outstanding balance if (intval($balance_to_pay) !== intval($pi_amount_paid)) { - exit("Something went wrong confirming this payment. Please get in touch."); + error_log("Stripe payment error - Invoice balance does not match amount paid for $pi_id"); + exit(WORDING_PAYMENT_FAILED); } // Apply payment @@ -319,11 +288,6 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent mysqli_query($mysqli, "INSERT INTO payments SET payment_date = '$pi_date', payment_amount = $pi_amount_paid, payment_currency_code = '$pi_currency', payment_account_id = $config_stripe_account, payment_method = 'Stripe', payment_reference = 'Stripe - $pi_id', payment_invoice_id = $invoice_id"); mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Paid', history_description = 'Payment added - $ip - $os - $browser', history_invoice_id = $invoice_id"); - // Add Gateway fees to history if applicable - if ($config_stripe_client_pays_fees == 1) { - mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Paid', history_description = 'Gateway fees of $gateway_fee has been billed', history_invoice_id = $invoice_id"); - } - // Notify mysqli_query($mysqli, "INSERT INTO notifications SET notification_type = 'Invoice Paid', notification = 'Invoice $invoice_prefix$invoice_number has been paid - $ip - $os - $browser', notification_action = 'invoice.php?invoice_id=$invoice_id', notification_client_id = $pi_client_id"); @@ -332,9 +296,7 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent if (!$pi_livemode) { $extended_log_desc = '(DEV MODE)'; } - if ($config_stripe_client_pays_fees == 1) { - $extended_log_desc .= ' (Client Pays Fees [' . numfmt_format_currency($currency_format, $gateway_fee, $invoice_currency_code) . ']])'; - } + mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Payment', log_action = 'Create', log_description = 'Stripe payment of $pi_currency $pi_amount_paid against invoice $invoice_prefix$invoice_number - $pi_id $extended_log_desc', log_ip = '$ip', log_user_agent = '$user_agent', log_client_id = $pi_client_id"); @@ -369,22 +331,16 @@ if (isset($_GET['invoice_id'], $_GET['url_key']) && !isset($_GET['payment_intent ]; $mail = addToMailQueue($mysqli, $data); - // Email Logging - if ($mail === true) { - mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Sent', history_description = 'Emailed Receipt!', history_invoice_id = $invoice_id"); - } else { - mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Sent', history_description = 'Email Receipt Failed!', history_invoice_id = $invoice_id"); + // Email logging + mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Sent', history_description = 'Emailed Receipt!', history_invoice_id = $invoice_id"); - mysqli_query($mysqli, "INSERT INTO notifications SET notification_type = 'Mail', notification = 'Failed to send email to $contact_email'"); - mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Mail', log_action = 'Error', log_description = 'Failed to send email to $contact_email regarding $subject. $mail'"); - } } // Redirect user to invoice header('Location: //' . $config_base_url . '/guest_view_invoice.php?invoice_id=' . $pi_invoice_id . '&url_key=' . $invoice_url_key); } else { - echo "

Oops, something went wrong! Please raise a ticket if you believe this is an error.

"; + exit(WORDING_PAYMENT_FAILED); } diff --git a/guest_view_invoice.php b/guest_view_invoice.php index 2621bb91..5397aee3 100644 --- a/guest_view_invoice.php +++ b/guest_view_invoice.php @@ -81,7 +81,6 @@ $config_invoice_footer = nullable_htmlentities($row['config_invoice_footer']); $config_stripe_enable = intval($row['config_stripe_enable']); $config_stripe_percentage_fee = floatval($row['config_stripe_percentage_fee']); $config_stripe_flat_fee = floatval($row['config_stripe_flat_fee']); -$config_stripe_client_pays_fees = intval($row['config_stripe_client_pays_fees']); //Set Currency Format $currency_format = numfmt_create($company_locale, NumberFormatter::CURRENCY); @@ -113,16 +112,6 @@ $amount_paid = floatval($row['amount_paid']); // Calculate the balance owed $balance = $invoice_amount - $amount_paid; -// Calculate Gateway Fee -if ($config_stripe_client_pays_fees == 1) { - $balance_before_fees = $balance; - // See here for passing costs on to client https://support.stripe.com/questions/passing-the-stripe-fee-on-to-customers - // Calculate the amount to charge the client - $balance_to_pay = ($balance + $config_stripe_flat_fee) / (1 - $config_stripe_percentage_fee); - // Calculate the fee amount - $gateway_fee = round($balance_to_pay - $balance_before_fees, 2); -} - //check to see if overdue $invoice_color = $invoice_badge_color; // Default if ($invoice_status !== "Paid" && $invoice_status !== "Draft" && $invoice_status !== "Cancelled") { @@ -170,7 +159,7 @@ if ($balance > 0) { ');">Download - Pay Now + Pay Now diff --git a/post/invoice.php b/post/invoice.php index 34190698..7b596b63 100644 --- a/post/invoice.php +++ b/post/invoice.php @@ -931,6 +931,9 @@ if (isset($_GET['delete_payment'])) { $_SESSION['alert_type'] = "error"; $_SESSION['alert_message'] = "Payment deleted"; + if ($config_stripe_enable) { + $_SESSION['alert_message'] = "Payment deleted - Stripe payments must be manually refunded in Stripe"; + } header("Location: " . $_SERVER["HTTP_REFERER"]); diff --git a/post/setting.php b/post/setting.php index 9b562043..1cee0eb0 100644 --- a/post/setting.php +++ b/post/setting.php @@ -458,9 +458,8 @@ if (isset($_POST['edit_online_payment_settings'])) { $config_stripe_expense_category = intval($_POST['config_stripe_expense_category']); $config_stripe_percentage_fee = floatval($_POST['config_stripe_percentage_fee']) / 100; $config_stripe_flat_fee = floatval($_POST['config_stripe_flat_fee']); - $config_stripe_client_pays_fees = intval($_POST['config_stripe_client_pays_fees']); - mysqli_query($mysqli,"UPDATE settings SET config_stripe_enable = $config_stripe_enable, config_stripe_publishable = '$config_stripe_publishable', config_stripe_secret = '$config_stripe_secret', config_stripe_account = $config_stripe_account, config_stripe_expense_vendor = $config_stripe_expense_vendor, config_stripe_expense_category = $config_stripe_expense_category, config_stripe_percentage_fee = $config_stripe_percentage_fee, config_stripe_flat_fee = $config_stripe_flat_fee, config_stripe_client_pays_fees = $config_stripe_client_pays_fees WHERE company_id = 1"); + mysqli_query($mysqli,"UPDATE settings SET config_stripe_enable = $config_stripe_enable, config_stripe_publishable = '$config_stripe_publishable', config_stripe_secret = '$config_stripe_secret', config_stripe_account = $config_stripe_account, config_stripe_expense_vendor = $config_stripe_expense_vendor, config_stripe_expense_category = $config_stripe_expense_category, config_stripe_percentage_fee = $config_stripe_percentage_fee, config_stripe_flat_fee = $config_stripe_flat_fee WHERE company_id = 1"); //Logging mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Settings', log_action = 'Modify', log_description = '$session_name modified online payment settings', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_user_id = $session_user_id"); diff --git a/settings_online_payment.php b/settings_online_payment.php index bf5418c9..16066f5a 100644 --- a/settings_online_payment.php +++ b/settings_online_payment.php @@ -2,107 +2,69 @@ require_once "inc_all_admin.php"; - ?> -
-
-

Online Payment

-
-
-
- - - -
-
- value="1" id="enableStripeSwitch"> - -
-
- -
"> - -
- -
-
- -
- -
-
- -
- -
-
- -
- -
-
- -
- -
-
- -
- -
-
- -
- - - -
- -
-
- -
- -
- Please click here for the latest Stripe Fees. -
- -
- -
-
- -
- -
- Please click here for the latest Stripe Fees. -
+
+
+

Online Payment

+
+
+ +
- value="1" id="clientPaysFeesSwitch"> - - Note: It is illegal to pass payment gateway fees in certain countries, states and provinces. Please check with your local laws before enabling. Click here for more details. + value="1" id="enableStripeSwitch"> +
-
"> +
"> + +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
@@ -111,7 +73,7 @@ require_once "inc_all_admin.php";
@@ -135,7 +96,7 @@ require_once "inc_all_admin.php";
+
+ See here for the latest Stripe Fees. +
+ +
+ +
+
+ +
+ +
+ See here for the latest Stripe Fees. +
+
-
+
-
+
- + - +