src/Controller/Webhook/StripeController.php line 107

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Webhook;
  3. use App\Enum\PaymentStatusEnum;
  4. use App\Enum\PaymentTypeEnum;
  5. use App\Enum\RefundStatusEnum;
  6. use App\Repository\RefundRepository;
  7. use App\Service\StripeAPI;
  8. use App\Traits\SentryNotifyTrait;
  9. use App\Utils\InvoiceUtils;
  10. use Doctrine\ORM\EntityManagerInterface;
  11. use Evo\Infrastructure\MappingORM\Invoice;
  12. use Evo\Infrastructure\MappingORM\Payment;
  13. use Evo\Infrastructure\MappingORM\Refund;
  14. use Evo\Infrastructure\Repository\InvoiceRepository;
  15. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. class StripeController extends AbstractController
  20. {
  21.     use SentryNotifyTrait;
  22.     private EntityManagerInterface $em;
  23.     private StripeAPI $stripeAPI;
  24.     private InvoiceUtils $invoiceUtils;
  25.     public function __construct(
  26.         StripeAPI $stripeAPI,
  27.         EntityManagerInterface $em,
  28.         InvoiceUtils $invoiceUtils
  29.     ) {
  30.         $this->em $em;
  31.         $this->stripeAPI $stripeAPI;
  32.         $this->invoiceUtils $invoiceUtils;
  33.     }
  34.     /**
  35.      * @Route("/stripe", name="app_webhook_stripe", methods={"POST"})
  36.      *
  37.      * @return Response
  38.      */
  39.     public function webhook(Request $request)
  40.     {
  41.         $request_body file_get_contents('php://input');
  42.         $event $this->stripeAPI->webhookCheck($request_body$request);
  43.         $response = new Response();
  44.         if (null !== $event) {
  45.             $data $event->data->toArray();
  46.             $object $data['object'] ?? null;
  47.             switch ($event->type) {
  48.                 case 'charge.succeeded':
  49.                     $this->handleChargeSucceeded($object);
  50.                     break;
  51.                 case 'charge.dispute.closed':
  52.                 case 'payment_intent.canceled':
  53.                 case 'charge.failed':
  54.                     $this->handleFailed($object);
  55.                     break;
  56.                 case 'charge.refunded':
  57.                     $this->handleChargeRefunded($object);
  58.                     break;
  59.                 case 'payment_intent.succeeded':
  60.                     $this->handlePaymentIntentSucceeded($object);
  61.                     break;
  62.             }
  63.             $response->setStatusCode(Response::HTTP_OK);
  64.             return $response;
  65.         }
  66.         $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
  67.         return $response;
  68.     }
  69.     private function handleChargeRefunded($object)
  70.     {
  71.         if ($object) {
  72.             $reference $object['payment_intent'];
  73.             /** @var RefundRepository $refundRepository */
  74.             $refundRepository $this->em->getRepository(Refund::class);
  75.             $refund $refundRepository->findOneBy(['reference' => $reference]);
  76.             if (null !== $refund) {
  77.                 switch ($object['status']) {
  78.                     case 'succeeded':
  79.                         $refund->setStatus(RefundStatusEnum::SUCCESS);
  80.                         break;
  81.                     case 'failed':
  82.                     case 'cancelled':
  83.                         $refund->setStatus(RefundStatusEnum::ERROR);
  84.                         break;
  85.                     case 'pending':
  86.                         $refund->setStatus(RefundStatusEnum::SENT);
  87.                         break;
  88.                 }
  89.                 $this->em->persist($refund);
  90.                 $this->em->flush();
  91.             }
  92.         }
  93.     }
  94.     private function handleChargeSucceeded($object)
  95.     {
  96.         if ($object) {
  97.             $repository $this->em->getRepository(Invoice::class);
  98.             $metadata $object['metadata'];
  99.             $id $object['id'];
  100.             $charge $this->stripeAPI->getCharge($id);
  101.             $paymentId $charge->payment_intent;
  102.             if (!empty($metadata) && isset($metadata['invoices']) && 'STRIPE' !== $metadata['type_payment']) {
  103.                 echo 'metadata exists';
  104.                 $invoices explode(','$metadata['invoices']);
  105.                 foreach ($invoices as $invoiceID) {
  106.                     /** @var Invoice $invoice */
  107.                     $invoice $repository->find($invoiceID);
  108.                     if ($invoice) {
  109.                         $response $this->invoiceUtils->paid($invoicePaymentTypeEnum::STRIPE$paymentId);
  110.                         echo 'response:';
  111.                         if ($response) {
  112.                             echo sprintf('update invoice #%s'$invoiceID);
  113.                         }
  114.                     }
  115.                 }
  116.             } elseif ($charge && $charge->metadata) {
  117.                 $invoices explode(','$charge->metadata->invoices);
  118.                 if ('STRIPE - SEPA' === $charge->metadata->type_payment) {
  119.                     foreach ($invoices as $invoiceID) {
  120.                         $invoiceID htmlspecialchars($invoiceID);
  121.                         /** @var Invoice $invoice */
  122.                         $invoice $repository->find($invoiceID);
  123.                         if ($invoice) {
  124.                             $response $this->invoiceUtils->paid($invoicePaymentTypeEnum::STRIPE$paymentId);
  125.                             echo 'response:';
  126.                             if ($response) {
  127.                                 echo sprintf('update invoice #%s'$invoiceID);
  128.                             }
  129.                         }
  130.                     }
  131.                 }
  132.             }
  133.         }
  134.     }
  135.     private function handleFailed($object)
  136.     {
  137.         if ($object) {
  138.             $repository $this->em->getRepository(Invoice::class);
  139.             $metadata $object['metadata'];
  140.             $id $object['id'];
  141.             $charge null;
  142.             $paymentId null;
  143.             $dispute $this->stripeAPI->getDispute($id);
  144.             if ($dispute) {
  145.                 $charge $this->stripeAPI->getCharge($dispute->charge);
  146.                 $paymentId $charge->payment_intent;
  147.             }
  148.             if (!empty($metadata) && isset($metadata['invoices'])) {
  149.                 echo 'metadata exists';
  150.                 $invoices explode(','$metadata['invoices']);
  151.                 foreach ($invoices as $invoiceID) {
  152.                     /** @var Invoice $invoice */
  153.                     $invoice $repository->find($invoiceID);
  154.                     if ($invoice) {
  155.                         $response $this->invoiceUtils->unpaid($invoicePaymentTypeEnum::STRIPE$paymentId);
  156.                         echo 'response:';
  157.                         if ($response) {
  158.                             echo sprintf('update invoice #%s'$invoiceID);
  159.                         }
  160.                     }
  161.                 }
  162.             } elseif ($charge && $charge->metadata) {
  163.                 $invoices explode(','$charge->metadata->invoices);
  164.                 foreach ($invoices as $invoiceID) {
  165.                     /** @var Invoice $invoice */
  166.                     $invoice $repository->find($invoiceID);
  167.                     if ($invoice) {
  168.                         $response $this->invoiceUtils->unpaid($invoicePaymentTypeEnum::STRIPE$id);
  169.                         echo 'response:';
  170.                         if ($response) {
  171.                             echo sprintf('update invoice #%s'$invoiceID);
  172.                         }
  173.                     }
  174.                 }
  175.             }
  176.         }
  177.     }
  178.     private function handlePaymentIntentSucceeded($object)
  179.     {
  180.         if ($object) {
  181.             $metadata $object['metadata'];
  182.             $id $object['id'];
  183.             if (!empty($metadata) && isset($metadata['invoices'])) {
  184.                 echo 'metadata exists';
  185.                 /** @var InvoiceRepository $repository */
  186.                 $repository $this->em->getRepository(Invoice::class);
  187.                 $invoices explode(','$metadata['invoices']);
  188.                 if ('STRIPE' === $metadata['type_payment']) {
  189.                     foreach ($invoices as $invoiceID) {
  190.                         /** @var Invoice $invoice */
  191.                         $invoice $repository->find($invoiceID);
  192.                         if ($invoice) {
  193.                             $amount $invoice->getRemainingToPay();
  194.                             $payment $this->invoiceUtils->getPayment($invoicePaymentTypeEnum::STRIPE);
  195.                             if (null === $payment) {
  196.                                 $payment = new Payment();
  197.                                 $payment->setType(PaymentTypeEnum::STRIPE);
  198.                                 $payment->setAmount($amount);
  199.                             }
  200.                             $payment->setReference($id);
  201.                             $payment->setStatus(PaymentStatusEnum::SUCCESS);
  202.                             $invoice->addPayment($payment);
  203.                             try {
  204.                                 $this->em->persist($invoice);
  205.                                 $this->em->flush();
  206.                             } catch (\Exception $e) {
  207.                                 $this->captureSentryException($e);
  208.                             }
  209.                             echo sprintf('update invoice #%s'$invoiceID);
  210.                         }
  211.                     }
  212.                 }
  213.             }
  214.         }
  215.     }
  216. }