Почему смарт-кнопки PayPal не работают с моей корзиной?

Я пытаюсь встроить интеллектуальные кнопки оплаты PayPal в свою корзину на моем веб-сайте. Моя корзина интегрирована с использованием VanillaCart JS, и вот мой файл main.js:

'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();
}

Чтобы разбить его на части, эта функция позволяет мне добавлять товары в раздел корзины, добавлять и убирать количества, очищать всю корзину и отображать кнопку оплаты с указанием суммы, которую должен заплатить пользователь, и эта часть работает. Учебное пособие, которое я использовал, является старым, а метод оплаты PayPal был старым и не работал. Так что зашел на https://developer.paypal.com/docs/checkout/ и попытался следовать этому руководству.

Он дает различные шаги для рендеринга кнопок, и в итоге получается скрипт, подобный этому:

<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: Ɔ.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>

Это работает, когда сделано, однако, это берет с клиента любые данные в «значение:« 0,01 »». Но мне нужна кнопка PayPal, чтобы зарядить всю корзину. Проблема в том, что скрипт запускает index.html и код корзины находится в файле main.js.

Переменная, которая содержит значение корзины, называется 'cartTotal', но когда я перемещаю код Paypal в main.js, он перестает работать, и когда я изменяю 'value: 0.01' на 'value: cartTotal', это не работать либо

Корзина выглядит так, с добавленными товарами:

введите описание изображения здесь

Строка JavaScript для кнопки оплаты:

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

HTML-форма моего файла выглядит следующим образом:

<!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>

Раздел корзины:

<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>

И раздел файла main.js, который содержит cartTotal:

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

Окно PayPal всплывает, а затем исчезает, и я попробовал следующий код:

<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>

И

<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>

Но когда я заменяю "value: document.getElementById ('cartTotal'). Value" или "value: countCartTotal ()", скажем, "value: '0.01'", окно загружается нормально?

Всего 1 ответ


Ваша функция на самом деле не возвращает значение:

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

Похоже, вам нужно расширить его с помощью последней строки:

    ...
    return cartTotal;
}

Тогда вы сможете использовать его по своему усмотрению:

                amount: {
                    value: countCartTotal()
                }

Кроме того, вам может потребоваться &currency=GBP в качестве параметра при включении сценария PayPal sdk / js.


Есть идеи?

10000