<?php
namespace App\EventSubscriber;
/*
bin/stripe listen --forward-to localhost:4242/cultureroute/public/stripe/webhook
*/
use App\Event\OrderPaymentEvent;
use App\Event\StripeEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use App\Entity\User;
use App\Entity\StripeCustomer;
use Psr\Log\LoggerInterface;
use Doctrine\ORM\EntityManagerInterface;
class StripeSubscriber implements EventSubscriberInterface
{
private $entityManager;
private $logger;
private $stripe;
public function __construct(LoggerInterface $lifecycleLogger, EntityManagerInterface $entityManager, OrderPaymentEventSubscriber $orderEventSubscriber)
{
$config = new \App\Entity\Configuration;
$this->logger = $lifecycleLogger;
$this->entityManager = $entityManager;
$this->stripe = new \Stripe\StripeClient($config->getStripeSecretKey());
$this->dispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
$this->dispatcher->addSubscriber($orderEventSubscriber);
}
public static function getSubscribedEvents() : array
{
return [
StripeEvent::CHARGE_SUCCEEDED => 'onChargeSucceeded',
StripeEvent::SESSION_COMPLETED => 'onSessionCompleted',
StripeEvent::CUSTOMER_CREATED => 'onCustomerCreated',
StripeEvent::PAYMENT_INTENT_CREATED => 'onPaymentCreated',
];
}
public function getSession(\Stripe\PaymentIntent $payment_intent): ?\Stripe\Checkout\Session
{
$sessions = $this->stripe->checkout->sessions->all(['payment_intent' => $payment_intent->id, 'limit'=>1]);
$this->logger->info('getSession', [
'sessions' =>$sessions
]);
if (!count($sessions)) {
$this->logger->error('getSession', [
'payment_intent' => $payment_intent->id
]);
return null;
}
$session = $sessions->first();
$this->logger->info('getSession', [
'session' =>$session
]);
return $session;
}
public function onPaymentCreated(StripeEvent $event)
{
$stripeEvent = $event->getEvent(); //Stripe event object (instanceof \Stripe\Event)
$payment_intent = $event->getDataObject(); //Stripe session object (instanceof \Stripe\PaymentIntent)
// Log the event
$this->logger->info('StripePaymentCreated', [
'amount' => $payment_intent->amount,
'customer' => $payment_intent->customer,
'pi_id' => $payment_intent->id,
]);
$session = $this->getSession($payment_intent);
$OrderPaymentEvent = new OrderPaymentEvent($session->client_reference_id);
$this->dispatcher->dispatch($OrderPaymentEvent, OrderPaymentEvent::CREATED);
}
public function onSessionCompleted(StripeEvent $event)
{
$stripeEvent = $event->getEvent(); //Stripe event object (instanceof \Stripe\Event)
$session = $event->getDataObject(); //Stripe session object (instanceof \Stripe\Session)
// Log the event
$this->logger->info('StripeSessionCompleted', [
'payment_status' => $session->payment_status,
'client_reference_id' => $session->client_reference_id,
'customer' => $session->customer
]);
// si c'est payé on le dit(pour séparer Stripe de la gestion de la commande)
$OrderPaymentEvent = new OrderPaymentEvent($session->client_reference_id);
if($session->payment_status == 'paid')
$this->dispatcher->dispatch($OrderPaymentEvent, OrderPaymentEvent::SUCCESS);
// On met à jour les infos de l'utilisateur sur Stripe
// Si le process normal a été suivi, on a déjà le lien entre les User et les customers
$User = $this->entityManager->getRepository(User::class)->findOneByReference($session->customer);
if (!$User) {
throw new \Error('Pas de client avec la référence "'.$reference.'"');
return;
}
$paramsCustomer = [];
$paramsCustomer['address']['city'] = $User->getVille();
$paramsCustomer['address']['postal_code'] = $User->getCp();
if (count($User->getShopUserAdresses())) {
$paramsCustomer['address']['city'] = $User->getShopUserAdresses()[0]->getVille();
$paramsCustomer['address']['postal_code'] = $User->getShopUserAdresses()[0]->getCodePostal();
$paramsCustomer['address']['line1'] = $User->getShopUserAdresses()[0]->getAdresse();
}
$paramsCustomer["name"] = $User->getPrenom().' '.$User->getNom();
$paramsCustomer["phone"] = $User->getTelephone();
$this->stripe->customers->update(
$User->getReference(),
$paramsCustomer
);
}
// permet de faire le lien entre un Use et un customer
public function onCustomerCreated(StripeEvent $event)
{
$stripeEvent = $event->getEvent(); //Stripe event object (instanceof \Stripe\Event)
$customer = $event->getDataObject(); //Stripe customer object (instanceof \Stripe\Customer)
// Log the event
$this->logger->info('StripeSessionCompleted', [
'email' => $customer->email,
'id' => $customer->id
]);
$reference = $customer->email;
$User = $this->entityManager->getRepository(User::class)->findOneByMail($reference);
if (!$User) {
throw new \Error('Pas de client avec la référence "'.$reference.'"');
return;
}
if (!$User->getReference()) {
$User->setReference($customer->id);
$this->entityManager->flush();
}
}
public function onChargeSucceeded(StripeEvent $event)
{
$stripeEvent = $event->getEvent(); //Stripe event object (instanceof \Stripe\Event)
$charge = $event->getDataObject(); //Stripe charge object (instanceof \Stripe\Charge)
// Log the event
$this->logger->info($stripeEvent::CHARGE_SUCCEEDED, [
'stripeEvent' => var_export($stripeEvent,true)
]);
}
}