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!
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
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
Next, we want to initiate a Vue project, so let's create a Vue app
npm init vue@latest
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
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
Wait! ๐ Before you continue!
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
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)
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
Now let's write some code.
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>
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>
The interesting things here are to be noted:
-
mode: This is the type of Checkout we're asking Stripe to create, either
payment
orsubscription
. We're making a one-time payment form, so let's set it topayment
. - 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>
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>
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>
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
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?
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.
๐ 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!
Top comments (3)
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.
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?
Great post. Thank you so much!