PayPal Pay Later button is not being displayed

1.8k Views Asked by At

I am following a tutorial, where the teacher is integrating PayPal into an e-commerce website. The thing is, that I have only 2 buttons, (image 1) but the instructor has 3 of them. (image 2) I was trying to follow him step by step, but maybe it is a matter of newer version of react-paypal-button-v2 library or something like that. The other 2 buttons are being displayed properly. (even though it would be fine, if the "Debit or Credit Card" button would have a description) As You can see, I am also missing the "Powered by PayPal" line underneath the buttons. I have tested the functionality of the main PayPal button through the sandbox accounts and everything is ok in this regard. Could anybody please help me with this issue? Thank You very much for Your eventual assistance.

These are my current PayPal buttons - (image 0)

enter image description here

Update - After removing the comments (I have left them on their places here on SO, so I can see, where they were) from the code, I have solved the issue with the "Powered by PayPal" and "Debit or Credit Card" lines. So now my buttons look like this - (image 1)

enter image description here

And here is the desired outcome - (image 2)

enter image description here

OrderScreen.js - (please note, that despite the fact, that some of the comments are not gray here on Stack Overflow, they are actually grey in my IDE)

import React, { useState, useEffect } from "react";
import { Button, Row, Col, ListGroup, Image, Card } from "react-bootstrap";
import { Link } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { PayPalButton } from 'react-paypal-button-v2'
import Message from "../components/Message";
import Loader from '../components/Loader'
import { getOrderDetails, payOrder } from "../actions/orderActions";
import { ORDER_PAY_RESET } from '../constants/orderConstants'

