cocoastorm / vue-paypal-checkout

A simple Vue.js wrapper component for paypal-checkout
MIT License
153 stars 66 forks source link

No handler found for post message #47

Open JamesFreeman opened 6 years ago

JamesFreeman commented 6 years ago

Hi,

I've been looking to implement your package today, and I kept running into the same problem of Error: No handler found for post message: xcomponent_init from

My code is as follows:

<template>
    <PayPal
            amount="10.00"
            currency="USD"
            :client="credentials"
            :items="myItems"
            :invoice-number="'201705051001'"
            env="sandbox"></PayPal>
</template>

<script>
    import PayPal from 'vue-paypal-checkout';

    export default {
        components: {
            PayPal
        },

        data(){
            return {
                credentials: {
                    sandbox: '<SANDBOX ID>',
                    production: ''
                },
                myItems: [
                    {
                        "name": "hat",
                        "description": "Brown hat.",
                        "quantity": "1",
                        "price": "5",
                        "currency": "USD"
                    },
                    {
                        "name": "handbag",
                        "description": "Black handbag.",
                        "quantity": "1",
                        "price": "5",
                        "currency": "USD"
                    }
                ]
            }
        }
    }
</script>

image I've done some googling and apperently it may be something to do with how VueJS handles the button? See https://github.com/paypal/paypal-checkout/issues/130 and https://github.com/paypal/paypal-checkout/issues/126 or am I doing something completely wrong here?

I look forward to hearing back from you. James.

JamesFreeman commented 6 years ago

I've been playing around with this some more and it works fine, when I put <paypal-checkout> straight into the div#app but when I start to nest my components that's where it causes these issues. going to play around with inline-templates to see if that has any effect.

JamesFreeman commented 6 years ago

@khoanguyen96 I've been unable to track down what actually causing this issue, would you be able to take a look at this?

cocoastorm commented 6 years ago

Hey @iamthefreeman,

Sorry for the late reply. I'm thinking it might be because it's nested in your components. If the parent component has a v-if, it might be breaking the button.

Is there any chance you can show me what your parent components look/behave like?

Thanks!

JamesFreeman commented 6 years ago

Hi @khoanguyen96, thanks for your response. I've built a repo to reproduce the issue for you. It was productive to do this as I can see actually what is causing the issue, nesting the components work fine, and doesn't appear to cause the issue. It appears that https://foundation.zurb.com/sites/docs/sticky.html is causing the issue as it's manipulating the parent div in the dom.

Repo URL: https://github.com/iamthefreeman/paypal-express-vue-issue

Thanks, James.

JamesFreeman commented 6 years ago

@khoanguyen96 have you been able to look into this?

cocoastorm commented 6 years ago

@iamthefreeman, hey sorry I just got some time to look at it today.

You're definitely right, it's caused by the sticky. Since Zurb Foundation uses jQuery which manipulates the DOM directly, Vue.js has no way of telling the DOM was changed so the container the vue-paypal-checkout component has a reference to becomes undefined.

I'm not sure if I can find a clean solution to fix this... At least this is what I think is happening. I also don't really know much about the foundation framework as well.

cocoastorm commented 6 years ago

@iamthefreeman, so I managed to get around it with a very hacky workaround.

<template>
    <div>
        <div id="checkout">
            <div ref="sticky" data-sticky data-anchor="checkout" data-margin-top="0" data-sticky-on="large"></div>
        </div>
    </div>
</template>
<script>
import Vue from 'vue'
import PayPal from 'vue-paypal-checkout'

export default {
    mounted() {
        const button = new (Vue.extend(PayPal))({
            propsData: {
                amount: '10.00',
                currency: 'GBP',
                client: this.paypal,
                env: 'sandbox',
            }
        }).$mount(this.$refs.sticky);

        console.log(button);

        button.$on('payment-authorized', this.logPayment)
    },
    data() {
            return {
                paypal: {
                    sandbox: 'AZDh28XUkdZSgT7CaR79z4u6cm-P2SJdIYyPjugeT5gbD5n2gS5h-JiQG0dpT5_elt0fDrZ6QvIt67ET',
                    production: ''
                },
                sticky: null,
            }
        },
        components: {
            PayPal
        },
        methods: {
            logPayment(e) {
                console.log(e)
            }
        }
}
</script>
JamesFreeman commented 6 years ago

Thanks for looking into that for me, I'll try an implement this in my project shortly 👍

nickfaughey commented 5 years ago

Any update on this? Just ran into it when the PayPal button is contained in a Vuetify v-dialog. As mentioned in this Stack Overflow post, it's likely caused by inconsistencies in the order of loading the DOM and JS script.

In fact, I can reproduce a "fix" consistently - refreshing my Vue app with the browser triggers the error, but letting webpack hot reload the app doesn't.

butaminas commented 5 years ago

Still an issue...