diff --git a/migrations/Version20260319194243.php b/migrations/Version20260319194243.php new file mode 100644 index 0000000..76c2bc4 --- /dev/null +++ b/migrations/Version20260319194243.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE "user" ADD stripe_charges_enabled BOOLEAN NOT NULL DEFAULT FALSE'); + $this->addSql('ALTER TABLE "user" ADD stripe_payouts_enabled BOOLEAN NOT NULL DEFAULT FALSE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE "user" DROP stripe_charges_enabled'); + $this->addSql('ALTER TABLE "user" DROP stripe_payouts_enabled'); + } +} diff --git a/src/Controller/StripeWebhookController.php b/src/Controller/StripeWebhookController.php index 9d69ca7..dec2e43 100644 --- a/src/Controller/StripeWebhookController.php +++ b/src/Controller/StripeWebhookController.php @@ -2,7 +2,9 @@ namespace App\Controller; +use App\Entity\User; use App\Service\StripeService; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -11,7 +13,7 @@ use Symfony\Component\Routing\Attribute\Route; class StripeWebhookController extends AbstractController { #[Route('/stripe/webhook', name: 'app_stripe_webhook', methods: ['POST'])] - public function webhook(Request $request, StripeService $stripeService): Response + public function webhook(Request $request, StripeService $stripeService, EntityManagerInterface $em): Response { $payload = $request->getContent(); $signature = $request->headers->get('Stripe-Signature', ''); @@ -22,6 +24,21 @@ class StripeWebhookController extends AbstractController return new Response('Invalid signature', 400); } + if ('account.updated' === $event->type) { + $account = $event->data->object; + $accountId = $account->id ?? null; + + if ($accountId) { + $user = $em->getRepository(User::class)->findOneBy(['stripeAccountId' => $accountId]); + + if ($user) { + $user->setStripeChargesEnabled((bool) ($account->charges_enabled ?? false)); + $user->setStripePayoutsEnabled((bool) ($account->payouts_enabled ?? false)); + $em->flush(); + } + } + } + return new Response('OK', 200); } } diff --git a/src/Entity/User.php b/src/Entity/User.php index 102cf89..36ddec3 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -88,6 +88,12 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(length: 255, nullable: true)] private ?string $stripeAccountId = null; + #[ORM\Column] + private bool $stripeChargesEnabled = false; + + #[ORM\Column] + private bool $stripePayoutsEnabled = false; + #[ORM\Column(length: 64, nullable: true)] private ?string $emailVerificationToken = null; @@ -311,6 +317,30 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface return $this; } + public function isStripeChargesEnabled(): bool + { + return $this->stripeChargesEnabled; + } + + public function setStripeChargesEnabled(bool $stripeChargesEnabled): static + { + $this->stripeChargesEnabled = $stripeChargesEnabled; + + return $this; + } + + public function isStripePayoutsEnabled(): bool + { + return $this->stripePayoutsEnabled; + } + + public function setStripePayoutsEnabled(bool $stripePayoutsEnabled): static + { + $this->stripePayoutsEnabled = $stripePayoutsEnabled; + + return $this; + } + public function getResetCode(): ?string { return $this->resetCode; diff --git a/src/Service/StripeService.php b/src/Service/StripeService.php index 0195be8..6725cf1 100644 --- a/src/Service/StripeService.php +++ b/src/Service/StripeService.php @@ -2,6 +2,7 @@ namespace App\Service; +use App\Entity\User; use Stripe\Event; use Stripe\Exception\SignatureVerificationException; use Stripe\StripeClient; @@ -75,6 +76,38 @@ class StripeService } } + public function createAccountConnect(User $user): string + { + $account = $this->stripe->accounts->create([ + 'type' => 'express', + 'country' => 'FR', + 'email' => $user->getEmail(), + 'capabilities' => [ + 'card_payments' => ['requested' => true], + 'transfers' => ['requested' => true], + ], + 'business_type' => \in_array('ROLE_ORGANIZER', $user->getRoles(), true) ? 'company' : 'individual', + 'business_profile' => [ + 'name' => $user->getCompanyName(), + 'url' => $this->outsideUrl, + ], + ]); + + return $account->id; + } + + public function createAccountLink(string $accountId): string + { + $link = $this->stripe->accountLinks->create([ + 'account' => $accountId, + 'refresh_url' => $this->outsideUrl.'/stripe/connect/refresh', + 'return_url' => $this->outsideUrl.'/stripe/connect/return', + 'type' => 'account_onboarding', + ]); + + return $link->url; + } + public function getClient(): StripeClient { return $this->stripe; diff --git a/templates/email/organizer_approved.html.twig b/templates/email/organizer_approved.html.twig index 21da7ef..88ebfb2 100644 --- a/templates/email/organizer_approved.html.twig +++ b/templates/email/organizer_approved.html.twig @@ -6,6 +6,10 @@
Votre demande de compte organisateur a ete approuvee par l'equipe E-Ticket.
Vous pouvez desormais vous connecter et commencer a creer vos evenements.
+Important :
+Une fois connecte a votre compte, vous devrez effectuer la verification Stripe pour pouvoir recevoir les paiements de vos evenements. Cette etape est obligatoire pour activer les virements sur votre compte bancaire.
+