From 9bc3f41ae04627ee86443947eb167a42035f8122 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Mon, 29 Sep 2025 08:43:48 +0200 Subject: [PATCH 1/6] Feat: use a dedicated not-None schema for a payer user --- app/core/myeclpay/endpoints_myeclpay.py | 22 +++----- app/core/payment/payment_tool.py | 50 ++++++++----------- app/core/payment/schemas_payment.py | 8 +++ app/modules/cdr/endpoints_cdr.py | 32 +++--------- app/modules/raid/endpoints_raid.py | 12 +++-- .../endpoints_sport_competition.py | 18 +++---- 6 files changed, 58 insertions(+), 84 deletions(-) diff --git a/app/core/myeclpay/endpoints_myeclpay.py b/app/core/myeclpay/endpoints_myeclpay.py index 30f6e30749..787c6d97a9 100644 --- a/app/core/myeclpay/endpoints_myeclpay.py +++ b/app/core/myeclpay/endpoints_myeclpay.py @@ -1725,27 +1725,17 @@ async def init_ha_transfer( detail="Wallet balance would exceed the maximum allowed balance", ) - user_schema = schemas_users.CoreUser( - account_type=user.account_type, - school_id=user.school_id, - email=user.email, - birthday=user.birthday, - promo=user.promo, - floor=user.floor, - phone=user.phone, - created_on=user.created_on, - groups=[], - id=user.id, - name=user.name, - firstname=user.firstname, - nickname=user.nickname, - ) checkout = await payment_tool.init_checkout( module="myeclpay", checkout_amount=transfer_info.amount, checkout_name="Recharge MyECL Pay", redirection_uri=f"{settings.CLIENT_URL}myeclpay/transfer/redirect?url={transfer_info.redirect_url}", - payer_user=user_schema, + payer_user=schemas_payment.PayerUser( + firstname=user.firstname, + name=user.name, + email=user.email, + birthday=user.birthday, + ), db=db, ) diff --git a/app/core/payment/payment_tool.py b/app/core/payment/payment_tool.py index e0b4166c70..9c867d8a4c 100644 --- a/app/core/payment/payment_tool.py +++ b/app/core/payment/payment_tool.py @@ -19,7 +19,6 @@ from app.core.payment import cruds_payment, models_payment, schemas_payment from app.core.payment.types_payment import HelloAssoConfig -from app.core.users import schemas_users from app.core.utils import security from app.types.exceptions import ( MissingHelloAssoCheckoutIdError, @@ -130,7 +129,7 @@ async def init_checkout( checkout_amount: int, checkout_name: str, db: AsyncSession, - payer_user: schemas_users.CoreUser | None = None, + payer_user: schemas_payment.PayerUser, redirection_uri: str | None = None, ) -> schemas_payment.Checkout: """ @@ -161,14 +160,12 @@ async def init_checkout( # We want to ensure that any error is logged, even if modules tries to try/except this method # Thus we catch any exception and log it, then reraise it try: - payer: HelloAssoApiV5ModelsCartsCheckoutPayer | None = None - if payer_user: - payer = HelloAssoApiV5ModelsCartsCheckoutPayer( - firstName=payer_user.firstname, - lastName=payer_user.name, - email=payer_user.email, - dateOfBirth=payer_user.birthday, - ) + payer = HelloAssoApiV5ModelsCartsCheckoutPayer( + firstName=payer_user.firstname, + lastName=payer_user.name, + email=payer_user.email, + dateOfBirth=payer_user.birthday, + ) checkout_model_id = uuid.uuid4() secret = security.generate_token(nbytes=12) @@ -200,28 +197,23 @@ async def init_checkout( # We know that HelloAsso may refuse some payer infos, like using the firstname "test" # Even when prefilling the payer infos,the user will be able to edit them on the payment page, # so we can safely retry without the payer infos - if not payer_user: - hyperion_error_logger.exception( - f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name} (no payer info provided).", + payer_user_name = f"{payer_user.firstname} {payer_user.name}" + hyperion_error_logger.warning( + f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name}. Retrying without payer infos for {payer_user_name}", + ) + + init_checkout_body.payer = None + try: + response = checkout_api.organizations_organization_slug_checkout_intents_post( + self._helloasso_slug, + init_checkout_body, ) - else: - payer_user_name = f"{payer_user.firstname} {payer_user.name}" - hyperion_error_logger.warning( - f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name}. Retrying without payer infos for {payer_user_name}", + except UnauthorizedException: + # HelloAsso returned a 401 unauthorized again + hyperion_error_logger.exception( + f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name}, with and without payer {payer_user_name} infos", ) - init_checkout_body.payer = None - try: - response = checkout_api.organizations_organization_slug_checkout_intents_post( - self._helloasso_slug, - init_checkout_body, - ) - except UnauthorizedException: - # HelloAsso returned a 401 unauthorized again - hyperion_error_logger.exception( - f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name}, with and without payer {payer_user_name} infos", - ) - if response and response.id: checkout_model = models_payment.Checkout( id=checkout_model_id, diff --git a/app/core/payment/schemas_payment.py b/app/core/payment/schemas_payment.py index ab40eadf65..13f4ae4737 100644 --- a/app/core/payment/schemas_payment.py +++ b/app/core/payment/schemas_payment.py @@ -1,4 +1,5 @@ import uuid +from datetime import date from pydantic import BaseModel, computed_field @@ -38,3 +39,10 @@ class HelloAssoCheckoutMetadata(BaseModel): class PaymentUrl(BaseModel): url: str + + +class PayerUser(BaseModel): + firstname: str + name: str + email: str + birthday: date | None = None diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index fa486eb9e7..abc053a407 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -15,10 +15,11 @@ from fastapi.responses import FileResponse from sqlalchemy.ext.asyncio import AsyncSession -from app.core.groups import cruds_groups, schemas_groups +from app.core.groups import cruds_groups from app.core.groups.groups_type import GroupType from app.core.memberships import cruds_memberships, schemas_memberships from app.core.payment.payment_tool import PaymentTool +from app.core.payment.schemas_payment import PayerUser from app.core.payment.types_payment import HelloAssoConfigName from app.core.users import cruds_users, models_users, schemas_users from app.core.users.cruds_users import get_user_by_id, get_users @@ -2619,33 +2620,16 @@ async def get_payment_url( status_code=403, detail="Please give an amount in cents, greater than 1€.", ) - user_schema = schemas_users.CoreUser( - account_type=user.account_type, - school_id=user.school_id, - email=user.email, - birthday=user.birthday, - promo=user.promo, - floor=user.floor, - phone=user.phone, - created_on=user.created_on, - groups=[ - schemas_groups.CoreGroupSimple( - id=group.id, - name=group.name, - description=group.description, - ) - for group in user.groups - ], - id=user.id, - name=user.name, - firstname=user.firstname, - nickname=user.nickname, - ) checkout = await payment_tool.init_checkout( module=module.root, checkout_amount=amount, checkout_name="Chaine de rentrée", - payer_user=user_schema, + payer_user=PayerUser( + firstname=user.firstname, + name=user.name, + email=user.email, + birthday=user.birthday, + ), db=db, ) hyperion_error_logger.info(f"CDR: Logging Checkout id {checkout.id}") diff --git a/app/modules/raid/endpoints_raid.py b/app/modules/raid/endpoints_raid.py index 9b866fd244..a0f914138d 100644 --- a/app/modules/raid/endpoints_raid.py +++ b/app/modules/raid/endpoints_raid.py @@ -9,8 +9,9 @@ from app.core.groups.groups_type import AccountType, GroupType from app.core.payment.payment_tool import PaymentTool +from app.core.payment.schemas_payment import PayerUser from app.core.payment.types_payment import HelloAssoConfigName -from app.core.users import models_users, schemas_users +from app.core.users import models_users from app.dependencies import ( get_db, get_payment_tool, @@ -900,13 +901,16 @@ async def get_payment_url( if not participant: raise HTTPException(status_code=403, detail="You are not a participant.") price, checkout_name = calculate_raid_payment(participant, raid_prices) - user_dict = user.__dict__ - user_dict.pop("school", None) checkout = await payment_tool.init_checkout( module=module.root, checkout_amount=price, checkout_name=checkout_name, - payer_user=schemas_users.CoreUser(**user_dict), + payer_user=PayerUser( + firstname=user.firstname, + name=user.name, + email=user.email, + birthday=user.birthday, + ), db=db, ) hyperion_error_logger.info(f"RAID: Logging Checkout id {checkout.id}") diff --git a/app/modules/sport_competition/endpoints_sport_competition.py b/app/modules/sport_competition/endpoints_sport_competition.py index a480f22a07..5219d20d17 100644 --- a/app/modules/sport_competition/endpoints_sport_competition.py +++ b/app/modules/sport_competition/endpoints_sport_competition.py @@ -8,6 +8,7 @@ from app.core.groups.groups_type import GroupType, get_account_types_except_externals from app.core.payment.payment_tool import PaymentTool +from app.core.payment.schemas_payment import PayerUser from app.core.payment.types_payment import HelloAssoConfigName from app.core.schools import cruds_schools from app.core.schools.schools_type import SchoolType @@ -3486,21 +3487,16 @@ async def get_payment_url( status_code=403, detail="Please give an amount in cents, greater than 1€.", ) - user_schema = schemas_users.CoreUser( - account_type=user.account_type, - school_id=user.school_id, - id=user.id, - email=user.email, - name=user.name, - firstname=user.firstname, - created_on=user.created_on, - groups=[], - ) checkout = await payment_tool.init_checkout( module=module.root, checkout_amount=amount, checkout_name=f"Challenge {edition.name}", - payer_user=user_schema, + payer_user=PayerUser( + firstname=user.firstname, + name=user.name, + email=user.email, + birthday=user.birthday, + ), db=db, ) hyperion_error_logger.info(f"Competition: Logging Checkout id {checkout.id}") From 11e2be6078b0f062646e0fb97f16645a43491fdb Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Mon, 29 Sep 2025 20:07:51 +0200 Subject: [PATCH 2/6] Fix: tests --- tests/commons.py | 4 ++-- tests/test_payment.py | 33 +++++++++++++-------------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/tests/commons.py b/tests/commons.py index 5b664defad..abc69b2969 100644 --- a/tests/commons.py +++ b/tests/commons.py @@ -20,7 +20,7 @@ from app.core.payment.payment_tool import PaymentTool from app.core.payment.types_payment import HelloAssoConfig, HelloAssoConfigName from app.core.schools.schools_type import SchoolType -from app.core.users import cruds_users, models_users, schemas_users +from app.core.users import cruds_users, models_users from app.core.utils import security from app.core.utils.config import Settings from app.types import core_data @@ -305,7 +305,7 @@ async def init_checkout( checkout_amount: int, checkout_name: str, db: AsyncSession, - payer_user: schemas_users.CoreUser | None = None, + payer_user: schemas_payment.PayerUser, redirection_uri: str | None = None, ) -> schemas_payment.Checkout: exist = await cruds_payment.get_checkout_by_id(mocked_checkout_id, db) diff --git a/tests/test_payment.py b/tests/test_payment.py index 88cd84264a..f7f4552d52 100644 --- a/tests/test_payment.py +++ b/tests/test_payment.py @@ -4,7 +4,7 @@ import pytest import pytest_asyncio from fastapi.testclient import TestClient -from helloasso_python.exceptions import UnauthorizedException +from helloasso_python.exceptions import BadRequestException from helloasso_python.models.hello_asso_api_v5_models_carts_init_checkout_body import ( HelloAssoApiV5ModelsCartsInitCheckoutBody, ) @@ -18,8 +18,6 @@ from app.core.payment import cruds_payment, models_payment, schemas_payment from app.core.payment.payment_tool import PaymentTool from app.core.payment.types_payment import HelloAssoConfig, HelloAssoConfigName -from app.core.schools import schemas_schools -from app.core.users import schemas_users from app.types.module import Module from tests.commons import ( MockedPaymentTool, @@ -35,7 +33,7 @@ existing_checkout_payment: models_payment.CheckoutPayment checkout: models_payment.Checkout -user_schema: schemas_users.CoreUser +payer_user: schemas_payment.PayerUser TEST_MODULE_ROOT = "tests" @@ -74,19 +72,14 @@ async def init_objects() -> None: ) await add_object_to_db(checkout) - global user_schema - user = await create_user_with_groups( - groups=[], + user = await create_user_with_groups(groups=[]) + global payer_user + payer_user = schemas_payment.PayerUser( + firstname=user.firstname, + name=user.name, + email=user.email, + birthday=user.birthday, ) - school = schemas_schools.CoreSchool( - id=user.school.id, - name=user.school.name, - email_regex=user.school.email_regex, - ) - user_dict = user.__dict__ - user_dict.pop("school") - - user_schema = schemas_users.CoreUser(**user_dict, school=school) # Test endpoints # @@ -451,7 +444,7 @@ async def test_payment_tool_init_checkout( checkout_name="test", redirection_uri="redirect", db=db, - payer_user=user_schema, + payer_user=payer_user, ) assert returned_checkout.payment_url == redirect_url @@ -497,7 +490,7 @@ def init_a_checkout_side_effect( if init_checkout_body.payer is not None: r = Response() r.status_code = 400 - raise UnauthorizedException + raise BadRequestException return HelloAssoApiV5ModelsCartsInitCheckoutResponse( id=7, redirect_url=redirect_url, @@ -526,7 +519,7 @@ def init_a_checkout_side_effect( checkout_name="test", redirection_uri="redirect", db=db, - payer_user=user_schema, + payer_user=payer_user, ) assert returned_checkout.payment_url == redirect_url @@ -592,7 +585,7 @@ async def test_payment_tool_init_checkout_fail( checkout_name="test", redirection_uri="redirect", db=db, - payer_user=user_schema, + payer_user=payer_user, ) mocked_hyperion_security_logger.assert_called() From a22bbfd2eb6cfa95ed651ef08291c51a4af8d069 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Mon, 29 Sep 2025 20:11:15 +0200 Subject: [PATCH 3/6] Rewrite of init_checkout --- app/core/payment/payment_tool.py | 99 ++++++++++++++++---------------- 1 file changed, 48 insertions(+), 51 deletions(-) diff --git a/app/core/payment/payment_tool.py b/app/core/payment/payment_tool.py index 9c867d8a4c..6b8ab20f96 100644 --- a/app/core/payment/payment_tool.py +++ b/app/core/payment/payment_tool.py @@ -8,7 +8,7 @@ from helloasso_python.api.paiements_api import PaiementsApi from helloasso_python.api_client import ApiClient from helloasso_python.configuration import Configuration -from helloasso_python.exceptions import UnauthorizedException +from helloasso_python.exceptions import BadRequestException, UnauthorizedException from helloasso_python.models.hello_asso_api_v5_models_carts_checkout_payer import ( HelloAssoApiV5ModelsCartsCheckoutPayer, ) @@ -151,25 +151,24 @@ async def init_checkout( This method use HelloAsso API. It may raise exceptions if HA checkout initialization fails. Exceptions can be imported from `helloasso_python` package. """ - configuration = self.get_hello_asso_configuration() redirection_uri = redirection_uri or self._redirection_uri if not redirection_uri: raise UnsetRedirectionUriError - # We want to ensure that any error is logged, even if modules tries to try/except this method - # Thus we catch any exception and log it, then reraise it + exception_start = f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name} for payer {payer_user.firstname} {payer_user.name}" try: + # We want to ensure that any error is logged + # Thus we catch any exception and log it, then reraise it + + checkout_model_id = uuid.uuid4() + secret = security.generate_token(nbytes=12) payer = HelloAssoApiV5ModelsCartsCheckoutPayer( firstName=payer_user.firstname, lastName=payer_user.name, email=payer_user.email, dateOfBirth=payer_user.birthday, ) - - checkout_model_id = uuid.uuid4() - secret = security.generate_token(nbytes=12) - init_checkout_body = HelloAssoApiV5ModelsCartsInitCheckoutBody( total_amount=checkout_amount, initial_amount=checkout_amount, @@ -186,6 +185,7 @@ async def init_checkout( ) response: HelloAssoApiV5ModelsCartsInitCheckoutResponse + configuration = self.get_hello_asso_configuration() with ApiClient(configuration) as api_client: checkout_api = CheckoutApi(api_client) try: @@ -193,57 +193,54 @@ async def init_checkout( self._helloasso_slug, init_checkout_body, ) - except UnauthorizedException: - # We know that HelloAsso may refuse some payer infos, like using the firstname "test" - # Even when prefilling the payer infos,the user will be able to edit them on the payment page, - # so we can safely retry without the payer infos - payer_user_name = f"{payer_user.firstname} {payer_user.name}" + except BadRequestException: + # In this case only, we retry hyperion_error_logger.warning( - f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name}. Retrying without payer infos for {payer_user_name}", + f"{exception_start}: retrying without payer infos", ) - init_checkout_body.payer = None - try: - response = checkout_api.organizations_organization_slug_checkout_intents_post( - self._helloasso_slug, - init_checkout_body, - ) - except UnauthorizedException: - # HelloAsso returned a 401 unauthorized again - hyperion_error_logger.exception( - f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name}, with and without payer {payer_user_name} infos", - ) - - if response and response.id: - checkout_model = models_payment.Checkout( - id=checkout_model_id, - module=module, - name=checkout_name, - amount=checkout_amount, - hello_asso_checkout_id=response.id, - secret=secret, - ) - - await cruds_payment.create_checkout(db=db, checkout=checkout_model) - - return schemas_payment.Checkout( - id=checkout_model_id, - payment_url=response.redirect_url, - ) - hyperion_error_logger.error( - f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name}. No checkout id returned", + response = checkout_api.organizations_organization_slug_checkout_intents_post( + self._helloasso_slug, + init_checkout_body, + ) + if response.id is None: + raise MissingHelloAssoCheckoutIdError() # noqa: TRY301 + + checkout_model = models_payment.Checkout( + id=checkout_model_id, + module=module, + name=checkout_name, + amount=checkout_amount, + hello_asso_checkout_id=response.id, + secret=secret, + ) + await cruds_payment.create_checkout(db=db, checkout=checkout_model) + return schemas_payment.Checkout( + id=checkout_model_id, + payment_url=response.redirect_url, ) - raise MissingHelloAssoCheckoutIdError() # noqa: TRY301 - except Exception: - # Different from a 401 unauthorized - payer_user_name = "" - if payer_user: - payer_user_name = f"{payer_user.firstname} {payer_user.name}" + except UnauthorizedException as e: + hyperion_error_logger.exception( + f"{exception_start}: unauthorized for headers {e.headers}.", + ) + raise + except BadRequestException as e: + # We know that HelloAsso may refuse some payer infos, + # e.g. >18 years old, valid email, and firstname and name without some characters and patterns. + # See https://dev.helloasso.com/docs/int%C3%A9grer-le-paiement-sur-votre-site#contr%C3%B4le-des-champs hyperion_error_logger.exception( - f"Payment: failed to init a checkout with HA for module {module} and name {checkout_name} with payer {payer_user_name} infos", + f"{exception_start}: bad request for reason {e.data or e.body}.", ) raise + except MissingHelloAssoCheckoutIdError: + hyperion_error_logger.exception( + f"{exception_start}: no checkout id returned.", + ) + raise + except Exception: + hyperion_error_logger.exception(f"{exception_start}: unknown exception.") + raise async def get_checkout( self, From 9acd5409c06ee20781c455970bc7e06df9a057fb Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Mon, 29 Sep 2025 20:49:05 +0200 Subject: [PATCH 4/6] Feat: catching exceptions in endpoints that use init_checkout --- app/core/myeclpay/endpoints_myeclpay.py | 36 ++++++++++--------- app/modules/cdr/endpoints_cdr.py | 30 +++++++++------- app/modules/raid/endpoints_raid.py | 28 ++++++++------- .../endpoints_sport_competition.py | 30 +++++++++------- 4 files changed, 70 insertions(+), 54 deletions(-) diff --git a/app/core/myeclpay/endpoints_myeclpay.py b/app/core/myeclpay/endpoints_myeclpay.py index 787c6d97a9..dfab09c900 100644 --- a/app/core/myeclpay/endpoints_myeclpay.py +++ b/app/core/myeclpay/endpoints_myeclpay.py @@ -1097,6 +1097,7 @@ async def register_user( accepted_tos_version=0, db=db, ) + db.flush() hyperion_myeclpay_logger.info( wallet_id, @@ -1685,7 +1686,7 @@ async def init_ha_transfer( ) raise HTTPException( status_code=400, - detail="Redirect URL is not trusted by hyperion", + detail="Redirect URL is not trusted by Hyperion", ) if transfer_info.amount < 100: @@ -1701,7 +1702,7 @@ async def init_ha_transfer( if user_payment is None: raise HTTPException( status_code=404, - detail="User is not registered for MyECL Pay", + detail="User is not registered for MyECLPay", ) if not is_user_latest_tos_signed(user_payment): @@ -1725,19 +1726,23 @@ async def init_ha_transfer( detail="Wallet balance would exceed the maximum allowed balance", ) - checkout = await payment_tool.init_checkout( - module="myeclpay", - checkout_amount=transfer_info.amount, - checkout_name="Recharge MyECL Pay", - redirection_uri=f"{settings.CLIENT_URL}myeclpay/transfer/redirect?url={transfer_info.redirect_url}", - payer_user=schemas_payment.PayerUser( - firstname=user.firstname, - name=user.name, - email=user.email, - birthday=user.birthday, - ), - db=db, - ) + try: + checkout = await payment_tool.init_checkout( + module="myeclpay", + checkout_amount=transfer_info.amount, + checkout_name="Recharge MyECL Pay", + redirection_uri=f"{settings.CLIENT_URL}myeclpay/transfer/redirect?url={transfer_info.redirect_url}", + payer_user=schemas_payment.PayerUser( + firstname=user.firstname, + name=user.name, + email=user.email, + birthday=user.birthday, + ), + db=db, + ) + except Exception: + raise HTTPException(status_code=502, detail="Cannot init the checkout") + hyperion_error_logger.info(f"Competition: Logging Checkout id {checkout.id}") await cruds_myeclpay.create_transfer( db=db, @@ -1752,7 +1757,6 @@ async def init_ha_transfer( confirmed=False, ), ) - return schemas_payment.PaymentUrl( url=checkout.payment_url, ) diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index abc053a407..dd751d094a 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -2620,19 +2620,24 @@ async def get_payment_url( status_code=403, detail="Please give an amount in cents, greater than 1€.", ) - checkout = await payment_tool.init_checkout( - module=module.root, - checkout_amount=amount, - checkout_name="Chaine de rentrée", - payer_user=PayerUser( - firstname=user.firstname, - name=user.name, - email=user.email, - birthday=user.birthday, - ), - db=db, - ) + + try: + checkout = await payment_tool.init_checkout( + module=module.root, + checkout_amount=amount, + checkout_name="Chaine de rentrée", + payer_user=PayerUser( + firstname=user.firstname, + name=user.name, + email=user.email, + birthday=user.birthday, + ), + db=db, + ) + except Exception: + raise HTTPException(status_code=502, detail="Cannot init the checkout") hyperion_error_logger.info(f"CDR: Logging Checkout id {checkout.id}") + cruds_cdr.create_checkout( db=db, checkout=models_cdr.Checkout( @@ -2641,7 +2646,6 @@ async def get_payment_url( checkout_id=checkout.id, ), ) - return schemas_cdr.PaymentUrl( url=checkout.payment_url, ) diff --git a/app/modules/raid/endpoints_raid.py b/app/modules/raid/endpoints_raid.py index a0f914138d..e455225c93 100644 --- a/app/modules/raid/endpoints_raid.py +++ b/app/modules/raid/endpoints_raid.py @@ -901,19 +901,23 @@ async def get_payment_url( if not participant: raise HTTPException(status_code=403, detail="You are not a participant.") price, checkout_name = calculate_raid_payment(participant, raid_prices) - checkout = await payment_tool.init_checkout( - module=module.root, - checkout_amount=price, - checkout_name=checkout_name, - payer_user=PayerUser( - firstname=user.firstname, - name=user.name, - email=user.email, - birthday=user.birthday, - ), - db=db, - ) + try: + checkout = await payment_tool.init_checkout( + module=module.root, + checkout_amount=price, + checkout_name=checkout_name, + payer_user=PayerUser( + firstname=user.firstname, + name=user.name, + email=user.email, + birthday=user.birthday, + ), + db=db, + ) + except Exception: + raise HTTPException(status_code=502, detail="Cannot init the checkout") hyperion_error_logger.info(f"RAID: Logging Checkout id {checkout.id}") + await cruds_raid.create_participant_checkout( models_raid.RaidParticipantCheckout( id=str(uuid.uuid4()), diff --git a/app/modules/sport_competition/endpoints_sport_competition.py b/app/modules/sport_competition/endpoints_sport_competition.py index 5219d20d17..eec6fe154d 100644 --- a/app/modules/sport_competition/endpoints_sport_competition.py +++ b/app/modules/sport_competition/endpoints_sport_competition.py @@ -3487,19 +3487,24 @@ async def get_payment_url( status_code=403, detail="Please give an amount in cents, greater than 1€.", ) - checkout = await payment_tool.init_checkout( - module=module.root, - checkout_amount=amount, - checkout_name=f"Challenge {edition.name}", - payer_user=PayerUser( - firstname=user.firstname, - name=user.name, - email=user.email, - birthday=user.birthday, - ), - db=db, - ) + + try: + checkout = await payment_tool.init_checkout( + module=module.root, + checkout_amount=amount, + checkout_name=f"Challenge {edition.name}", + payer_user=PayerUser( + firstname=user.firstname, + name=user.name, + email=user.email, + birthday=user.birthday, + ), + db=db, + ) + except Exception: + raise HTTPException(status_code=502, detail="Cannot init the checkout") hyperion_error_logger.info(f"Competition: Logging Checkout id {checkout.id}") + cruds_sport_competition.add_checkout( db=db, checkout=schemas_sport_competition.Checkout( @@ -3509,7 +3514,6 @@ async def get_payment_url( checkout_id=checkout.id, ), ) - return schemas_sport_competition.PaymentUrl( url=checkout.payment_url, ) From 04984f9500ccb5093b41f353f42fe71706565c58 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Mon, 29 Sep 2025 20:53:17 +0200 Subject: [PATCH 5/6] not very discreet... --- app/core/myeclpay/endpoints_myeclpay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/core/myeclpay/endpoints_myeclpay.py b/app/core/myeclpay/endpoints_myeclpay.py index dfab09c900..8ceca54c1e 100644 --- a/app/core/myeclpay/endpoints_myeclpay.py +++ b/app/core/myeclpay/endpoints_myeclpay.py @@ -1097,7 +1097,7 @@ async def register_user( accepted_tos_version=0, db=db, ) - db.flush() + await db.flush() hyperion_myeclpay_logger.info( wallet_id, From 2dd0f371e983d6f829e8cdd026998a161291d591 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Mon, 29 Sep 2025 21:05:18 +0200 Subject: [PATCH 6/6] no comment --- tests/test_myeclpay.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_myeclpay.py b/tests/test_myeclpay.py index 99f11199db..66fdf82018 100644 --- a/tests/test_myeclpay.py +++ b/tests/test_myeclpay.py @@ -1789,7 +1789,7 @@ def test_transfer_with_redirect_url_not_trusted(client: TestClient): ) assert response.status_code == 400 - assert response.json()["detail"] == "Redirect URL is not trusted by hyperion" + assert response.json()["detail"] == "Redirect URL is not trusted by Hyperion" def test_transfer_with_unregistered_user(client: TestClient): @@ -1804,7 +1804,7 @@ def test_transfer_with_unregistered_user(client: TestClient): ) assert response.status_code == 404 - assert response.json()["detail"] == "User is not registered for MyECL Pay" + assert response.json()["detail"] == "User is not registered for MyECLPay" def test_transfer_with_too_small_amount(client: TestClient):