File size: 16,075 Bytes
383cb38 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | """
Stripe Integration Setup Script
Comprehensive setup and configuration script for Stripe payment processing integration
"""
from datetime import datetime
import json
import logging
import os
import subprocess
import sys
import time
from typing import Any, Dict, List, Optional
import requests
# Configure logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handlers=[logging.FileHandler("stripe_setup.log"), logging.StreamHandler()],
)
logger = logging.getLogger(__name__)
class StripeIntegrationSetup:
"""Comprehensive setup class for Stripe integration"""
def __init__(self):
self.base_dir = os.path.dirname(os.path.abspath(__file__))
self.integrations_dir = os.path.join(self.base_dir, "integrations")
self.python_api_dir = os.path.join(self.base_dir, "python-api-service")
self.env_file = os.path.join(self.base_dir, ".env")
self.setup_results = {
"timestamp": datetime.now().isoformat(),
"steps": [],
"success": True,
"environment_configured": False,
}
def log_step(self, step_name: str, success: bool, details: str = ""):
"""Log setup step result"""
status = "✅ SUCCESS" if success else "❌ FAILED"
step_result = {
"step": step_name,
"status": status,
"details": details,
"timestamp": datetime.now().isoformat(),
}
self.setup_results["steps"].append(step_result)
print(f"{status} {step_name}")
if details:
print(f" Details: {details}")
if not success:
self.setup_results["success"] = False
def check_prerequisites(self) -> bool:
"""Check system prerequisites"""
print("\n🔍 Checking Prerequisites...")
# Check Python version
try:
python_version = sys.version_info
if python_version.major >= 3 and python_version.minor >= 8:
self.log_step(
"Python Version Check",
True,
f"Python {python_version.major}.{python_version.minor}.{python_version.micro}",
)
else:
self.log_step(
"Python Version Check",
False,
f"Python 3.8+ required, found {python_version.major}.{python_version.minor}",
)
return False
except Exception as e:
self.log_step("Python Version Check", False, f"Error: {str(e)}")
return False
# Check required directories
required_dirs = [self.integrations_dir, self.python_api_dir]
for dir_path in required_dirs:
if os.path.exists(dir_path):
self.log_step(f"Directory Check: {os.path.basename(dir_path)}", True)
else:
self.log_step(
f"Directory Check: {os.path.basename(dir_path)}",
False,
"Directory not found",
)
return False
# Check if Stripe files exist
stripe_files = [
os.path.join(self.integrations_dir, "stripe_routes.py"),
os.path.join(self.python_api_dir, "stripe_service.py"),
os.path.join(self.integrations_dir, "test_stripe_integration.py"),
]
for file_path in stripe_files:
if os.path.exists(file_path):
self.log_step(f"File Check: {os.path.basename(file_path)}", True)
else:
self.log_step(
f"File Check: {os.path.basename(file_path)}",
False,
"File not found",
)
return False
return True
def install_dependencies(self) -> bool:
"""Install required Python dependencies"""
print("\n📦 Installing Dependencies...")
dependencies = [
"stripe>=8.0.0",
"fastapi>=0.100.0",
"uvicorn>=0.23.0",
"requests>=2.31.0",
"loguru>=0.7.0",
"pydantic>=2.0.0",
"python-multipart>=0.0.6",
"python-jose[cryptography]>=3.3.0",
"passlib[bcrypt]>=1.7.4",
]
try:
import importlib
import pkg_resources
for dep in dependencies:
package_name = dep.split(">=")[0].split("[")[0]
try:
importlib.import_module(package_name.replace("-", "_"))
self.log_step(
f"Dependency: {package_name}", True, "Already installed"
)
except ImportError:
self.log_step(f"Dependency: {package_name}", False, "Not installed")
return False
self.log_step(
"All Dependencies", True, "All required packages are available"
)
return True
except Exception as e:
self.log_step("Dependency Check", False, f"Error: {str(e)}")
return False
def setup_environment(self, stripe_config: Dict[str, str]) -> bool:
"""Setup environment configuration"""
print("\n⚙️ Setting Up Environment...")
try:
# Check if .env file exists
if os.path.exists(self.env_file):
self.log_step("Environment File", True, ".env file already exists")
else:
# Create .env file from template
template_path = os.path.join(self.base_dir, ".env.template")
if os.path.exists(template_path):
with open(template_path, "r") as f:
template_content = f.read()
# Replace template values with actual configuration
env_content = template_content
for key, value in stripe_config.items():
env_content = env_content.replace(f"your_{key}_here", value)
with open(self.env_file, "w") as f:
f.write(env_content)
self.log_step(
"Environment File", True, "Created .env file from template"
)
else:
self.log_step("Environment File", False, "Template file not found")
return False
# Set environment variables
for key, value in stripe_config.items():
os.environ[key] = value
self.setup_results["environment_configured"] = True
self.log_step("Environment Variables", True, "Environment variables set")
return True
except Exception as e:
self.log_step("Environment Setup", False, f"Error: {str(e)}")
return False
def test_integration(self) -> bool:
"""Test Stripe integration functionality"""
print("\n🧪 Testing Integration...")
try:
# Run the integration tests
test_script = os.path.join(
self.integrations_dir, "test_stripe_integration.py"
)
if not os.path.exists(test_script):
self.log_step("Integration Test", False, "Test script not found")
return False
# Run the test script
result = subprocess.run(
[sys.executable, test_script],
cwd=self.integrations_dir,
capture_output=True,
text=True,
timeout=60,
)
if result.returncode == 0:
self.log_step("Integration Test", True, "All tests passed")
# Parse test results
try:
results_file = os.path.join(
self.integrations_dir, "stripe_integration_test_results.json"
)
if os.path.exists(results_file):
with open(results_file, "r") as f:
test_results = json.load(f)
passed = test_results["test_run"]["passed_tests"]
total = test_results["test_run"]["total_tests"]
self.log_step(
"Test Results", True, f"{passed}/{total} tests passed"
)
except Exception as e:
logger.warning(f"Could not parse test results: {e}")
return True
else:
self.log_step(
"Integration Test", False, f"Tests failed: {result.stderr}"
)
return False
except subprocess.TimeoutExpired:
self.log_step("Integration Test", False, "Test execution timed out")
return False
except Exception as e:
self.log_step("Integration Test", False, f"Error: {str(e)}")
return False
def verify_api_integration(self) -> bool:
"""Verify API integration with main application"""
print("\n🔗 Verifying API Integration...")
try:
# Check if Stripe routes are imported in main API
main_api_file = os.path.join(self.base_dir, "main_api_app.py")
if not os.path.exists(main_api_file):
self.log_step("API Integration", False, "Main API file not found")
return False
with open(main_api_file, "r") as f:
content = f.read()
# Check for Stripe integration imports
if "stripe_routes" in content and "STRIPE_AVAILABLE" in content:
self.log_step(
"API Integration", True, "Stripe routes integrated in main API"
)
else:
self.log_step(
"API Integration", False, "Stripe routes not found in main API"
)
return False
# Test API health endpoint
try:
# Start the API server in background for testing
import threading
import uvicorn
def run_server():
uvicorn.run(
"main_api_app:app",
host="0.0.0.0",
port=8000,
log_level="error",
access_log=False,
)
server_thread = threading.Thread(target=run_server, daemon=True)
server_thread.start()
# Wait for server to start
time.sleep(3)
# Test health endpoint
response = requests.get(
"http://localhost:8000/stripe/health", timeout=10
)
if response.status_code == 200:
self.log_step(
"API Health Check", True, "Stripe health endpoint responding"
)
else:
self.log_step(
"API Health Check",
False,
f"Health endpoint returned {response.status_code}",
)
return False
except Exception as e:
self.log_step("API Health Check", False, f"Error: {str(e)}")
# This might be expected if server is already running or can't start
return True
except Exception as e:
self.log_step("API Integration", False, f"Error: {str(e)}")
return False
def create_setup_summary(self):
"""Create comprehensive setup summary"""
print("\n📋 Setup Summary")
print("=" * 50)
total_steps = len(self.setup_results["steps"])
successful_steps = sum(
1 for step in self.setup_results["steps"] if "SUCCESS" in step["status"]
)
print(f"Total Steps: {total_steps}")
print(f"Successful: {successful_steps}")
print(f"Failed: {total_steps - successful_steps}")
print(f"Success Rate: {(successful_steps / total_steps) * 100:.1f}%")
# Save detailed results
summary_file = os.path.join(self.base_dir, "stripe_setup_summary.json")
with open(summary_file, "w") as f:
json.dump(self.setup_results, f, indent=2)
print(f"\n📄 Detailed summary saved to: {summary_file}")
if self.setup_results["success"]:
print("\n🎉 Stripe Integration Setup Completed Successfully!")
print("\nNext Steps:")
print("1. Configure your Stripe account in the Stripe Dashboard")
print("2. Update the .env file with your production credentials")
print("3. Run production tests: python test_stripe_production.py")
print("4. Deploy to your production environment")
else:
print(
"\n⚠️ Setup completed with errors. Please review the failed steps above."
)
def run_complete_setup(self, stripe_config: Dict[str, str] = None):
"""Run complete setup process"""
print("🚀 Starting Stripe Integration Setup")
print("=" * 60)
print(f"Start Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("=" * 60)
# Default configuration for testing
if stripe_config is None:
stripe_config = {
"STRIPE_CLIENT_ID": "ca_test_123456789",
"STRIPE_CLIENT_SECRET": "sk_test_123456789",
"STRIPE_REDIRECT_URI": "http://localhost:3000/auth/stripe/callback",
"STRIPE_PUBLISHABLE_KEY": "pk_test_123456789",
"STRIPE_SECRET_KEY": "sk_test_123456789",
"STRIPE_WEBHOOK_SECRET": "whsec_test_123456789",
}
# Run all setup steps
steps = [
("Prerequisites Check", self.check_prerequisites),
("Dependencies Check", self.install_dependencies),
("Environment Setup", lambda: self.setup_environment(stripe_config)),
("Integration Testing", self.test_integration),
("API Integration", self.verify_api_integration),
]
for step_name, step_function in steps:
if not step_function():
print(f"\n❌ Setup failed at: {step_name}")
break
# Create final summary
self.create_setup_summary()
return self.setup_results["success"]
def main():
"""Main setup execution function"""
import argparse
parser = argparse.ArgumentParser(description="Stripe Integration Setup")
parser.add_argument("--client-id", help="Stripe Client ID")
parser.add_argument("--client-secret", help="Stripe Client Secret")
parser.add_argument("--redirect-uri", help="Stripe Redirect URI")
parser.add_argument("--publishable-key", help="Stripe Publishable Key")
parser.add_argument("--secret-key", help="Stripe Secret Key")
parser.add_argument("--webhook-secret", help="Stripe Webhook Secret")
args = parser.parse_args()
# Build configuration from command line arguments
stripe_config = {}
if args.client_id:
stripe_config["STRIPE_CLIENT_ID"] = args.client_id
if args.client_secret:
stripe_config["STRIPE_CLIENT_SECRET"] = args.client_secret
if args.redirect_uri:
stripe_config["STRIPE_REDIRECT_URI"] = args.redirect_uri
if args.publishable_key:
stripe_config["STRIPE_PUBLISHABLE_KEY"] = args.publishable_key
if args.secret_key:
stripe_config["STRIPE_SECRET_KEY"] = args.secret_key
if args.webhook_secret:
stripe_config["STRIPE_WEBHOOK_SECRET"] = args.webhook_secret
setup = StripeIntegrationSetup()
success = setup.run_complete_setup(stripe_config)
return 0 if success else 1
if __name__ == "__main__":
exit_code = main()
sys.exit(exit_code)
|