payment gateways and plans billing and signup pages refactored

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-07 13:02:53 +00:00
parent ad1756c349
commit ad75fa031e
17 changed files with 4587 additions and 500 deletions

View File

@@ -121,55 +121,9 @@ class RegisterView(APIView):
}
}
# For Stripe payment method with paid plan, create checkout session
payment_method = request.data.get('payment_method', '')
import logging
logger = logging.getLogger(__name__)
logger.info(f"Registration: payment_method={payment_method}, account_status={account.status if account else 'no account'}")
if account and account.status == 'pending_payment' and payment_method == 'stripe':
try:
from igny8_core.business.billing.services.stripe_service import StripeService
stripe_service = StripeService()
logger.info(f"Creating Stripe checkout for account {account.id}, plan {account.plan.name}")
checkout_data = stripe_service.create_checkout_session(
account=account,
plan=account.plan,
)
logger.info(f"Stripe checkout created: {checkout_data}")
response_data['checkout_url'] = checkout_data.get('checkout_url')
response_data['checkout_session_id'] = checkout_data.get('session_id')
except Exception as e:
logger.error(f"Failed to create Stripe checkout session: {e}", exc_info=True)
# Don't fail registration, just log the error
# User can still complete payment from the plans page
# For PayPal payment method with paid plan, create PayPal order
elif account and account.status == 'pending_payment' and payment_method == 'paypal':
try:
from django.conf import settings
from igny8_core.business.billing.services.paypal_service import PayPalService
paypal_service = PayPalService()
frontend_url = getattr(settings, 'FRONTEND_URL', 'https://app.igny8.com')
logger.info(f"Creating PayPal order for account {account.id}, amount {account.plan.price}")
order = paypal_service.create_order(
account=account,
amount=float(account.plan.price),
description=f'{account.plan.name} Plan Subscription',
return_url=f'{frontend_url}/account/plans?paypal=success&plan_id={account.plan.id}',
cancel_url=f'{frontend_url}/account/plans?paypal=cancel',
metadata={
'plan_id': str(account.plan.id),
'type': 'subscription',
}
)
logger.info(f"PayPal order created: {order}")
response_data['checkout_url'] = order.get('approval_url')
response_data['paypal_order_id'] = order.get('order_id')
except Exception as e:
logger.error(f"Failed to create PayPal order: {e}", exc_info=True)
# Don't fail registration, just log the error
# NOTE: Payment checkout is NO LONGER created at registration
# User will complete payment on /account/plans after signup
# This simplifies the signup flow and consolidates all payment handling
return success_response(
data=response_data,
@@ -432,6 +386,77 @@ class RefreshTokenView(APIView):
)
@extend_schema(
tags=['Authentication'],
summary='Get Country List',
description='Returns list of countries for registration country selection'
)
class CountryListView(APIView):
"""Returns list of countries for signup dropdown"""
permission_classes = [permissions.AllowAny] # Public endpoint
def get(self, request):
"""Get list of countries with codes and names"""
# Comprehensive list of countries for billing purposes
countries = [
{'code': 'US', 'name': 'United States'},
{'code': 'GB', 'name': 'United Kingdom'},
{'code': 'CA', 'name': 'Canada'},
{'code': 'AU', 'name': 'Australia'},
{'code': 'DE', 'name': 'Germany'},
{'code': 'FR', 'name': 'France'},
{'code': 'ES', 'name': 'Spain'},
{'code': 'IT', 'name': 'Italy'},
{'code': 'NL', 'name': 'Netherlands'},
{'code': 'BE', 'name': 'Belgium'},
{'code': 'CH', 'name': 'Switzerland'},
{'code': 'AT', 'name': 'Austria'},
{'code': 'SE', 'name': 'Sweden'},
{'code': 'NO', 'name': 'Norway'},
{'code': 'DK', 'name': 'Denmark'},
{'code': 'FI', 'name': 'Finland'},
{'code': 'IE', 'name': 'Ireland'},
{'code': 'PT', 'name': 'Portugal'},
{'code': 'PL', 'name': 'Poland'},
{'code': 'CZ', 'name': 'Czech Republic'},
{'code': 'NZ', 'name': 'New Zealand'},
{'code': 'SG', 'name': 'Singapore'},
{'code': 'HK', 'name': 'Hong Kong'},
{'code': 'JP', 'name': 'Japan'},
{'code': 'KR', 'name': 'South Korea'},
{'code': 'IN', 'name': 'India'},
{'code': 'PK', 'name': 'Pakistan'},
{'code': 'BD', 'name': 'Bangladesh'},
{'code': 'AE', 'name': 'United Arab Emirates'},
{'code': 'SA', 'name': 'Saudi Arabia'},
{'code': 'ZA', 'name': 'South Africa'},
{'code': 'NG', 'name': 'Nigeria'},
{'code': 'EG', 'name': 'Egypt'},
{'code': 'KE', 'name': 'Kenya'},
{'code': 'BR', 'name': 'Brazil'},
{'code': 'MX', 'name': 'Mexico'},
{'code': 'AR', 'name': 'Argentina'},
{'code': 'CL', 'name': 'Chile'},
{'code': 'CO', 'name': 'Colombia'},
{'code': 'PE', 'name': 'Peru'},
{'code': 'MY', 'name': 'Malaysia'},
{'code': 'TH', 'name': 'Thailand'},
{'code': 'VN', 'name': 'Vietnam'},
{'code': 'PH', 'name': 'Philippines'},
{'code': 'ID', 'name': 'Indonesia'},
{'code': 'TR', 'name': 'Turkey'},
{'code': 'RU', 'name': 'Russia'},
{'code': 'UA', 'name': 'Ukraine'},
{'code': 'RO', 'name': 'Romania'},
{'code': 'GR', 'name': 'Greece'},
{'code': 'IL', 'name': 'Israel'},
{'code': 'TW', 'name': 'Taiwan'},
]
# Sort alphabetically by name
countries.sort(key=lambda x: x['name'])
return Response({'countries': countries})
@extend_schema(exclude=True) # Exclude from public API documentation - internal authenticated endpoint
class MeView(APIView):
"""Get current user information."""
@@ -456,5 +481,6 @@ urlpatterns = [
path('refresh/', csrf_exempt(RefreshTokenView.as_view()), name='auth-refresh'),
path('change-password/', ChangePasswordView.as_view(), name='auth-change-password'),
path('me/', MeView.as_view(), name='auth-me'),
path('countries/', CountryListView.as_view(), name='auth-countries'),
]