mirror of
https://github.com/itflow-org/itflow
synced 2026-09-02 21:05:13 +00:00
Stripe Invoice Payments
- Add ability to refund Stripe payments rather than just deleting & manually refunding - Limit refunding / deleting payments to Full/3 Sales&Financial permissions, as this is a delete rather than modify action
This commit is contained in:
@@ -119,7 +119,7 @@ if (isset($_GET['invoice_id'])) {
|
||||
|
||||
$sql_history = mysqli_query($mysqli, "SELECT history_created_at, history_description, history_status FROM history WHERE history_invoice_id = $invoice_id ORDER BY history_id DESC");
|
||||
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT account_name, payment_amount, payment_currency_code, payment_date, payment_id,
|
||||
$sql_payments = mysqli_query($mysqli, "SELECT account_name, payment_amount, payment_currency_code, payment_method, payment_date, payment_id,
|
||||
payment_reference FROM payments, accounts WHERE payment_account_id = account_id AND payment_invoice_id = $invoice_id ORDER BY payments.payment_id DESC");
|
||||
|
||||
$sql_tickets = mysqli_query($mysqli, "
|
||||
@@ -681,7 +681,9 @@ if (isset($_GET['invoice_id'])) {
|
||||
<th class="text-end">Amount</th>
|
||||
<th>Reference</th>
|
||||
<th>Account</th>
|
||||
<th></th>
|
||||
<?php if (lookupUserPermission("module_sales") >= 3 && lookupUserPermission("module_financial") >= 3) { ?>
|
||||
<th></th>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -692,6 +694,7 @@ if (isset($_GET['invoice_id'])) {
|
||||
$payment_date = escapeHtml($row['payment_date']);
|
||||
$payment_amount = floatval($row['payment_amount']);
|
||||
$payment_currency_code = escapeHtml($row['payment_currency_code']);
|
||||
$payment_method = escapeHtml($row['payment_method']);
|
||||
$payment_reference = escapeHtml($row['payment_reference']);
|
||||
$account_name = escapeHtml($row['account_name']);
|
||||
|
||||
@@ -701,7 +704,14 @@ if (isset($_GET['invoice_id'])) {
|
||||
<td class="text-end"><?= numfmt_format_currency($currency_format, $payment_amount, $payment_currency_code) ?></td>
|
||||
<td><?= $payment_reference ?></td>
|
||||
<td><?= $account_name ?></td>
|
||||
<td class="text-center"><a class="btn btn-light text-danger confirm-link" href="post.php?delete_payment=<?= $payment_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><i class="fa fa-times"></i></a></td>
|
||||
<?php if (lookupUserPermission("module_sales") >= 3 && lookupUserPermission("module_financial") >= 3) { ?>
|
||||
<td class="text-center">
|
||||
<?php if ($payment_method == "Stripe") { ?>
|
||||
<a class="btn btn-light text-warning confirm-link" title="Refund Payment" href="post.php?refund_payment_stripe=<?= $payment_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><i class="fa fa-undo"></i></a>
|
||||
<?php } ?>
|
||||
<a class="btn btn-light text-danger confirm-link" title="Delete Payment" href="post.php?delete_payment=<?= $payment_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><i class="fa fa-times"></i></a>
|
||||
</td>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
@@ -653,8 +653,8 @@ if (isset($_GET['delete_payment'])) {
|
||||
|
||||
validateCSRFToken();
|
||||
|
||||
enforceUserPermission('module_sales', 2);
|
||||
enforceUserPermission('module_financial', 2);
|
||||
enforceUserPermission('module_sales', 3);
|
||||
enforceUserPermission('module_financial', 3);
|
||||
|
||||
$payment_id = intval($_GET['delete_payment']);
|
||||
|
||||
@@ -689,3 +689,102 @@ if (isset($_GET['delete_payment'])) {
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['refund_payment_stripe'])) {
|
||||
|
||||
validateCSRFToken();
|
||||
|
||||
enforceUserPermission('module_sales', 3);
|
||||
enforceUserPermission('module_financial', 3);
|
||||
|
||||
$payment_id = intval($_GET['refund_payment_stripe']);
|
||||
|
||||
// payments has no client column - the client comes from the invoice the payment sits on
|
||||
$sql = mysqli_query($mysqli,"SELECT invoice_client_id, invoice_number, invoice_prefix, payment_invoice_id FROM payments
|
||||
LEFT JOIN invoices ON payment_invoice_id = invoice_id
|
||||
WHERE payment_id = $payment_id
|
||||
AND payment_method = 'Stripe'
|
||||
LIMIT 1"
|
||||
);
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
$invoice_id = intval($row['payment_invoice_id']);
|
||||
$invoice_prefix = escapeSql($row['invoice_prefix']);
|
||||
$invoice_number = intval($row['invoice_number']);
|
||||
$client_id = intval($row['invoice_client_id']);
|
||||
|
||||
enforceClientAccess();
|
||||
|
||||
// Get Stripe Payment Intent ID
|
||||
$sql = mysqli_query($mysqli,"SELECT payment_reference FROM payments WHERE payment_id = $payment_id LIMIT 1");
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
if (preg_match('/(?<payment_intent>pi_[A-Za-z0-9]+)/', $row['payment_reference'], $matches)) {
|
||||
$stripe_payment_intent_id = $matches['payment_intent'];
|
||||
}
|
||||
|
||||
// Get invoice details
|
||||
$sql = mysqli_query($mysqli,"SELECT client_id, client_name, contact_email, contact_extension, contact_mobile,
|
||||
contact_mobile_country_code, contact_name, contact_phone, contact_phone_country_code,
|
||||
invoice_amount, invoice_currency_code, invoice_number, invoice_prefix, invoice_status,
|
||||
invoice_url_key FROM invoices
|
||||
LEFT JOIN clients ON invoice_client_id = client_id
|
||||
LEFT JOIN contacts ON client_id = contact_client_id AND contact_primary = 1
|
||||
WHERE invoice_id = $invoice_id"
|
||||
);
|
||||
$row = mysqli_fetch_assoc($sql);
|
||||
$invoice_number = intval($row['invoice_number']);
|
||||
$invoice_status = escapeSql($row['invoice_status']);
|
||||
$invoice_amount = floatval($row['invoice_amount']);
|
||||
$invoice_prefix = escapeSql($row['invoice_prefix']);
|
||||
$invoice_number = intval($row['invoice_number']);
|
||||
$invoice_url_key = escapeSql($row['invoice_url_key']);
|
||||
$invoice_currency_code = escapeSql($row['invoice_currency_code']);
|
||||
$client_id = intval($row['client_id']);
|
||||
$client_name = escapeSql($row['client_name']);
|
||||
$contact_name = escapeSql($row['contact_name']);
|
||||
$contact_email = escapeSql($row['contact_email']);
|
||||
$contact_phone = escapeSql(formatPhoneNumber($row['contact_phone'], $row['contact_phone_country_code']));
|
||||
$contact_extension = preg_replace("/[^0-9]/", '',$row['contact_extension']);
|
||||
$contact_mobile = escapeSql(formatPhoneNumber($row['contact_mobile'], $row['contact_mobile_country_code']));
|
||||
|
||||
$stripe_provider = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT payment_provider_private_key FROM payment_providers WHERE payment_provider_name = 'Stripe' LIMIT 1"));
|
||||
if (!$stripe_provider) {
|
||||
exit("Stripe not enabled / configured");
|
||||
}
|
||||
$stripe_secret_key = $stripe_provider['payment_provider_private_key'];
|
||||
|
||||
// Initialize Stripe
|
||||
try {
|
||||
require_once __DIR__ . '/../../includes/stripe_init.php';
|
||||
$stripe = new \Stripe\StripeClient($stripe_secret_key);
|
||||
|
||||
// Refund
|
||||
$refund = $stripe->refunds->create([
|
||||
'payment_intent' => $stripe_payment_intent_id
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
error_log("Stripe refund error - encountered exception during refund for invoice ID $invoice_id / $invoice_prefix$invoice_number: $error");
|
||||
logApp("Stripe", "error", "Exception during refund for invoice ID $invoice_id: $error");
|
||||
flashAlert("Stripe refund failed: $error", 'error');
|
||||
redirect();
|
||||
}
|
||||
|
||||
mysqli_query($mysqli,"DELETE FROM payments WHERE payment_id = $payment_id");
|
||||
|
||||
// Recalculate from what is left rather than from the pre-delete total
|
||||
$invoice_status = updateInvoiceStatusFromPayments($invoice_id);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO history SET history_status = '$invoice_status', history_description = 'Payment $stripe_payment_intent_id deleted and refunded', history_invoice_id = $invoice_id");
|
||||
|
||||
// Log info
|
||||
$extended_log_desc = '';
|
||||
if (!$pi_livemode) {
|
||||
$extended_log_desc = '(DEV MODE)';
|
||||
}
|
||||
logAudit("Invoice", "Edit", "$session_name refunded and deleted Payment $stripe_payment_intent_id on Invoice $invoice_prefix$invoice_number", $client_id, $invoice_id);
|
||||
|
||||
flashAlert("Payment deleted and refunded in Stripe", 'error');
|
||||
|
||||
redirect();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user