4

I'm trying to get Stripe working with my Vue.js 2 application. For PCI-DSS reasons, Stripe requires that their Javascript is always loaded from js.stripe.com. I've followed the instructions in:

but I get a 'Stripe' is not defined error when I try to use the library. These solutions seemed to be aimed at merely getting a <script> tag into the output HTML (e.g. for analytics), not actually consuming the functions and objects in that script.

Here's what my component Javascript looks like:

<script>
    export default {
        name: "PaymentPage",
        mounted() {
            let stripeScript = document.createElement('script');
            stripeScript.setAttribute('src', 'https://js.stripe.com/v3/');
            document.head.appendChild(stripeScript);

            let s = Stripe('pk_test_Fooo');
            console.log(s);
        }
    }
</script>

I also tried adding the script tag to my public/index.html file instead, but I get the same outcome. This would probably be my preferred route, since Stripe encourages developers to import their script on all pages on the site.

<!DOCTYPE html>
<html lang="en">
  <head>
    // ...
    <script src="https://js.stripe.com/v3/"></script>
  </head>

How can I pull a script from an external CDN and use it within my component's Javascript?

I'm aware of some libraries to integrate Vue.js with Stripe (e.g. matfish2/vue-stripe and jofftiquez/vue-stripe-checkout), but the former doesn't import properly for me (I'm hitting issue #24) and the latter is built against the older Stripe API and the new version is still in beta.

5
  • Do you need this to be specifically inside a script tag or can you also bring in the object from a component or the store? Commented Sep 8, 2019 at 9:08
  • Is the Stripe script being fetched correctly? Check the Network tab. I have created a new project and have tried the index.html & createElement ways, and they do work. The only issue I had was that the createElement way doesn't wait for script to fetch/execute, so you have to add a onload listener. Commented Sep 8, 2019 at 9:12
  • Also with a SPA you are always on the same page, index.html, so I think there is no need to worry for including the script on "all pages". Commented Sep 8, 2019 at 9:15
  • @yuriy636 I think part of my issue was paying attention to IDE errors (from Webstorm) and the output of npm run serve rather than looking to see what's happening in the browser and Javascript console. Commented Sep 8, 2019 at 9:19
  • Hello I'm the author of vue-stripe-checkout. The latest version is out now. Kindly check. Thanks. Commented Mar 2, 2020 at 12:47

4 Answers 4

5

You aren't giving the script time to load before checking if Stripe is there. What you need is something like this:

<script>
    export default {
        name: "PaymentPage",
        mounted() {
            let stripeScript = document.createElement('script');
            stripeScript.setAttribute('src', 'https://js.stripe.com/v3/');
            stripeScript.onload = () => {
              let s = Stripe('pk_test_Fooo');
              console.log(s);
            };

            document.head.appendChild(stripeScript);
        }
    }
</script>
Sign up to request clarification or add additional context in comments.

Comments

4

Thanks to yuriy636's comment, I realised that errors were only from the linter, which presumably can't statically figure out what I'm up to.

I opted to put the script into index.html, then ensured I squashed linter errors with:

// eslint-disable-next-line no-undef
let s = Stripe('pk_test_Fooo');

2 Comments

I am still curious why the Stripe object needs to be used in your app via a script tag
@Michael The main thing is it needs to be served, live, from their website. There may be other ways to achieve that with Vue that I'm not familiar with.
0

In my case, I still had errors calling functions of the specific script. So it was required to specify the ¨window¨ scope. Also, if you need to access any Vue element inside the ¨onload¨function, you need a new variable for the ¨this¨ instance.

<script>
export default {
    name: "PaymentPage",
    mounted() {
        let stripeScript = document.createElement('script');
        // new variable for Vue elements.
        let self = this;

        stripeScript.onload = () => {
          // call a script function using 'window' scope.
          window.Stripe('pk_test_Fooo');
          // call other Vue elements
          self.otherVueMethod();
          
        };
        stripeScript.setAttribute('src', 'https://js.stripe.com/v3/');
        document.head.appendChild(stripeScript);
    }
}

I worked with this on Vue 2.6.

Comments

0

Just install the npm package npm install @stripe/stripe-js and use it like a regular import

import { loadStripe } from "@stripe/stripe-js";

export default {
  async mounted() {
    // init stripe
    const stripe = await loadStripe('your_stripe_key_here');
    this.stripe = stripe; // store the stripe instance
    // access the stripe instance in your methods or where you want to use them
  },
}

It's working as of 6th Jan 2022.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.