DEV Community

Cover image for I built a checkout button with vue-stripe
orliesaurus
orliesaurus

Posted on • Updated on

I built a checkout button with vue-stripe

TL;DR

In this blogpost, I explain how I built a very simple product page using vue-stripe. If you decide to follow along, you can too start selling your product or your services today!

I am also going to share about how to resolve the most common problems while building this, using a tool called Dashcam.

Why?

Selling online is fun! If you have a project you want to monetize, this is the fastest way to get started!

lets do this

Let's get started! ๐Ÿ”ฅ

Let's assume you already have node.js and npm installed. If not, you can learn how to do it here

The first thing we want to do is set up the environment. We're going to be super vanilla and make a folder called:

stripe-vue
Enter fullscreen mode Exit fullscreen mode

This will be the root directory, within which we're gonna initiate our Vue project!

Go ahead and type the following command in your terminal of choice:

mkdir stripe-vue && cd stripe-vue
Enter fullscreen mode Exit fullscreen mode

Next, we want to initiate a Vue project, so let's create a Vue app

npm init vue@latest
Enter fullscreen mode Exit fullscreen mode

What this does is, it initializes a new project with Vue.js as a dependency using npm.

I use vue@latest - because @latest indicates that the latest version of Vue.js should be installed.

๐Ÿคซ
(I use npm but if you're more advanced, or picky, you can choose your package manager of choice)

Configure your vue project

When you run this command, npm will prompt you to provide information about the project (e.g., project name, options, etc).
npm will generate a package.json file and install the latest version of Vue.js as a project dependency.
Personally, I selected No on each option, because I am just building a simple checkout button, but your mileage may vary

After this step, the CLI tells me to run some commands

cd vue-stripe-checkout
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

I am going to run the top 2 of them, but not the last one, because I don't wanna run the project just yet...!

The first two commands place me inside the actual project folder, where our code will go and install the dependencies.

When that's finished I need one more dependency: vue-stripe

npm install @vue-stripe/vue-stripe
Enter fullscreen mode Exit fullscreen mode

Wait! ๐Ÿ‘‹ Before you continue!
wait

Create products and prices on Stripe and enable Checkout

If you want to sell something you need to tell Stripe what you're selling.

In this demo we're selling Jars of spicy condiment/ $15 a jar. It's delicious, I promise

Creating a product & set price

stripe product

Before we continue, we have to do something on Stripe's side. We have to create the product, and attach a price to it. There's a beautiful step by step tutorial on the Stripe Doc portal

Once you have created your product with a price, you need to note down the SKU id, you can find this on the Product settings page you just created and it looks like this sku_OHSgXJ1rXvtqrt

Using the SKU id value will tell Stripe's Checkout to find the default price of the product.

Creating a product price

If you have multiple prices for the same product (perhaps you're offering different geo location/currencies) instead of noting down the SKU id (red arrow), find the price id (green arrow)

screenshot of prices

Ensuring checkout is enabled

We also need to make sure that the checkout functionality is enabled, that's just a switch and it can be done quickly, the docs on Stripe's website clearly show the steps

After creating the product, having attached a price to it (and additionally another price), making sure checkout is enabledโ€ฆ now let's move on to creating the actual checkout page in Vue.

Creating a vue component

Back to our Vue project, let's make a new file in the components folder, if you followed this article step by step that should be:

stripe-vue/vue-stripe-checkout/src/components/CheckoutButton.vue
Enter fullscreen mode Exit fullscreen mode

Now let's write some code.

write some code in vscode

Open the Checkout component and let's build a button that will lead to a Stripe checkout, first by importing StripeCheckout from the vue-stripe library

Then we're going to export an object with the default export.

We make StripeCheckout as an exportable component. This way it can be rendered and used within our app!

<template>
  <!-- We're going to put our Stripe Checkout code here in a moment -->
</template>

<script>
import { StripeCheckout } from '@vue-stripe/vue-stripe';
export default {
  components: {
    StripeCheckout,
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

Next we're going to write some code to customize our Stripe Checkout button.

We're gonna write some code in this component within the <template></template> section.

<template>
    <div>
      <stripe-checkout
        ref="checkoutRef"
        mode="payment"
        :pk="publishableKey"
        :line-items="lineItems"
        :success-url="successURL"
        :cancel-url="cancelURL"
        @loading="v => loading = v"
      />
      <button @click="submit">Pay now!</button>
    </div>
  </template>
Enter fullscreen mode Exit fullscreen mode

The interesting things here are to be noted:

  • mode: This is the type of Checkout we're asking Stripe to create, either payment or subscription. We're making a one-time payment form, so let's set it to payment.
  • line-items: The items that should be purchased by the customer, they're shown on the Checkout interface and make up the total amount to be collected by Checkout.
  • success-url: The success URL to redirect the customer after purchase
  • cancel-url: The cancellation URL that we should redirect customers when payment is canceled (i.e. you click the back arrow on the Stripe checkout UI)

Also, let's add a button with a label saying "Pay now!" so we can purchase the Spicy jar condiment we're going to sell when clicking the button.
Let's write some JavaScript to specify the config for our Stripe checkout that will appear once the button is clicked!

vue-stripe component setup

Let's now hook up the component we have added with the ability to be purchased.

We're going to set it up like this between the <script></script> tags

Notice that we have to set up a couple of variables:

  • publishableKey: your PK from Stripe's developer dashboard
  • lineItems: an array of objects; each object has a price for a product you're trying to sell and a quantity. You can have multiple objects in this array to create more "complex" checkouts, for example, if you sell multiple products at once
  • succesURL: The value of the URL after the user purchases
  • cancelURL: The value of the URL if the user cancels
<script>
  import { StripeCheckout } from '@vue-stripe/vue-stripe';
  export default {
    components: {
      StripeCheckout,
    },
    data () {
      return {
        publishableKey: "<YOUR-STRIPE-PUBLIC-KEY>",
        loading: false,
        lineItems: [
          {
            price: '<YOUR-SKU-ID>', // The SKU id of the product created in the Stripe dashboard
            //price: '<YOUR-PRICE-ID>', // the Price id of the product I want to sell, if you have multiple prices, pick one

            quantity: 1,
          }
        ],
        successURL: '<URL_SUCCESS>',
        cancelURL: '<URL_CANCEL>',
      };
    },
    methods: {
      submit () {
        this.$refs.checkoutRef.redirectToCheckout();
      },
    },
  };
  </script>
Enter fullscreen mode Exit fullscreen mode

Now that we're done with the code, our final component should look like this:

<template>
    <div>
      <stripe-checkout
        ref="checkoutRef"
        mode="payment"
        :pk="publishableKey"
        :line-items="lineItems"
        :success-url="successURL"
        :cancel-url="cancelURL"
        @loading="v => loading = v"
      />
      <button @click="submit">Pay now!</button>
    </div>
  </template>
<script>
  import { StripeCheckout } from '@vue-stripe/vue-stripe';
  export default {
    components: {
      StripeCheckout,
    },
    data () {
      return {
        publishableKey: "<YOUR-STRIPE-PUBLIC-KEY>",
        loading: false,
        lineItems: [
          {
            price: '<YOUR-SKU-ID>', // The SKU id of the product created in the Stripe dashboard
            //price: '<YOUR-PRICE-ID>', // the Price id of the product I want to sell, if you have multiple prices, pick one

            quantity: 1,
          }
        ],
        successURL: '<URL_SUCCESS>',
        cancelURL: '<URL_CANCEL>',
      };
    },
    methods: {
      submit () {
        this.$refs.checkoutRef.redirectToCheckout();
      },
    },
  };
  </script>
Enter fullscreen mode Exit fullscreen mode

Display the Checkout component

We're going to load our component into the App.vue file so that it can be shown to our

So create an App.vue file (if one exists, delete the original one) and let's write some code

<script setup>
import CheckoutButton from './components/CheckoutButton.vue'
</script>

<template>
  <div>
    <h1>Purchase a Spicy Jar</h1>
    <p>A Spicy Jar of condiment, delicious and adds a touch of fire to blander dishes</p>
    <div id="image"></div>
    <Checkout></Checkout>
</div>
</template>

<style>
  #app {display: inline-block;}
  #image {
    width: 108px; 
    height: 108px; 
    border-radius: 4px;
    background-size: cover;
    background-image: url("https://stripe-camo.global.ssl.fastly.net/1da6f350ad1131277e51712ee1b3a992efb07a9333055c2926e8db1ceb633ab6/68747470733a2f2f66696c65732e7374726970652e636f6d2f6c696e6b732f4d44423859574e6a6446387851335673596e564762484e50633367355a58565366475a735833526c6333526663564a3463577075617a4a51654746784e57786857585a61656c4261633063793030657347736d436d4f");
  }
</style>

Enter fullscreen mode Exit fullscreen mode

First let's import our Checkout element from the CheckoutButton.vue file we created a moment ago, on line 2.

Then within this file, let's add some context (line 7-9) so users know what they're buying and the <Checkout></Checkout> component (line 10). When this component renders, a button will be rendered.

Launching the Vue app

preview

Save all your files and head to your terminal:

Make sure you're in the right directory stripe-vue/vue-stripe-checkout and run npm run dev

Navigate to the URL and see your checkout button in action!

Debugging the Vue app

What do you do when the code doesn't work?
debug
To debug the Vue app we're going to use Dashcam (disclaimer: I am working on Dashcam, a video-first code debugging tool for debs).

Dashcam allows you to debug your work, it's a screen recorder app for debugging that gives you the error logs alongside a video of what caused them, all locally on your computer.

Here's an example of me using Dashcam to debug the above code while I was writing this tutorial.

Debug code
Watch it now

๐Ÿ‘€ Looking at the video I can see that I made a typo when pasting the API key (publishable one) that caused to Stripe checkout to not be able to be launched when I clicked the button.
๐Ÿซ  Easy fix!

Conclusion: Writing code and understanding errors

In this article we learned how to:

  • ๐Ÿ‘€ Set up a simple Vue project from scratch
  • ๐Ÿ™ Create a checkout button (some would call it a product page or a one-item cart page) that leads to a checkout page hosted by Stripe using Vue.
  • ๐Ÿ”ฅ Debug your web apps using video and error logs through Dashcam.

Just looking at error logs sometimes is just not enough, especially when you're working with friends or team-mates asynchronously.

Sharing a video is worth a million words. IMHO adding video evidence to error logs truly makes a difference: I truly believe debugging with Dashcam is pretty useful because it gives you the video context alongside the Dev Tools and Network errors.

We'll see how to debug the backend in the next article!

Thank you for reading this far and let me know if you have any comments or questions below this article!


Download Dashcam (Free - Open Beta)

Explore vue-stripe further

Top comments (3)

Collapse
 
erikch profile image
Erik Hanchett

This is really neat! But when I looked up vue-stripe it looks like it doesn't support Vue 3 yet. And the creator has taken a break, and there has been no pushes to the repo for six months. I guess it still works for some scenarios, I'd worry to try this out in production though.

Collapse
 
orliesaurus profile image
orliesaurus

Yeah, but it's open source - so perhaps someone will step up and do some PRs? Are there other alternatives that you found while doing your research?

Collapse
 
jakovsijarto profile image
JakovSijarto

Great post. Thank you so much!