diff --git a/payments/templates/pages/stripe_checkout.py b/payments/templates/pages/stripe_checkout.py index 7f4a30e0b..9b29c469c 100644 --- a/payments/templates/pages/stripe_checkout.py +++ b/payments/templates/pages/stripe_checkout.py @@ -5,6 +5,7 @@ import frappe from frappe import _ from frappe.utils import cint, fmt_money +from payments.utils import check_payment_status from payments.payment_gateways.doctype.stripe_settings.stripe_settings import ( get_gateway_controller, @@ -32,6 +33,20 @@ def get_context(context): if not (set(expected_keys) - set(list(frappe.form_dict))): for key in expected_keys: context[key] = frappe.form_dict[key] + + # Check if payment already completed + if check_payment_status( + context.reference_doctype, + context.reference_docname + ): + frappe.redirect_to_message( + _('Payment Completed'), + _('This payment request has already been processed'), + http_status_code=400 + ) + frappe.local.flags.redirect_location = frappe.local.response.location + raise frappe.Redirect + gateway_controller = get_gateway_controller( context.reference_doctype, context.reference_docname, context.payment_gateway ) @@ -73,6 +88,10 @@ def get_header_image(doc, gateway_controller): def make_payment(stripe_token_id, data, reference_doctype=None, reference_docname=None, payment_gateway=None): data = json.loads(data) + # Check if payment already completed Redundancy Safeguard + if check_payment_status(reference_doctype, reference_docname): + frappe.throw(_('This payment has already been completed')) + data.update({"stripe_token_id": stripe_token_id}) gateway_controller = get_gateway_controller(reference_doctype, reference_docname, payment_gateway) diff --git a/payments/utils/__init__.py b/payments/utils/__init__.py index 1a494cb7f..fed2abd5e 100644 --- a/payments/utils/__init__.py +++ b/payments/utils/__init__.py @@ -3,6 +3,7 @@ create_payment_gateway, delete_custom_fields, erpnext_app_import_guard, + check_payment_status, get_payment_gateway_controller, make_custom_fields, ) diff --git a/payments/utils/utils.py b/payments/utils/utils.py index 64e79a99d..79de007a3 100644 --- a/payments/utils/utils.py +++ b/payments/utils/utils.py @@ -26,6 +26,17 @@ def get_payment_gateway_controller(payment_gateway): frappe.throw(_("{0} Settings not found").format(payment_gateway)) +def check_payment_status(reference_doctype, reference_docname): + """Verify if payment request is already completed""" + try: + doc = frappe.get_doc(reference_doctype, reference_docname) + return doc.status in ['Paid'] + except frappe.DoesNotExistError: + frappe.throw(_("Payment Request not found")) + except Exception as e: + frappe.log_error(_("Payment status check failed"), e) + + @frappe.whitelist(allow_guest=True, xss_safe=True) def get_checkout_url(**kwargs): try: