refractor: clean up the codes for online services
This commit is contained in:
parent
ccc995f599
commit
a8f0a714ae
24
.env
24
.env
@ -1,24 +0,0 @@
|
|||||||
APP_NAME=payment
|
|
||||||
export SERVICE_API_ACCESS_HOST=0.0.0.0
|
|
||||||
export SERVICE_API_ACCESS_PORT=8006
|
|
||||||
export CONTAINER_APP_ROOT=/app
|
|
||||||
export LOG_BASE_PATH=$CONTAINER_APP_ROOT/log/$APP_NAME
|
|
||||||
export BACKEND_LOG_FILE_NAME=$APP_NAME
|
|
||||||
export APPLICATION_ACTIVITY_LOG=$APP_NAME-activity
|
|
||||||
export MONGODB_NAME=freeleaps2
|
|
||||||
export MONGODB_PORT=27017
|
|
||||||
GIT_REPO_ROOT=/Users/sunhaolou/Downloads/Freeleaps/freeleaps-service-hub
|
|
||||||
CODEBASE_ROOT=/Users/sunhaolou/Downloads/Freeleaps/freeleaps-service-hub/apps/payment
|
|
||||||
SITE_DEPLOY_FOLDER=/Users/sunhaolou/Downloads/Freeleaps/freeleaps-service-hub/sites/payment/deploy
|
|
||||||
#!/bin/bash
|
|
||||||
export VENV_DIR=venv_t
|
|
||||||
export VENV_ACTIVATE=venv_t/bin/activate
|
|
||||||
export DOCKER_HOME=/var/lib/docker
|
|
||||||
export DOCKER_APP_HOME=$DOCKER_HOME/app
|
|
||||||
export DOCKER_BACKEND_HOME=$DOCKER_APP_HOME/$APP_NAME
|
|
||||||
export DOCKER_BACKEND_LOG_HOME=$DOCKER_BACKEND_HOME/log
|
|
||||||
export MONGODB_URI=mongodb://localhost:27017/
|
|
||||||
export FREELEAPS_ENV=local
|
|
||||||
export SITE_URL_ROOT=http://localhost:5173/
|
|
||||||
export LOG_BASE_PATH=${CODEBASE_ROOT}/log
|
|
||||||
export STRIPE_API_KEY=sk_test_51Ogsw5B0IyqaSJBrwczlr820jnmvA1qQQGoLZ2XxOsIzikpmXo4pRLjw4XVMTEBR8DdVTYySiAv1XX53Zv5xqynF00GfMqttFd
|
|
||||||
@ -7,9 +7,9 @@ export BACKEND_LOG_FILE_NAME=$APP_NAME
|
|||||||
export APPLICATION_ACTIVITY_LOG=$APP_NAME-activity
|
export APPLICATION_ACTIVITY_LOG=$APP_NAME-activity
|
||||||
export MONGODB_NAME=freeleaps2
|
export MONGODB_NAME=freeleaps2
|
||||||
export MONGODB_PORT=27017
|
export MONGODB_PORT=27017
|
||||||
GIT_REPO_ROOT=/Users/sunhaolou/Downloads/Freeleaps/freeleaps-service-hub
|
GIT_REPO_ROOT=/mnt/freeleaps/freeleaps-service-hub
|
||||||
CODEBASE_ROOT=/Users/sunhaolou/Downloads/Freeleaps/freeleaps-service-hub/apps/payment
|
CODEBASE_ROOT=/mnt/freeleaps/freeleaps-service-hub/apps/payment
|
||||||
SITE_DEPLOY_FOLDER=/Users/sunhaolou/Downloads/Freeleaps/freeleaps-service-hub/sites/payment/deploy
|
SITE_DEPLOY_FOLDER=/mnt/freeleaps/freeleaps-service-hub/sites/payment/deploy
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
export VENV_DIR=venv_t
|
export VENV_DIR=venv_t
|
||||||
export VENV_ACTIVATE=venv_t/bin/activate
|
export VENV_ACTIVATE=venv_t/bin/activate
|
||||||
|
|||||||
@ -16,7 +16,7 @@ stripe.api_key = app_settings.STRIPE_API_KEY
|
|||||||
|
|
||||||
class StripeManager:
|
class StripeManager:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.site_url_root = "http://localhost:8888"
|
self.site_url_root = app_settings.SITE_URL_ROOT.rstrip("/")
|
||||||
self.module_logger = ModuleLogger(sender_id="StripeManager")
|
self.module_logger = ModuleLogger(sender_id="StripeManager")
|
||||||
|
|
||||||
async def create_stripe_account(self) -> Optional[str]:
|
async def create_stripe_account(self) -> Optional[str]:
|
||||||
@ -29,15 +29,15 @@ class StripeManager:
|
|||||||
if link_type == "account_update" and account.tos_acceptance.date:
|
if link_type == "account_update" and account.tos_acceptance.date:
|
||||||
login_link = stripe.Account.create_login_link(
|
login_link = stripe.Account.create_login_link(
|
||||||
account_id,
|
account_id,
|
||||||
redirect_url="http://localhost:8888/work"
|
redirect_url="{}/work".format(self.site_url_root)
|
||||||
)
|
)
|
||||||
return login_link.url
|
return login_link.url
|
||||||
|
|
||||||
# Otherwise show onboarding
|
# Otherwise show onboarding
|
||||||
account_link = stripe.AccountLink.create(
|
account_link = stripe.AccountLink.create(
|
||||||
account=account_id,
|
account=account_id,
|
||||||
refresh_url="http://localhost:8888/front-door",
|
refresh_url="{}/front-door".format(self.site_url_root),
|
||||||
return_url="http://localhost:8888/work",
|
return_url="{}/work".format(self.site_url_root),
|
||||||
type="account_onboarding",
|
type="account_onboarding",
|
||||||
)
|
)
|
||||||
return account_link.url
|
return account_link.url
|
||||||
@ -71,20 +71,10 @@ class StripeManager:
|
|||||||
async def __fetch_transaction_by_session_id(
|
async def __fetch_transaction_by_session_id(
|
||||||
self, session_id: str
|
self, session_id: str
|
||||||
) -> Optional[StripeTransactionDoc]:
|
) -> Optional[StripeTransactionDoc]:
|
||||||
await self.module_logger.log_info(
|
|
||||||
f"Looking up transaction for session_id: {session_id}",
|
|
||||||
properties={"session_id": session_id}
|
|
||||||
)
|
|
||||||
|
|
||||||
transactions = await StripeTransactionDoc.find(
|
transactions = await StripeTransactionDoc.find(
|
||||||
StripeTransactionDoc.stripe_checkout_session_id == session_id
|
StripeTransactionDoc.stripe_checkout_session_id == session_id
|
||||||
).to_list()
|
).to_list()
|
||||||
|
|
||||||
await self.module_logger.log_info(
|
|
||||||
f"Found {len(transactions)} transactions for session_id: {session_id}",
|
|
||||||
properties={"session_id": session_id, "transaction_count": len(transactions)}
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(transactions) > 1:
|
if len(transactions) > 1:
|
||||||
await self.module_logger.log_error(
|
await self.module_logger.log_error(
|
||||||
error="More than one transaction found for session_id: {}".format(
|
error="More than one transaction found for session_id: {}".format(
|
||||||
@ -99,18 +89,7 @@ class StripeManager:
|
|||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
transaction = transactions[0]
|
return transactions[0]
|
||||||
await self.module_logger.log_info(
|
|
||||||
f"Found transaction: project_id={transaction.project_id}, milestone_index={transaction.milestone_index}, status={transaction.status}",
|
|
||||||
properties={
|
|
||||||
"session_id": session_id,
|
|
||||||
"project_id": transaction.project_id,
|
|
||||||
"milestone_index": transaction.milestone_index,
|
|
||||||
"status": transaction.status
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return transaction
|
|
||||||
|
|
||||||
async def fetch_transaction_by_session_id(
|
async def fetch_transaction_by_session_id(
|
||||||
self, session_id: str
|
self, session_id: str
|
||||||
@ -324,8 +303,8 @@ class StripeManager:
|
|||||||
],
|
],
|
||||||
"payment_intent_data": payment_intent_data,
|
"payment_intent_data": payment_intent_data,
|
||||||
"mode": "payment",
|
"mode": "payment",
|
||||||
"success_url": "http://localhost:8888/projects",
|
"success_url": "{}/projects".format(self.site_url_root),
|
||||||
"cancel_url": "http://localhost:8888/projects",
|
"cancel_url": "{}/projects".format(self.site_url_root),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -369,10 +348,6 @@ class StripeManager:
|
|||||||
# Handle the checkout.session.completed event
|
# Handle the checkout.session.completed event
|
||||||
if event["type"] == "checkout.session.completed":
|
if event["type"] == "checkout.session.completed":
|
||||||
session = event["data"]["object"]
|
session = event["data"]["object"]
|
||||||
await self.module_logger.log_info(
|
|
||||||
f"Processing checkout.session.completed webhook for session_id: {session['id']}",
|
|
||||||
properties={"session_id": session["id"]}
|
|
||||||
)
|
|
||||||
|
|
||||||
transaction = await self.__fetch_transaction_by_session_id(session["id"])
|
transaction = await self.__fetch_transaction_by_session_id(session["id"])
|
||||||
if not transaction:
|
if not transaction:
|
||||||
@ -387,69 +362,31 @@ class StripeManager:
|
|||||||
transaction.updated_time = datetime.now(timezone.utc)
|
transaction.updated_time = datetime.now(timezone.utc)
|
||||||
await transaction.save()
|
await transaction.save()
|
||||||
|
|
||||||
await self.module_logger.log_info(
|
|
||||||
f"Successfully updated transaction status to COMPLETED for project_id: {transaction.project_id}, milestone_index: {transaction.milestone_index}",
|
|
||||||
properties={
|
|
||||||
"project_id": transaction.project_id,
|
|
||||||
"milestone_index": transaction.milestone_index,
|
|
||||||
"session_id": session["id"]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Save payment method information
|
# Save payment method information
|
||||||
payment_method_saved = False
|
payment_method_saved = False
|
||||||
try:
|
try:
|
||||||
print("=" * 50)
|
|
||||||
print("STARTING PAYMENT METHOD PROCESSING")
|
|
||||||
print("=" * 50)
|
|
||||||
print(f"Starting payment method processing for session {session['id']}")
|
|
||||||
|
|
||||||
# Get the Stripe session to extract payment method details
|
# Get the Stripe session to extract payment method details
|
||||||
try:
|
stripe_session = stripe.checkout.Session.retrieve(session["id"])
|
||||||
stripe_session = stripe.checkout.Session.retrieve(session["id"])
|
|
||||||
print(f"Successfully retrieved Stripe session: {session['id']}")
|
|
||||||
except Exception as session_error:
|
|
||||||
print(f"Failed to retrieve Stripe session {session['id']}: {session_error}")
|
|
||||||
raise session_error
|
|
||||||
|
|
||||||
payment_intent_id = stripe_session.get('payment_intent')
|
payment_intent_id = stripe_session.get('payment_intent')
|
||||||
print(f"Payment intent ID from session: {payment_intent_id}")
|
|
||||||
|
|
||||||
if payment_intent_id:
|
if payment_intent_id:
|
||||||
try:
|
payment_intent = stripe.PaymentIntent.retrieve(payment_intent_id)
|
||||||
payment_intent = stripe.PaymentIntent.retrieve(payment_intent_id)
|
|
||||||
print(f"Successfully retrieved payment intent: {payment_intent_id}")
|
|
||||||
except Exception as pi_error:
|
|
||||||
print(f"Failed to retrieve payment intent {payment_intent_id}: {pi_error}")
|
|
||||||
raise pi_error
|
|
||||||
|
|
||||||
payment_method_id = payment_intent.get('payment_method')
|
payment_method_id = payment_intent.get('payment_method')
|
||||||
print(f"Payment method ID from payment intent: {payment_method_id}")
|
|
||||||
|
|
||||||
if payment_method_id:
|
if payment_method_id:
|
||||||
try:
|
payment_method = stripe.PaymentMethod.retrieve(payment_method_id)
|
||||||
payment_method = stripe.PaymentMethod.retrieve(payment_method_id)
|
|
||||||
print(f"Successfully retrieved payment method: {payment_method_id}")
|
|
||||||
except Exception as pm_error:
|
|
||||||
print(f"Failed to retrieve payment method {payment_method_id}: {pm_error}")
|
|
||||||
raise pm_error
|
|
||||||
|
|
||||||
card_details = payment_method.get('card', {})
|
card_details = payment_method.get('card', {})
|
||||||
print(f"Card details: {card_details}")
|
|
||||||
|
|
||||||
# Get user email (use a fallback since we don't have access to user profile)
|
# Get user email (use a fallback since we don't have access to user profile)
|
||||||
user_email = f"user_{transaction.from_user}@freeleaps.com"
|
user_email = f"user_{transaction.from_user}@freeleaps.com"
|
||||||
print(f"User email for customer creation: {user_email}")
|
|
||||||
|
|
||||||
# Get or create customer for the user
|
# Get or create customer for the user
|
||||||
# Try to find existing customer first
|
|
||||||
customer_id = None
|
customer_id = None
|
||||||
try:
|
try:
|
||||||
# Search for existing customers by email
|
# Search for existing customers by email
|
||||||
customers = stripe.Customer.list(email=user_email, limit=1)
|
customers = stripe.Customer.list(email=user_email, limit=1)
|
||||||
if customers.data:
|
if customers.data:
|
||||||
customer_id = customers.data[0].id
|
customer_id = customers.data[0].id
|
||||||
print(f"Found existing customer: {customer_id}")
|
|
||||||
else:
|
else:
|
||||||
# Create new customer
|
# Create new customer
|
||||||
customer = stripe.Customer.create(
|
customer = stripe.Customer.create(
|
||||||
@ -457,9 +394,7 @@ class StripeManager:
|
|||||||
metadata={"user_id": transaction.from_user}
|
metadata={"user_id": transaction.from_user}
|
||||||
)
|
)
|
||||||
customer_id = customer.id
|
customer_id = customer.id
|
||||||
print(f"Created new customer: {customer_id}")
|
|
||||||
except Exception as customer_error:
|
except Exception as customer_error:
|
||||||
print(f"Error creating/finding customer: {customer_error}")
|
|
||||||
# Use a fallback customer ID or skip payment method saving
|
# Use a fallback customer ID or skip payment method saving
|
||||||
customer_id = None
|
customer_id = None
|
||||||
|
|
||||||
@ -468,7 +403,6 @@ class StripeManager:
|
|||||||
# Check if payment method is already attached to a customer
|
# Check if payment method is already attached to a customer
|
||||||
payment_method_obj = stripe.PaymentMethod.retrieve(payment_method_id)
|
payment_method_obj = stripe.PaymentMethod.retrieve(payment_method_id)
|
||||||
if payment_method_obj.customer:
|
if payment_method_obj.customer:
|
||||||
print(f"Payment method {payment_method_id} already attached to customer {payment_method_obj.customer}")
|
|
||||||
# Use the existing customer ID
|
# Use the existing customer ID
|
||||||
customer_id = payment_method_obj.customer
|
customer_id = payment_method_obj.customer
|
||||||
else:
|
else:
|
||||||
@ -477,7 +411,6 @@ class StripeManager:
|
|||||||
payment_method_id,
|
payment_method_id,
|
||||||
customer=customer_id
|
customer=customer_id
|
||||||
)
|
)
|
||||||
print(f"Successfully attached payment method {payment_method_id} to customer {customer_id}")
|
|
||||||
|
|
||||||
# Check if payment method already exists in our database
|
# Check if payment method already exists in our database
|
||||||
from backend.infra.payment.models import StripePaymentMethodDoc
|
from backend.infra.payment.models import StripePaymentMethodDoc
|
||||||
@ -486,7 +419,6 @@ class StripeManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if existing_payment_method:
|
if existing_payment_method:
|
||||||
print(f"Payment method {payment_method_id} already exists in database, skipping save")
|
|
||||||
payment_method_saved = True
|
payment_method_saved = True
|
||||||
else:
|
else:
|
||||||
# Save to our database only if it doesn't exist
|
# Save to our database only if it doesn't exist
|
||||||
@ -503,10 +435,8 @@ class StripeManager:
|
|||||||
)
|
)
|
||||||
await payment_method_doc.save()
|
await payment_method_doc.save()
|
||||||
payment_method_saved = True
|
payment_method_saved = True
|
||||||
print(f"Successfully saved payment method {payment_method_id} for user {transaction.from_user}")
|
|
||||||
except stripe.error.InvalidRequestError as attach_error:
|
except stripe.error.InvalidRequestError as attach_error:
|
||||||
if "already attached" in str(attach_error).lower():
|
if "already attached" in str(attach_error).lower():
|
||||||
print(f"Payment method {payment_method_id} already attached to customer {customer_id}")
|
|
||||||
# Check if payment method already exists in our database
|
# Check if payment method already exists in our database
|
||||||
from backend.infra.payment.models import StripePaymentMethodDoc
|
from backend.infra.payment.models import StripePaymentMethodDoc
|
||||||
existing_payment_method = await StripePaymentMethodDoc.find_one(
|
existing_payment_method = await StripePaymentMethodDoc.find_one(
|
||||||
@ -514,7 +444,6 @@ class StripeManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if existing_payment_method:
|
if existing_payment_method:
|
||||||
print(f"Payment method {payment_method_id} already exists in database, skipping save")
|
|
||||||
payment_method_saved = True
|
payment_method_saved = True
|
||||||
else:
|
else:
|
||||||
# Still save to our database since it's already attached
|
# Still save to our database since it's already attached
|
||||||
@ -531,10 +460,7 @@ class StripeManager:
|
|||||||
)
|
)
|
||||||
await payment_method_doc.save()
|
await payment_method_doc.save()
|
||||||
payment_method_saved = True
|
payment_method_saved = True
|
||||||
print(f"Successfully saved payment method {payment_method_id} for user {transaction.from_user}")
|
|
||||||
elif "may not be used again" in str(attach_error).lower():
|
elif "may not be used again" in str(attach_error).lower():
|
||||||
print(f"Payment method {payment_method_id} was already used and cannot be attached to customer")
|
|
||||||
print(f"This is normal for one-time payment methods. Saving card details to database anyway.")
|
|
||||||
# Check if payment method already exists in our database
|
# Check if payment method already exists in our database
|
||||||
from backend.infra.payment.models import StripePaymentMethodDoc
|
from backend.infra.payment.models import StripePaymentMethodDoc
|
||||||
existing_payment_method = await StripePaymentMethodDoc.find_one(
|
existing_payment_method = await StripePaymentMethodDoc.find_one(
|
||||||
@ -542,7 +468,6 @@ class StripeManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if existing_payment_method:
|
if existing_payment_method:
|
||||||
print(f"Payment method {payment_method_id} already exists in database, skipping save")
|
|
||||||
payment_method_saved = True
|
payment_method_saved = True
|
||||||
else:
|
else:
|
||||||
# Save to our database even though it can't be attached
|
# Save to our database even though it can't be attached
|
||||||
@ -559,30 +484,18 @@ class StripeManager:
|
|||||||
)
|
)
|
||||||
await payment_method_doc.save()
|
await payment_method_doc.save()
|
||||||
payment_method_saved = True
|
payment_method_saved = True
|
||||||
print(f"Successfully saved payment method {payment_method_id} for user {transaction.from_user} (one-time use)")
|
|
||||||
else:
|
|
||||||
print(f"Error attaching payment method: {attach_error}")
|
|
||||||
except Exception as save_error:
|
except Exception as save_error:
|
||||||
print(f"Error saving payment method to database: {save_error}")
|
await self.module_logger.log_error(
|
||||||
else:
|
error=f"Error saving payment method to database: {save_error}",
|
||||||
print(f"Could not create customer for user {transaction.from_user}, skipping payment method save")
|
properties={"payment_method_id": payment_method_id, "user_id": transaction.from_user}
|
||||||
else:
|
)
|
||||||
print(f"No payment method found in payment intent {payment_intent_id}")
|
|
||||||
else:
|
|
||||||
print(f"No payment intent found in session {session['id']}")
|
|
||||||
|
|
||||||
except Exception as payment_method_error:
|
except Exception as payment_method_error:
|
||||||
print(f"Error processing payment method: {payment_method_error}")
|
await self.module_logger.log_error(
|
||||||
import traceback
|
error=f"Error processing payment method: {payment_method_error}",
|
||||||
print(f"Full traceback for payment method error:")
|
properties={"session_id": session["id"], "user_id": transaction.from_user}
|
||||||
print(traceback.format_exc())
|
)
|
||||||
# Don't fail the webhook if payment method saving fails, but log it
|
# Don't fail the webhook if payment method saving fails, but log it
|
||||||
|
|
||||||
print(f"Payment method saved: {payment_method_saved}")
|
|
||||||
return True, transaction.project_id, transaction.milestone_index
|
return True, transaction.project_id, transaction.milestone_index
|
||||||
|
|
||||||
await self.module_logger.log_info(
|
|
||||||
f"Received non-checkout.session.completed webhook event: {event['type']}",
|
|
||||||
properties={"event_type": event["type"]}
|
|
||||||
)
|
|
||||||
return False, None, None
|
return False, None, None
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user