Files
igny8/backend/api_integration_example.py
2025-12-09 00:11:35 +00:00

374 lines
12 KiB
Python

#!/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")