How do I add PayPal's Smart Buttons to an existing javascript cart?

瘦欲@ 提交于 2020-04-07 07:04:21

问题


I am trying to integrate PayPal's Smart Payment Buttons into my cart on my website. My cart is integrated using VanillaCart JS and here is my main.js file:

'use strict';

let cart = (JSON.parse(localStorage.getItem('cart')) || []);
const cartDOM = document.querySelector('.cart');
const addToCartButtonsDOM = document.querySelectorAll('[data-action="ADD_TO_CART"]');

if (cart.length > 0) {
    cart.forEach(cartItem => {
        const product = cartItem;
        insertItemToDOM(product);
        countCartTotal();

        addToCartButtonsDOM.forEach(addToCartButtonDOM => {
            const productDOM = addToCartButtonDOM.parentNode;

            if (productDOM.querySelector('.product__name').innerText === product.name) {
                handleActionButtons(addToCartButtonDOM, product);
            }
        });

    });
}

addToCartButtonsDOM.forEach(addToCartButtonDOM => {
    addToCartButtonDOM.addEventListener('click', () => {
        const productDOM = addToCartButtonDOM.parentNode;
        const product = {
            image: productDOM.querySelector('.product__image').getAttribute('src'),
            name: productDOM.querySelector('.product__name').innerText,
            price: productDOM.querySelector('.product__price').innerText,
            quantity: 1,
        };

        const isInCart = (cart.filter(cartItem => (cartItem.name === product.name)).length > 0);

        if (!isInCart) {
            insertItemToDOM(product);
            cart.push(product);
            saveCart();
            handleActionButtons(addToCartButtonDOM, product);
        }
    });
});

function insertItemToDOM(product) {
    cartDOM.insertAdjacentHTML('beforeend', `
    <div class="cart__item">
      <img class="cart__item__image" src="${product.image}" alt="${product.name}">
      <h3 class="cart__item__name">${product.name}</h3>
      <h3 class="cart__item__price">${product.price}</h3>
      <button class="btn btn--primary btn--small${(product.quantity === 1 ? ' btn--danger' : '')}" data-action="DECREASE_ITEM">&minus;</button>
      <h3 class="cart__item__quantity">${product.quantity}</h3>
      <button class="btn btn--primary btn--small" data-action="INCREASE_ITEM">&plus;</button>
      <button class="btn btn--danger btn--small" data-action="REMOVE_ITEM">&times;</button>
    </div>
  `);

    addCartFooter();
}

function handleActionButtons(addToCartButtonDOM, product) {
    addToCartButtonDOM.innerText = 'In Cart';
    addToCartButtonDOM.disabled = true;

    const cartItemsDOM = cartDOM.querySelectorAll('.cart__item');
    cartItemsDOM.forEach(cartItemDOM => {
        if (cartItemDOM.querySelector('.cart__item__name').innerText === product.name) {
            cartItemDOM.querySelector('[data-action="INCREASE_ITEM"]').addEventListener('click', () => increaseItem(product, cartItemDOM));
            cartItemDOM.querySelector('[data-action="DECREASE_ITEM"]').addEventListener('click', () => decreaseItem(product, cartItemDOM, addToCartButtonDOM));
            cartItemDOM.querySelector('[data-action="REMOVE_ITEM"]').addEventListener('click', () => removeItem(product, cartItemDOM, addToCartButtonDOM));
        }
    });
}

function increaseItem(product, cartItemDOM) {
    cart.forEach(cartItem => {
        if (cartItem.name === product.name) {
            cartItemDOM.querySelector('.cart__item__quantity').innerText = ++cartItem.quantity;
            cartItemDOM.querySelector('[data-action="DECREASE_ITEM"]').classList.remove('btn--danger');
            saveCart();
        }
    });
}

function decreaseItem(product, cartItemDOM, addToCartButtonDOM) {
    cart.forEach(cartItem => {
        if (cartItem.name === product.name) {
            if (cartItem.quantity > 1) {
                cartItemDOM.querySelector('.cart__item__quantity').innerText = --cartItem.quantity;
                saveCart();
            } else {
                removeItem(product, cartItemDOM, addToCartButtonDOM);
            }

            if (cartItem.quantity === 1) {
                cartItemDOM.querySelector('[data-action="DECREASE_ITEM"]').classList.add('btn--danger');
            }
        }
    });
}

function removeItem(product, cartItemDOM, addToCartButtonDOM) {
    cartItemDOM.classList.add('cart__item--removed');
    setTimeout(() => cartItemDOM.remove(), 250);
    cart = cart.filter(cartItem => cartItem.name !== product.name);
    saveCart();
    addToCartButtonDOM.innerText = 'Add To Cart';
    addToCartButtonDOM.disabled = false;

    if (cart.length < 1) {
        document.querySelector('.cart-footer').remove();
    }
}

