Home > Net >  Dynamic display checkout Stripe : difficulty to retrieve data on Symfony
Dynamic display checkout Stripe : difficulty to retrieve data on Symfony

Time:09-27

I'm trying to implement Stripe on my Symony web app. The checkout page is displayed fine, but I can't make the price and title displayed be those of the product concerned.

enter image description here

Page code above:

booking.html.twig

{% extends "base.html.twig" %}

{% block title %}Réservation
{% endblock %}

{% block body %}
    <h1>Bienvenue sur la page de réservation</h1>

    <div >
        <div >
            Réserver et payer son activité
        </div>
        <div >
            <h5 >{{product.title}}</h5>
            <p >{{product.price}}</p>
            <button id="checkout-button">Payer {{product.price / 100}} €</button>
        </div>
    </div>
{% endblock %}

{% block javascripts %}
    <script type="text/javascript">
        var stripe = Stripe("pk_test_51LkttkIFe6WM20DzgFS9hQa8fx9jydub6UygVtVg0VBj1xTFt8g04EjfbYjdQkrQOpjiptaesRjTCpxUt0H9W4Qy00vl8ZEgpN");
        var checkoutButton = document.getElementById("checkout-button");

        checkoutButton.addEventListener('click', function () {
            fetch('/create-checkout-session', {
                method : 'POST',
            })
            .then(function(response) {
                return response.json()
            })
            .then(function(session) {
                return stripe.redirectToCheckout({ sessionId : session.id});
            })
            .then(function(result) {
                if (result.error) {
                    alert(result.error.message);
                }
            })
            .catch(function(error) {
                console.error('Error', error);
            });
        });
    </script>
{% endblock %}

Here is the controller linked to the reservation page (page where the checkout button is) and to the creation of the checkout session :

BookingController.php :

class BookingController extends AbstractController
{

    #[Route('/reservation', name: 'booking')]
    public function index(ProductRepository $product)
    {


        $event = $product->findOneBy(['id' => $_GET['id']]);

        dump($event);

 // App\Entity\Product {#627 ▼
        //   -id: 14
        //   -title: "Cours de cuisine"
        //   -photo: "30-ecole-de-cuisine-4-scaled-1662990399.jpg"
        //   -description: "Cours de cuisine"
        //   -start_date: DateTime @1663056000 {#585 ▶}
        //   -end_date: DateTime @1663070400 {#632 ▶}
        //   -place: "Restaurant Place St Jean - 77000 MELUN"
        //   -duration: DateTime @14400 {#577 ▶}
        //   -price: "15000.00"
        //   -creator: App\Entity\User {#830 ▶}
        // 
}//

        return $this->render('booking/booking.html.twig', [
            'product' => $event
        ]);
    }

    #[Route('/create-checkout-session', name: 'checkout')]
    public function checkout()
    {
        \Stripe\Stripe::setApiKey('*confidential*');
        
        $session = \Stripe\Checkout\Session::create([
            "locale" => "fr",
            'line_items' => [[
              'price_data' => [
                'currency' => 'eur',
                'product_data' => [
                  'name' => '**HERE PUT THE NAME OF THE PRODUCT CONCERNED** ',
                ],
                'unit_amount' => **HERE PUT THE PRICE OF THE PRODUCT CONCERNED**,
              ],
              'quantity' => 1,
            ]],
            'mode' => 'payment',
            'success_url' => $this->generateUrl('success', [], UrlGeneratorInterface::ABSOLUTE_URL),
            'cancel_url' => $this->generateUrl('error', [], UrlGeneratorInterface::ABSOLUTE_URL),
          ]);

          return new JsonResponse(['id' => $session->id]);
    }

The goal is to put a variable to retrieve the name of the product and its price and integrate it into the checkout session to have a dynamic payment page. I have not found any information that works in this case.

CodePudding user response:

You can try to send the product ID in your FETCH

checkoutButton.addEventListener('click', function () {
  fetch('/create-checkout-session?productId=2', {
    method : 'POST',
})

Now in your controller

    #[Route('/create-checkout-session', name: 'checkout')]
    public function checkout(Request $request, ProductRepository $product)
    {
        \Stripe\Stripe::setApiKey('*confidential*');
        $product = $repository->findOneBye(['id' => $request->query->get('productId')]);

        //If product not found
        if(!$product){
            return new JsonResponse(['message' => 'Product not found'], 404);
        }
        
        $session = \Stripe\Checkout\Session::create([
            "locale" => "fr",
            'line_items' => [[
              'price_data' => [
                'currency' => 'eur',
                'product_data' => [
                  'name' => $product->getTitle(),
                ],
                'unit_amount' => $product->getPrice(),
              ],
              'quantity' => 1,
            ]],
            'mode' => 'payment',
            'success_url' => $this->generateUrl('success', [], UrlGeneratorInterface::ABSOLUTE_URL),
            'cancel_url' => $this->generateUrl('error', [], UrlGeneratorInterface::ABSOLUTE_URL),
          ]);

          return new JsonResponse(['id' => $session->id]);
    }

By passing in your controller, for the route ... Inject the Class Request and use this to get the product ID. Your method is not recommended because it is risky

    #[Route('/reservation', name: 'booking')]
    public function index(ProductRepository $product, Request $request)
    {


        $event = $product->findOneBy(['id' => $request->query->get('id')]);
  • Related