src/Controller/Webhook/GocardlessController.php line 55

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Webhook;
  3. use App\Enum\ActionTypeEnum;
  4. use App\Enum\DocumentStatusEnum;
  5. use App\Enum\DocumentTypeOrganizationEnum;
  6. use App\Service\DocumentUtils;
  7. use App\Service\GocardlessAPI;
  8. use App\Service\SegmentAPI;
  9. use App\Service\SubscriptionUtils;
  10. use App\Traits\SentryNotifyTrait;
  11. use Doctrine\ORM\EntityManagerInterface;
  12. use Evo\Infrastructure\MappingORM\Document;
  13. use Evo\Infrastructure\MappingORM\Organization;
  14. use Evo\Infrastructure\MappingORM\Subscription;
  15. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  16. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  17. use Symfony\Component\HttpFoundation\JsonResponse;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\Response;
  20. use Symfony\Component\Routing\Annotation\Route;
  21. use Symfony\Contracts\Translation\TranslatorInterface;
  22. class GocardlessController extends AbstractController
  23. {
  24.     use SentryNotifyTrait;
  25.     private GocardlessAPI $gocardlessAPI;
  26.     private EntityManagerInterface $em;
  27.     private ParameterBagInterface $params;
  28.     private TranslatorInterface $translator;
  29.     private SegmentAPI $segment;
  30.     private DocumentUtils $documentUtils;
  31.     public function __construct(
  32.         GocardlessAPI $gocardlessAPI,
  33.         EntityManagerInterface $em,
  34.         SegmentAPI $segment,
  35.         TranslatorInterface $translator,
  36.         DocumentUtils $documentUtils,
  37.         ParameterBagInterface $params
  38.     ) {
  39.         $this->gocardlessAPI $gocardlessAPI;
  40.         $this->em $em;
  41.         $this->segment $segment;
  42.         $this->documentUtils $documentUtils;
  43.         $this->translator $translator;
  44.         $this->params $params;
  45.     }
  46.     /**
  47.      * @Route("/gocardless", name="app_webhook_gocardless", methods={"POST"})
  48.      */
  49.     public function index(Request $request)
  50.     {
  51.         $request_body file_get_contents('php://input');
  52.         $headers $this->gocardlessAPI->getallheaders($request);
  53.         $signature_header $headers['Webhook-Signature'];
  54.         $webhook_endpoint_secret $this->params->get('webhook_secret');
  55.         $events $this->gocardlessAPI->webhookParse($request_body$signature_header$webhook_endpoint_secret);
  56.         if (500 === $events) {
  57.             return new Response(''498);
  58.         }
  59.         foreach ($events as $event) {
  60.             if ('mandates' === $event->resource_type) {
  61.                 $this->mandatesEvent($event);
  62.             }
  63.         }
  64.         return new Response(''Response::HTTP_OK);
  65.     }
  66.     /**
  67.      * @Route("/customers", name="app_webhook_customers", methods={"POST"})
  68.      */
  69.     public function customers(): JsonResponse
  70.     {
  71.         $payload file_get_contents('php://input');
  72.         if (!$payload) {
  73.             return $this->json(['message' => 'No payload'], Response::HTTP_BAD_REQUEST);
  74.         }
  75.         $data json_decode($payloadtrue512JSON_THROW_ON_ERROR);
  76.         if (!isset($data['registerID']) || !isset($data['sessionID'])) {
  77.             return $this->json(['message' => 'Not found parameter registerID'], Response::HTTP_NOT_FOUND);
  78.         }
  79.         $registerID $data['registerID'];
  80.         $sessionID $data['sessionID'];
  81.         $organizationID $data['organization'];
  82.         $action $data['action'];
  83.         $redirectFlows $this->gocardlessAPI->getRedirectFlows($registerID$sessionID);
  84.         if (!$redirectFlows) {
  85.             return $this->json(['message' => 'RedirectFlows not found'], Response::HTTP_NOT_FOUND);
  86.         }
  87.         $mandatID $redirectFlows->links->mandate;
  88.         $mandate $this->gocardlessAPI->getMandate($mandatID);
  89.         $customerID $redirectFlows->links->customer;
  90.         $customerBankAccountsID $redirectFlows->links->customer_bank_account;
  91.         if (!$mandate || !$mandate->reference) {
  92.             return $this->json(['message' => 'Mandate not found'], Response::HTTP_NOT_FOUND);
  93.         }
  94.         $customerBankAccounts $this->gocardlessAPI->getCustomerBankAccounts($customerBankAccountsID);
  95.         if (!$customerBankAccounts) {
  96.             return $this->json(['message' => 'CustomerBankAccounts not found'], Response::HTTP_NOT_FOUND);
  97.         }
  98.         $iban $customerBankAccounts->account_number_ending;
  99.         if (!$iban) {
  100.             return $this->json(['message' => 'Iban not found'], Response::HTTP_NOT_FOUND);
  101.         }
  102.         /**
  103.          * Update customers.
  104.          */
  105.         $params = [
  106.             'metadata' => [
  107.                     'id_client' => (string) $organizationID,
  108.                 ],
  109.         ];
  110.         $this->gocardlessAPI->updateCustomer($customerID$params);
  111.         $repository $this->em->getRepository(Organization::class);
  112.         /** @var Organization $organization */
  113.         $organization $repository->find($organizationID);
  114.         if (!$organization) {
  115.             return $this->json(['message' => 'organization not found'], Response::HTTP_NOT_FOUND);
  116.         }
  117.         $trans DocumentTypeOrganizationEnum::getReadableValue(DocumentTypeOrganizationEnum::RIB);
  118.         if (ActionTypeEnum::NEW === $action) {
  119.             $document = new Document();
  120.             $document
  121.                 ->setType(DocumentTypeOrganizationEnum::RIB)
  122.                 ->setStatus(DocumentStatusEnum::APPROVED)
  123.                 ->setOrganization($organization)
  124.                 ->setName($this->translator->trans($trans));
  125.             $this->em->persist($document);
  126.         } elseif (ActionTypeEnum::EDIT === $action) {
  127.             /** @var Subscription $subscription */
  128.             $subscription SubscriptionUtils::getDomSubscription($organization);
  129.             /*
  130.              * Génération du RIB
  131.              */
  132.             if ($subscription) {
  133.                 $document = new Document();
  134.                 $document
  135.                     ->setType(DocumentTypeOrganizationEnum::RIB)
  136.                     ->setStatus(DocumentStatusEnum::APPROVED)
  137.                     ->setOrganization($organization)
  138.                     ->setName($this->translator->trans($trans));
  139.                 $this->em->persist($document);
  140.             }
  141.         }
  142.         $this->em->flush();
  143.         // Update organization
  144.         $this->em->clear();
  145.         $organization $this->em->getRepository(Organization::class)->find($organizationID);
  146.         /**
  147.          * Annulation mandate gocardless.
  148.          */
  149.         $oldMandateID $organization->getMandatID();
  150.         if ($oldMandateID && $oldMandateID !== $mandatID) {
  151.             $this->gocardlessAPI->canceledMandate($oldMandateID);
  152.             $organization->setReferenceGocardless(null);
  153.             $organization->setMandatID(null);
  154.         }
  155.         $organization->setReferenceGocardless($mandate->reference);
  156.         $bankName $customerBankAccounts->bank_name;
  157.         $titulaire $customerBankAccounts->account_holder_name;
  158.         $organization->setIban($iban);
  159.         $organization->setBankName($bankName);
  160.         $organization->setTitulaire($titulaire);
  161.         $organization->setMandatID($mandatID);
  162.         $organization->setIsAuthorizedDebit(true);
  163.         $this->em->flush();
  164.         $params SubscriptionUtils::getSubscriptionDataToSegment($organization);
  165.         $documentRIB = new Document();
  166.         $documentRIB
  167.             ->setType(DocumentTypeOrganizationEnum::RIB)
  168.             ->setStatus(DocumentStatusEnum::APPROVED)
  169.             ->setOrganization($organization);
  170.         $this->segment->trackApprovedDocument($documentRIB$params);
  171.         return $this->json(['message' => 'Gocardless updated''result' => 200], Response::HTTP_OK);
  172.     }
  173.     private function mandatesEvent($event): ?bool
  174.     {
  175.         if ('cancelled' === $event->action) {
  176.             $mandateID $event->links->mandate;
  177.             $mandate $this->gocardlessAPI->getMandate($mandateID);
  178.             $customer $this->gocardlessAPI->getCustomer($mandate->links->customer);
  179.             $customerBankAccounts $this->gocardlessAPI->getCustomerBankAccounts($mandate->links->customer_bank_account);
  180.             $organizationID $customer->metadata->id_client;
  181.             $repositoryOrganization $this->em->getRepository(Organization::class);
  182.             $organization $repositoryOrganization->find($organizationID);
  183.             if (!$organization instanceof Organization) {
  184.                 return null;
  185.             }
  186.             if ($organization->getMandatID() === $mandateID) {
  187.                 $organization->setReferenceGocardless(null);
  188.                 $organization->setMandatID(null);
  189.                 $this->em->persist($organization);
  190.                 $this->em->flush();
  191.                 $params = [];
  192.                 /** @var Subscription $subscription */
  193.                 foreach ($organization->getSubscriptions() as $subscription) {
  194.                     $params[] = [
  195.                         'price' => $subscription->getTotalPriceWithTax(),
  196.                         'date' => null !== $organization->getDomiciliationStartDate() ? $organization->getDomiciliationStartDate()->format('Y-m-d') : null,
  197.                         'frequence' => $subscription->getType(),
  198.                         'reference' => ($mandate) ? $mandate->reference '',
  199.                         'iban_last2' => (null !== $customerBankAccounts) ? $customerBankAccounts->account_number_ending '',
  200.                     ];
  201.                 }
  202.                 $document = new Document();
  203.                 $document
  204.                     ->setType(DocumentTypeOrganizationEnum::RIB)
  205.                     ->setStatus(DocumentStatusEnum::APPROVED)
  206.                     ->setOrganization($organization);
  207.                 $this->segment->trackRejectedDocument($document$params);
  208.             }
  209.         }
  210.         return true;
  211.     }
  212. }