stighy
stighy

Reputation: 7170

How to add multiple stripe button in one page?

I'm following this guide to add stripe checkout to my home-made website. https://stripe.com/docs/checkout/integration-builder

I've a database and a PHP page. In this page I loop a mysql table with products and for each product I display information and add a 'Buy Now' stripe button. I call each button with a unique name (tag id and name). Follow example:

<?php
    <button id="checkout-button-<?php $row['productid']; ?>">Buy <?php echo $row['productname']; ?></button>
?>

My problem is with javascript:

<!-- Start Stripe Integration -->
<script type="text/javascript">
  // Create an instance of the Stripe object with your publishable API key
  var stripe = Stripe("<?php echo $stripe_key_public ?>");
  var checkoutButton = document.getElementById("checkout-button **$$Here is the problem$$**");
  checkoutButton.addEventListener("click", function() {
    fetch("my-stripe-checkout.php", {
        method: "POST",
      })
        .then(function(response) {
          return response.json();
        })
        .then(function(session) {
          return stripe.redirectToCheckout({
            sessionId: session.id
          });
        })
        .then(function(result) {
          // If redirectToCheckout fails due to a browser or network
          // error, you should display the localized error message to your
          // customer using error.message.
          if (result.error) {
            alert(result.error.message);
          }
        })
        .catch(function(error) {
          console.error("Error:", error);
        });
  });
</script>
<!-- End Stripe Integration -->

How can I add custom eventListener or, parametrize javascript function (with item description, price/amount etc), for each button outside my PHP loop?

Or am I wrong approach solution? Is there a better way to add stripe checkout button for a list of products?

Thanks

Upvotes: 1

Views: 530

Answers (2)

Bemn
Bemn

Reputation: 1391

If you want to render a list of checkout buttons, it will be a good idea to use the data attributes.

The Code

Add a data attribute to the checkout buttons:

<?php
  <button 
    data-product-id="<?php $row['productid']; ?>"
  >
    Buy <?php echo $row['productname']; ?>
  </button>
?>

And add the event listener to all the buttons with that data attribute:

// getting buttons with specific data attribute
let checkout_btns = document.querySelectorAll("[data-product-id]");

// adding the event listener by looping
checkout_btns.forEach((checkout_btn) => {
  checkout_btn.addEventListener("click", function (event) {
    // retrieving the dataset
    let product_data = event.target.dataset;
    
    // getting stripe session id
    fetch("my-stripe-checkout.php", {
        method: "POST",
        body: JSON.stringify(product_data), // passing all data attributes to the backend
      })
      .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);
      });
  });
});

Note:

product_data is an object containing all the data attributes, which means

body: JSON.stringify(product_data)

is passing an object to your backend.

If you just want to pass the product id, you need to do this:

let product_id = product_data['productId']; // camelCase of 'product-id'

and pass product_id to your backend.

You may also see this if you want to convert event.target.dataset to a json object for later use.

The advantage of using .dataset

You can store extra data using the data attributes and get them by calling .dataset property . For example, you can add extra data attributes to the button:

<?php
  <button 
    data-product-id="<?php $row['productid']; ?>"
    data-product-description="<?php $row['productdescription']; ?>"
    data-product-price="<?php $row['productprice']; ?>"
  >
    Buy <?php echo $row['productname']; ?>
  </button>
?>

Since you are sending product_data in the POST call, you don't have to modify the event listener. This gives your code a higher flexibility and easier to manage.

Upvotes: 2

Justin Michael
Justin Michael

Reputation: 6530

You need to add JavaScript to the page to listen to and handle events from all the buttons on the page. There are several ways to approach this, but I would recommend changing the buttons so they work something like this:

<button onclick="checkoutButtonPressed('<?php $row['productid']; ?>')">Buy <?php echo $row['productname']; ?> </button>

Then implement the checkoutButtonPressed() function in JavaScript to create a Checkout Session based on the Product ID provided:

var stripe = Stripe("<?php echo $stripe_key_public ?>");

function checkoutButtonPressed(productID) {
    var session = // Fetch Checkout Session using productID

    stripe.redirectToCheckout({ sessionId: session.id });
}

Upvotes: 2

Related Questions