feat(billing): add missing payment methods and configurations
- Added migration to include global payment method configurations for Stripe and PayPal (both disabled). - Ensured existing payment methods like bank transfer and manual payment are correctly configured. - Added database constraints and indexes for improved data integrity in billing models. - Introduced foreign key relationship between CreditTransaction and Payment models. - Added webhook configuration fields to PaymentMethodConfig for future payment gateway integrations. - Updated SignUpFormUnified component to handle payment method selection based on user country and plan. - Implemented PaymentHistory component to display user's payment history with status indicators.
This commit is contained in:
@@ -15,7 +15,8 @@ import PaymentConfirmationModal from './PaymentConfirmationModal';
|
||||
interface Invoice {
|
||||
id: number;
|
||||
invoice_number: string;
|
||||
total_amount: string; // Backend returns 'total_amount' in serialized response
|
||||
total?: string; // For backward compatibility
|
||||
total_amount?: string; // Backend returns 'total_amount'
|
||||
currency: string;
|
||||
status: string;
|
||||
due_date?: string;
|
||||
@@ -65,9 +66,9 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
|
||||
if (response.ok && data.success && data.results?.length > 0) {
|
||||
setInvoice(data.results[0]);
|
||||
|
||||
// Load payment method if available
|
||||
// Load payment method if available - use public endpoint
|
||||
const country = (user?.account as any)?.billing_country || 'US';
|
||||
const pmResponse = await fetch(`${API_BASE_URL}/v1/billing/admin/payment-methods/?country=${country}`, {
|
||||
const pmResponse = await fetch(`${API_BASE_URL}/v1/billing/payment-configs/payment-methods/?country=${country}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -75,8 +76,10 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
|
||||
});
|
||||
|
||||
const pmData = await pmResponse.json();
|
||||
// API returns array directly from DRF Response
|
||||
if (pmResponse.ok && Array.isArray(pmData) && pmData.length > 0) {
|
||||
// Use public endpoint response format
|
||||
if (pmResponse.ok && pmData.success && pmData.results?.length > 0) {
|
||||
setPaymentMethod(pmData.results[0]);
|
||||
} else if (pmResponse.ok && Array.isArray(pmData) && pmData.length > 0) {
|
||||
setPaymentMethod(pmData[0]);
|
||||
}
|
||||
}
|
||||
@@ -123,10 +126,15 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
|
||||
<p className="mt-1 text-sm text-amber-800 dark:text-amber-200">
|
||||
Your account is pending payment. Please complete your payment to activate your subscription.
|
||||
</p>
|
||||
<div className="mt-3">
|
||||
<div className="mt-3 flex gap-2">
|
||||
<Link to="/account/plans">
|
||||
<Button variant="primary" size="sm">
|
||||
View Billing Details
|
||||
Complete Payment
|
||||
</Button>
|
||||
</Link>
|
||||
<Link to="/dashboard">
|
||||
<Button variant="outline" size="sm">
|
||||
Go to Dashboard
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
@@ -251,13 +259,17 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
|
||||
</div>
|
||||
|
||||
{/* Payment Confirmation Modal */}
|
||||
{showPaymentModal && invoice && paymentMethod && (
|
||||
{showPaymentModal && invoice && (
|
||||
<PaymentConfirmationModal
|
||||
isOpen={showPaymentModal}
|
||||
onClose={() => setShowPaymentModal(false)}
|
||||
onSuccess={handlePaymentSuccess}
|
||||
invoice={invoice}
|
||||
paymentMethod={paymentMethod}
|
||||
paymentMethod={paymentMethod || {
|
||||
payment_method: 'bank_transfer',
|
||||
display_name: 'Bank Transfer',
|
||||
country_code: 'US'
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user