Files
igny8/multi-tenancy/in-progress/PAYMENT-WORKFLOW-QUICK-START.md
2025-12-09 02:43:51 +00:00

397 lines
11 KiB
Markdown

# 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/