Building an e-commerce website from scratch can sometimes be a nightmare for most software developers, but as you read this article, you will realize that I have achieved it. And you will learn how to make and publish an e-commerce site yourself.
The term "e-commerce," which stands for "electronic commerce," describes the exchange of goods and services over the internet. It includes a broad range of online business activities, such as the sale of digital goods like music, movies, and e-books, as well as the purchase of tangible goods through online retail websites. E-commerce also refers to the exchange of information and services, such as ordering takeout or booking a hotel room via a website or app.
What is Altogic?
Altogic is a backend-as-a-service platform enabling developers and businesses to design, deploy, and manage scalable backend apps. The Altogic platform has visual development tools and a cloud platform. You use the development tools to build and manage your backend applications, while the cloud platform hosts and runs them.
What is Stripe?
Stripe is a company that provides a way for businesses to accept payments over the internet. They offer a suite of tools and APIs for businesses to integrate into their websites and mobile apps to easily accept payments from customers. They support a wide range of payment methods, including credit and debit cards, as well as alternative payment methods like Apple Pay, Google Pay, and SEPA Direct Debit. Stripe also offers features like fraud detection, recurring billing, and automatic invoicing. They also provide reporting and analytics to help businesses track their transactions and revenue. Stripe is commonly used by online retailers, service providers, and app developers to accept payments from their customers.
Preparing Development Environment
Creating an Altogic Application
As you are aware, Altogic will be used in this project, so if you do not already have an account, you have to create one from the Altogic Designer.
note
If you are new to Altogic, you can check out our installation page to learn how to install the Altogic client.
Creating a Stripe Account
In order to access the Stripe management screen, let's create an account on the official Stripe website. There may be pop-ups requesting information about the business after creating an account. It can be disregarded. In this tutorial, we'll use test mode.
Create Stripe Secret Key
Get the Secret key so we can integrate Stripe with Altogic. So let's go to the Developers API keys view of the Stripe Dashboard and click the Reveal test key button to copy the Secret key.
Then, open Altogic Designer and visit the Parameters view of the Settings to create a new application parameter for the Secret key as STRIPE_SECRET_KEY
.
Setting Up Your Development Environment
In this application, we will use React (TypeScript) with Vite as the front end, and we need to install it with the following command:
npm create vite@latest e-commerce-app -- --template react-ts
For those wondering why I use Vite, it provides a pretty fast development environment, and I think that's reason enough to use it.
Installing Altogic Client Library
The Altogic client library is required for our front-end application because the backend will use Altogic. To set up, use the "cd” command to navigate to the project folder, then type the code below to install Altogic.
cd e-commerce-app && npm install altogic
Creating Altogic instance
Let’s create a libs/
folder inside the src/
directory to add the altogic.ts file. Open altogic.ts and paste below code block to export the altogic client instance.
import { createClient } from "altogic";
const ENV_URL = ""; // replace with your envUrl
const CLIENT_KEY = ""; // replace with your clientKey
const altogic = createClient(ENV_URL, CLIENT_KEY, {
signInRedirect: "/login", // Path to the login page of your app
});
export default altogic;
Replace ENV_URL
and CLIENT_KEY
which are shown in the Home view of Altogic Designer.
Designing The User Interface for Your Ecommerce App
We will be using Tailwind CSS to style our application. Tailwind CSS is a utility-first CSS framework for rapidly building custom user interfaces. It is a highly customizable, low-level CSS framework that gives you all of the building blocks you need to build bespoke designs without any annoying opinionated styles you have to fight to override. It is a great tool for designing a user interface. In this project, we won't deep dive into the front-end, but we will focus on the backend.
Preview of The Application’s Homepage

Creating The Backend for your E-commerce App with Altogic
In this section we will create the backend for our e-commerce application. We will use Altogic to create the backend.
Database Models and Relations
Now let's create the database models and relations.
In order to make this application's database schema easier to understand, I ve developed a less complicated database schema. In the photo below, you can see the schema of the database which i've created.

Services
With the client library in Altogic, we can perform a wide range of tasks, but occasionally we may need to handle multiple tasks at once or there may be circumstances where additional security is necessary. In these situations, we can write a service using drag and drop in Altogic.
Here is a list of the services for this application:

Service of adding tracking URL to order:
I use this service to send an informational e-mail to the owner of the order after entering the cargo tracking URL for each order.

Service of updating order status:
As part of this service, I update the status of the orders and inform the order's owner via email.
Note: Although this service and my previous one have exactly the same appearance, they serve very different purposes.