function OrderScreen({ match }) {
  const orderId = match.params.id
  const dispatch = useDispatch();

  const [sdkReady, setSdkReady] = useState(false)
  //we are updating the setSdkReady
  //false is the default value, but once we load the setSdkReady, then it will be set to true
  //if we are not ready, then we will not add the button, but if we are ready, we will add the button
  //that is going to depend on whether successPay is true or not (?)

  const orderDetails = useSelector(state => state.orderDetails)
  const {order, error, loading} = orderDetails

  const orderPay = useSelector(state => state.orderPay)
  const { loading:loadingPay, success:successPay } = orderPay //here we are setting a custom name for the loading
  
  if(!loading && !error){
     order.itemsPrice = order.orderItems
     .reduce((acc, item) => acc + item.price * item.qty, 0)
     .toFixed(2);
    //acc znamená accumulator, toFixed(2) znamená, že výsledné číslo bude mít maximálně jen 2 decimal places
  } //orderItems gets calculated only once we have that order
  
  const addPayPalScript = () => { //this function is going to be dependent on our order status
      const script = document.createElement('script')
      script.type = 'text/javascript'
      script.src = 'https://www.paypal.com/sdk/js?client-id=AVrrJLnByiAFSjPZ91_-o5OeBqUzCQulKVl0aly2FyVOQfZ9cHn2kvUSDNvSJqMv8S9KzBc2_lxRBnuV'
      script.async = true
      script.onload = () => {
        setSdkReady(true)
      }
      document.body.appendChild(script) //we are appending the script to the dom
  }
  
  useEffect(() => {
      if (!order || successPay || order._id !== Number(orderId)){ //we are going to dispatch this, if we don´t have an order or if the order id is not here yet
          dispatch({ type:ORDER_PAY_RESET })
          dispatch(getOrderDetails(orderId)) //this is going to make the api call using that id
          //we only get the order details when we don´t have that information yet
      } else if(!order.isPaid){ //if order is not paid
           if(!window.paypal){
              addPayPalScript() //if the script is not there, then add it
           } else {
             setSdkReady(true) //this gets our script ready
           }
      }   
  }, [dispatch, order, orderId, successPay]) //uvnitř hranatých závorek jsou dependencies

  const successPaymentHandler = (paymentResult) => {
    //paymentResult is going to be the data, that the paypal will give us
    //it will be the response from paypal
    dispatch(payOrder(orderId, paymentResult)) //payOrder is taking in 2 parameters
    //payOrder sends our API call and it goes and updates our database
  }

  return loading ? ( //we are checking, if (?) we are loading
      <Loader/> //load spinner
  ) : error ? ( //if we are not loading, then (else je :) we will check for an error
      <Message variant='danger'>{error}</Message> //if there is an error, let´s throw out that message
  ) : ( //if none of the above are true, then pass in the final component
    <div>
      <h1>Order: {order._id}</h1>
      <Row>
        <Col md={8}>
          <ListGroup variant="flush">
            <ListGroup.Item>
              <h2>Shipping</h2>
              <p><strong>Name: </strong> {order.user.name}</p>
              <p><strong>Email: </strong><a href={`mailto:${order.user.email}`}>{order.user.email}</a></p>
              <p>
                <strong>Shipping: </strong>
                {order.shippingAddress.address}, {order.shippingAddress.city}
                {"  "}
                {order.shippingAddress.postalCode},{"  "}
                {order.shippingAddress.country}
              </p>

              {order.isDelivered ? ( //this will be updated from the admin panel
                  <Message variant='success'>Delivered on {order.deliveredAt}</Message>
              ) : ( // if this is not delivered, then the else statement will take place
                  <Message variant='warning'>Not Delivered</Message>
              )}
            </ListGroup.Item>

            <ListGroup.Item>
              <h2>Payment Method</h2>
              <p>
                <strong>Method: </strong>
                {order.paymentMethod}
              </p>
              {order.isPaid ? ( //this will be updated from the admin panel
                  <Message variant='success'>Paid on {order.paidAt}</Message>
              ) : ( // if this is not paid, then the else statement will take place
                  <Message variant='warning'>Not Paid</Message>
              )}
            </ListGroup.Item>

            <ListGroup.Item>
              <h2>Order Items</h2>
              {order.orderItems.length === 0 ? (
                <Message variant="info">Order is empty</Message>
              ) : (
                <ListGroup variant="flush">
                  {order.orderItems.map((item, index) => (
                    <ListGroup.Item key={index}>
                      <Row>
                        <Col md={1}>
                          <Image
                            src={item.image}
                            alt={item.name}
                            fluid
                            rounded
                          />
                        </Col>

                        <Col>
                          <Link to={`/product/${item.product}`}>
                            {item.name}
                          </Link>
                        </Col>

                        <Col md={4}>
                          {item.qty} X ${item.price} = $
                          {(item.qty * item.price).toFixed(2)}
                        </Col>
                      </Row>
                    </ListGroup.Item>
                  ))}
                </ListGroup>
              )}
            </ListGroup.Item>
          </ListGroup>
        </Col>

        <Col md={4}>
          <Card>
            <ListGroup variant="flush">
              <ListGroup.Item>
                <h2>Order Summary</h2>
              </ListGroup.Item>

              <ListGroup.Item>
                <Row>
                  <Col>Items:</Col>
                  <Col>${order.itemsPrice}</Col>
                </Row>
              </ListGroup.Item>

              <ListGroup.Item>
                <Row>
                  <Col>Shipping:</Col>
                  <Col>${order.shippingPrice}</Col>
                </Row>
              </ListGroup.Item>

              <ListGroup.Item>
                <Row>
                  <Col>Tax:</Col>
                  <Col>${order.taxPrice}</Col>
                </Row>
              </ListGroup.Item>

              <ListGroup.Item>
                <Row>
                  <Col>Total:</Col>
                  <Col>${order.totalPrice}</Col>
                </Row>
              </ListGroup.Item>

              {!order.isPaid && (
                <ListGroup.Item>
                  {loadingPay && <Loader/>}
                  
                  {!sdkReady ? ( //while we are loading, then output the loader
                    <Loader/>
                  ) : ( //else
                      <PayPalButton
                          amount={order.totalPrice}
                          onSuccess={successPaymentHandler}
                      />
                  )}
                </ListGroup.Item>
              )}

            </ListGroup>
          </Card>
        </Col>
      </Row>
    </div>
  );
}

export default OrderScreen;
0

There are 0 best solutions below