This commit is contained in:
IGNY8 VPS (Salman)
2025-12-08 07:33:37 +00:00
parent d144f5d19a
commit 42d04fb7f2
3 changed files with 21 additions and 47 deletions

View File

@@ -288,21 +288,14 @@ class RegisterSerializer(serializers.Serializer):
from igny8_core.business.billing.models import CreditTransaction from igny8_core.business.billing.models import CreditTransaction
with transaction.atomic(): with transaction.atomic():
# ALWAYS assign Free Trial plan for simple signup # ALWAYS assign the existing free plan for simple signup
# Ignore plan_id parameter - this is for free trial signups only # No fallbacks: if free plan is misconfigured, surface error immediately
try: try:
plan = Plan.objects.get(slug='free-trial', is_active=True) plan = Plan.objects.get(slug='free', is_active=True)
except Plan.DoesNotExist: except Plan.DoesNotExist:
# Fallback to 'free' if free-trial doesn't exist raise serializers.ValidationError({
try: "plan": "Free plan not configured. Please contact support."
plan = Plan.objects.get(slug='free', is_active=True) })
except Plan.DoesNotExist:
# Last fallback: get cheapest active plan
plan = Plan.objects.filter(is_active=True).order_by('price').first()
if not plan:
raise serializers.ValidationError({
"plan": "Free trial plan not configured. Please contact support."
})
# Generate account name if not provided # Generate account name if not provided
account_name = validated_data.get('account_name') account_name = validated_data.get('account_name')
@@ -364,7 +357,7 @@ class RegisterSerializer(serializers.Serializer):
transaction_type='subscription', transaction_type='subscription',
amount=trial_credits, amount=trial_credits,
balance_after=trial_credits, balance_after=trial_credits,
description=f'Free trial credits from {plan.name}', description=f'Free plan credits from {plan.name}',
metadata={ metadata={
'plan_slug': plan.slug, 'plan_slug': plan.slug,
'registration': True, 'registration': True,

View File

@@ -1,28 +1,14 @@
""" """Billing routes including bank transfer confirmation and credit endpoints."""
URL patterns for business billing module (invoices, payments, credit packages)
"""
from django.urls import path, include from django.urls import path, include
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from .views import ( from .views import BillingViewSet
InvoiceViewSet,
PaymentViewSet,
CreditPackageViewSet,
CreditTransactionViewSet,
AdminBillingViewSet,
AccountPaymentMethodViewSet,
BillingViewSet,
)
from igny8_core.modules.billing.views import ( from igny8_core.modules.billing.views import (
CreditBalanceViewSet, CreditBalanceViewSet,
CreditUsageViewSet, CreditUsageViewSet,
CreditTransactionViewSet,
) )
router = DefaultRouter() router = DefaultRouter()
router.register(r'invoices', InvoiceViewSet, basename='invoice')
router.register(r'payments', PaymentViewSet, basename='payment')
router.register(r'credit-packages', CreditPackageViewSet, basename='credit-package')
router.register(r'transactions', CreditTransactionViewSet, basename='transaction')
router.register(r'payment-methods', AccountPaymentMethodViewSet, basename='payment-method')
router.register(r'admin', BillingViewSet, basename='billing-admin') router.register(r'admin', BillingViewSet, basename='billing-admin')
# Canonical credits endpoints (unified billing) # Canonical credits endpoints (unified billing)
router.register(r'credits/balance', CreditBalanceViewSet, basename='credit-balance') router.register(r'credits/balance', CreditBalanceViewSet, basename='credit-balance')
@@ -30,7 +16,5 @@ router.register(r'credits/usage', CreditUsageViewSet, basename='credit-usage')
router.register(r'credits/transactions', CreditTransactionViewSet, basename='credit-transactions') router.register(r'credits/transactions', CreditTransactionViewSet, basename='credit-transactions')
urlpatterns = [ urlpatterns = [
# Country/config-driven available methods (legacy alias)
path('payment-methods/available/', PaymentViewSet.as_view({'get': 'available_methods'}), name='payment-methods-available'),
path('', include(router.urls)), path('', include(router.urls)),
] ]

View File

@@ -2,9 +2,6 @@ from django.urls import path
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from .views import AdminBillingViewSet from .views import AdminBillingViewSet
from igny8_core.business.billing.views import (
AdminBillingViewSet as BillingAdminViewSet,
)
router = DefaultRouter() router = DefaultRouter()
@@ -13,27 +10,27 @@ urlpatterns = [
path('users/', AdminBillingViewSet.as_view({'get': 'list_users'}), name='admin-users-list'), path('users/', AdminBillingViewSet.as_view({'get': 'list_users'}), name='admin-users-list'),
path('users/<int:user_id>/adjust-credits/', AdminBillingViewSet.as_view({'post': 'adjust_credits'}), name='admin-adjust-credits'), path('users/<int:user_id>/adjust-credits/', AdminBillingViewSet.as_view({'post': 'adjust_credits'}), name='admin-adjust-credits'),
path('credit-costs/', AdminBillingViewSet.as_view({'get': 'list_credit_costs', 'post': 'update_credit_costs'}), name='admin-credit-costs'), path('credit-costs/', AdminBillingViewSet.as_view({'get': 'list_credit_costs', 'post': 'update_credit_costs'}), name='admin-credit-costs'),
# Unified admin billing endpoints (alias legacy /billing/admin/* under /admin/billing/*) # Unified admin billing endpoints (legacy aliases routed to AdminBillingViewSet)
path('billing/invoices/', BillingAdminViewSet.as_view({'get': 'invoices'}), name='admin-billing-invoices'), path('billing/invoices/', AdminBillingViewSet.as_view({'get': 'invoices'}), name='admin-billing-invoices'),
path('billing/payments/', BillingAdminViewSet.as_view({'get': 'payments'}), name='admin-billing-payments'), path('billing/payments/', AdminBillingViewSet.as_view({'get': 'payments'}), name='admin-billing-payments'),
path('billing/pending_payments/', BillingAdminViewSet.as_view({'get': 'pending_payments'}), name='admin-billing-pending-payments'), path('billing/pending_payments/', AdminBillingViewSet.as_view({'get': 'pending_payments'}), name='admin-billing-pending-payments'),
path('billing/<int:pk>/approve_payment/', BillingAdminViewSet.as_view({'post': 'approve_payment'}), name='admin-billing-approve-payment'), path('billing/<int:pk>/approve_payment/', AdminBillingViewSet.as_view({'post': 'approve_payment'}), name='admin-billing-approve-payment'),
path('billing/<int:pk>/reject_payment/', BillingAdminViewSet.as_view({'post': 'reject_payment'}), name='admin-billing-reject-payment'), path('billing/<int:pk>/reject_payment/', AdminBillingViewSet.as_view({'post': 'reject_payment'}), name='admin-billing-reject-payment'),
path('billing/payment-method-configs/', BillingAdminViewSet.as_view({'get': 'payment_method_configs', 'post': 'payment_method_configs'}), name='admin-billing-payment-method-configs'), path('billing/payment-method-configs/', AdminBillingViewSet.as_view({'get': 'payment_method_configs', 'post': 'payment_method_configs'}), name='admin-billing-payment-method-configs'),
path('billing/payment-method-configs/<int:pk>/', BillingAdminViewSet.as_view({ path('billing/payment-method-configs/<int:pk>/', AdminBillingViewSet.as_view({
'get': 'payment_method_config', 'get': 'payment_method_config',
'patch': 'payment_method_config', 'patch': 'payment_method_config',
'put': 'payment_method_config', 'put': 'payment_method_config',
'delete': 'payment_method_config', 'delete': 'payment_method_config',
}), name='admin-billing-payment-method-config'), }), name='admin-billing-payment-method-config'),
path('billing/account-payment-methods/', BillingAdminViewSet.as_view({'get': 'account_payment_methods', 'post': 'account_payment_methods'}), name='admin-billing-account-payment-methods'), path('billing/account-payment-methods/', AdminBillingViewSet.as_view({'get': 'account_payment_methods', 'post': 'account_payment_methods'}), name='admin-billing-account-payment-methods'),
path('billing/account-payment-methods/<int:pk>/', BillingAdminViewSet.as_view({ path('billing/account-payment-methods/<int:pk>/', AdminBillingViewSet.as_view({
'get': 'account_payment_method', 'get': 'account_payment_method',
'patch': 'account_payment_method', 'patch': 'account_payment_method',
'put': 'account_payment_method', 'put': 'account_payment_method',
'delete': 'account_payment_method', 'delete': 'account_payment_method',
}), name='admin-billing-account-payment-method'), }), name='admin-billing-account-payment-method'),
path('billing/account-payment-methods/<int:pk>/set_default/', BillingAdminViewSet.as_view({'post': 'set_default_account_payment_method'}), name='admin-billing-account-payment-method-set-default'), path('billing/account-payment-methods/<int:pk>/set_default/', AdminBillingViewSet.as_view({'post': 'set_default_account_payment_method'}), name='admin-billing-account-payment-method-set-default'),
] ]
urlpatterns += router.urls urlpatterns += router.urls