Home > Software design >  PayPal API PopUp closes immediately after clicking PayPal button (Sandbox)
PayPal API PopUp closes immediately after clicking PayPal button (Sandbox)

Time:09-17

I am trying to implement the PayPal API into my Django / Vue checkout system, but everytime i try to access checkout via the paypal checkout buttons, thepopup closes immediately and i get these errors: Error messages in developer tools

Obviously it has something to do with the cart's items' attributes and i tried to adjust them accordingly, but i can't figure out how to fix it. My Code:

<template>
    <div >
        <div >
            <div >
                <h1 >Kasse</h1>
            </div>

            <div >
                <table >
                    <thead>
                        <tr>
                            <th>Artikel</th>
                            <th>Preis</th>
                            <th>Anzahl</th>
                            <th>Gesamt</th>
                        </tr>
                    </thead>
                    <!-- vue for loop for looping through items in cart and displaying them in a table -->
                    <tbody>
                        <tr
                            v-for="item in cart.items"
                            v-bind:key="item.product.id"
                        >
                            <td>{{ item.product.name }}</td>
                            <td>{{ item.product.price }}€</td>
                            <td>{{ item.quantity }}</td>
                            <td>{{ getItemTotal(item).toFixed(2) }}€</td>
                        </tr>
                    </tbody>

                    <tfoot>
                        <tr style="font-weight: bolder; font-size: larger;">
                            <td colspan="2">Insgesamt</td>
                            <td>{{ cartTotalLength }}</td>
                            <td>{{ cartTotalPrice.toFixed(2) }}€</td>
                        </tr>
                    </tfoot>
                </table>
            </div>

            <!-- Fields for user information -->
            <div >
                <h2 >Versanddetails</h2>

                <p >*Felder müssen ausgefüllt sein</p>

                <div >
                    <div >
                        <div >
                            <label>*Vorname</label>
                            <div >
                                <input type="text"  v-model="first_name">
                            </div>
                        </div>

                        <div >
                            <label>*Nachname</label>
                            <div >
                                <input type="text"  v-model="last_name">
                            </div>
                        </div>

                        <div >
                            <label>*E-Mail</label>
                            <div >
                                <input type="email"  v-model="email">
                            </div>
                        </div>

                        <div >
                            <label>*Telefonnummer</label>
                            <div >
                                <input type="text"  v-model="phone">
                            </div>
                        </div>

                        <div >
                        <div >
                            <label>*Adresse</label>
                            <div >
                                <input type="text"  v-model="address">
                            </div>
                        </div>

                        <div >
                            <label>*Postleitzahl</label>
                            <div >
                                <input type="text"  v-model="zipcode">
                            </div>
                        </div>

                        <div >
                            <label>*Ort</label>
                            <div >
                                <input type="text"  v-model="place">
                            </div>
                        </div>
                    </div>
                    <!-- looping through errors for authorization -->
                    <div  v-if="errors.length">
                        <p v-for="error in errors" v-bind:key="error">{{ error }}</p>
                    </div>

                    <hr>

                    <div id="card-element" ></div>

                    <!-- Part for PayPal implementation -->
                    <template v-if="cartTotalLength">
                        <hr>

                        <!-- Set up a container element for the button -->
                        <div id="paypal-button-container"></div>


                        <!-- Include the PayPal JavaScript SDK -->
                        <div ref="paypal"></div>

                        <!-- <button  @click="submitForm">Weiter mit PayPal</button> -->
                    </template>
                </div>

                </div>
            </div>
        </div>
    </div>
</template>
     
