<?php namespace App\EventListener; use Payum\Core\Extension\Context; use Payum\Core\Extension\ExtensionInterface; use Payum\Core\Model\PaymentInterface; use Payum\Core\Request\Generic; use Payum\Core\Request\GetHumanStatus; use Payum\Core\Request\GetStatusInterface; use Payum\Core\Bridge\Symfony\Event\ExecuteEvent; use Doctrine\ORM\EntityManagerInterface; use FOS\UserBundle\Model\UserManagerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Serializer\SerializerInterface; use App\Events\MLCEvents; use App\Events\FluxEvent; use App\Entity\Flux; use App\Entity\Payment; use App\Entity\PaymentToken; use App\Entity\Siege; use App\Entity\User; use App\Entity\Adherent; use App\Entity\Prestataire; use App\Entity\Geoloc; use App\Entity\Groupe; use App\Entity\Usergroup; use App\Entity\AchatMonnaieAdherent; use App\Entity\AchatMonnaiePrestataire; use App\Entity\CotisationAdherent; use App\Entity\CotisationPrestataire; use App\Entity\Don; use App\Utils\OperationUtils; use App\Utils\TAVCotisationUtils; class PaymentStatusExtension implements ExtensionInterface { private $em; private $eventDispatcher; private $serializer; private $userManager; private $operationUtils; private $tavCotisationsUtils; /** * PaymentStatusExtension constructor. * * @param EntityManagerInterface $em */ public function __construct( EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher, SerializerInterface $serializer, UserManagerInterface $userManager, OperationUtils $operationUtils, TAVCotisationUtils $tavCotisationsUtils ) { $this->em = $em; $this->eventDispatcher = $eventDispatcher; $this->serializer = $serializer; $this->userManager = $userManager; $this->operationUtils = $operationUtils; $this->tavCotisationsUtils = $tavCotisationsUtils; } /** * Fired after a payum 'execute' to detect payment status changes after a notification * {@inheritDoc} */ public function onPostExecute(Context $context) { $request = $context->getRequest(); if (false == $request instanceof Generic) { return; } if ($request instanceof GetStatusInterface) { return; } $payment = $request->getFirstModel(); if (false == $payment instanceof PaymentInterface) { return; } try { $token = $request->getToken(); } catch (\Exception $e) { return; } // Get current & new status $context->getGateway()->execute($status = new GetHumanStatus($payment)); $current_payment_status = $payment->getStatus(); // Payment can be captured if it hasn't been captured before if ($current_payment_status !== GetHumanStatus::STATUS_CAPTURED && $current_payment_status != GetHumanStatus::STATUS_AUTHORIZED) { // If payment succesful, persist serialized 'Flux' stored in payment if ($status->getValue() == GetHumanStatus::STATUS_CAPTURED || $status->getValue() == GetHumanStatus::STATUS_AUTHORIZED) { $flux_array = json_decode($payment->getFluxData(), true); $type = $payment->getDescription(); if (Payment::TYPE_ACHAT_MONNAIE_ADHERENT == $type) { $flux = $this->serializer->deserialize( $payment->getFluxData(), AchatMonnaieAdherent::class, 'json', ['disable_type_enforcement' => true] ); $exp = $this->em->getRepository(Siege::class)->find($flux_array['expediteur']); $flux->setExpediteur($exp); $dest = $this->em->getRepository(Adherent::class)->find($flux_array['destinataire']); $flux->setDestinataire($dest); $op = $this->em->getRepository(User::class)->find($flux_array['operateur']); $flux->setOperateur($op); $flux->setReconverti(true); if (null != $flux->getDon()) { $flux->getDon()->setType(Don::TYPE_DON_ADHERENT); $flux->getDon()->setOperateur($op); $flux->getDon()->setExpediteur($dest); $flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true])); } } else if (Payment::TYPE_ACHAT_MONNAIE_PRESTA == $type) { $flux = $this->serializer->deserialize( $payment->getFluxData(), AchatMonnaiePrestataire::class, 'json', ['disable_type_enforcement' => true] ); $exp = $this->em->getRepository(Siege::class)->find($flux_array['expediteur']); $flux->setExpediteur($exp); $dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']); $flux->setDestinataire($dest); $op = $this->em->getRepository(User::class)->find($flux_array['operateur']); $flux->setOperateur($op); $flux->setReconverti(true); if (null != $flux->getDon()) { $flux->getDon()->setType(Don::TYPE_DON_PRESTATAIRE); $flux->getDon()->setOperateur($op); $flux->getDon()->setExpediteur($dest); $flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true])); } } else if (Payment::TYPE_COTISATION_ADHERENT == $type) { $flux = $this->serializer->deserialize( $payment->getFluxData(), CotisationAdherent::class, 'json', ['disable_type_enforcement' => true] ); $exp = $this->em->getRepository(Adherent::class)->find($flux_array['expediteur']); $flux->setExpediteur($exp); $dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']); $flux->setDestinataire($dest); $op = $this->em->getRepository(User::class)->find($flux_array['operateur']); $flux->setOperateur($op); $flux->setRecu(true); if (null != $flux->getDon()) { $flux->getDon()->setType(Don::TYPE_DON_ADHERENT); $flux->getDon()->setOperateur($op); $flux->getDon()->setExpediteur($exp); $flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true])); } } else if (Payment::TYPE_COTISATION_PRESTA == $type) { $flux = $this->serializer->deserialize( $payment->getFluxData(), CotisationPrestataire::class, 'json', ['disable_type_enforcement' => true] ); $exp = $this->em->getRepository(Prestataire::class)->find($flux_array['expediteur']); $flux->setExpediteur($exp); $dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']); $flux->setDestinataire($dest); $op = $this->em->getRepository(User::class)->find($flux_array['operateur']); $flux->setOperateur($op); $flux->setRecu(true); if (null != $flux->getDon()) { $flux->getDon()->setType(Don::TYPE_DON_PRESTATAIRE); $flux->getDon()->setOperateur($op); $flux->getDon()->setExpediteur($exp); $flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true])); } } else if (Payment::TYPE_ADHESION == $type) { $new_adherent_data = json_decode($payment->getExtraData()); $adherent = new Adherent(); $user = $this->userManager->createUser(); $usergroup = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent'); $group = $this->em->getRepository(Groupe::class)->findOneBy(array('id' => $new_adherent_data->groupe->id)); $user->setEmail($new_adherent_data->user->email); $user->setUsername($new_adherent_data->user->username); $user->setFirstname($new_adherent_data->user->firstname); $user->setLastname($new_adherent_data->user->lastname); $user->setPlainPassword($new_adherent_data->user->plainPassword); $user->setEnabled(true); $user->addPossiblegroup($usergroup); $user->addGroup($usergroup); $user->addRole('ROLE_ADHERENT'); $user->setAdherent($adherent); $adherent->setEcompte('0'); $adherent->setUser($user); $adherent->setGroupe($group); if ($adherent->getGeoloc() == null) { $geoloc = new Geoloc(); $geoloc->setAdresse($new_adherent_data->geoloc->adresse); $geoloc->setCpostal($new_adherent_data->geoloc->cpostal); $geoloc->setVille($new_adherent_data->geoloc->ville); $adherent->setGeoloc($geoloc); } $this->em->persist($adherent); $this->em->flush(); // Create first cotisation $flux = $this->serializer->deserialize( $payment->getFluxData(), CotisationAdherent::class, 'json', ['disable_type_enforcement' => true] ); $flux->setOperateur($user); $flux->setExpediteur($adherent); $flux->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(array('mlc' => true))); $flux->setRole('Adherent'); $flux->setRecu(true); // Update payment with new user id, remove user data $payment->setClientId($user->getId()); $payment->setExtraData(''); $this->em->persist($payment); } else if (Payment::TYPE_PAIEMENT_COTISATION_TAV == $type) { $flux = $this->serializer->deserialize( $payment->getFluxData(), AchatMonnaieAdherent::class, 'json', ['disable_type_enforcement' => true] ); $exp = $this->em->getRepository(Siege::class)->find($flux_array['expediteur']); $flux->setExpediteur($exp); $dest = $this->em->getRepository(Adherent::class)->find($flux_array['destinataire']); $flux->setDestinataire($dest); $op = $this->em->getRepository(User::class)->find($flux_array['operateur']); $flux->setOperateur($op); $flux->setReconverti(true); if (null != $flux->getDon()) { $flux->getDon()->setType(Don::TYPE_DON_ADHERENT); $flux->getDon()->setOperateur($op); $flux->getDon()->setExpediteur($dest); $flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true])); } } else { // Bad request } $this->em->persist($flux); $this->operationUtils->executeOperations($flux); if (Payment::TYPE_PAIEMENT_COTISATION_TAV == $type) { // Apply cotisation rate, create new flux $this->tavCotisationsUtils->applyTauxCotisation($flux); } // Invalidate (delete) notify token after payment is captured $this->em->remove($token); $this->em->flush(); } } // Update payment status with status received in payzen response $payment->setStatus($status->getValue()); $this->em->persist($payment); $this->em->flush(); } /** * {@inheritDoc} */ public function onPreExecute(Context $context) { } /** * {@inheritDoc} */ public function onExecute(Context $context) { } }