<?php
namespace App\EventListener\PostValidate;
use App\DTO\StripeSubscription\StripeSubscription;
use App\Repository\DiscountRepository;
use App\Repository\SiteRepository;
use App\Repository\StripeSubscriptionRepository;
use App\Repository\SubscriptionPriceRepository;
use App\Stripe\Service\StripeApi;
use App\Service\Manager\StripeSubscriptionManager;
use App\Service\UserProvider;
use Stripe\Exception\ApiErrorException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class CreateStripeSubscriptionPostValidateTransformer implements EventSubscriberInterface
{
private $userProvider;
private $siteRepository;
private $stripeSubscriptionRepository;
private $translator;
private $priceRepository;
private $discountRepository;
private $stripeApi;
private $manager;
private $normalizer;
private $request;
public function __construct(
UserProvider $userProvider,
SiteRepository $siteRepository,
StripeSubscriptionRepository $stripeSubscriptionRepository,
TranslatorInterface $translator,
SubscriptionPriceRepository $priceRepository,
DiscountRepository $discountRepository,
StripeApi $stripeApi,
StripeSubscriptionManager $stripeSubscriptionManager,
NormalizerInterface $normalizer,
RequestStack $requestStack
) {
$this->userProvider = $userProvider;
$this->siteRepository = $siteRepository;
$this->stripeSubscriptionRepository = $stripeSubscriptionRepository;
$this->translator = $translator;
$this->priceRepository = $priceRepository;
$this->discountRepository = $discountRepository;
$this->stripeApi = $stripeApi;
$this->manager = $stripeSubscriptionManager;
$this->normalizer = $normalizer;
$this->request = $requestStack->getCurrentRequest();
}
public static function getSubscribedEvents()
{
return [
PostValidateListener::POST_VALIDATE_TRANSFORMATION => 'transform',
];
}
public function supportTransformation($payload)
{
return $payload instanceof StripeSubscription;
}
public function transform(ViewEvent $event)
{
/** @var StripeSubscription $payload */
$payload = $event->getControllerResult();
if (!$this->supportTransformation($payload)) {
return;
}
$site = $this->siteRepository->find($this->request->get('id'));
if (null === $site) {
throw new NotFoundHttpException();
}
if (null !== $this->stripeSubscriptionRepository->findOneBy([
'site' => $site,
'isActive' => true,
])) {
throw new BadRequestHttpException($this->translator->trans('stripe_subscription.exist'));
}
$user = $this->userProvider->getUser();
$subscriptionPrice = $this->priceRepository->find($payload->price);
$discount = $payload->discount ? $this->discountRepository->find($payload->discount) : null;
try {
$customer = $this->stripeApi->createCustomer($user->getEmail(), $payload->token);
$subscription = $this->stripeApi->createSubscription(
$customer,
$subscriptionPrice->getStripeId(),
$discount ? $discount->getUtm() : null
);
} catch (ApiErrorException $exception) {
throw new BadRequestHttpException($exception->getMessage());
}
$stripeSubscription = $this->manager->create($site, $subscriptionPrice->getCurrency(), $user, $subscription->id);
$event->setResponse(new JsonResponse($this->normalizer->normalize($stripeSubscription)));
}
}