# Payment Workflow Quick Start Guide **Date:** December 8, 2025 **Backend Port:** 8011 --- ## ๐Ÿš€ Quick Test Commands ### 1. Test Payment Methods API ```bash # Get payment methods for Pakistan curl "http://localhost:8011/api/v1/billing/admin/payment-methods/?country=PK" | jq # Get payment methods for USA curl "http://localhost:8011/api/v1/billing/admin/payment-methods/?country=US" | jq # Get all global payment methods curl "http://localhost:8011/api/v1/billing/admin/payment-methods/" | jq ``` ### 2. Register Free Trial User ```bash curl -X POST http://localhost:8011/api/v1/auth/register/ \ -H "Content-Type: application/json" \ -d '{ "email": "freetrial@test.com", "password": "TestPass123!", "password_confirm": "TestPass123!", "first_name": "Free", "last_name": "Trial" }' | jq ``` **Expected Result:** - Account created with status='trial' - 1000 credits allocated - Free plan assigned - No subscription/invoice created ### 3. Register Paid User with Billing Info ```bash curl -X POST http://localhost:8011/api/v1/auth/register/ \ -H "Content-Type: application/json" \ -d '{ "email": "paiduser@test.com", "password": "TestPass123!", "password_confirm": "TestPass123!", "first_name": "Paid", "last_name": "User", "plan_slug": "starter", "billing_email": "billing@test.com", "billing_country": "PK", "billing_city": "Karachi", "billing_address_line1": "123 Main Street", "payment_method": "bank_transfer" }' | jq ``` **Expected Result:** - Account created with status='pending_payment' - 0 credits (awaiting payment) - Subscription created with status='pending_payment' - Invoice created with status='pending' - AccountPaymentMethod created (type='bank_transfer') - Billing info saved in account AND snapshotted in invoice metadata --- ## ๐Ÿ”„ Complete Manual Payment Workflow ### Step 1: User Registers with Paid Plan ```bash # User fills signup form with billing info # Backend creates: Account, Subscription, Invoice, AccountPaymentMethod ``` ### Step 2: User Sees Payment Instructions ```bash # Frontend displays invoice details and payment instructions # For bank_transfer: Bank account details # For local_wallet: Mobile wallet number ``` ### Step 3: User Makes External Payment ``` User transfers money via bank or mobile wallet User keeps transaction reference: "BT-20251208-12345" ``` ### Step 4: User Confirms Payment ```bash # Get auth token first TOKEN=$(curl -X POST http://localhost:8011/api/v1/auth/login/ \ -H "Content-Type: application/json" \ -d '{"email": "paiduser@test.com", "password": "TestPass123!"}' | jq -r '.data.token') # Submit payment confirmation curl -X POST http://localhost:8011/api/v1/billing/admin/payments/confirm/ \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "invoice_id": 1, "payment_method": "bank_transfer", "manual_reference": "BT-20251208-12345", "manual_notes": "Transferred via ABC Bank on Dec 8, 2025", "amount": "89.00" }' | jq ``` **Expected Response:** ```json { "success": true, "message": "Payment confirmation submitted for review. You will be notified once approved.", "data": { "payment_id": 1, "invoice_id": 1, "invoice_number": "INV-2-202512-0001", "status": "pending_approval", "amount": "89.00", "currency": "USD", "manual_reference": "BT-20251208-12345" } } ``` ### Step 5: Admin Approves Payment **Option A: Via Django Admin Panel** ``` 1. Go to: http://localhost:8011/admin/billing/payment/ 2. Filter by status: "pending_approval" 3. Select payment(s) 4. Actions dropdown: "Approve selected manual payments" 5. Click "Go" ``` **Option B: Via API (Admin Token Required)** ```bash # Get admin token ADMIN_TOKEN=$(curl -X POST http://localhost:8011/api/v1/auth/login/ \ -H "Content-Type: application/json" \ -d '{"email": "admin@example.com", "password": "adminpass"}' | jq -r '.data.token') # Approve payment curl -X POST http://localhost:8011/api/v1/billing/admin/payments/1/approve/ \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "admin_notes": "Verified payment in bank statement on Dec 8, 2025" }' | jq ``` **Expected Response:** ```json { "success": true, "message": "Payment approved successfully. Account activated.", "data": { "payment_id": 1, "invoice_id": 1, "invoice_number": "INV-2-202512-0001", "account_id": 2, "account_status": "active", "subscription_status": "active", "credits_added": 1000, "total_credits": 1000, "approved_by": "admin@example.com", "approved_at": "2025-12-08T15:30:00Z" } } ``` **What Happens Atomically:** 1. โœ… Payment.status โ†’ 'succeeded' 2. โœ… Invoice.status โ†’ 'paid' 3. โœ… Subscription.status โ†’ 'active' 4. โœ… Account.status โ†’ 'active' 5. โœ… Credits added: 1000 (plan.included_credits) 6. โœ… CreditTransaction logged --- ## ๐Ÿ” Verification Queries ### Check Account Status ```bash docker compose -f docker-compose.app.yml exec -T igny8_backend python manage.py shell <<'EOF' from igny8_core.auth.models import Account account = Account.objects.get(id=2) # Replace with actual ID print(f'Account: {account.name}') print(f'Status: {account.status}') print(f'Credits: {account.credits}') print(f'Plan: {account.plan.name}') print(f'Billing Email: {account.billing_email}') EOF ``` ### Check Subscription & Invoice ```bash docker compose -f docker-compose.app.yml exec -T igny8_backend python manage.py shell <<'EOF' from igny8_core.auth.models import Subscription from igny8_core.business.billing.models import Invoice, Payment # Check subscription sub = Subscription.objects.filter(account_id=2).first() if sub: print(f'Subscription Status: {sub.status}') print(f'Plan: {sub.plan.name if sub.plan else "None"}') # Check invoice invoice = Invoice.objects.filter(account_id=2).first() if invoice: print(f'\nInvoice: {invoice.invoice_number}') print(f'Status: {invoice.status}') print(f'Total: ${invoice.total}') print(f'Has billing snapshot: {"billing_snapshot" in invoice.metadata}') # Check payment payment = Payment.objects.filter(invoice=invoice).first() if payment: print(f'\nPayment Status: {payment.status}') print(f'Reference: {payment.manual_reference}') print(f'Approved by: {payment.approved_by}') EOF ``` ### Check Credit Transactions ```bash docker compose -f docker-compose.app.yml exec -T igny8_backend python manage.py shell <<'EOF' from igny8_core.business.billing.models import CreditTransaction transactions = CreditTransaction.objects.filter(account_id=2).order_by('-created_at') print(f'Credit Transactions: {transactions.count()}\n') for t in transactions: print(f'{t.created_at.strftime("%Y-%m-%d %H:%M")} | {t.transaction_type:15} | {t.amount:6} credits | Balance: {t.balance_after}') print(f' {t.description}') EOF ``` --- ## ๐Ÿ“‹ Payment Method Configurations | Country | Method | Display Name | Instructions | |---------|--------|--------------|--------------| | * (Global) | stripe | Credit/Debit Card (Stripe) | - | | * (Global) | paypal | PayPal | - | | * (Global) | bank_transfer | Bank Transfer | Bank: ABC Bank, Account: 1234567890, SWIFT: ABCPKKA | | PK | local_wallet | JazzCash / Easypaisa | JazzCash: 03001234567 | --- ## ๐Ÿงช Test Scenarios ### Scenario 1: Free Trial User Journey ``` 1. Register without plan_slug โ†’ Free plan assigned 2. Account status: 'trial' 3. Credits: 1000 4. Create 1 site (max_sites=1) 5. Site requires industry selection 6. SiteUserAccess auto-created 7. Use AI features with 1000 credits ``` ### Scenario 2: Paid User Journey (Happy Path) ``` 1. Register with plan_slug='starter' 2. Fill billing form 3. Select payment_method='bank_transfer' 4. Account status: 'pending_payment', Credits: 0 5. Subscription status: 'pending_payment' 6. Invoice created (status='pending') 7. User transfers money externally 8. User submits payment confirmation with reference 9. Payment created (status='pending_approval') 10. Admin approves payment 11. Account status: 'active', Credits: 1000 12. Subscription status: 'active' 13. Invoice status: 'paid' 14. User can create 1 site and use features ``` ### Scenario 3: Rejected Payment ``` 1-9. Same as Scenario 2 10. Admin rejects payment (reference not found) 11. Payment status: 'failed' 12. Account remains: status='pending_payment' 13. User notified (email - when implemented) 14. User can re-submit with correct reference ``` --- ## ๐Ÿ” Admin Panel Access ### Access Payment Management ``` URL: http://localhost:8011/admin/billing/payment/ Login: Use superuser credentials Features: - Filter by status (pending_approval, succeeded, failed) - Search by manual_reference, invoice_number, account_name - Bulk approve payments action - Bulk reject payments action - View payment details (reference, notes, proof) ``` ### Approve Multiple Payments ``` 1. Go to Payments admin 2. Filter: status = "pending_approval" 3. Select multiple payments (checkboxes) 4. Action: "Approve selected manual payments" 5. Click "Go" 6. All selected payments processed atomically ``` --- ## ๐Ÿ“Š Database Schema Changes ### New/Modified Tables **igny8_subscriptions:** - Added: `plan_id` (FK to igny8_plans) - Removed: `payment_method` (now property from Account) **igny8_sites:** - Modified: `industry_id` (now NOT NULL, required) **igny8_payment_method_config:** - 14 records created for global + country-specific methods **igny8_invoices:** - `billing_period_start`, `billing_period_end`, `billing_email` โ†’ properties only - `metadata` now contains billing_snapshot **igny8_payments:** - `transaction_reference` removed (duplicate of manual_reference) --- ## ๐Ÿ› Troubleshooting ### Issue: "Invoice not found" **Cause:** Wrong invoice_id or invoice doesn't belong to user's account **Fix:** Query invoices: `Invoice.objects.filter(account=request.account)` ### Issue: "Amount mismatch" **Cause:** Submitted amount doesn't match invoice.total **Fix:** Ensure exact amount from invoice (including decimals) ### Issue: "Payment not pending approval" **Cause:** Trying to approve already processed payment **Fix:** Check payment.status before approval ### Issue: "Site creation fails - industry required" **Cause:** Industry field is now required **Fix:** Always include industry_id when creating sites ### Issue: "No credits after approval" **Cause:** Plan might not have included_credits **Fix:** Check plan.included_credits in database --- ## ๐Ÿ“ Next Steps ### For Frontend Development: 1. Implement billing form step in signup flow 2. Create PaymentMethodSelect component 3. Build payment confirmation modal 4. Add pending payment status banner to dashboard ### For Testing: 1. Write E2E tests for free trial flow 2. Write E2E tests for paid signup flow 3. Test payment approval workflow 4. Test payment rejection workflow ### For Enhancement: 1. Add email notifications (payment submitted, approved, rejected) 2. Implement S3 upload for payment proof 3. Add Stripe/PayPal webhook handlers for automation 4. Create payment analytics dashboard --- **Last Updated:** December 8, 2025 **Backend Version:** Phase 2 & 3 Complete **API Base URL:** http://localhost:8011/api/v1/