Imporve UI and token
This commit is contained in:
@@ -5,6 +5,7 @@ This module implements the PaymentProvider interface for Stripe
|
||||
|
||||
import stripe
|
||||
import structlog
|
||||
import uuid
|
||||
from typing import Dict, Any, Optional
|
||||
from datetime import datetime
|
||||
|
||||
@@ -28,16 +29,26 @@ class StripeProvider(PaymentProvider):
|
||||
|
||||
async def create_customer(self, customer_data: Dict[str, Any]) -> PaymentCustomer:
|
||||
"""
|
||||
Create a customer in Stripe
|
||||
Create a customer in Stripe with idempotency key
|
||||
"""
|
||||
try:
|
||||
idempotency_key = f"create_customer_{uuid.uuid4()}"
|
||||
|
||||
logger.info("Creating Stripe customer",
|
||||
email=customer_data.get('email'),
|
||||
customer_name=customer_data.get('name'))
|
||||
|
||||
stripe_customer = stripe.Customer.create(
|
||||
email=customer_data.get('email'),
|
||||
name=customer_data.get('name'),
|
||||
phone=customer_data.get('phone'),
|
||||
metadata=customer_data.get('metadata', {})
|
||||
metadata=customer_data.get('metadata', {}),
|
||||
idempotency_key=idempotency_key
|
||||
)
|
||||
|
||||
logger.info("Stripe customer created successfully",
|
||||
customer_id=stripe_customer.id)
|
||||
|
||||
return PaymentCustomer(
|
||||
id=stripe_customer.id,
|
||||
email=stripe_customer.email,
|
||||
@@ -45,40 +56,70 @@ class StripeProvider(PaymentProvider):
|
||||
created_at=datetime.fromtimestamp(stripe_customer.created)
|
||||
)
|
||||
except stripe.error.StripeError as e:
|
||||
logger.error("Failed to create Stripe customer", error=str(e))
|
||||
logger.error("Failed to create Stripe customer",
|
||||
error=str(e),
|
||||
error_type=type(e).__name__,
|
||||
email=customer_data.get('email'))
|
||||
raise e
|
||||
|
||||
async def create_subscription(self, customer_id: str, plan_id: str, payment_method_id: str, trial_period_days: Optional[int] = None) -> Subscription:
|
||||
"""
|
||||
Create a subscription in Stripe
|
||||
Create a subscription in Stripe with idempotency and enhanced error handling
|
||||
"""
|
||||
try:
|
||||
# Attach payment method to customer
|
||||
subscription_idempotency_key = f"create_subscription_{uuid.uuid4()}"
|
||||
payment_method_idempotency_key = f"attach_pm_{uuid.uuid4()}"
|
||||
customer_update_idempotency_key = f"update_customer_{uuid.uuid4()}"
|
||||
|
||||
logger.info("Creating Stripe subscription",
|
||||
customer_id=customer_id,
|
||||
plan_id=plan_id,
|
||||
payment_method_id=payment_method_id)
|
||||
|
||||
# Attach payment method to customer with idempotency
|
||||
stripe.PaymentMethod.attach(
|
||||
payment_method_id,
|
||||
customer=customer_id,
|
||||
idempotency_key=payment_method_idempotency_key
|
||||
)
|
||||
|
||||
# Set customer's default payment method
|
||||
logger.info("Payment method attached to customer",
|
||||
customer_id=customer_id,
|
||||
payment_method_id=payment_method_id)
|
||||
|
||||
# Set customer's default payment method with idempotency
|
||||
stripe.Customer.modify(
|
||||
customer_id,
|
||||
invoice_settings={
|
||||
'default_payment_method': payment_method_id
|
||||
}
|
||||
},
|
||||
idempotency_key=customer_update_idempotency_key
|
||||
)
|
||||
|
||||
logger.info("Customer default payment method updated",
|
||||
customer_id=customer_id)
|
||||
|
||||
# Create subscription with trial period if specified
|
||||
subscription_params = {
|
||||
'customer': customer_id,
|
||||
'items': [{'price': plan_id}],
|
||||
'default_payment_method': payment_method_id,
|
||||
'idempotency_key': subscription_idempotency_key,
|
||||
'expand': ['latest_invoice.payment_intent']
|
||||
}
|
||||
|
||||
if trial_period_days:
|
||||
subscription_params['trial_period_days'] = trial_period_days
|
||||
logger.info("Subscription includes trial period",
|
||||
trial_period_days=trial_period_days)
|
||||
|
||||
stripe_subscription = stripe.Subscription.create(**subscription_params)
|
||||
|
||||
logger.info("Stripe subscription created successfully",
|
||||
subscription_id=stripe_subscription.id,
|
||||
status=stripe_subscription.status,
|
||||
current_period_end=stripe_subscription.current_period_end)
|
||||
|
||||
return Subscription(
|
||||
id=stripe_subscription.id,
|
||||
customer_id=stripe_subscription.customer,
|
||||
@@ -88,8 +129,25 @@ class StripeProvider(PaymentProvider):
|
||||
current_period_end=datetime.fromtimestamp(stripe_subscription.current_period_end),
|
||||
created_at=datetime.fromtimestamp(stripe_subscription.created)
|
||||
)
|
||||
except stripe.error.CardError as e:
|
||||
logger.error("Card error during subscription creation",
|
||||
error=str(e),
|
||||
error_code=e.code,
|
||||
decline_code=e.decline_code,
|
||||
customer_id=customer_id)
|
||||
raise e
|
||||
except stripe.error.InvalidRequestError as e:
|
||||
logger.error("Invalid request during subscription creation",
|
||||
error=str(e),
|
||||
param=e.param,
|
||||
customer_id=customer_id)
|
||||
raise e
|
||||
except stripe.error.StripeError as e:
|
||||
logger.error("Failed to create Stripe subscription", error=str(e))
|
||||
logger.error("Failed to create Stripe subscription",
|
||||
error=str(e),
|
||||
error_type=type(e).__name__,
|
||||
customer_id=customer_id,
|
||||
plan_id=plan_id)
|
||||
raise e
|
||||
|
||||
async def update_payment_method(self, customer_id: str, payment_method_id: str) -> PaymentMethod:
|
||||
|
||||
Reference in New Issue
Block a user