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