You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

137 lines
5.4 KiB

"""
Notification Handler Module
This module handles failed payment notifications and ticket creation.
"""
import logging
from payment_services.payment_service import create_customer_friendly_message
from notification_service import NotificationService
logger = logging.getLogger(__name__)
def handle_failed_payment_notification(payment_record, error_details: str, cust_stripe_details: dict, payment_type: str = "batch"):
"""
Handle notification and ticket creation for failed payments.
Args:
payment_record: Database payment record (Payments or SinglePayments)
error_details: Error message details
payment_type: Type of payment ("batch" or "single")
"""
# Import here to avoid circular dependencies
from splynx import Splynx, SPLYNX_URL, SPLYNX_KEY, SPLYNX_SECRET
from config import Config
try:
# Initialize services
splynx = Splynx(url=SPLYNX_URL, key=SPLYNX_KEY, secret=SPLYNX_SECRET)
notification_service = NotificationService()
# Get customer information from Splynx
try:
customer_data = splynx.Customer(payment_record.Splynx_ID)
customer_name = customer_data.get('name', 'Unknown Customer') if customer_data != 'unknown' else 'Unknown Customer'
except:
customer_name = 'Unknown Customer'
# Prepare payment data for notification
payment_data = {
'payment_id': payment_record.id,
'splynx_id': payment_record.Splynx_ID,
'amount': abs(payment_record.Payment_Amount),
'error': error_details,
'payment_method': payment_record.Payment_Method or 'Unknown',
'customer_name': customer_name,
'payment_type': payment_type,
'stripe_customer_id': payment_record.Stripe_Customer_ID,
'payment_intent': payment_record.Payment_Intent
}
# Revert pending invoices back to "not_paid" (only in live mode)
from payment_services.payment_service import find_set_pending_splynx_invoices_to_unpaid
updated_invoices = find_set_pending_splynx_invoices_to_unpaid(splynx, payment_record.Splynx_ID)
if updated_invoices:
logger.info(f"Payment failure: pending invoices reverted to not_paid for Splynx ID {payment_record.Splynx_ID}")
else:
logger.warning(f"No pending invoices to revert for Splynx ID {payment_record.Splynx_ID}")
# Send email notification
email_sent = notification_service.send_payment_failure_notification(payment_data)
if email_sent:
logger.info(f"Payment failure email sent for payment {payment_record.id}")
else:
logger.error(f"Failed to send payment failure email for payment {payment_record.id}")
# Create Splynx ticket
ticket_subject = f"Payment Failure - Customer {payment_record.Splynx_ID} - ${abs(payment_record.Payment_Amount):.2f}"
internal_message = f"""
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<body>
<div>Payment processing has failed for customer {customer_name} (ID: {payment_record.Splynx_ID}).</div>
<div><br></div>
<div><strong>Payment Details:</strong></div>
<ul>
<li>Payment ID: {payment_record.id} ({payment_type})</li>
<li>Amount: ${abs(payment_record.Payment_Amount):.2f} AUD</li>
<li>Payment Method: {payment_record.Payment_Method or 'Unknown'}</li>
<li>Stripe Customer: {payment_record.Stripe_Customer_ID}</li>
<li>Payment Intent: {payment_record.Payment_Intent or 'N/A'}</li>
</ul>
<div><br></div>
<div><strong>Error Information:</strong></div>
<div>{error_details}</div>
<div><br></div>
<div>This ticket was automatically created by the Plutus Payment System.</div>
</body>
</html>
"""
# Create customer-friendly message
payment_data_for_msg = {
'amount': payment_data['amount'],
'splynx_id': payment_data['splynx_id'],
'pi_json': payment_record.PI_JSON,
'stripe_customer_id': payment_record.Stripe_Customer_ID,
'cust_stripe_details': cust_stripe_details
}
customer_message = create_customer_friendly_message(payment_data_for_msg, error_details)
ticket_result = splynx.create_ticket(
customer_id=payment_record.Splynx_ID,
subject=ticket_subject,
priority='medium',
type_id=1,
group_id=7,
status_id=1,
)
if ticket_result.get('success'):
logger.info(f"Splynx ticket created: #{ticket_result['ticket_id']} for payment {payment_record.id}")
# Add internal note
splynx.add_ticket_message(
ticket_id=ticket_result['ticket_id'],
message=internal_message,
is_admin=False,
hide_for_customer=True,
message_type="note"
)
# Add customer-visible message
splynx.add_ticket_message(
ticket_id=ticket_result['ticket_id'],
message=customer_message,
is_admin=False,
hide_for_customer=False,
message_type="message"
)
else:
logger.error(f"Failed to create Splynx ticket for payment {payment_record.id}: {ticket_result.get('error')}")
except Exception as e:
logger.error(f"Error handling failed payment notification for payment {payment_record.id}: {e}")