# Django Admin Access Guide - Payment & Email Integration Settings **Last Updated:** January 20, 2026 **Version:** 1.8.4 **Purpose:** Guide to configure Stripe, PayPal, and Resend credentials via Django Admin --- ## Table of Contents 1. [Accessing Django Admin](#1-accessing-django-admin) 2. [Integration Providers Settings](#2-integration-providers-settings) 3. [Stripe Configuration](#3-stripe-configuration) 4. [PayPal Configuration](#4-paypal-configuration) 5. [Resend Configuration](#5-resend-configuration) 6. [Plan & Pricing Configuration](#6-plan--pricing-configuration) 7. [Credit Packages Configuration](#7-credit-packages-configuration) 8. [Testing Checklist](#8-testing-checklist) --- ## 1. Accessing Django Admin ### 1.1 URL Access **Local Development:** ``` http://localhost:8000/admin/ ``` **Staging/Production:** ``` https://api.igny8.com/admin/ ``` ### 1.2 Login Use your superuser credentials: - **Username:** (your admin username) - **Password:** (your admin password) **Create Superuser (if needed):** ```bash cd /data/app/igny8/backend python manage.py createsuperuser ``` --- ## 2. Integration Providers Settings ### 2.1 Navigating to Integration Providers 1. Log in to Django Admin 2. Look for **"MODULES"** section (or similar grouping) 3. Click on **"System" → "Integration providers"** **Direct URL Path:** ``` /admin/system/integrationprovider/ ``` ### 2.2 Pre-seeded Providers You should see these providers already created: | Provider ID | Display Name | Type | Status | |-------------|--------------|------|--------| | `stripe` | Stripe | payment | Active (sandbox) | | `paypal` | PayPal | payment | Active (sandbox) | | `resend` | Resend | email | Active | | `openai` | OpenAI | ai | Active | | `anthropic` | Anthropic | ai | Active | | `google` | Google | ai | Active | | `runware` | Runware | ai | Active | | `cloudflare_r2` | Cloudflare R2 | storage | Active | --- ## 3. Stripe Configuration ### 3.1 Getting Stripe Credentials #### Step 1: Login to Stripe Dashboard Go to [dashboard.stripe.com](https://dashboard.stripe.com) #### Step 2: Get API Keys **Test Mode (Sandbox):** 1. Toggle to "Test mode" in top-right 2. Go to **Developers → API keys** 3. Copy: - **Publishable key** (starts with `pk_test_...`) - **Secret key** (starts with `sk_test_...`) **Live Mode (Production):** 1. Toggle to "Live mode" 2. Go to **Developers → API keys** 3. Copy: - **Publishable key** (starts with `pk_live_...`) - **Secret key** (starts with `sk_live_...`) #### Step 3: Configure Webhook 1. Go to **Developers → Webhooks** 2. Click **"Add endpoint"** 3. Enter endpoint URL: ``` Test: https://api-staging.igny8.com/api/v1/billing/webhooks/stripe/ Live: https://api.igny8.com/api/v1/billing/webhooks/stripe/ ``` 4. Select events to listen for: - `checkout.session.completed` - `invoice.paid` - `invoice.payment_failed` - `customer.subscription.updated` - `customer.subscription.deleted` 5. Click **"Add endpoint"** 6. Copy the **Signing secret** (starts with `whsec_...`) #### Step 4: Create Products and Prices 1. Go to **Products → Add product** 2. Create these products: **Starter Plan** - Name: `Starter Plan` - Description: `Basic plan for small projects` - Pricing: `$99.00 / month` - Copy the **Price ID** (starts with `price_...`) **Growth Plan** - Name: `Growth Plan` - Description: `For growing businesses` - Pricing: `$199.00 / month` - Copy the **Price ID** **Scale Plan** - Name: `Scale Plan` - Description: `For large enterprises` - Pricing: `$299.00 / month` - Copy the **Price ID** ### 3.2 Adding to Django Admin 1. Go to Django Admin → **System → Integration providers** 2. Click on **"stripe"** 3. Fill in the fields: ``` Provider ID: stripe (already set) Display name: Stripe (already set) Provider type: payment (already set) API key: pk_test_xxxxxxxxxxxxx (or pk_live_ for production) API secret: sk_test_xxxxxxxxxxxxx (or sk_live_ for production) Webhook secret: whsec_xxxxxxxxxxxxx API endpoint: [leave empty - uses default] Config (JSON): { "currency": "usd", "payment_methods": ["card"], "billing_portal_enabled": true } ✅ Is active: Checked ✅ Is sandbox: Checked (for test mode) / Unchecked (for live mode) ``` 4. Click **"Save"** ### 3.3 Update Plan Models with Stripe Price IDs 1. Go to Django Admin → **Auth → Plans** 2. Edit each plan: **Starter Plan:** - Stripe price id: `price_xxxxxxxxxxxxx` (from Stripe dashboard) - Stripe product id: `prod_xxxxxxxxxxxxx` (optional) **Growth Plan:** - Stripe price id: `price_xxxxxxxxxxxxx` **Scale Plan:** - Stripe price id: `price_xxxxxxxxxxxxx` 3. Save each plan --- ## 4. PayPal Configuration ### 4.1 Getting PayPal Credentials #### Step 1: Login to PayPal Developer Dashboard Go to [developer.paypal.com](https://developer.paypal.com) #### Step 2: Create an App 1. Go to **My Apps & Credentials** 2. Select **Sandbox** (for testing) or **Live** (for production) 3. Click **"Create App"** 4. Enter app name: `IGNY8 Payment Integration` 5. Click **"Create App"** 6. Copy: - **Client ID** (starts with `AY...` or similar) - **Secret** (click "Show" to reveal) #### Step 3: Configure Webhooks 1. In your app settings, scroll to **"WEBHOOKS"** 2. Click **"Add Webhook"** 3. Enter webhook URL: ``` Sandbox: https://api-staging.igny8.com/api/v1/billing/webhooks/paypal/ Live: https://api.igny8.com/api/v1/billing/webhooks/paypal/ ``` 4. Select event types: - `CHECKOUT.ORDER.APPROVED` - `PAYMENT.CAPTURE.COMPLETED` - `PAYMENT.CAPTURE.DENIED` - `BILLING.SUBSCRIPTION.ACTIVATED` - `BILLING.SUBSCRIPTION.CANCELLED` 5. Click **"Save"** 6. Copy the **Webhook ID** (starts with `WH-...`) #### Step 4: Create Subscription Plans (Required for Subscriptions) PayPal subscriptions require creating **Products** and **Plans** in the PayPal dashboard. This is a manual process (not done via API in our implementation). ##### 4.4.1 Create a PayPal Product 1. Go to [sandbox.paypal.com/billing/plans](https://www.sandbox.paypal.com/billing/plans) (Sandbox) or [paypal.com/billing/plans](https://www.paypal.com/billing/plans) (Live) 2. Click **"Create product"** (or go to Products tab first) 3. Fill in: - **Product name**: `IGNY8 Subscription` - **Product type**: `Service` - **Product ID**: `IGNY8-SUB` (or auto-generate) - **Description**: `IGNY8 subscription plans` 4. Click **"Create product"** 5. Note the **Product ID** (e.g., `PROD-xxxxxxxxxxxxx`) ##### 4.4.2 Create PayPal Plans (One Per IGNY8 Plan) For each plan in your system (Starter, Growth, Scale), create a PayPal plan: 1. In PayPal dashboard, click **"Create plan"** 2. Select the product you just created 3. Fill in plan details: **Starter Plan:** - **Plan name**: `Starter Plan - Monthly` - **Description**: `Basic plan for small projects` - **Pricing**: - Billing cycle: `Monthly` - Price: `$99.00 USD` - Total cycles: `0` (infinite) - **Setup fee**: `$0.00` (optional) 4. Click **"Create plan"** 5. **Copy the Plan ID** (starts with `P-...`, e.g., `P-5ML4271244454362WXXX`) Repeat for Growth ($199/month) and Scale ($299/month) plans. ##### 4.4.3 Map PayPal Plan IDs to Django Plans 1. Go to Django Admin → **Auth → Plans** 2. Edit **Starter Plan**: - Scroll to **"PayPal Integration"** section - **Paypal plan id**: Paste `P-xxxxxxxxxxxxx` 3. Click **"Save"** 4. Repeat for Growth and Scale plans **Note:** Without `paypal_plan_id` set, the subscription creation API will return an error. ### 4.2 Adding to Django Admin 1. Go to Django Admin → **System → Integration providers** 2. Click on **"paypal"** 3. Fill in the fields: ``` Provider ID: paypal (already set) Display name: PayPal (already set) Provider type: payment (already set) API key: AYxxxxxxxxxxx (Client ID) API secret: ELxxxxxxxxxxx (Secret) Webhook secret: [leave empty - not used by PayPal] API endpoint: Sandbox: https://api-m.sandbox.paypal.com Live: https://api-m.paypal.com Config (JSON): { "currency": "USD", "webhook_id": "WH-xxxxxxxxxxxxx", "return_url": "https://app.igny8.com/account/plans?paypal=success", "cancel_url": "https://app.igny8.com/account/plans?paypal=cancel" } ✅ Is active: Checked ✅ Is sandbox: Checked (for sandbox) / Unchecked (for live) ``` 4. Click **"Save"** ### 4.3 Live PayPal Payment Enablement (Production) Use this section when switching from sandbox to live PayPal payments. #### Step 1: Create/Select a Live App 1. Go to [developer.paypal.com](https://developer.paypal.com) 2. Select **Live** (top toggle) 3. Create a new app or select your existing live app 4. Copy the **Live Client ID** and **Live Secret** #### Step 2: Configure Live Webhook 1. In your live app settings, add a webhook: ``` https://api.igny8.com/api/v1/billing/webhooks/paypal/ ``` 2. Select events: - `CHECKOUT.ORDER.APPROVED` - `PAYMENT.CAPTURE.COMPLETED` - `PAYMENT.CAPTURE.DENIED` - `BILLING.SUBSCRIPTION.ACTIVATED` - `BILLING.SUBSCRIPTION.CANCELLED` 3. Copy the **Live Webhook ID** #### Step 3: Update Django Admin Provider (Live) 1. Go to **System → Integration providers → paypal** 2. Update fields: - **API key**: Live Client ID - **API secret**: Live Secret - **API endpoint**: `https://api-m.paypal.com` - **Config (JSON)**: set `webhook_id` to the live webhook ID 3. Set: - ✅ `is_active` = True - ✅ `is_sandbox` = False 4. Click **"Save"** #### Step 3.1: Map PayPal Plan IDs in Django PayPal subscription webhooks only work if your plans are mapped. 1. Go to Django Admin → **Auth → Plans** 2. For each plan, set: - **Paypal plan id**: Live PayPal Plan ID (starts with `P-...`) 3. Save each plan #### Step 4: Validate Live Payment Flow 1. Open frontend: `/account/usage` 2. Select **PayPal** and complete a real payment 3. Confirm: - Order is captured - Credits are added - Payment email is sent #### Step 5: Validate PayPal Subscriptions (If Enabled) 1. Open frontend: `/account/plans` 2. Select **PayPal** and subscribe to a plan 3. Confirm: - Subscription is activated - Webhook events are processed - Account plan is updated --- ## 5. Resend Configuration ### 5.1 Getting Resend API Key #### Step 1: Login to Resend Go to [resend.com](https://resend.com) #### Step 2: Create API Key 1. Go to **API Keys** 2. Click **"Create API Key"** 3. Enter name: `IGNY8 Production` (or `IGNY8 Development`) 4. Select permission: **"Sending access"** 5. Click **"Add"** 6. Copy the API key (starts with `re_...`) 7. **Save it securely** - you won't see it again! #### Step 3: Verify Your Domain 1. Go to **Domains** 2. Click **"Add Domain"** 3. Enter your domain: `igny8.com` 4. Follow instructions to add DNS records: - **DKIM Record** (TXT) - **SPF Record** (TXT) - **DMARC Record** (TXT) 5. Click **"Verify"** 6. Wait for verification (can take a few minutes to 24 hours) ### 5.2 Adding to Django Admin 1. Go to Django Admin → **System → Integration providers** 2. Click on **"resend"** 3. Fill in the fields: ``` Provider ID: resend (already set) Display name: Resend (already set) Provider type: email (already set) API key: re_xxxxxxxxxxxxx API secret: [leave empty] Webhook secret: [leave empty] API endpoint: [leave empty - uses default] Config (JSON): { "from_email": "noreply@igny8.com", "from_name": "IGNY8", "reply_to": "support@igny8.com" } ✅ Is active: Checked ✅ Is sandbox: Unchecked (Resend doesn't have sandbox mode) ``` 4. Click **"Save"** ### 5.3 Email Settings Management IGNY8 provides a dedicated **Email Settings** navigation group in Django Admin: | Menu Item | URL | Purpose | |-----------|-----|---------| | Email Configuration | `/admin/system/emailsettings/` | Global email defaults (from, reply-to, feature flags) | | Email Templates | `/admin/system/emailtemplate/` | Manage/test email templates | | Email Logs | `/admin/system/emaillog/` | View sent email history | | Resend Provider | `/admin/system/integrationprovider/resend/change/` | API key & config | **Email Configuration Settings:** - `from_email` - Default sender (must be verified in Resend) - `from_name` - Display name for sender - `reply_to_email` - Reply-to address - `send_welcome_emails` - Toggle welcome emails on/off - `send_billing_emails` - Toggle payment/invoice emails - `send_subscription_emails` - Toggle renewal reminders - `low_credit_threshold` - Credits level to trigger warning email ### 5.4 Testing Email Delivery **Method 1: Django Admin UI (Recommended)** 1. Go to **Email Settings → Email Templates** 2. Click the **"Test"** button next to any template 3. Enter recipient email and customize context JSON 4. Click **"Send Test Email"** 5. Check **Email Logs** to verify delivery **Method 2: Command Line (Docker)** ```bash docker exec -it igny8_backend python manage.py shell -c " from igny8_core.business.billing.services.email_service import get_email_service service = get_email_service() result = service.send_transactional( to='your-email@example.com', subject='Test Email from IGNY8', html='

