Creating a Vue.js Serverless Checkout Form: Stripe Function and Hosting
We’re now in the second post of a four-part series where we’re creating a checkout form application in Vue.js that can accept payments via the Stripe API. In part one, we looked at the concept of serverless functions, set one up in Azure, and connected it to a Stripe account. In this post, we’ll focus on setting up Stripe as a serverless function and hosting it all on Github.
Article Series:
- Setup and Testing
- Stripe Function and Hosting (This Post)
- Application and Checkout Component (Coming Soon)
- Configure the Checkout Component (Coming Soon)
First, we’re going write our function and test it out in the portal, but eventually we’re going to move it over to Github and have Azure pull in the code. I’ll explain why we do this in a moment.
For now, in order to get it working and testable, we’re going to write it in the portal and fill in the request body to perform the test. But we need to know what Stripe will expect from us first.
Dun dun dun…
Working With Stripe as a Serverless Function
If you check out Stripe’s documentation, you can see that we’ll need to grab the Stripe token in the dashboard. This will eventually mirror the POST parameters submitted by our form. Stripe makes it easy, so it’s fairly straightforward to use their library for the server-side function with Express:
app.get('/', (req, res) => res.render('index.pug', { keyPublishable }));
app.post('/charge', (req, res) => {
let amount = 500;
stripe.customers
.create({
email: req.body.stripeEmail,
source: req.body.stripeToken
})
.then(customer =>
stripe.charges.create({
amount,
description: 'Sample Charge',
currency: 'usd',
customer: customer.id
})
)
.then(charge => res.render('charge.pug'));
});
app.listen(4567);
We won’t need to set up all of Node and Express for this, though, as what we really need is the amount, the currency, the description, and the token, which we can integrate with the testing code we were provided earlier in the portal’s view of our function. So, let’s head over to the Azure portal where our function lives and update that default testing code to accept the parameters we need for Stripe, and also populate the request.body
in the test panel.
We’ll add our Stripe testing key and kick everything off. To be totally sure, we’re going to log what we’ve gotten started:
var stripe = require('stripe')('sk_test_whateveryourtestingkeyisgoeshere');
// ^ this is a stripe testing key
module.exports = function(context, req) {
context.log('starting to get down');
If we have a request body, an email, and a token, then let’s get started. We’ll create a customer from the email and then use that customer to create the Stripe charges, passing in the amount of the charge as we do so.
if (
req.body &&
req.body.stripeEmail &&
req.body.stripeToken &&
req.body.stripeAmt
){
stripe.customers
.create({
email: req.body.stripeEmail,
source: req.body.stripeToken
})
.then(customer => {
context.log('starting the stripe charges');
stripe.charges.create({
amount: req.body.stripeAmt,
description: 'Sample Charge',
currency: 'usd',
customer: customer.id
});
})
...
We also want to test if this all completed successfully, or if it errored out. If it did error, we need to log what that error is. We’ll also see if the whole thing errored entirely, making sure we’re logging everything appropriately along the way.
You’ll note that I log a lot. I think it’s not enough to know that something has errored. I want to know when the error happened and why so that I can track it down. This makes it much easier to debug if something were to go wrong.
...
.then(charge => {
context.log('finished the stripe charges');
context.res = {
// status: 200
body: 'This has been completed'
};
context.done();
})
.catch(err => {
context.log(err);
context.done();
});
} else {
context.log(req.body);
context.res = {
status: 400,
body: "We're missing something"
};
context.done();
}
};
In the testing area on the right side of the portal, we’ll fill the request.body
with the stripeEmail
, stripeToken
(a testing token in this case), and some random amount for the charge. When we run this, we can see that it works! We get a 200 OK Status, and we’ve logged This has been completed
in the output.
Github-Hosted Serverless Function
Let’s put everything in Github now that it’s working. One big reason we want to do this is because our function will have a dependency on Stripe’s library. If you head over to the sample-stripe-handler repo I’ve created for this tutorial, you’ll see a package.json
file. The most important lines in that file are these:
"dependencies": {
"stripe": "^5.3.0"
}
This tells the function to pull in the correct version of the Stripe API that we need to use in order for our app to properly function. As a note, you could also use this method to write other kinds of functions using other libraries. This means the possibilities for what to create are endless!
We’ll pull everything from our function into this repo. This includes the function itself, the package.json
file, as well as the contents of the function.json
file that you’ll see in the “View Files” tab on the right in the Azure portal.
Once we have that all in ready to go in a Github repo, we’ll head back over to the Azure portal, because now we have to let Azure know that we’d like to use this repo to host our function instead of our test. We can still test our function inside the portal—we just won’t be able to edit it via the GUI anymore.
Click on the “Platform Features” tab and select the “Deployment Options” item.
From here, click “Settings” then “Choose source” and a number of options will be provided. I’m going to choose Github because that’s where I want to host mine, but you can see that there are a lot of other ways we could have done this.
Once Github has been selected, you will be able to configure which repo you would like to use as your deployment source. I chose the sample-stripe-handler repo that we created earlier.
After we’ve done this and it’s loaded, you’ll be taken to a “Deployments” screen that shows the last commit that you made to the repo. That means everything’s working correctly!
Let’s test this a little further. My function didn’t work properly the first time because I was using ES6. I could have added in Babel, but I just converted it back to ES5 and pushed to the master
branch. You can see the function.json
becomes inactive as the last deployment, and my latest commit message—which is mostly me grumbling—is now the latest deploy! Awesome.
We can’t be too careful so, to check that these tests did indeed work, I’m going to head over to the Stripe dashboard. Sure enough, there are testing charges showing up in our dashboard ?
One last thing!
We would be remiss to exclude our good friend CORS, which we need to properly enable for everything to communicate as it should. Let’s go to our function in the dashboard, and select CORS:
In the prompt that appears, we’ll whitelist our localhost dev server, as well as our final URL for the site. Voila! We’re all set.
Next Up…
We got a lot done in this post! Next, we’ll want to learn how to move away from testing only within the function and get this sucker communicating freely with a checkout experience that we’ll build within a Vue.js application. Stay tuned!
Article Series:
- Setup and Testing
- Stripe Function and Hosting (This Post)
- Application and Checkout Component (Coming Soon)
- Configure the Checkout Component (Coming Soon)
Creating a Vue.js Serverless Checkout Form: Stripe Function and Hosting is a post from CSS-Tricks