<?php
namespace App\Controller\Client;
use App\Entity\{CreditTransaction, Invoice};
use App\Form\CreditReloadType;
use Stripe\Stripe;
use Stripe\PaymentIntent;
use Stripe\PaymentMethod;
use App\Service\{AccessClientService, StripePaymentService};
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* @Route("/client")
*/
class PaymentController extends AbstractController
{
private $stripePaymentService;
public function __construct(StripePaymentService $stripePaymentService)
{
$this->stripePaymentService = $stripePaymentService;
}
/**
* @Route("/credit-reload", name="app_client_credit_reload")
*/
public function creditReload(Request $request, AccessClientService $accessClientService, EntityManagerInterface $entityManager): Response
{
$accessClientService->handleAccessControl();
$form = $this->createForm(CreditReloadType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$amount = $form->get('amount')->getData() * 100;
Stripe::setApiKey($this->getParameter('stripe_secret_key'));
$paymentIntent = PaymentIntent::create([
'amount' => $amount,
'currency' => 'eur',
'payment_method_types' => ['card'],
]);
if ($request->isXmlHttpRequest()) {
return new JsonResponse([
'client_secret' => $paymentIntent->client_secret,
'success' => true
]);
}
}
return $this->render('client/payment/credit_reload.html.twig', [
'form' => $form->createView(),
'stripe_public_key' => $this->getParameter('stripe_public_key')
]);
}
/**
* @Route("/complete-payment", name="app_client_complete_payment")
*/
public function completePayment(Request $request, EntityManagerInterface $entityManager): JsonResponse
{
$data = json_decode($request->getContent(), true);
$paymentIntentId = $data['payment_intent_id'] ?? null;
$amount = $data['amount'] ?? null;
$status = $data['status'] ?? null;
if (!$paymentIntentId || !$status) {
return new JsonResponse(['error' => 'Informations de paiement manquantes'], 400);
}
Stripe::setApiKey($this->getParameter('stripe_secret_key'));
try {
$paymentIntent = PaymentIntent::retrieve($paymentIntentId);
if ($paymentIntent->status === 'succeeded') {
$user = $this->getUser();
if (!$user) {
throw new NotFoundHttpException('Utilisateur non trouvé');
}
$paymentMethodId = $paymentIntent->payment_method;
$paymentMethod = PaymentMethod::retrieve($paymentMethodId);
$cardDetails = $paymentMethod->card;
$cardType = $cardDetails->brand;
$last4 = $cardDetails->last4;
$cardNumber = '**** **** **** ' . $last4;
$cardHolder = $paymentMethod->billing_details->name;
$expMonth = $cardDetails->exp_month;
$expYear = $cardDetails->exp_year;
$cardExpiration = $expMonth . '/' . $expYear;
$transaction = new CreditTransaction();
$transaction->setAmount($amount / 100);
$transaction->setStatus('succeeded');
$transaction->setPaymentIntentId($paymentIntent->id);
$transaction->setCardType($cardType);
$transaction->setCardNumber($cardNumber);
$transaction->setCardHolder($cardHolder);
$transaction->setCardExpiration($cardExpiration);
$transaction->setDescription('Recharge crédit');
$transaction->setTransactionType('credit');
$transaction->setUser($user);
$entityManager->persist($transaction);
$entityManager->flush();
$transaction->generateTransactionNumber();
$user->setCreditBalance($user->getCreditBalance() + ($amount / 100));
$entityManager->flush();
$invoice = new Invoice();
$invoice->setStatus('Paid');
$invoice->setCreditTransaction($transaction);
$entityManager->persist($invoice);
$entityManager->flush();
$invoice->setInvoiceNumber('F' . str_pad($invoice->getId(), 5, '0', STR_PAD_LEFT));
$entityManager->flush();
// $this->addFlash('success', 'Succès ! Paiement réussi et crédit ajouté.');
return new JsonResponse([
'success' => true,
]);
} else {
$this->addFlash('danger', 'Error ! Le paiement a échoué, veuillez réessayer.');
return new JsonResponse([
'success' => false,
]);
}
} catch (\Exception $e) {
return new JsonResponse([
'error' => $e->getMessage(),
'success' => false
]);
}
}
/**
* @Route("/credit-reload/confirmation/{paymentIntentId}", name="app_client_credit_reload_confirmation")
*/
public function creditReloadConfirmation(AccessClientService $accessClientService, $paymentIntentId, Request $request, EntityManagerInterface $entityManager): Response
{
$accessClientService->handleAccessControl();
$user = $this->getUser();
$client = $user->getClient();
if (!$client) {
throw new NotFoundHttpException('Aucun client trouvé pour cet utilisateur ' . $user->getFirstname());
}
$transaction = $entityManager->getRepository(CreditTransaction::class)->findOneBy(['paymentIntentId' => $paymentIntentId, 'user' => $user], ['id' => 'DESC']);
if (!$transaction) {
throw new NotFoundHttpException('Transaction non trouvée');
}
return $this->render('client/payment/confirmation.html.twig', [
'transaction' => $transaction,
]);
}
/**
* @Route("/transactions", name="app_client_credit_transactions")
*/
public function transactions(AccessClientService $accessClientService, Request $request, EntityManagerInterface $entityManager, PaginatorInterface $paginator): Response
{
$accessClientService->handleAccessControl();
$user = $this->getUser();
$client = $user->getClient();
if (!$client) {
throw new NotFoundHttpException('Aucun client trouvé pour cet utilisateur ' . $user->getFirstname());
}
$query = $entityManager->getRepository(CreditTransaction::class)->findBy(['user' => $user], ['id' => 'DESC']);
$pagination = $paginator->paginate(
$query,
$request->query->getInt('page', 1),
12
);
return $this->render('client/payment/transactions.html.twig', [
'transactions' => $pagination,
]);
}
// ****************** MODAL ******************* //
/**
* @Route("/reload-credit", name="app_client_credit_reload_modal")
*/
public function creditReloadModal(Request $request, AccessClientService $accessClientService): Response
{
$accessClientService->handleAccessControl();
if ($request->isXmlHttpRequest()) {
$amount = $request->request->get('sg_credit_reload')['amount'] * 100;
Stripe::setApiKey($this->getParameter('stripe_secret_key'));
$paymentIntent = PaymentIntent::create([
'amount' => $amount,
'currency' => 'eur',
'payment_method_types' => ['card'],
]);
return new JsonResponse([
'client_secret' => $paymentIntent->client_secret,
'success' => true
]);
}
}
/**
* @Route("/confirm-payment", name="app_client_complete_payment_modal")
*/
public function completePaymentModal(Request $request, EntityManagerInterface $entityManager): JsonResponse
{
$data = json_decode($request->getContent(), true);
$paymentIntentId = $data['payment_intent_id'] ?? null;
$amount = $data['amount'] ?? null;
$status = $data['status'] ?? null;
if (!$paymentIntentId || !$status) {
return new JsonResponse(['error' => 'Informations de paiement manquantes'], 400);
}
Stripe::setApiKey($this->getParameter('stripe_secret_key'));
try {
$paymentIntent = PaymentIntent::retrieve($paymentIntentId);
if ($paymentIntent->status === 'succeeded') {
$user = $this->getUser();
if (!$user) {
throw new NotFoundHttpException('Utilisateur non trouvé');
}
$paymentMethodId = $paymentIntent->payment_method;
$paymentMethod = PaymentMethod::retrieve($paymentMethodId);
$cardDetails = $paymentMethod->card;
$cardType = $cardDetails->brand;
$last4 = $cardDetails->last4;
$cardNumber = '**** **** **** ' . $last4;
$cardHolder = $paymentMethod->billing_details->name;
$expMonth = $cardDetails->exp_month;
$expYear = $cardDetails->exp_year;
$cardExpiration = $expMonth . '/' . $expYear;
$transaction = new CreditTransaction();
$transaction->setAmount($amount / 100);
$transaction->setStatus('succeeded');
$transaction->setPaymentIntentId($paymentIntent->id);
$transaction->setCardType($cardType);
$transaction->setCardNumber($cardNumber);
$transaction->setCardHolder($cardHolder);
$transaction->setCardExpiration($cardExpiration);
$transaction->setDescription('Recharge crédit');
$transaction->setTransactionType('credit');
$transaction->setUser($user);
$entityManager->persist($transaction);
$entityManager->flush();
$transaction->generateTransactionNumber();
$user->setCreditBalance($user->getCreditBalance() + ($amount / 100));
$entityManager->flush();
$invoice = new Invoice();
$invoice->setStatus('Paid');
$invoice->setCreditTransaction($transaction);
$entityManager->persist($invoice);
$entityManager->flush();
$invoice->setInvoiceNumber('F' . str_pad($invoice->getId(), 5, '0', STR_PAD_LEFT));
$entityManager->flush();
$this->addFlash('success', 'Succès ! Paiement réussi et crédit ajouté.');
return new JsonResponse([
'success' => true,
]);
} else {
$this->addFlash('danger', 'Error ! Le paiement a échoué, veuillez réessayer.');
return new JsonResponse([
'success' => false,
]);
}
} catch (\Exception $e) {
return new JsonResponse([
'error' => $e->getMessage(),
'success' => false
]);
}
}
}