diff --git a/sources/AppBundle/Controller/Website/Membership/PayboxCallbackAction.php b/sources/AppBundle/Controller/Website/Membership/PayboxCallbackAction.php index c9faa4bfd..b06efab56 100644 --- a/sources/AppBundle/Controller/Website/Membership/PayboxCallbackAction.php +++ b/sources/AppBundle/Controller/Website/Membership/PayboxCallbackAction.php @@ -48,8 +48,17 @@ public function __invoke(Request $request): Response $etat = MembershipFeePaymentStatus::Rejected; } + $cmd = $payboxResponse->getCmd(); + + $cleanedCmd = $cmd; + // cf payboxfactory, on a un suffixe pour gérer l'unicité et éviter une erreur "An error occurred while creating or updating row in fappel" + $suffixPos = strpos($cleanedCmd, '__'); + if (false !== $suffixPos) { + $cleanedCmd = substr($cleanedCmd, 0, $suffixPos); + } + if ($etat == MembershipFeePaymentStatus::Paid) { - $account = $this->onlinePaymentHandler->getAccountFromCmd($payboxResponse->getCmd()); + $account = $this->onlinePaymentHandler->getAccountFromCmd($cleanedCmd); $lastCotisation = $this->membershipFeeService->getLatestByUserTypeAndId(MemberType::from($account['type']), $account['id']); if (!$lastCotisation instanceof MembershipFee && $account['type'] == MemberType::MemberPhysical->value) { @@ -57,9 +66,9 @@ public function __invoke(Request $request): Response $this->eventDispatcher->dispatch(new NewMemberEvent($user)); } - $this->onlinePaymentHandler->validerReglementEnLigne($payboxResponse->getCmd(), round($payboxResponse->getTotal() / 100, 2), $payboxResponse->getAuthorizationId(), $payboxResponse->getTransactionId()); - $this->membershipFeeMailer->notifierReglementEnLigneAuTresorier($payboxResponse->getCmd(), round($payboxResponse->getTotal() / 100, 2), $payboxResponse->getAuthorizationId(), $payboxResponse->getTransactionId()); - $this->audit->log("Ajout de la cotisation " . $payboxResponse->getCmd() . " via Paybox."); + $this->onlinePaymentHandler->validerReglementEnLigne($cleanedCmd, round($payboxResponse->getTotal() / 100, 2), $payboxResponse->getAuthorizationId(), $payboxResponse->getTransactionId()); + $this->membershipFeeMailer->notifierReglementEnLigneAuTresorier($cleanedCmd, round($payboxResponse->getTotal() / 100, 2), $payboxResponse->getAuthorizationId(), $payboxResponse->getTransactionId()); + $this->audit->log("Ajout de la cotisation " . $cleanedCmd . " via Paybox."); } return new Response(); } diff --git a/sources/AppBundle/Payment/PayboxFactory.php b/sources/AppBundle/Payment/PayboxFactory.php index 5701757f7..9a7fe0d9b 100644 --- a/sources/AppBundle/Payment/PayboxFactory.php +++ b/sources/AppBundle/Payment/PayboxFactory.php @@ -34,7 +34,7 @@ public function createPayboxForSubscription($facture, $montant, $email, PayboxBi $paybox ->setTotal((int) $montant * 100) // Total de la commande, en centimes d'euros - ->setCmd($facture) // Référence de la commande + ->setCmd($facture . '__' . uniqid()) // Référence de la commande + un suffixe pour gérer l'unicité et éviter une erreur "An error occurred while creating or updating row in fappel" sur paybox notamment en environnement de test ->setPorteur($email) // Email du client final (Le porteur de la carte) ->setUrlRetourEffectue($this->router->generate('membership_payment_redirect', ['type' => 'success'], RouterInterface::ABSOLUTE_URL)) ->setUrlRetourRefuse($this->router->generate('membership_payment_redirect', ['type' => 'refused'], RouterInterface::ABSOLUTE_URL)) diff --git a/tests/behat/bootstrap/FormContext.php b/tests/behat/bootstrap/FormContext.php index 824be5abd..2906a4859 100644 --- a/tests/behat/bootstrap/FormContext.php +++ b/tests/behat/bootstrap/FormContext.php @@ -25,6 +25,21 @@ public function submitFormWithName(string $formName): void $form->submit(); } + #[Then('I submit the form with id :formId')] + public function submitFormWithId(string $formId): void + { + $form = $this->minkContext->getSession()->getPage()->find('xpath', "//form[@id='$formId']"); + + if (null === $form) { + throw new ExpectationException( + sprintf('The form of id "%s" not found', $formId), + $this->minkContext->getSession()->getDriver(), + ); + } + + $form->submit(); + } + #[Then('The :field field should only contain the follow values :expectedValuesJson')] public function selectHasValues(string $field, string $expectedValuesJson): void { diff --git a/tests/behat/features/EventPages/Ticketing.feature b/tests/behat/features/EventPages/Ticketing.feature index e3350db96..fe28a58c0 100644 --- a/tests/behat/features/EventPages/Ticketing.feature +++ b/tests/behat/features/EventPages/Ticketing.feature @@ -32,6 +32,7 @@ Feature: Event pages - Ticketing When I press "Régler par carte" # Pour suivre la redirection POST de Paybox And I submit the form with name "PAYBOX" + And I submit the form with id "payment_page_redirect_form" When I fill in "NUMERO_CARTE" with "1111222233334444" And I select "12" from "MOIS_VALIDITE" And I select "26" from "AN_VALIDITE" diff --git a/tests/behat/features/PublicSite/Register.feature b/tests/behat/features/PublicSite/Register.feature index 1e264e4c2..335a097aa 100644 --- a/tests/behat/features/PublicSite/Register.feature +++ b/tests/behat/features/PublicSite/Register.feature @@ -46,6 +46,7 @@ Feature: Site Public - Register When I press "Régler par carte" # Pour suivre la redirection POST de Paybox And I submit the form with name "PAYBOX" + And I submit the form with id "payment_page_redirect_form" When I fill in "NUMERO_CARTE" with "1111222233334444" And I select "12" from "MOIS_VALIDITE" And I select "26" from "AN_VALIDITE" @@ -85,6 +86,7 @@ Feature: Site Public - Register When I press "Régler par carte" # Pour suivre la redirection POST de Paybox And I submit the form with name "PAYBOX" + And I submit the form with id "payment_page_redirect_form" When I fill in "NUMERO_CARTE" with "1111222233334444" And I select "12" from "MOIS_VALIDITE" And I select "26" from "AN_VALIDITE"