Service of creating or getting variant id:
The items in our store might come in more than one variation, but they are all the same items that are just different in size and color. All of the variants must have a matching id in order to match these products to one another.
If a variant id hasn't already been created for us, this service creates one for us, and it then returns the id to us as a response.

Service of adding to cart:
In this service, as you guessed, I add the products to the cart. Of course, we have some checks before adding to the cart, you can see them in the image below, but let me explain. If the product has sufficient stock, the process continues, otherwise, an error message returns. If the product is in the cart, its quantity is increased or added from scratch.

Service of adding or updating user address:
Addresses are crucial in an e-commerce application, as you are aware. Users, therefore, require address information, and this service is intended exclusively for that. If the address has already been added, it edits it; otherwise, it adds it.

Service of the adding product
We have to add the products we want to sell to Stripe, and of course, if we want our own management panel, we also need to keep the products in our own database. So we prepared a flowchart like below

We create a product on the strip using the Stripe Node named 'Create a Product' and the parameters of this node are as follows.
Stripe API Key ⇒ Your Stripe Secret Key (required)
Product Name ⇒ Your product name (required)
Product Description ⇒ Your product description (required in our case)
Product Image URL ⇒ Your product image URL (required in our case)
Product Currency ⇒ Currency such as ‘usd’, ‘eur’, ‘try’ (required)
Product Price ⇒ Product price as a floating number such as 25.95 (required)
Product Meta Data ⇒ A data you want, I added the product id in my own database (required in our case)
Service of the updating product
As you know, we may sometimes need to change the products we add. In this case, we need to update the relevant product both in Stripe and in our own database. For this, we have prepared a flowchart as follows

In the diagram you see above, there are two important nodes. Yes, you guessed nodes, 'Create a Price' and 'Update a Product', I think you understand what they do, so I'll just give you the parameters I used in them below.
Create a Price node’s parameters:
Stripe API Key ⇒ Your Stripe Secret Key (required)
Product Id ⇒ Id of the stripe product it belongs to (required)
Currency ⇒ Currency such as ‘usd’, ‘eur’, ‘try’
Unit amount ⇒ Price as a floating number such as 25.95
Update a Product node’s parameters:
Stripe API Key ⇒ Your Stripe Secret Key (required)
Product Id ⇒ Id of the stripe product it belongs to (required)
Product Name ⇒ New name of the product
Product Description ⇒ New description of the product
Product Image URL ⇒ New image URL of the product
Product Default Price ID ⇒ The id of the new price we created
Service of the checkout
This part is very important because now we are moving to Stripe integration
I know the image below looks very confusing, but we are going to the payment step, after all, there are a few security checks here. Is the address of the user registered, Is the stock of the product in the basket sufficient at that moment? etc…

