From 40e5ba084ba048598ca42ca5725437c2bb5643f6 Mon Sep 17 00:00:00 2001 From: kilian Date: Wed, 5 Nov 2025 07:42:00 +0100 Subject: [PATCH] towards mroe robust backend transactions --- backend/src/payments/payment_handler.py | 23 +++++++++++++++++------ backend/src/payments/payment_router.py | 19 ++++++++++++------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/backend/src/payments/payment_handler.py b/backend/src/payments/payment_handler.py index 0fe93d0..26e4057 100644 --- a/backend/src/payments/payment_handler.py +++ b/backend/src/payments/payment_handler.py @@ -5,6 +5,7 @@ from datetime import datetime, timedelta import requests from pydantic import BaseModel, Field, field_validator +from fastapi.responses import RedirectResponse from ..configuration.environment import Environment from ..cache import CreditCache, make_credit_cache_key @@ -268,8 +269,11 @@ class PaypalClient: } } ], + # No redirect from paypal 'application_context': { - 'return_url': return_url_success, + # 'return_url': f'https://anydev.info/orders/{json.loads(order_response.text)["id"]}/{order_request.user_id}capture', # This returns to backend capture-payment URL + # 'cancel_url': return_url_failure + 'return_url': 'https://anydev.info/api/paypal/capture', 'cancel_url': return_url_failure } } @@ -289,10 +293,16 @@ class PaypalClient: self.logger.error(f'Error creating PayPal order: {exc}') return None - order_response.raise_for_status() + try: + order_response.raise_for_status() + except: + return RedirectResponse(url=return_url_failure) + + user_id = order_request.user_id + order_id = json.loads(order_response.text)["id"] # TODO Now that we have the order ID, we can inscribe the details in sql database using the order id given by paypal - # DB for storing the transactions: + # DB for storing the transaction records: # order_id (key): json.loads(order_response.text)["id"] # user_id : order_request.user_id @@ -305,12 +315,13 @@ class PaypalClient: # Create a cache item for credits to be granted to user CreditCache.set_credits( - user_id = order_request.user_id, - order_id = json.loads(order_response.text)["id"], + user_id = user_id, + order_id = order_id, credits_to_grant = order_request.total_credits) - return order_response.json() + # return order_response.json() + return RedirectResponse(url=f'https://anydev.info/orders/{order_id}/{user_id}capture') # Standalone function to capture a payment diff --git a/backend/src/payments/payment_router.py b/backend/src/payments/payment_router.py index 890535d..5c9108c 100644 --- a/backend/src/payments/payment_router.py +++ b/backend/src/payments/payment_router.py @@ -2,6 +2,7 @@ import logging from typing import Literal from fastapi import APIRouter, Query, Body +from fastapi.responses import RedirectResponse from ..payments import PaypalClient, OrderRequest from ..supabase.supabase import SupabaseClient from ..cache import CreditCache, make_credit_cache_key @@ -24,8 +25,8 @@ def create_order( user_id: str = Query(...), basket: list = Query(...), currency: str = Query(...), - return_url_success: str = Query('https://anydev.info'), - return_url_failure: str = Query('https://anydev.info') + return_url_success: str = Query('https://anydev.info/orders/success'), + return_url_failure: str = Query('https://anydev.info/orders/failed') ): """ Creates a new PayPal order. @@ -47,7 +48,10 @@ def create_order( ) # 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) + return paypal_client.order( + order_request=order, + return_url_success=return_url_success, + return_url_failure=return_url_failure) @@ -72,11 +76,12 @@ def capture_order(order_id: str, user_id: str): 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}') + logger.info(f'Payment capture succeeded: incrementing balance of user {user_id} by {credits}.') + return RedirectResponse(url='https://anydev.info/orders/success') + + logger.error(f'Capture payment failed. Could not find cache key for user {user_id} and order {order_id}') - return result + return RedirectResponse(url='https://anydev.info/orders/failed')