function addCartFooter() {
    if (document.querySelector('.cart-footer') === null) {
        cartDOM.insertAdjacentHTML('afterend', `
      <div class="cart-footer">
        <button class="btn btn--danger" data-action="CLEAR_CART">Clear Cart</button>
        <button class="btn btn--primary" data-action="CHECKOUT">Pay</button>
      </div>
    `);

        document.querySelector('[data-action="CLEAR_CART"]').addEventListener('click', () => clearCart());
        document.querySelector('[data-action="CHECKOUT"]').addEventListener('click', () => checkout());
    }
}

function clearCart() {
    cartDOM.querySelectorAll('.cart__item').forEach(cartItemDOM => {
        cartItemDOM.classList.add('cart__item--removed');
        setTimeout(() => cartItemDOM.remove(), 250);
    });

    cart = [];
    localStorage.removeItem('cart');
    document.querySelector('.cart-footer').remove();

    addToCartButtonsDOM.forEach(addToCartButtonDOM => {
        addToCartButtonDOM.innerText = 'Add To Cart';
        addToCartButtonDOM.disabled = false;
    });
}

function checkout() {

}

function countCartTotal() {
    let cartTotal = 0;
    cart.forEach(cartItem => cartTotal += cartItem.quantity * cartItem.price);
    document.querySelector('[data-action="CHECKOUT"]').innerText = `Pay $${cartTotal}`;
}

function saveCart() {
    localStorage.setItem('cart', JSON.stringify(cart));
    countCartTotal();
}

To break it down, this function allows me to add products to the cart section, add and take away quantities, clear the whole cart and display the pay button with how much the user must pay and this part works. The tutorial I was using is an old one and the PayPal payment method was an old one and didn't really work. So went to https://developer.paypal.com/docs/checkout/ and tried to follow this tutorial.

It gives various steps that render the buttons and you end up with a script like this:

<script
    src="https://www.paypal.com/sdk/js?client-id=SB_CLIENT_ID"> // Required. Replace SB_CLIENT_ID with your sandbox client ID.
  </script>

  <div id="paypal-button-container"></div>

  <script>
    paypal.Buttons().render('#paypal-button-container');
    // This function displays Smart Payment Buttons on your web page.
  </script>


<script>
  paypal.Buttons({
    createOrder: function(data, actions) {
      // This function sets up the details of the transaction, including the amount and line item details.
      return actions.order.create({
        purchase_units: [{
          amount: {
            value: '0.01'
          }
        }]
      });
    },
    onApprove: function(data, actions) {
      // This function captures the funds from the transaction.
      return actions.order.capture().then(function(details) {
        // This function shows a transaction success message to your buyer.
        alert('Transaction completed by ' + details.payer.name.given_name);
      });
    }
  }).render('#paypal-button-container');
  //This function displays Smart Payment Buttons on your web page.
</script>

This works when done, however, it charges the customer whatever data is in the "value: '0.01'". But I need the PayPal button to charge the total of the cart. The issue is the script is run the index.html and the cart code is in the main.js file.

The variable that holds the value of the cart is called 'cartTotal', but when I move the Paypal code to the main.js is stops working and when I change the 'value:0.01' to 'value:cartTotal' this doesn't work either

The cart looks like this, with items added:

The JavaScript line for the pay button is:

<button class="btn btn--primary" data-action="CHECKOUT">Pay</button>

The part after answers:

My file html form looks like this:

<!DOCTYPE html>
<html>
<!-- Title -->
<title>Mobile Masters | Shop</title>

<!-- Meta Tags -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="Ross Currie">
<meta name="description" content="Mobile Gaming Accessories">
<meta name="keywords" content="Ferg, iFerg, Gaming, Mobile, Accessories, Youtube">

<!-- Links to css -->
<link rel="stylesheet" href="mmCSS.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Karma">

<body>

<script src="https://www.paypal.com/sdk/js?client-id=Ab_w_ypGev9_rr3eUjNMbF0fbqnelXD6C6fakevQDAOdLs0YAnxyvwAuQCKl-Ijie-m-hcS9C99sUw6E"> </script>

