Complete Implemenation of tenancy
This commit is contained in:
373
backend/api_integration_example.py
Normal file
373
backend/api_integration_example.py
Normal file
@@ -0,0 +1,373 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Payment Workflow API Integration Examples
|
||||
Demonstrates how to interact with the payment APIs programmatically
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
from decimal import Decimal
|
||||
|
||||
# Base URL for the API
|
||||
BASE_URL = "http://localhost:8011/api/v1"
|
||||
|
||||
class PaymentAPIClient:
|
||||
"""Example API client for payment workflow"""
|
||||
|
||||
def __init__(self, base_url=BASE_URL):
|
||||
self.base_url = base_url
|
||||
self.token = None
|
||||
self.session = requests.Session()
|
||||
|
||||
def register_free_trial(self, email, password, first_name, last_name):
|
||||
"""Register a new free trial user"""
|
||||
url = f"{self.base_url}/auth/register/"
|
||||
data = {
|
||||
"email": email,
|
||||
"password": password,
|
||||
"password_confirm": password,
|
||||
"first_name": first_name,
|
||||
"last_name": last_name
|
||||
}
|
||||
|
||||
response = self.session.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
print(f"✓ Free trial account created: {result['data']['account']['name']}")
|
||||
print(f" Status: {result['data']['account']['status']}")
|
||||
print(f" Credits: {result['data']['account']['credits']}")
|
||||
|
||||
return result['data']
|
||||
|
||||
def register_paid_user(self, email, password, first_name, last_name,
|
||||
plan_slug, billing_info):
|
||||
"""Register a new paid user with billing information"""
|
||||
url = f"{self.base_url}/auth/register/"
|
||||
data = {
|
||||
"email": email,
|
||||
"password": password,
|
||||
"password_confirm": password,
|
||||
"first_name": first_name,
|
||||
"last_name": last_name,
|
||||
"plan_slug": plan_slug,
|
||||
**billing_info
|
||||
}
|
||||
|
||||
response = self.session.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
print(f"✓ Paid account created: {result['data']['account']['name']}")
|
||||
print(f" Status: {result['data']['account']['status']}")
|
||||
print(f" Credits: {result['data']['account']['credits']}")
|
||||
|
||||
if 'invoice' in result['data']:
|
||||
inv = result['data']['invoice']
|
||||
print(f" Invoice: {inv['invoice_number']} - ${inv['total']}")
|
||||
|
||||
return result['data']
|
||||
|
||||
def login(self, email, password):
|
||||
"""Login and get authentication token"""
|
||||
url = f"{self.base_url}/auth/login/"
|
||||
data = {
|
||||
"email": email,
|
||||
"password": password
|
||||
}
|
||||
|
||||
response = self.session.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
self.token = result['data']['token']
|
||||
self.session.headers.update({
|
||||
'Authorization': f'Bearer {self.token}'
|
||||
})
|
||||
|
||||
print(f"✓ Logged in as: {email}")
|
||||
return result['data']
|
||||
|
||||
def get_payment_methods(self, country_code=None):
|
||||
"""Get available payment methods for a country"""
|
||||
url = f"{self.base_url}/billing/admin/payment-methods/"
|
||||
params = {}
|
||||
if country_code:
|
||||
params['country'] = country_code
|
||||
|
||||
response = self.session.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
methods = response.json()
|
||||
|
||||
print(f"✓ Payment methods available: {len(methods)}")
|
||||
for method in methods:
|
||||
print(f" - {method['display_name']} ({method['payment_method']})")
|
||||
|
||||
return methods
|
||||
|
||||
def confirm_payment(self, invoice_id, payment_method, amount,
|
||||
manual_reference, manual_notes=""):
|
||||
"""Submit payment confirmation for manual payments"""
|
||||
url = f"{self.base_url}/billing/admin/payments/confirm/"
|
||||
data = {
|
||||
"invoice_id": invoice_id,
|
||||
"payment_method": payment_method,
|
||||
"amount": str(amount),
|
||||
"manual_reference": manual_reference,
|
||||
"manual_notes": manual_notes
|
||||
}
|
||||
|
||||
response = self.session.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
payment = result['data']
|
||||
print(f"✓ Payment confirmation submitted")
|
||||
print(f" Payment ID: {payment['payment_id']}")
|
||||
print(f" Invoice: {payment['invoice_number']}")
|
||||
print(f" Status: {payment['status']}")
|
||||
print(f" Reference: {payment['manual_reference']}")
|
||||
|
||||
return result['data']
|
||||
|
||||
def approve_payment(self, payment_id, admin_notes=""):
|
||||
"""Approve a pending payment (admin only)"""
|
||||
url = f"{self.base_url}/billing/admin/payments/{payment_id}/approve/"
|
||||
data = {
|
||||
"admin_notes": admin_notes
|
||||
}
|
||||
|
||||
response = self.session.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
payment = result['data']
|
||||
print(f"✓ Payment approved")
|
||||
print(f" Account Status: {payment['account_status']}")
|
||||
print(f" Subscription Status: {payment['subscription_status']}")
|
||||
print(f" Credits Added: {payment['credits_added']}")
|
||||
print(f" Total Credits: {payment['total_credits']}")
|
||||
|
||||
return result['data']
|
||||
|
||||
def reject_payment(self, payment_id, admin_notes):
|
||||
"""Reject a pending payment (admin only)"""
|
||||
url = f"{self.base_url}/billing/admin/payments/{payment_id}/reject/"
|
||||
data = {
|
||||
"admin_notes": admin_notes
|
||||
}
|
||||
|
||||
response = self.session.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
payment = result['data']
|
||||
print(f"✓ Payment rejected")
|
||||
print(f" Status: {payment['status']}")
|
||||
print(f" Reason: {admin_notes}")
|
||||
|
||||
return result['data']
|
||||
|
||||
|
||||
def example_free_trial_workflow():
|
||||
"""Example: Free trial signup workflow"""
|
||||
print("\n" + "="*60)
|
||||
print("EXAMPLE 1: FREE TRIAL SIGNUP")
|
||||
print("="*60 + "\n")
|
||||
|
||||
client = PaymentAPIClient()
|
||||
|
||||
# Step 1: Register free trial user
|
||||
user_data = client.register_free_trial(
|
||||
email="freetrial_demo@example.com",
|
||||
password="SecurePass123!",
|
||||
first_name="Free",
|
||||
last_name="Trial"
|
||||
)
|
||||
|
||||
# Step 2: Login
|
||||
login_data = client.login(
|
||||
email="freetrial_demo@example.com",
|
||||
password="SecurePass123!"
|
||||
)
|
||||
|
||||
print(f"\n✓ Free trial workflow complete!")
|
||||
print(f" User can now create {user_data['account']['max_sites']} site(s)")
|
||||
print(f" Available credits: {user_data['account']['credits']}")
|
||||
|
||||
|
||||
def example_paid_signup_workflow():
|
||||
"""Example: Paid signup with manual payment approval"""
|
||||
print("\n" + "="*60)
|
||||
print("EXAMPLE 2: PAID SIGNUP WITH MANUAL PAYMENT")
|
||||
print("="*60 + "\n")
|
||||
|
||||
client = PaymentAPIClient()
|
||||
|
||||
# Step 1: Check available payment methods
|
||||
print("Step 1: Check Payment Methods for Pakistan")
|
||||
methods = client.get_payment_methods(country_code="PK")
|
||||
|
||||
# Step 2: Register with paid plan
|
||||
print("\nStep 2: Register Paid User")
|
||||
billing_info = {
|
||||
"billing_email": "billing@example.com",
|
||||
"billing_address_line1": "123 Main Street",
|
||||
"billing_city": "Karachi",
|
||||
"billing_country": "PK",
|
||||
"payment_method": "bank_transfer"
|
||||
}
|
||||
|
||||
user_data = client.register_paid_user(
|
||||
email="paiduser_demo@example.com",
|
||||
password="SecurePass123!",
|
||||
first_name="Paid",
|
||||
last_name="User",
|
||||
plan_slug="starter",
|
||||
billing_info=billing_info
|
||||
)
|
||||
|
||||
# Step 3: Login
|
||||
print("\nStep 3: User Login")
|
||||
login_data = client.login(
|
||||
email="paiduser_demo@example.com",
|
||||
password="SecurePass123!"
|
||||
)
|
||||
|
||||
# Step 4: User makes external payment and submits confirmation
|
||||
print("\nStep 4: Submit Payment Confirmation")
|
||||
invoice_id = user_data['invoice']['id']
|
||||
invoice_total = user_data['invoice']['total']
|
||||
|
||||
payment_data = client.confirm_payment(
|
||||
invoice_id=invoice_id,
|
||||
payment_method="bank_transfer",
|
||||
amount=invoice_total,
|
||||
manual_reference="DEMO-BANK-2025-001",
|
||||
manual_notes="Transferred via ABC Bank on Dec 8, 2025"
|
||||
)
|
||||
|
||||
print(f"\n✓ Payment submitted! Waiting for admin approval...")
|
||||
print(f" Payment ID: {payment_data['payment_id']}")
|
||||
print(f" Account remains in 'pending_payment' status")
|
||||
|
||||
# Step 5: Admin approves (requires admin token)
|
||||
print("\nStep 5: Admin Approval (requires admin credentials)")
|
||||
print(" → Admin would login separately and approve the payment")
|
||||
print(f" → POST /billing/admin/payments/{payment_data['payment_id']}/approve/")
|
||||
print(" → Account status changes to 'active'")
|
||||
print(" → Credits allocated: 1000")
|
||||
|
||||
return payment_data
|
||||
|
||||
|
||||
def example_admin_approval():
|
||||
"""Example: Admin approving a payment"""
|
||||
print("\n" + "="*60)
|
||||
print("EXAMPLE 3: ADMIN PAYMENT APPROVAL")
|
||||
print("="*60 + "\n")
|
||||
|
||||
# This requires admin credentials
|
||||
admin_client = PaymentAPIClient()
|
||||
|
||||
print("Step 1: Admin Login")
|
||||
try:
|
||||
admin_client.login(
|
||||
email="dev@igny8.com", # Replace with actual admin email
|
||||
password="admin_password" # Replace with actual password
|
||||
)
|
||||
|
||||
print("\nStep 2: Approve Payment")
|
||||
# Replace with actual payment ID
|
||||
payment_id = 5 # Example payment ID
|
||||
|
||||
result = admin_client.approve_payment(
|
||||
payment_id=payment_id,
|
||||
admin_notes="Verified payment in bank statement. Reference matches."
|
||||
)
|
||||
|
||||
print(f"\n✓ Payment approval complete!")
|
||||
print(f" Account activated with {result['total_credits']} credits")
|
||||
|
||||
except requests.exceptions.HTTPError as e:
|
||||
print(f"✗ Admin approval failed: {e}")
|
||||
print(" (This is expected if you don't have admin credentials)")
|
||||
|
||||
|
||||
def example_payment_rejection():
|
||||
"""Example: Admin rejecting a payment"""
|
||||
print("\n" + "="*60)
|
||||
print("EXAMPLE 4: ADMIN PAYMENT REJECTION")
|
||||
print("="*60 + "\n")
|
||||
|
||||
admin_client = PaymentAPIClient()
|
||||
|
||||
print("Step 1: Admin Login")
|
||||
try:
|
||||
admin_client.login(
|
||||
email="dev@igny8.com",
|
||||
password="admin_password"
|
||||
)
|
||||
|
||||
print("\nStep 2: Reject Payment")
|
||||
payment_id = 7 # Example payment ID
|
||||
|
||||
result = admin_client.reject_payment(
|
||||
payment_id=payment_id,
|
||||
admin_notes="Reference number not found in bank statement. Please verify and resubmit."
|
||||
)
|
||||
|
||||
print(f"\n✓ Payment rejected!")
|
||||
print(f" User can resubmit with correct reference")
|
||||
|
||||
except requests.exceptions.HTTPError as e:
|
||||
print(f"✗ Payment rejection failed: {e}")
|
||||
print(" (This is expected if you don't have admin credentials)")
|
||||
|
||||
|
||||
def main():
|
||||
"""Run all examples"""
|
||||
print("\n" + "="*60)
|
||||
print("PAYMENT WORKFLOW API INTEGRATION EXAMPLES")
|
||||
print("="*60)
|
||||
print("\nThese examples demonstrate how to integrate with the")
|
||||
print("multi-tenancy payment workflow APIs.\n")
|
||||
|
||||
try:
|
||||
# Example 1: Free trial
|
||||
example_free_trial_workflow()
|
||||
|
||||
# Example 2: Paid signup
|
||||
# example_paid_signup_workflow()
|
||||
|
||||
# Example 3: Admin approval (requires admin credentials)
|
||||
# example_admin_approval()
|
||||
|
||||
# Example 4: Payment rejection (requires admin credentials)
|
||||
# example_payment_rejection()
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"\n✗ API Error: {e}")
|
||||
print("\nMake sure the backend is running on http://localhost:8011")
|
||||
except Exception as e:
|
||||
print(f"\n✗ Error: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Note: Uncomment examples you want to run
|
||||
# Some examples may create actual data in the database
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("API INTEGRATION EXAMPLES - READ ONLY MODE")
|
||||
print("="*60)
|
||||
print("\nTo run examples, uncomment the desired function calls")
|
||||
print("in the main() function.\n")
|
||||
print("Available examples:")
|
||||
print(" 1. example_free_trial_workflow()")
|
||||
print(" 2. example_paid_signup_workflow()")
|
||||
print(" 3. example_admin_approval()")
|
||||
print(" 4. example_payment_rejection()")
|
||||
print("\nWarning: Running these will create data in the database!")
|
||||
print("="*60 + "\n")
|
||||
Reference in New Issue
Block a user