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
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}")
|
|
|