<script>
    import axios from 'axios'

    export default {
        name: 'Checkout',
        data() {
            return {
                loaded: false,
                paidFor: false,
                cart: {
                    items: []
                },
                stripe: {},
                card: {},
                first_name: '',
                last_name: '',
                email: '',
                phone: '',
                address: '',
                zipcode: '',
                place: '',
                errors: []
            }
        },
        mounted() {
            document.title = 'Kasse | RELOAD'

            this.cart = this.$store.state.cart
            
            // Imported PayPal functionality from https://fireship.io/lessons/paypal-checkout-frontend/
            const script = document.createElement("script");
            script.src = "https://www.paypal.com/sdk/js?client-id=AeAKmRDX7HTesdUvfqYqCQz3fZHIkjAoQ5-BG6K-7xnL5GBMVvwQba53v-I8Fx1p9wurUtoBuk7D6bV1"; // Replace YOUR-CLIENT-ID with paypal credentials
            script.addEventListener("load", this.setLoaded);
            document.body.appendChild(script); // Adds script to the document's body
        },
        watch: {
            $route(to, from,) {
                if (to.name === 'Category') {
                    this.getCategory()
                }
            }
        },
        methods: {
            getItemTotal(item) {
                return item.quantity * item.product.price
            },
            // Authorization methods
            submitForm() {
                this.errors = []

                if (this.first_name === '') {
                    this.errors.push('Bitte Vornamen angeben')
                }

                if (this.last_name === '') {
                    this.errors.push('Bitte Nachnamen angeben')
                }

                if (this.email === '') {
                    this.errors.push('Bitte E-Mail angeben')
                }

                if (this.phone === '') {
                    this.errors.push('Bitte Telefonnummer angeben')
                }

                if (this.adress === '') {
                    this.errors.push('Bitte Adresse angeben')
                }

                if (this.zipcode === '') {
                    this.errors.push('Bitte Postleitzahl angeben')
                }

                if (this.place === '') {
                    this.errors.push('Bitte Ort angeben')
                }

            },
            // Imported PayPal functionality from https://fireship.io/lessons/paypal-checkout-frontend/
            setLoaded() {
                this.loaded = true;
                window.paypal
                    .Buttons({
                    // createOrder: (data, actions) => {
                    //     return actions.order.create({
                    //     purchase_units: [
                    //         {
                    //         description: this.product.description,
                    //         amount: {
                    //             currency_code: "EUR",
                    //             value: this.product.price
                    //         }
                    //         }
                    //     ]
                    createOrder: (data, actions) => {
                        return actions.order.create({
                            "purchase_units": [{
                                "amount": {
                                    "currency_code": "EUR",
                                    "value": item.product.price,
                                "breakdown": {
                                    "item_total": {  /* Required when including the items array */
                                    "currency_code": "EUR",
                                    "value": item.quantity * product.price
                                    }
                                }
                                },
                                "items": [
                                {
                                    "name": item.product.name, /* Shows within upper-right dropdown during payment approval */
                                    "description": item.product.description, /* Item details will also be in the completed paypal.com transaction view */
                                    "unit_amount": {
                                    "currency_code": "EUR",
                                    "value": item.product.price
                                    },
                                    "quantity": item.product.quantity
                                },
                                ]
                            }]
                        });
                    },
                    onApprove: async (data, actions) => {
                        const order = await actions.order.capture();
                        this.paidFor = true;
                        console.log(order);
                    },
                    one rror: err => {
                        console.log(err);
                    }
                    })
                    .render(this.$refs.paypal);
                }
        },
        computed: {
            // Computing total price and total amount of all items 
            cartTotalPrice() {
                return this.cart.items.reduce((acc, curVal) => {
                    return acc  = curVal.product.price * curVal.quantity
                }, 0)
            },
            cartTotalLength() {
                return this.cart.items.reduce((acc, curVal) => {
                    return acc  = curVal.quantity
                }, 0)
            }
        }
    }
</script>

CodePudding user response:

The createOrder function inside setLoaded() is assigning properties using item although it's not clear where item comes from as it's not being passed in from anywhere:

setLoaded() {
  this.loaded = true;
  window.paypal.Buttons({
    createOrder: (data, actions) => {
      return actions.order.create({
        purchase_units: [
          {
            amount: {
              currency_code: "EUR",
              value: item.product.price,  // <--- item is not defined here
              breakdown: {
                item_total: {
                  currency_code: "EUR",
                  value: item.quantity * product.price,  // <--- or here
                },
              },
            },
            ...

If you mean to reference the items in the cart data property you need to use this.cart.items and possibly loop through it if you're trying to send individual item details.

  • Related