crypto.ai/cryptoai/routes/payment.py
2025-06-13 11:08:36 +08:00

149 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from fastapi import APIRouter
from pydantic import BaseModel
from cryptoai.utils.upay import Upay
from datetime import datetime
from cryptoai.models.subscription_order import SubscriptionOrderManager
import random
from cryptoai.routes.user import get_current_user
from cryptoai.models.user import User
from fastapi import Depends
from sqlalchemy.orm import Session
from cryptoai.utils.db_manager import get_db
from cryptoai.models.user_subscription import UserSubscriptionManager
from datetime import timedelta
import logging
router = APIRouter()
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
class CreateOrderRequest(BaseModel):
subscribe_type: int
pricing = {
"price_month": 29,
"price_year": 269
}
@router.get('/pricing')
async def pricing_info():
return {
"code": 200,
"data": {
"price_month": pricing["price_month"],
"price_year": pricing["price_year"]
}
}
@router.post("/create_order")
async def create_order(request: CreateOrderRequest,
current_user: User = Depends(get_current_user),
session: Session = Depends(get_db)):
upay = Upay()
# 生成唯一的商户订单号
merchant_order_no = f"D{datetime.now().strftime('%Y%m%d%H%M%S')}{random.randint(100, 999)}"
## 1=包月2=包年
if request.subscribe_type == 1:
fiat_amount = str(pricing["price_month"])
product_name = "会员订阅1个月"
elif request.subscribe_type == 2:
fiat_amount = str(pricing["price_year"])
product_name = "会员订阅1年"
else:
return {
"code": 500,
"message": "Invalid subscribe type"
}
result = upay.create_order(
merchant_order_no=merchant_order_no,
chain_type="1", ## TRC20
fiat_amount=fiat_amount,
fiat_currency="USD",
notify_url="https://api.ibtc.work/payment/notify",
product_name=product_name,
redirect_url="https://tradus.vip/subscription-success"
)
print(result)
if result['code'] == "1":
payment_order_id = result['data']['orderNo']
order_id = result['data']['merchantOrderNo']
## 创建订阅记录
subscription_order_manager = SubscriptionOrderManager(session)
subscription_order_manager.create_order(
order_id=order_id,
user_id=current_user["id"],
payment_order_id=payment_order_id,
amount=float(fiat_amount),
member_type=1,
currency="USD",
time_type=request.subscribe_type,
status=1
)
return {
"code": 200,
"data": {
"order_no": result['data']['orderNo'],
"pay_url": result['data']['payUrl'],
"status": result['data']['status']
}
}
else:
return {
"code": 500,
"message": result['message']
}
class NotifyRequest(BaseModel):
merchantOrderNo: str
status: str
@router.post("/notify")
async def notify(notify: NotifyRequest, session: Session = Depends(get_db)):
try:
subscription_order_manager = SubscriptionOrderManager(session)
## 订单完成
if notify.status == "1":
# 更新订单状态
subscription_order_manager.update_order_status(notify.merchantOrderNo, 2)
order = subscription_order_manager.get_order_by_id(notify.merchantOrderNo)
if order is None:
return {
"code": 500,
"message": "Order not found"
}
user_id = order['user_id']
member_type = order['member_type']
time_type = order['time_type']
if time_type == 1:
expire_time = datetime.now().replace(hour=23, minute=59, second=59) + timedelta(days=30)
elif time_type == 2:
expire_time = datetime.now().replace(hour=23, minute=59, second=59) + timedelta(days=365)
#增加用户订阅记录
user_subscription_manager = UserSubscriptionManager(session)
user_subscription_manager.create_subscription(user_id,
member_type,
time_type,
notify.merchantOrderNo,
expire_time)
else:
subscription_order_manager.update_order_status(notify.merchantOrderNo, 4)
return "ok"
except Exception as e:
logger.error(f"创建用户订阅失败: {e}")
raise e