Some checks failed
Build and deploy the backend to staging / Build and push image (pull_request) Failing after 1m59s
Build and deploy the backend to staging / Deploy to staging (pull_request) Has been skipped
Run linting on the backend code / Build (pull_request) Successful in 46s
Run testing on the backend code / Build (pull_request) Failing after 2m46s
163 lines
4.8 KiB
Python
163 lines
4.8 KiB
Python
import logging
|
|
from typing import Literal
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from ..payments import PaypalClient, OrderRequest
|
|
from ..supabase.supabase import SupabaseClient
|
|
from ..cache import CreditCache, make_credit_cache_key
|
|
|
|
|
|
# Create a PayPal & Supabase client
|
|
paypal_client = PaypalClient(sandbox_mode=False)
|
|
supabase = SupabaseClient()
|
|
|
|
# Initialize the API router
|
|
router = APIRouter()
|
|
|
|
# Initialize the logger
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# TODO: add the return url in the API payload to redirect the user to the app.
|
|
@router.post("/orders/new")
|
|
def create_order(
|
|
user_id: str,
|
|
basket: list,
|
|
currency: Literal['CHF', 'EUR', 'USD'],
|
|
return_url_success: str = 'https://anydev.info',
|
|
return_url_failure: str = 'https://anydev.info'
|
|
):
|
|
"""
|
|
Creates a new PayPal order.
|
|
|
|
Args:
|
|
user_id (str): The ID of the user placing the order.
|
|
basket (list): The basket items.
|
|
currency (str): The currency code.
|
|
|
|
Returns:
|
|
dict: The PayPal order details.
|
|
"""
|
|
|
|
# Create order :
|
|
order = OrderRequest(
|
|
user_id = user_id,
|
|
basket=basket,
|
|
currency=currency
|
|
)
|
|
|
|
# Process the order and return the details
|
|
return paypal_client.order(order_request=order, return_url_success=return_url_success, return_url_failure=return_url_failure)
|
|
|
|
|
|
|
|
@router.post("/orders/{order_id}/{user_id}capture")
|
|
def capture_order(order_id: str, user_id: str):
|
|
"""
|
|
Captures payment for an existing PayPal order.
|
|
|
|
Args:
|
|
order_id (str): The PayPal order ID.
|
|
|
|
Returns:
|
|
dict: The PayPal capture response.
|
|
"""
|
|
# Capture the payment
|
|
result = paypal_client.capture(order_id)
|
|
|
|
# Grant the user the correct amount of credits:
|
|
credits = CreditCache.get_credits(user_id, order_id)
|
|
if credits:
|
|
supabase.increment_credit_balance(
|
|
user_id=user_id,
|
|
amount=credits
|
|
)
|
|
logger.info('Payment capture succeeded: incrementing balance of user {user_id} by {credits}.')
|
|
else:
|
|
logger.error('Capture payment failed. Could not find cache key for user {user_id} and order {order_id}')
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
# import logging
|
|
# import paypalrestsdk
|
|
# from fastapi import HTTPException, APIRouter
|
|
|
|
# from ..supabase.supabase import SupabaseClient
|
|
# from .payment_handler import PaymentRequest, PaymentHandler
|
|
|
|
# # Set up logging and supabase
|
|
# logger = logging.getLogger(__name__)
|
|
# supabase = SupabaseClient()
|
|
|
|
# # Configure PayPal SDK
|
|
# paypalrestsdk.configure({
|
|
# "mode": "sandbox", # Use 'live' for production
|
|
# "client_id": "YOUR_PAYPAL_CLIENT_ID",
|
|
# "client_secret": "YOUR_PAYPAL_SECRET"
|
|
# })
|
|
|
|
|
|
# # Define the API router
|
|
# router = APIRouter()
|
|
|
|
# @router.post("/purchase/credits")
|
|
# def purchase_credits(payment_request: PaymentRequest):
|
|
# """
|
|
# Handles token purchases. Calculates the number of tokens based on the amount paid,
|
|
# updates the user's balance, and processes PayPal payment.
|
|
# """
|
|
# payment_handler = PaymentHandler(payment_request)
|
|
|
|
# # Create PayPal payment and get the approval URL
|
|
# approval_url = payment_handler.create_paypal_payment()
|
|
|
|
# return {
|
|
# "message": "Purchase initiated successfully",
|
|
# "payment_id": payment_handler.payment_id,
|
|
# "credits": payment_request.credit_amount,
|
|
# "approval_url": approval_url,
|
|
# }
|
|
|
|
|
|
# @router.get("/payment/success")
|
|
# def payment_success(paymentId: str, PayerID: str):
|
|
# """
|
|
# Handles successful PayPal payment.
|
|
# """
|
|
# payment = paypalrestsdk.Payment.find(paymentId)
|
|
|
|
# if payment.execute({"payer_id": PayerID}):
|
|
# logger.info("Payment executed successfully")
|
|
|
|
# # Retrieve transaction details from the database
|
|
# result = supabase.table("pending_payments").select("*").eq("payment_id", paymentId).single().execute()
|
|
# if not result.data:
|
|
# raise HTTPException(status_code=404, detail="Transaction not found")
|
|
|
|
# # Extract the necessary information
|
|
# user_id = result.data["user_id"]
|
|
# credit_amount = result.data["credit_amount"]
|
|
|
|
# # Update the user's balance
|
|
# supabase.increment_credit_balance(user_id, amount=credit_amount)
|
|
|
|
# # Optionally, delete the pending payment entry since the transaction is completed
|
|
# supabase.table("pending_payments").delete().eq("payment_id", paymentId).execute()
|
|
|
|
# return {"message": "Payment completed successfully"}
|
|
# else:
|
|
# logger.error(f"Payment execution failed: {payment.error}")
|
|
# raise HTTPException(status_code=500, detail="Payment execution failed")
|
|
|
|
|
|
# @router.get("/payment/cancel")
|
|
# def payment_cancel():
|
|
# """
|
|
# Handles PayPal payment cancellation.
|
|
# """
|
|
# return {"message": "Payment was cancelled"}
|
|
|