bank trnasfer deteiasl udaptes and issues fixed

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-20 02:15:46 +00:00
parent 9b93d22d22
commit 4996e2e1aa
6 changed files with 299 additions and 100 deletions

View File

@@ -87,7 +87,7 @@ class PaymentMethodConfigSerializer(serializers.ModelSerializer):
fields = [
'id', 'country_code', 'payment_method', 'payment_method_display',
'is_enabled', 'display_name', 'instructions',
'bank_name', 'account_number', 'swift_code',
'bank_name', 'account_title', 'account_number', 'routing_number', 'swift_code', 'iban',
'wallet_type', 'wallet_id', 'sort_order'
]
read_only_fields = ['id']

View File

@@ -642,34 +642,154 @@ class AdminBillingViewSet(viewsets.ViewSet):
return Response({'results': data})
def approve_payment(self, request, pk):
"""Approve a pending payment"""
"""Approve a pending payment - activates account, subscription, and adds credits"""
from django.db import transaction
from igny8_core.business.billing.models import Payment
from igny8_core.modules.billing.services import CreditService
import logging
logger = logging.getLogger(__name__)
try:
payment = Payment.objects.get(pk=pk, status='pending_approval')
payment.status = 'completed'
payment.processed_at = timezone.now()
payment.save()
# If payment has an invoice, mark it as paid
if payment.invoice:
payment.invoice.status = 'paid'
payment.invoice.paid_at = timezone.now()
payment.invoice.save()
return Response({'success': True, 'message': 'Payment approved'})
with transaction.atomic():
# Get payment with related objects
payment = Payment.objects.select_related(
'invoice',
'invoice__subscription',
'invoice__subscription__plan',
'account',
'account__subscription',
'account__subscription__plan',
'account__plan'
).get(pk=pk, status='pending_approval')
admin_notes = request.data.get('notes', '')
# 1. Update Payment status
payment.status = 'succeeded'
payment.processed_at = timezone.now()
payment.approved_by = request.user
payment.approved_at = timezone.now()
if admin_notes:
payment.admin_notes = admin_notes
payment.save()
invoice = payment.invoice
account = payment.account
# 2. Mark invoice as paid
if invoice:
invoice.status = 'paid'
invoice.paid_at = timezone.now()
invoice.save()
# 3. Get and activate subscription
subscription = None
if invoice and hasattr(invoice, 'subscription') and invoice.subscription:
subscription = invoice.subscription
elif account and hasattr(account, 'subscription'):
try:
subscription = account.subscription
except Exception:
pass
if subscription:
subscription.status = 'active'
subscription.external_payment_id = payment.manual_reference
subscription.save(update_fields=['status', 'external_payment_id'])
# 4. CRITICAL: Set account status to active
account.status = 'active'
account.save(update_fields=['status'])
# 5. Add credits if plan has included credits
credits_added = 0
try:
plan = None
if subscription and subscription.plan:
plan = subscription.plan
elif account and account.plan:
plan = account.plan
if plan and plan.included_credits > 0:
credits_added = plan.included_credits
CreditService.add_credits(
account=account,
amount=credits_added,
transaction_type='subscription',
description=f'{plan.name} plan credits - Invoice {invoice.invoice_number if invoice else "N/A"}',
metadata={
'subscription_id': subscription.id if subscription else None,
'invoice_id': invoice.id if invoice else None,
'payment_id': payment.id,
'plan_id': plan.id,
'approved_by': request.user.email
}
)
except Exception as credit_error:
logger.error(f'Credit addition failed for payment {payment.id}: {credit_error}', exc_info=True)
# Don't fail the approval if credits fail - account is still activated
logger.info(
f'Payment approved: Payment {payment.id}, Account {account.id} set to active, '
f'{credits_added} credits added'
)
# 6. Send approval email
try:
from igny8_core.business.billing.services.email_service import BillingEmailService
BillingEmailService.send_payment_approved_email(payment, account, subscription)
except Exception as e:
logger.error(f'Failed to send payment approved email: {str(e)}')
return Response({
'success': True,
'message': 'Payment approved. Account activated.',
'payment': {
'id': payment.id,
'status': payment.status,
'account_status': account.status,
'credits_added': credits_added
}
})
except Payment.DoesNotExist:
return Response({'error': 'Payment not found or not pending'}, status=404)
except Exception as e:
logger.error(f'Error approving payment {pk}: {str(e)}', exc_info=True)
return Response({'error': f'Failed to approve payment: {str(e)}'}, status=500)
def reject_payment(self, request, pk):
"""Reject a pending payment"""
from igny8_core.business.billing.models import Payment
import logging
logger = logging.getLogger(__name__)
try:
payment = Payment.objects.get(pk=pk, status='pending_approval')
payment = Payment.objects.select_related('account').get(pk=pk, status='pending_approval')
rejection_reason = request.data.get('reason', 'Rejected by admin')
payment.status = 'failed'
payment.failed_at = timezone.now()
payment.failure_reason = request.data.get('reason', 'Rejected by admin')
payment.failure_reason = rejection_reason
payment.approved_by = request.user
payment.approved_at = timezone.now()
payment.admin_notes = rejection_reason
payment.save()
# Update account status to allow retry (if not already active)
account = payment.account
if account and account.status != 'active':
account.status = 'pending_payment'
account.save(update_fields=['status'])
logger.info(f'Payment rejected: Payment {payment.id}, Reason: {rejection_reason}')
# Send rejection email
try:
from igny8_core.business.billing.services.email_service import BillingEmailService
BillingEmailService.send_payment_rejected_email(payment, account, rejection_reason)
except Exception as e:
logger.error(f'Failed to send payment rejected email: {str(e)}')
return Response({'success': True, 'message': 'Payment rejected'})
except Payment.DoesNotExist:
return Response({'error': 'Payment not found or not pending'}, status=404)