<!-- Sidebar (hidden by default) -->
<nav class="mm-sidebar mm-bar-block mm-card mm-top mm-xlarge mm-animate-left" style="display: none; z-index: 2; width: 40%; max-width: 415px;" id="mySidebar">
    <a id="#products" onclick="mm_close()" class="mm-bar-item mm-button">STORE</a>
    <a id="#cart" onclick="mm_close()" class="mm-bar-item mm-button">CART</a>
    <a id="#socials" onclick="mm_close()" class="mm-bar-item mm-button">SOCIALS</a>
    <a href="#" onclick="mm_close()" class="mm-bar-item mm-button">LOGIN / SIGNUP</a>
    <a href="javascript:void(0)" onclick="mm_close()" class="mm-bar-item mm-button"><img src="images/back-icon.png" width="30px"></a>
</nav>

<!-- Top menu -->
<div class="mm-top">
    <div class="mm-white mm-xlarge" style="max-width:1400px; margin:auto">
        <div class="mm-button mm-padding-16 mm-left" onclick="mm_open()">☰</div>
        <div class="mm-center mm-padding-16"><img src="images/logo/Logo.png" width="400px"></div>
    </div>
</div>

<!-- !PAGE CONTENT! -->
<div class="mm-main mm-content mm-padding" style="max-width: 1400px; margin-top: 70px;">

    <h1 class="mm-heading-title">Shop</h1>

    <!-- First Photo Grid-->
    <div class="mm-row-padding mm-padding-16 mm-center" id="products">
        <div class="mm-quarter">
            <img class="product__image" src="images/products/Mobile-Fire-Button-Controller.jpg" alt="Product" style="width:100%">
            <h2 class="product__name">Mobile Trigger Attachments</h2>
            <p>Improve you accuracy, and defeat your opponent very time. This simple attachment ensures you will come out on top in any one vs one. Get yours today</p>
            <h3 class="product__price">10.00</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
            <br>
        </div>

        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 2</h2>
            <h3 class="product__price">15.00</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>

        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 3</h2>
            <h3 class="product__price">9.99</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>

        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 4</h2>
            <h3 class="product__price">0.01</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>
    </div>

    <!-- Second Photo Grid-->
    <div class="mm-row-padding mm-padding-16 mm-center">
        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 5</h2>
            <h3 class="product__price">Price</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>

        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 6</h2>
            <h3 class="product__price">Price</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>

        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 7</h2>
            <h3 class="product__price">Price</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>

        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 8</h2>
            <h3 class="product__price">Price</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>
    </div>

    <!-- Third Photo Grid-->
    <div class="mm-row-padding mm-padding-16 mm-center">
        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 9</h2>
            <h3 class="product__price">Price</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>

        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 10</h2>
            <h3 class="product__price">Price</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>

        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 11</h2>
            <h3 class="product__price">Price</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>

        <div class="mm-quarter">
            <img class="product__image" src="images/product-sample.png" alt="Product" style="width:100%">
            <h2 class="product__name">Product 12</h2>
            <h3 class="product__price">Price</h3>
            <button class="btn btn--primary" data-action="ADD_TO_CART">Add To Cart</button>
        </div>
    </div>

    <!-- Pagination -->
    <div class="mm-center mm-padding-32">
        <div class="mm-bar">
            <a href="index.html" class="mm-bar-item mm-black mm-button">1</a>
            <a href="shop-page2.html" class="mm-bar-item mm-button mm-hover-black">2</a>
            <a href="shop_page_3.html" class="mm-bar-item mm-button mm-hover-black">3</a>
            <a href="shop_page_4.html" class="mm-bar-item mm-button mm-hover-black">4</a>
            <a href="shop_page_2.html" class="mm-bar-item mm-button mm-hover-black">»</a>
        </div>
    </div>

    <hr>

    <div class="mm-twothird">
        <section class="section">
            <h1 class="mm-heading-title">Cart</h1>
            <div class="cart"></div>
        </section>
        <div class="mm-right">
            <div id="paypal-button-container" style="width: 25%;"></div>
        </div>
    </div>

    <div>
        <img src="images/Ferg%20Cart%20image%20copy.png">
    </div>

    <!-- Footer -->
    <footer class="mm-row-padding mm-padding-32">
        <hr>
        <h1 class="mm-heading-title">Socials</h1>
        <div class="mm-half">
            <p>Follow Ferg on...</p>
            <ul class="mm-ul mm-hoverable">
                <a href="https://www.facebook.com/IFerg-2022941574421321" class="social-links">
                    <li class="mm-padding-16">
                        <img src="images/Facebook-Icon.png" width="55px" class="mm-left mm-margin-right">
                        <span class="mm-large">Facebook</span><br>
                        <span>iFerg | Home</span>
                    </li>
                </a>

                <hr>

                <a href="https://www.instagram.com/ifergyt/" class="social-links">
                    <li class="mm-padding-16">
                        <img src="images/Insta-Icon.png" width="55px" class="mm-left mm-margin-right">
                        <span class="mm-large">Ferg🔥</span><br>
                        <span>(@ifergyt)</span>
                    </li>
                </a>

                <hr>

                <a href="https://twitter.com/Ferg" class="social-links">
                    <li class="mm-padding-16">
                        <img src="images/Twitter-Icon.png" width="55px" class="mm-left mm-margin-right">
                        <span class="mm-large">Ferg</span><br>
                        <span>(@Ferg)</span>
                    </li>
                </a>
            </ul>
        </div>

        <div class="mm-half">
            <p>Check out the links below...</p>
            <ul class="mm-ul mm-hoverable">
                <a href="https://www.youtube.com/channel/UCVYe9OwcrGrlRmlX8cSWgvg" class="social-links">
                    <li class="mm-padding-16">
                        <img src="images/iFerg-MainChannel-New.png" width="55px" class="mm-left mm-margin-right">
                        <span class="mm-large">iFerg</span><br>
                        <span>(Channel description)</span>
                    </li>
                </a>

                <hr>

                <a href="https://www.youtube.com/channel/UCVYe9OwcrGrlRmlX8cSWgvg" class="social-links">
                    <li class="mm-padding-16">
                        <img src="images/iFerg-SecondChannel.png" width="55px" class="mm-left mm-margin-right">
                        <span class="mm-large">iFerg - COD Mobile</span><br>
                        <span>(Channel description)</span>
                    </li>
                </a>

                <hr>

                <a href="https://www.youtube.com/channel/UCVYe9OwcrGrlRmlX8cSWgvg" class="social-links">
                    <li class="mm-padding-16">
                        <img src="images/iFerg-ThirdChannel.png" width="55px" class="mm-left mm-margin-right">
                        <span class="mm-large">iFerg - Highlights</span><br>
                        <span>(Channel description)</span>
                    </li>
                </a>
            </ul>
        </div>
    </footer>
    <!-- End page content -->
