import React, { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../components/ui/card'; import { Button } from '../../components/ui/button'; import { Input } from '../../components/ui/input'; import { Label } from '../../components/ui/label'; import { AlertCircle, CheckCircle, Settings as SettingsIcon, RefreshCw, Zap, Edit, Save, X, Copy, Eye, EyeOff, ExternalLink } from 'lucide-react'; import api from '../../utils/api'; import { toast } from 'sonner'; export default function AdminSettings() { const [stripeStatus, setStripeStatus] = useState(null); const [loadingStatus, setLoadingStatus] = useState(true); const [testing, setTesting] = useState(false); const [isEditing, setIsEditing] = useState(false); const [saving, setSaving] = useState(false); // Form state const [formData, setFormData] = useState({ secret_key: '', webhook_secret: '' }); // Show/hide sensitive values const [showSecretKey, setShowSecretKey] = useState(false); const [showWebhookSecret, setShowWebhookSecret] = useState(false); useEffect(() => { fetchStripeStatus(); }, []); const fetchStripeStatus = async () => { setLoadingStatus(true); try { const response = await api.get('/admin/settings/stripe/status'); setStripeStatus(response.data); } catch (error) { console.error('Failed to fetch Stripe status:', error); toast.error('Failed to load Stripe status'); } finally { setLoadingStatus(false); } }; const handleTestConnection = async () => { setTesting(true); try { const response = await api.post('/admin/settings/stripe/test-connection'); toast.success(response.data.message); } catch (error) { const message = error.response?.data?.detail || 'Connection test failed'; toast.error(message); } finally { setTesting(false); } }; const handleEditClick = () => { setIsEditing(true); setFormData({ secret_key: '', webhook_secret: '' }); }; const handleCancelEdit = () => { setIsEditing(false); setFormData({ secret_key: '', webhook_secret: '' }); setShowSecretKey(false); setShowWebhookSecret(false); }; const handleSave = async () => { // Validate inputs if (!formData.secret_key || !formData.webhook_secret) { toast.error('Both Secret Key and Webhook Secret are required'); return; } if (!formData.secret_key.startsWith('sk_test_') && !formData.secret_key.startsWith('sk_live_')) { toast.error('Invalid Secret Key format. Must start with sk_test_ or sk_live_'); return; } if (!formData.webhook_secret.startsWith('whsec_')) { toast.error('Invalid Webhook Secret format. Must start with whsec_'); return; } setSaving(true); try { await api.put('/admin/settings/stripe', formData); toast.success('Stripe settings updated successfully'); setIsEditing(false); setFormData({ secret_key: '', webhook_secret: '' }); setShowSecretKey(false); setShowWebhookSecret(false); // Refresh status await fetchStripeStatus(); } catch (error) { const message = error.response?.data?.detail || 'Failed to update Stripe settings'; toast.error(message); } finally { setSaving(false); } }; const copyToClipboard = (text, label) => { navigator.clipboard.writeText(text); toast.success(`${label} copied to clipboard`); }; if (loadingStatus) { return (
); } return (
{/* Stripe Integration Card */}
Stripe Integration Payment processing and subscription management
{!isEditing && ( )}
{isEditing ? ( /* Edit Mode */
{/* Secret Key Input */}
setFormData({ ...formData, secret_key: e.target.value })} placeholder="sk_test_... or sk_live_..." className="pr-10" />

Get this from your Stripe Dashboard → Developers → API keys

{/* Webhook Secret Input */}
setFormData({ ...formData, webhook_secret: e.target.value })} placeholder="whsec_..." className="pr-10" />

Get this from your Stripe Dashboard → Developers → Webhooks → Add endpoint

{/* Action Buttons */}
) : ( /* View Mode */ <> {/* Status Display */}

Configuration Status

Credentials stored in database (encrypted)

{stripeStatus?.configured ? ( <> Configured ) : ( <> Not Configured )}
{stripeStatus?.configured && ( <>

Environment

Detected from secret key prefix

{stripeStatus.environment === 'live' ? 'Live' : 'Test'}

Secret Key

{stripeStatus.secret_key_prefix}...

Webhook Secret

Webhook endpoint configuration

{stripeStatus.webhook_secret_set ? (
Set
) : (
Not Set
)}
{/* Webhook URL */}

Webhook URL

Configure this webhook endpoint in your Stripe Dashboard:

{stripeStatus.webhook_url}

Webhook Events to Configure:

✅ Required (Configure in Stripe):

  • checkout.session.completed - Handles subscriptions & donations

🔔 Automatically Triggered:

  • payment_intent.created
  • payment_intent.succeeded
  • charge.succeeded
  • charge.updated

These fire automatically with checkout.session.completed

🔄 Coming Soon (Recurring Subscriptions):

  • invoice.payment_succeeded
  • invoice.payment_failed
  • customer.subscription.updated
  • customer.subscription.deleted
)}
{/* Configuration Instructions (Not Configured) */} {!stripeStatus?.configured && ( <>

Configuration Required

Click "Edit Settings" above to configure your Stripe credentials.

Get your API keys from{' '} Stripe Dashboard

{/* Webhook URL Info (Always visible) */}

Webhook URL Configuration

After configuring your API keys, set up this webhook endpoint in your Stripe Dashboard:

{stripeStatus?.webhook_url || 'http://localhost:8000/api/webhooks/stripe'}

Webhook Events to Configure:

✅ Required (Configure in Stripe):

  • checkout.session.completed - Handles subscriptions & donations

🔔 Automatically Triggered:

  • payment_intent.created
  • payment_intent.succeeded
  • charge.succeeded
  • charge.updated

These fire automatically with checkout.session.completed

🔄 Coming Soon (Recurring Subscriptions):

  • invoice.payment_succeeded
  • invoice.payment_failed
  • customer.subscription.updated
  • customer.subscription.deleted
)} {/* Test Connection Button */} {stripeStatus?.configured && (
)} )}
{/* Future Settings Sections Placeholder */}

Additional settings sections will be added here

(Email, Storage, Notifications, etc.)

); }