Reputation: 483
I'm trying to add the paypal sdk via vue-head(https://www.npmjs.com/package/vue-head) in my component but I keep getting this error:
Error in mounted hook: "ReferenceError: paypal is not defined"
What am I doing wrong here? Is the SDK simply not loading before mounted?
Is there a better way to accomplish this? Does anyone have an example of their paypal implementation in vue? Any help would be greatly appreciated.
edit: Also if I include the script tag server side (rails) then try to access paypal in vue I see this error:
Could not find driver for framework: [object Object]
<template>
<div id="paypal-button" />
</template>
<script>
import { mapState as mapConfigState } from '../scripts/store/appConfig';
export default {
props: {
totalPrice: {
type: String,
required: true,
},
currency: {
type: String,
required: true,
'default': 'USD',
},
buttonStyle: {
type: Object,
required: false,
},
},
computed: {
...mapConfigState({
customer: state => state.customer,
}),
paypalEnvironment() {
return (this.customer.paypalTestingMode) ? 'sandbox' : 'production';
},
client() {
return {
sandbox: this.customer.paypalClientIdSandbox,
production: this.customer.paypalClientIdLIVE,
};
},
},
head: {
script() {
return [
{
type: 'text/javascript',
src: `https://www.paypal.com/sdk/js?client-id=${this.client[this.paypalEnvironment]}`,
},
];
},
},
mounted() {
const total = this.totalPrice;
const currency = this.currency;
paypal.Buttons.driver(
{
env: this.paypalEnvironment,
client: this.client,
style: this.buttonStyle,
createOrder(data, actions) {
return actions.order.create({
purchase_units: [
{
amount: {
value: total,
currency,
},
},
],
});
},
onApprove(data, actions) {
return actions.order.capture();
},
}, '#paypal-button'
);
},
};
</script>
edit2: I tried adding the script in my mounted hook like this:
let el = document.querySelector(`script[src="https://www.paypal.com/sdk/js?client-id=${this.client[this.paypalEnvironment]}"]`);
if (!el) {
const src = `https://www.paypal.com/sdk/js?client-id=${this.client[this.paypalEnvironment]}`;
el = document.createElement('script');
el.type = 'text/javascript';
el.async = true;
el.src = src;
document.head.appendChild(el);
}
I can see the script in the head tag in the dev console but paypal still is not defined.
Upvotes: 0
Views: 1366
Reputation: 483
For anyone else who is trying to implement PayPal in a Vue component:
<template>
<div id="paypal-button" />
</template>
<script>
export default {
mounted() {
function loadScript(url, callback) {
const el = document.querySelector(`script[src="${url}"]`);
if (!el) {
const s = document.createElement('script');
s.setAttribute('src', url); s.onload = callback;
document.head.insertBefore(s, document.head.firstElementChild);
}
}
loadScript('https://www.paypal.com/sdk/js?client-id=sb¤cy=USD', () => {
paypal.Buttons({
// Set up the transaction
createOrder(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '0.01',
},
}],
});
},
// Finalize the transaction
onApprove(data, actions) {
return actions.order.capture().then(details => {
// Show a success message to the buyer
alert(`Transaction completed by ${details.payer.name.given_name}`);
});
},
}).render('#paypal-button');
});
},
};
</script>
Alternatively you can use this: https://github.com/paypal/paypal-js
Upvotes: 1