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.
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')]);