Test Email

If you receive this, Resend is configured correctly!

', text='Test Email. If you receive this, Resend is configured correctly!' ) print('Result:', result) " ``` **Expected successful response:** ```python {'success': True, 'id': '81193754-6f27-4b1a-9c36-d83ae18f6a9a', 'provider': 'resend'} ``` **Method 3: Test with Template** ```bash docker exec -it igny8_backend python manage.py shell -c " from igny8_core.business.billing.services.email_service import get_email_service service = get_email_service() result = service.send_transactional( to='your-email@example.com', subject='Welcome Test', template='emails/welcome.html', context={ 'user_name': 'Test User', 'account_name': 'Test Account', 'login_url': 'https://app.igny8.com/login', 'frontend_url': 'https://app.igny8.com', }, tags=['test'] ) print('Result:', result) " ``` ### 5.5 Available Email Templates | Template | Type | Trigger | |----------|------|---------| | `welcome` | Auth | User registration | | `password_reset` | Auth | Password reset request | | `email_verification` | Auth | Email verification | | `payment_confirmation` | Billing | Manual payment submitted | | `payment_approved` | Billing | Payment approved | | `payment_rejected` | Billing | Payment declined | | `payment_failed` | Billing | Auto-payment failed | | `subscription_activated` | Billing | Subscription activated | | `subscription_renewal` | Billing | Renewal reminder | | `refund_notification` | Billing | Refund processed | | `low_credits` | Notification | Credits below threshold | ### 5.6 Email Service API Reference ```python send_transactional( to: str | List[str], # Required: recipient email(s) subject: str, # Required: email subject html: str = None, # HTML content text: str = None, # Plain text content template: str = None, # Template path (e.g., 'emails/welcome.html') context: dict = None, # Template context variables from_email: str = None, # Override sender email from_name: str = None, # Override sender name reply_to: str = None, # Reply-to address attachments: List = None, # File attachments tags: List[str] = None # Email tags for tracking ) ``` --- ## 6. Plan & Pricing Configuration ### 6.1 Viewing Plans 1. Go to Django Admin → **Auth → Plans** 2. You should see existing plans: - Free Plan - Starter Plan - Growth Plan - Scale Plan - Enterprise Plan ### 6.2 Editing Plan Details For each plan: ``` Name: Starter Plan Description: Perfect for small projects Price: 99.00 Billing period: monthly Included credits: 5000 Is active: ✅ Stripe price id: price_xxxxxxxxxxxxx (from Stripe dashboard) Stripe product id: prod_xxxxxxxxxxxxx (optional) Paypal plan id: P-xxxxxxxxxxxxx (if using PayPal subscriptions) Feature limits: Max keywords: 50 Max articles per month: 100 Max team members: 3 Max websites: 1 ``` ### 6.3 Creating Custom Plans 1. Click **"Add plan"** 2. Fill in all fields 3. Make sure to set: - ✅ `is_active` = True (to show to users) - Stripe price ID (from Stripe dashboard) - Included credits (monthly allocation) 4. Click **"Save"** --- ## 7. Credit Packages Configuration ### 7.1 Viewing Credit Packages 1. Go to Django Admin → **Billing → Credit packages** 2. You should see existing packages: - Starter: 500 credits @ $9.99 - Value: 2,000 credits @ $29.99 - Pro: 5,000 credits @ $59.99 - Enterprise: 15,000 credits @ $149.99 ### 7.2 Editing Credit Packages For each package: ``` Name: Value Package Description: Best value for money Credits: 2000 Price: 29.99 Display order: 2 ✅ Is active: Checked ✅ Is featured: Checked (to highlight on UI) Stripe product id: prod_xxxxxxxxxxxxx (optional - for tracking) Paypal product id: (optional) ``` ### 7.3 Creating Custom Credit Packages 1. Click **"Add credit package"** 2. Fill in: - Name: e.g., "Black Friday Special" - Credits: e.g., 10000 - Price: e.g., 79.99 - Description: "Limited time offer!" 3. Check ✅ `is_active` 4. Check ✅ `is_featured` (optional) 5. Click **"Save"** --- ## 8. Testing Checklist ### 8.1 Verify Integration Provider Settings Go to Admin → **System → Integration providers** - [ ] **Stripe** - API keys added, webhook secret added, is_active=True - [ ] **PayPal** - Client ID/Secret added, webhook ID in config, is_active=True - [ ] **Resend** - API key added, domain verified, is_active=True ### 8.2 Test Stripe Integration 1. **Get Config Endpoint:** ```bash curl -X GET https://api.igny8.com/api/v1/billing/stripe/config/ \ -H "Authorization: Bearer YOUR_JWT_TOKEN" ``` Should return publishable key and sandbox status 2. **Test Checkout Session:** - Go to frontend: `/account/plans` - Select "Stripe" as payment method - Click "Subscribe" on a plan - Should redirect to Stripe Checkout - Complete test payment with card: `4242 4242 4242 4242` - Should receive webhook and activate subscription 3. **Test Billing Portal:** - Click "Manage Subscription" button - Should redirect to Stripe Billing Portal - Can cancel/update subscription ### 8.3 Test PayPal Integration #### 8.3.1 Verify PayPal Provider Config ```bash curl -X GET https://api.igny8.com/api/v1/billing/paypal/config/ \ -H "Authorization: Bearer YOUR_JWT_TOKEN" ``` Should return `client_id` and `sandbox: true`. #### 8.3.2 Test One-Time Credit Purchase (Orders API) 1. Go to frontend: `/account/usage` 2. Select **PayPal** as payment method 3. Click **"Buy Credits"** on a package 4. Should redirect to PayPal sandbox 5. Login with sandbox buyer account: - Email: `sb-buyer@personal.example.com` (from PayPal sandbox accounts) - Password: (your sandbox password) 6. Complete payment 7. **Verify:** - Order is captured (check webhook logs) - Credits are added to account - Payment email is sent #### 8.3.3 Test PayPal Subscriptions (Subscriptions API) **Prerequisites:** - [ ] PayPal Plans created in dashboard (see Section 4, Step 4) - [ ] `paypal_plan_id` set on each Django Plan (Auth → Plans) **Test Steps:** 1. **Verify Plan Configuration:** ```bash # Check if plan has paypal_plan_id docker exec -it igny8_backend python manage.py shell -c " from igny8_core.auth.models import Plan for p in Plan.objects.filter(is_active=True): print(f'{p.name}: paypal_plan_id={p.paypal_plan_id}') " ``` All paid plans should show a `P-xxxxx` ID. 2. **Create PayPal Subscription:** - Go to frontend: `/account/plans` - Select **PayPal** as payment method - Click **"Subscribe"** on Starter/Growth/Scale plan - Redirects to PayPal for approval - Login with sandbox buyer account - Approve the subscription 3. **Verify Subscription Activation:** - Check webhook logs: `BILLING.SUBSCRIPTION.ACTIVATED` should fire - Account plan should be updated - `Subscription` record created with `external_payment_id` = PayPal subscription ID - Credits added based on plan's `included_credits` 4. **Verify in Django Admin:** - Go to **Auth → Subscriptions** - Find the new subscription - Confirm: - `status` = `active` - `external_payment_id` = `I-xxxxx` (PayPal subscription ID) - `plan` = correct plan 5. **Test Subscription Cancellation:** - In PayPal sandbox, go to **Pay & Get Paid → Subscriptions** - Cancel the test subscription - `BILLING.SUBSCRIPTION.CANCELLED` webhook should fire - Subscription status should update to `canceled` **Sandbox Test Accounts:** Create sandbox accounts at [developer.paypal.com/dashboard/accounts](https://developer.paypal.com/dashboard/accounts): - **Business account** - receives payments (seller) - **Personal account** - makes payments (buyer) Use the personal account credentials when approving payments/subscriptions. ### 8.4 Test Email Service 1. **Test Welcome Email:** ```bash cd /data/app/igny8/backend python manage.py shell ``` ```python from igny8_core.auth.models import User, Account from igny8_core.business.billing.services.email_service import send_welcome_email user = User.objects.first() account = user.account send_welcome_email(user, account) ``` Check your inbox for welcome email 2. **Test Payment Confirmation:** - Complete a test payment (Stripe or PayPal) - Should receive payment confirmation email - Check email content and formatting ### 8.5 Test Webhooks 1. **Check Webhook Logs:** ```bash cd /data/app/igny8/backend tail -f logs/django.log | grep webhook ``` 2. **Trigger Webhook Events:** - **Stripe:** Complete test checkout, then check webhook logs - **PayPal:** Complete test payment, then check webhook logs 3. **Verify Webhook Processing:** - Subscription should be activated - Credits should be added - Email notifications should be sent --- ## Quick Reference: Admin URLs ``` # Main sections /admin/system/integrationprovider/ # All integration providers /admin/auth/plan/ # Plans and pricing /admin/billing/creditpackage/ # Credit packages /admin/billing/payment/ # Payment history /admin/billing/invoice/ # Invoices /admin/auth/subscription/ # Active subscriptions /admin/billing/credittransaction/ # Credit transaction history # Specific provider configs /admin/system/integrationprovider/stripe/change/ /admin/system/integrationprovider/paypal/change/ /admin/system/integrationprovider/resend/change/ ``` --- ## Security Best Practices ### Never Commit API Keys - ❌ Don't add API keys to code - ❌ Don't commit `.env` files - ✅ Use Django Admin to store credentials - ✅ Use IntegrationProvider model (encrypted in DB) ### Use Environment-Specific Keys - **Development:** Use Stripe test mode, PayPal sandbox - **Staging:** Use separate test credentials - **Production:** Use live credentials ONLY in production ### Regular Key Rotation - Rotate API keys every 90 days - Rotate webhook secrets if compromised - Keep backup of old keys during rotation ### Monitor Webhook Security - Verify webhook signatures always - Log all webhook attempts - Alert on failed signature verification --- ## Troubleshooting ### Stripe Issues **"No such customer"** - Check if `stripe_customer_id` is set on Account model - Clear the field and let system recreate customer **"Invalid API Key"** - Verify API key in IntegrationProvider - Check if using test key in live mode (or vice versa) **Webhook not working** - Check webhook URL in Stripe dashboard - Verify webhook secret in IntegrationProvider - Check server logs for errors ### PayPal Issues **"Invalid client credentials"** - Verify Client ID and Secret in IntegrationProvider - Make sure using sandbox credentials for sandbox mode **"Webhook verification failed"** - Check webhook_id in config JSON - Verify webhook URL in PayPal dashboard **Order capture fails** - Check order status (must be APPROVED) - Verify order hasn't already been captured **"PayPal plan ID not configured for this plan"** - The Plan model is missing `paypal_plan_id` - Go to Django Admin → **Auth → Plans** - Edit the plan and add the PayPal Plan ID (starts with `P-...`) - Create the plan in PayPal dashboard first if not done **"No plan found with paypal_plan_id=..."** - Webhook received but no matching plan in Django - Verify the `paypal_plan_id` in Django matches exactly what's in PayPal - Check for typos or extra whitespace **Subscription not activating after approval** - Check webhook logs for `BILLING.SUBSCRIPTION.ACTIVATED` event - Verify webhook URL is correctly configured in PayPal app - Check that `webhook_id` in config JSON matches PayPal dashboard - Ensure sandbox/live environment matches between app and PayPal **PayPal subscription appears but no credits added** - Check `included_credits` field on the Plan model - Verify subscription webhook handler completed successfully - Look for errors in Django logs during webhook processing ### Resend Issues **"Invalid API key"** - Verify API key starts with `re_` - Create new API key if needed **"Domain not verified"** - Check DNS records in domain provider - Wait up to 24 hours for DNS propagation - Use Resend dashboard to verify domain status **Emails not delivered** - Check Resend dashboard logs - Verify from_email domain is verified - Check spam folder --- ## Next Steps After configuring all providers: 1. ✅ Test all payment flows in sandbox mode 2. ✅ Test email delivery 3. ✅ Verify webhook processing 4. ✅ Test frontend payment gateway selection 5. ✅ Switch to production credentials when ready to go live For production deployment, update: - `is_sandbox` = False for Stripe - `is_sandbox` = False for PayPal - `api_endpoint` = production URLs - Use live API keys for all providers --- **Support:** If you encounter issues, check Django logs: ```bash cd /data/app/igny8/backend tail -f logs/django.log ```