</div>

<script>
    // Script to open and close sidebar
    function mm_open() {
        document.getElementById("mySidebar").style.display = "block";
    }

    function mm_close() {
        document.getElementById("mySidebar").style.display = "none";
    }
</script>

<script src="main.js"></script>

<script>
    paypal.Buttons({
        createOrder: function(data, actions) {
            // This function sets up the details of the transaction, including the amount and line item details.
            return actions.order.create({
                purchase_units: [{
                    amount: {
                        value: checkout()
                    }
                }]
            });
        }
    }).render('#paypal-button-container');
</script>

</body>
</html>

The cart section is:

<div class="mm-twothird">
    <section class="section">
        <h1 class="mm-heading-title">Cart</h1>
        <div class="cart"></div>
    </section>
    <div class="mm-right">
        <div id="paypal-button-container" style="width: 25%;"></div>
    </div
</div>

And the section of main.js file that holds the cartTotal is:

function countCartTotal() {
    let cartTotal = 0;
    cart.forEach(cartItem => cartTotal += cartItem.quantity * cartItem.price);
    document.querySelector('[data-action="CHECKOUT"]').innerText = `Pay £ ${cartTotal}`;
}

The PayPal window pops up and then disappears and I have tried the following code:

<script>
    paypal.Buttons({
        createOrder: function(data, actions) {
            // This function sets up the details of the transaction, including the amount and line item details.
            return actions.order.create({
                purchase_units: [{
                    amount: {
                        value: countCartTotal()
                    }
                }]
            });
        }
    }).render('#paypal-button-container');
</script>

And

<script>
    paypal.Buttons({
        createOrder: function(data, actions) {
            // This function sets up the details of the transaction, including the amount and line item details.
            return actions.order.create({
                purchase_units: [{
                    amount: {
                        value: document.getElementById('cartTotal').value
                    }
                }]
            });
        }
    }).render('#paypal-button-container');
</script>

But when I replace "value: document.getElementById('cartTotal').value" or "value: countCartTotal()" with say "value: '0.01'", the window loads fine?


回答1:


This function of yours does not actually return a value:

function countCartTotal() {
    let cartTotal = 0;
    cart.forEach(cartItem => cartTotal += cartItem.quantity * cartItem.price);
    document.querySelector('[data-action="CHECKOUT"]').innerText = `Pay £ ${cartTotal}`;
}

It appears you would need to extend it with a final line:

    ...
    return cartTotal;
}

Then, you would be able to make use of it as desired:

                amount: {
                    value: countCartTotal()
                }

Additionally, you might need &currency=GBP as a parameter when you include the PayPal sdk/js script.



来源:https://stackoverflow.com/questions/60840763/how-do-i-add-paypals-smart-buttons-to-an-existing-javascript-cart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!