Back to changelog

How to Build a Single-Page Sales Funnel App using Node.js, Cosmic and Stripe

Mohamed Termoul's avatar

Mohamed Termoul

May 17, 2019

cover image

What is a sales funnel? And why is it important? A sales funnel is a path that your website's visitors take before purchasing a product. If you don’t understand your sales funnel, you can’t optimize it. Building a great sales funnel can influence how visitors move through the funnel and whether they eventually convert. In this little demo I will be showing you how to build a simple, one-page sales funnel using Node JS, Cosmic, and Stripe for handling credit card payments.


Why did I pick Cosmic

If you need to build a sales page quickly and freely, you can simply sign up for a free Cosmic account, copy my app, customize it and you're done. You'll have you sale funnel page ready in minutes. If you need to add a section or features then you can simply download the source-code and change any of the markup or the JavaScript behind this application.

How to clone your own version of this app:

In order for you to clone this application and have your own custom copy, you need to following these steps:

  • Sign up for a free Cosmic account
  • Login into Cosmic account
  • Go to the buckets page
  • Click on Add New Bucket button on the top right of the page
  • Select Choose an app below option and scroll to the applications list
  • Try to find the Sales Funnel application
  • Once you open the application click on the Install Free button
  • You can keep the same title and hit the Install App button to confirm
  • Then you will be taken to the application bucket
  • Then you need to clone the github repo. Open the terminal window and type:
git clone
cd nodejs-sales-page
npm install
  • edit and change Cosmic and Stripe API keys located in /crowd-pitch/.env.local file
  • Run the app server on your local machine
# start the app
npm run server

How to customize the application content

In order for you to change the text, images, and application content you need to follow these steps:

  • Login to Cosmic dashboard
  • Go to buckets --> crowd-pitch
  • Go to Pages --> Google cash machine
  • Change the pages section by editing the text for each part of the web page like the page title, header....
  • Change the page images by adding your own images. Make sure to keep the same image title and slug.
  • Hit save and publish

This part works like any CMS system, where you make changes to the back-end and the site can change immediately.

How to add new features to this application

This part and below would be an explanation on how the application front-end was developed and how you can dig deeper to customize more options like the layout, css, colors, and which fields to collect from the user. This application was build mainly using Node JS, and Stripe API. So let's take a look at the server.js file

As you can see from the code above we are using the following Javascript components:

Inside the server.js there is basically two function to handle server routing:

  • app.get('/') to handle the get request when the user visits the application. Inside this function we simply call Cosmic to fetch all data from our bucket and inject it as a server response local variable. The second part is just rendering the home view which is just an HTML/Handlebars template page.

  •'/pay') to handle the payment form posting. Inside this function there is simply one call to Stripe charges API to add one charge to the specified credit card.

How to customize the layout and CSS for the application?

As mentioned before, in this app we are using handlebars.js for the page templating. From the server get function we render views/home.handlebars page which is simply an html page with some handlebars tags to replace server variables with values from Cosmic CMS. Let's take a look:

As you can see, we reference server variables within a double curly brackets. For instance {{ cosmic.metadata.top_logo.url }} means get the value of variable from Cosmic, which the logo image url and put it in the home view page. There are also similar syntax to handle if and loop using handlebars syntax. For a full syntax help, please refer to Handlebars User Documentation.

You can also change some of the styling of the page from within home view page because we are simply using Bootstrap framework. For some other styling properties you can change it directly from /public/css/styles.css

For the application layout there the file /views/layouts/main.handlebars

This is basically the main html template for every page in our application. It's worth mentioning that we are referencing a couple of libraries from the client side like:

  • JQuery
  • Stripe
  • Bootstrap
  • Font-awesome
  • Axios.js to handle Ajax calls

Handling credit card payment with Stripe and Axios

To accept credit card payments in our application we use three steps process.

  • Validate the credit card info by calling stripe.createToken when the user hit the submit payment button. This function will simply send the info to Strip API and get a valid token if success. Otherwise it will return an invalid token.
  • Post the payment form form data to the server post method. This method will take data submitted from the client form and submit them again as a stripe charge by calling stripe.charges.create. Take a look:

As you can see, once the charge is sent to stripe, we will return success to the client if no errors from Stripe. Otherwise we will emit Stripe errors back to the client.

  • The last step is on the client side, we will display the payment result on the client form if success, or the error message if the payment fails.

How to add multiple page funnel to my application.

Sometimes the application will need more than one page to capture the user final action. If you want to do that, you can simply add more pages to the server view, more routes, and handle the post from one page to the other either via javascript functions or server post methods.

What about the main.js file?

This file contains one function right now to handle count down counter. However you can use it if you any other javascript interactions with your user. For the count down counter we store a variable on Cosmic server called

const dealCountDown = {{ cosmic.metadata.deal_countdown }};

and then we calls the initializeClock function which will run the count down until this variable reaches zero.

Take a look at the main.js file for the full implementation details.

Check user engagement with A/B testing

As most marketers have come to realize, the cost of acquiring any quality traffic can be huge. A/B testing lets you make the most out of your existing traffic and helps you increase conversion without having to spend on acquiring new traffic. A/B testing can give you high ROI as sometimes, even the most minor changes can result in a significant increase in conversions.
For the purpose of this app, I will add two style.css files and once the user visits the site I will be randomly selecting one stylesheet. The stylesheet selection will affect how the color theme will look like. So basically the user can see either version A of the site or version B.

Then we load either style A or B on the `main.handlebars` file like this:

We also have a javascript variable that will be used during the payment process to capture which page the user is coming from. This info will be stored along Stripe charge information.

const pageSource = {{#if pageB}} 'pageB' {{else}} 'pageA' {{/if}};

then we save the page source along the stripe charge on the server post method.


In this application, I've demonstrated how you can build a page that displays product info and handles credit card payments by leveraging the power of the Cosmic CMS plus a few other libraries that handle the payment function. You can add a function that will send an email to the user after the payment is submitted. Or add a function to send a user to another secure page to all him to download the digital product. The Cosmic Community  has a lot of examples on how to handle integration with email functions, download functions, and third party platforms.

As always, I really hope that you enjoyed this little app, and please do not hesitate to send me your thoughts or comments about what could I have done better.

If you have any comments or questions about building apps with Cosmic, reach out to us on Twitter and join the conversation on Slack.