The "Create a session" node, which I've indicated with an arrow, generates the payment page for us. However, there are a few parameters we must provide; I'll list them below.
Stripe API Key ⇒ Your Stripe Secret Key (required)
Cancel URL ⇒ URL to which the customer will be redirected if they abandon the payment step. For example https://example.com/cart (required)
Success URL ⇒ URL to redirect after payment step is successful. For example https://example.com/payment/success (required)
Mode ⇒ Payment (required)
Customer Email ⇒ Your customer’s email address (required in our case)
Line Item 1 - Price ⇒ The price id of the product on the stripe (required)
Line Item 1 - Quantity ⇒ Quantity of the product (required)
and the rest fill it with whatever meta information is needed for you.
Serverless Functions of Altogic
We know Altogic offers us good services, we can also run our own Node.js
code and add it to our endpoint.
In order to use serverless functions, we need to install the altogic-cli
package on our machine via npm.
Run the code below in your terminal to install.
$ npm install -g altogic-cli
Once the installation is complete, you can verify the installation using
$ altogic -v
Before using the CLI, you need to log in to your Altogic account.
$ altogic login
? Enter your email or username: [email protected]
? Enter your password: ********
If you have signed up to your Account using your Google credentials, a 6-digit authorization code is sent to your email address. You need to type this code to complete your login.
Creating a function
$ altogic create function
? To which application do you want to add the new function?
1) Altogic app 1 (611e7f8ae1a047001ccb65a8)
2) Altogic app 2 (6124cfbacc2932001a1afc5c)
3) E-Commerce app (612bdfbb8aa25b0019206549)
(Move up and down to reveal more choices)
Answer: 3
? What is the name of your function? **stripe-webhook-handler**
? What is the runtime of your function?
1) node.js-14.5
2) node.js-16.0
3) node.js-18.0
Answer: 2
The create function
command will create a folder in your current directory using the name of your function and it will also create an altogic.json
file to keep the configuration parameters.
Open the folder via vs code
code stripe-webhook-handler
then open the src/index.js
file and write your own code.
for example my codes are below:
const { createClient } = require("altogic");
const OrderService = require("./services/OrderService");
let altogic;
module.exports = async (req, res) => {
const ENV_URL = ""; // replace with your envUrl
const CLIENT_KEY = ""; // replace with your clientKey
if (!ENV_URL || !CLIENT_KEY) {
return res.json(
{
code: "missing-altogic-params",
message:
"Client library environment URL and/or client key variables are not set. Unless these variables are set, the cloud function cannot use Altogic Client Library.",
},
500
);
}
altogic = createClient(ENV_URL, CLIENT_KEY);
const userEmail = req.body.data.object.customer_email;
const user = await getUserByEmail(altogic, userEmail);
switch (req.body.type) {
case "checkout.session.completed": {
await OrderService.completed(altogic, req, res, user);
break;
}
default: {
await res.json(
{
code: "unknown-handler",
message: "Unknown requests cannot be handled",
},
500
);
}
}
};
async function getUserByEmail(altogic, email) {
const { data: user } = await altogic.db
.model("users")
.filter(`email == '${email}'`)
.getSingle();
return user;
}
class OrderService {
static async completed(altogic, req, res, user) {
const { data: paymentCheck, errors: checkingError } = await altogic.db
.model("orders")
.filter(`stripeCheckoutId == '${req.body.data.object.payment_intent}'`)
.getSingle();
if (checkingError) {
return res.json(checkingError, checkingError.status);
}
if (paymentCheck) {
return res.json({ message: "The order has already been processed" }, 500);
}
const { errors: cartDeleteError } = await altogic.db
.model("cart")
.filter(`user == '${user._id}'`)
.delete();
if (!cartDeleteError) {
altogic.realtime.send(user._id, "cleared-cart", true);
} else {
console.warn(cartDeleteError);
}
const data = {
totalPrice: req.body.data.object.amount_total / 100,
status: "waiting",
stripeCheckoutId: req.body.data.object.payment_intent,
...(user && { user: user._id }),
};
const { data: order, errors } = await altogic.db
.model("orders")
.create(data);
const orderItemIds = Object.values(req.body.data.object.metadata).filter(
Boolean
);
const orderItemsFilter = orderItemIds
.map((item) => `_id == '${item.split("-")[0]}'`)
.join(" || ");
if (errors) {
return res.json(errors, errors.status);
}
const { errors: orderItemsErrors } = await altogic.db
.model("orderItems")
.filter(orderItemsFilter)
.update({
order: order._id,
});
for (let orderItemId of orderItemIds) {
const [_, quantity, productId] = orderItemId.split("-");
const { errors } = await altogic.db
.model("products")
.object(productId)
.updateFields({
field: "qtyInStock",
updateType: "decrement",
value: Number(quantity),
});
if (errors) console.warn(errors);
}
if (orderItemsErrors) {
return res.json(orderItemsErrors, orderItemsErrors.status);
}
altogic.realtime.send("admin", "waiting-order-count", true);
altogic.realtime.close();
await res.json({ message: "ok" }, 201);
}
}
module.exports = OrderService;
Now that our serverless function is ready, we can deploy our code with the help of the below command.
$ altogic deploy
If you have a single execution environment for your app, your serverless function will be deployed to this environment. If you have more than one environment, you will be prompted to select the deployment environment.
After our serverless function is deployed, we need to connect it to our endpoint that we created in Altogic as below.

Creating WebHook on Stripe For Your E-Commerce App
Before we start, I have to say that the serverless function we just created was a preparation for the Webhook we are going to create now.
In this section, to take the required actions after the payment step is successful, we must create a trigger, also known as a Webhook, in Stripe.
Click Webhook from the left side menu on the Developer Dashboard as shown below.

Then click the ‘+Add endpoint’ button at the top right as shown below

and then, let's fill in what Stripe wants from us by doing the following and complete our process by clicking the Add endpoint button.

That's all. The Webhook in Stripe is ready, and the backend part of our application is completely finished.
Conclusion
In this article, we have created a complete e-commerce application with Altogic and Stripe. We have created a serverless function that will be triggered when a payment is successful. We have also created a webhook in Stripe that will trigger our serverless function.
Source code: https://github.com/altogic/react-e-commerce-app
Live Demo: https://recommerce-chi.vercel.app/
Thank you for your reading. I hope you enjoyed it. If you have any questions, please feel free to ask them in the community forum or discord channel.