feat: add marketplace metrics, privacy features, and service registry endpoints

- Add Prometheus metrics for marketplace API throughput and error rates with new dashboard panels
- Implement confidential transaction models with encryption support and access control
- Add key management system with registration, rotation, and audit logging
- Create services and registry routers for service discovery and management
- Integrate ZK proof generation for privacy-preserving receipts
- Add metrics instru
This commit is contained in:
oib
2025-12-22 10:33:23 +01:00
parent d98b2c7772
commit c8be9d7414
260 changed files with 59033 additions and 351 deletions

View File

@ -0,0 +1,489 @@
"""
Stripe payment connector for AITBC Enterprise
"""
import asyncio
import logging
from typing import Dict, Any, Optional, List
from datetime import datetime, timedelta
import stripe
from ..base import BaseConnector, OperationResult, Transaction
from ..core import ConnectorConfig
from .base import PaymentConnector, PaymentMethod, Charge, Refund, Subscription
from ..exceptions import PaymentError, ValidationError
class StripeConnector(PaymentConnector):
"""Stripe payment processor connector"""
def __init__(
self,
client: 'AITBCClient',
config: ConnectorConfig,
stripe_api_key: str,
webhook_secret: Optional[str] = None
):
super().__init__(client, config)
# Stripe configuration
self.stripe_api_key = stripe_api_key
self.webhook_secret = webhook_secret
# Initialize Stripe client
stripe.api_key = stripe_api_key
stripe.api_version = "2023-10-16"
# Stripe-specific configuration
self._stripe_config = {
"api_key": stripe_api_key,
"api_version": stripe.api_version,
"connect_timeout": config.timeout,
"read_timeout": config.timeout
}
async def _initialize(self) -> None:
"""Initialize Stripe connector"""
try:
# Test Stripe connection
await self._test_stripe_connection()
# Set up webhook handler
if self.webhook_secret:
await self._setup_webhook_handler()
self.logger.info("Stripe connector initialized")
except Exception as e:
raise PaymentError(f"Failed to initialize Stripe: {e}")
async def _cleanup(self) -> None:
"""Cleanup Stripe connector"""
# No specific cleanup needed for Stripe
pass
async def _execute_operation(
self,
operation: str,
data: Dict[str, Any],
**kwargs
) -> OperationResult:
"""Execute Stripe-specific operations"""
try:
if operation == "create_charge":
return await self._create_charge(data)
elif operation == "create_refund":
return await self._create_refund(data)
elif operation == "create_payment_method":
return await self._create_payment_method(data)
elif operation == "create_customer":
return await self._create_customer(data)
elif operation == "create_subscription":
return await self._create_subscription(data)
elif operation == "cancel_subscription":
return await self._cancel_subscription(data)
elif operation == "retrieve_balance":
return await self._retrieve_balance()
else:
raise ValidationError(f"Unknown operation: {operation}")
except stripe.error.StripeError as e:
self.logger.error(f"Stripe error: {e}")
return OperationResult(
success=False,
error=str(e),
metadata={"stripe_error_code": getattr(e, 'code', None)}
)
except Exception as e:
self.logger.error(f"Operation failed: {e}")
return OperationResult(
success=False,
error=str(e)
)
async def create_charge(
self,
amount: int,
currency: str,
source: str,
description: Optional[str] = None,
metadata: Optional[Dict[str, Any]] = None
) -> Charge:
"""Create a charge"""
result = await self.execute_operation(
"create_charge",
{
"amount": amount,
"currency": currency,
"source": source,
"description": description,
"metadata": metadata or {}
}
)
if not result.success:
raise PaymentError(result.error)
return Charge.from_stripe_charge(result.data)
async def create_refund(
self,
charge_id: str,
amount: Optional[int] = None,
reason: Optional[str] = None
) -> Refund:
"""Create a refund"""
result = await self.execute_operation(
"create_refund",
{
"charge": charge_id,
"amount": amount,
"reason": reason
}
)
if not result.success:
raise PaymentError(result.error)
return Refund.from_stripe_refund(result.data)
async def create_payment_method(
self,
type: str,
card: Dict[str, Any],
metadata: Optional[Dict[str, Any]] = None
) -> PaymentMethod:
"""Create a payment method"""
result = await self.execute_operation(
"create_payment_method",
{
"type": type,
"card": card,
"metadata": metadata or {}
}
)
if not result.success:
raise PaymentError(result.error)
return PaymentMethod.from_stripe_payment_method(result.data)
async def create_subscription(
self,
customer: str,
items: List[Dict[str, Any]],
metadata: Optional[Dict[str, Any]] = None
) -> Subscription:
"""Create a subscription"""
result = await self.execute_operation(
"create_subscription",
{
"customer": customer,
"items": items,
"metadata": metadata or {}
}
)
if not result.success:
raise PaymentError(result.error)
return Subscription.from_stripe_subscription(result.data)
async def cancel_subscription(
self,
subscription_id: str,
at_period_end: bool = True
) -> Subscription:
"""Cancel a subscription"""
result = await self.execute_operation(
"cancel_subscription",
{
"subscription": subscription_id,
"at_period_end": at_period_end
}
)
if not result.success:
raise PaymentError(result.error)
return Subscription.from_stripe_subscription(result.data)
async def retrieve_balance(self) -> Dict[str, Any]:
"""Retrieve account balance"""
result = await self.execute_operation("retrieve_balance", {})
if not result.success:
raise PaymentError(result.error)
return result.data
async def verify_webhook(self, payload: bytes, signature: str) -> bool:
"""Verify Stripe webhook signature"""
try:
stripe.WebhookSignature.verify_header(
payload,
signature,
self.webhook_secret,
300
)
return True
except stripe.error.SignatureVerificationError:
return False
async def handle_webhook(self, payload: bytes) -> Dict[str, Any]:
"""Handle Stripe webhook"""
try:
event = stripe.Webhook.construct_event(
payload,
None, # Already verified
self.webhook_secret,
300
)
# Process event based on type
result = await self._process_webhook_event(event)
return {
"processed": True,
"event_type": event.type,
"event_id": event.id,
"result": result
}
except Exception as e:
self.logger.error(f"Webhook processing failed: {e}")
return {
"processed": False,
"error": str(e)
}
# Private methods
async def _test_stripe_connection(self):
"""Test Stripe API connection"""
try:
# Use asyncio to run in thread
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, stripe.Balance.retrieve)
except Exception as e:
raise PaymentError(f"Stripe connection test failed: {e}")
async def _setup_webhook_handler(self):
"""Setup webhook handler"""
# Register webhook verification with base connector
self.add_operation_handler("webhook.verified", self._handle_verified_webhook)
async def _create_charge(self, data: Dict[str, Any]) -> OperationResult:
"""Create Stripe charge"""
loop = asyncio.get_event_loop()
try:
charge = await loop.run_in_executor(
None,
lambda: stripe.Charge.create(**data)
)
return OperationResult(
success=True,
data=charge.to_dict(),
metadata={"charge_id": charge.id}
)
except Exception as e:
raise PaymentError(f"Failed to create charge: {e}")
async def _create_refund(self, data: Dict[str, Any]) -> OperationResult:
"""Create Stripe refund"""
loop = asyncio.get_event_loop()
try:
refund = await loop.run_in_executor(
None,
lambda: stripe.Refund.create(**data)
)
return OperationResult(
success=True,
data=refund.to_dict(),
metadata={"refund_id": refund.id}
)
except Exception as e:
raise PaymentError(f"Failed to create refund: {e}")
async def _create_payment_method(self, data: Dict[str, Any]) -> OperationResult:
"""Create Stripe payment method"""
loop = asyncio.get_event_loop()
try:
pm = await loop.run_in_executor(
None,
lambda: stripe.PaymentMethod.create(**data)
)
return OperationResult(
success=True,
data=pm.to_dict(),
metadata={"payment_method_id": pm.id}
)
except Exception as e:
raise PaymentError(f"Failed to create payment method: {e}")
async def _create_customer(self, data: Dict[str, Any]) -> OperationResult:
"""Create Stripe customer"""
loop = asyncio.get_event_loop()
try:
customer = await loop.run_in_executor(
None,
lambda: stripe.Customer.create(**data)
)
return OperationResult(
success=True,
data=customer.to_dict(),
metadata={"customer_id": customer.id}
)
except Exception as e:
raise PaymentError(f"Failed to create customer: {e}")
async def _create_subscription(self, data: Dict[str, Any]) -> OperationResult:
"""Create Stripe subscription"""
loop = asyncio.get_event_loop()
try:
subscription = await loop.run_in_executor(
None,
lambda: stripe.Subscription.create(**data)
)
return OperationResult(
success=True,
data=subscription.to_dict(),
metadata={"subscription_id": subscription.id}
)
except Exception as e:
raise PaymentError(f"Failed to create subscription: {e}")
async def _cancel_subscription(self, data: Dict[str, Any]) -> OperationResult:
"""Cancel Stripe subscription"""
loop = asyncio.get_event_loop()
try:
subscription = await loop.run_in_executor(
None,
lambda: stripe.Subscription.retrieve(data["subscription"])
)
subscription = await loop.run_in_executor(
None,
lambda: subscription.cancel(at_period_end=data.get("at_period_end", True))
)
return OperationResult(
success=True,
data=subscription.to_dict(),
metadata={"subscription_id": subscription.id}
)
except Exception as e:
raise PaymentError(f"Failed to cancel subscription: {e}")
async def _retrieve_balance(self) -> OperationResult:
"""Retrieve Stripe balance"""
loop = asyncio.get_event_loop()
try:
balance = await loop.run_in_executor(None, stripe.Balance.retrieve)
return OperationResult(
success=True,
data=balance.to_dict()
)
except Exception as e:
raise PaymentError(f"Failed to retrieve balance: {e}")
async def _process_webhook_event(self, event) -> Dict[str, Any]:
"""Process webhook event"""
event_type = event.type
if event_type.startswith("charge."):
return await self._handle_charge_event(event)
elif event_type.startswith("payment_method."):
return await self._handle_payment_method_event(event)
elif event_type.startswith("customer."):
return await self._handle_customer_event(event)
elif event_type.startswith("invoice."):
return await self._handle_invoice_event(event)
else:
self.logger.info(f"Unhandled webhook event type: {event_type}")
return {"status": "ignored"}
async def _handle_charge_event(self, event) -> Dict[str, Any]:
"""Handle charge-related webhook events"""
charge = event.data.object
# Emit to AITBC
await self.client.post(
"/webhooks/stripe/charge",
json={
"event_id": event.id,
"event_type": event.type,
"charge": charge.to_dict()
}
)
return {"status": "processed", "charge_id": charge.id}
async def _handle_payment_method_event(self, event) -> Dict[str, Any]:
"""Handle payment method webhook events"""
pm = event.data.object
await self.client.post(
"/webhooks/stripe/payment_method",
json={
"event_id": event.id,
"event_type": event.type,
"payment_method": pm.to_dict()
}
)
return {"status": "processed", "payment_method_id": pm.id}
async def _handle_customer_event(self, event) -> Dict[str, Any]:
"""Handle customer webhook events"""
customer = event.data.object
await self.client.post(
"/webhooks/stripe/customer",
json={
"event_id": event.id,
"event_type": event.type,
"customer": customer.to_dict()
}
)
return {"status": "processed", "customer_id": customer.id}
async def _handle_invoice_event(self, event) -> Dict[str, Any]:
"""Handle invoice webhook events"""
invoice = event.data.object
await self.client.post(
"/webhooks/stripe/invoice",
json={
"event_id": event.id,
"event_type": event.type,
"invoice": invoice.to_dict()
}
)
return {"status": "processed", "invoice_id": invoice.id}
async def _handle_verified_webhook(self, data: Dict[str, Any]):
"""Handle verified webhook"""
self.logger.info(f"Webhook verified: {data}")