==== Amazon Clone ====
A simple Amazon clone that shows some shopping items in a CSS grid. The user can sign-in using Google and add the items to their basket. Then the user can checkout the basket and pay using Stripe. The user can also see their finished orders.
- NextJs
- React
- Redux Toolkit
- Tailwind CSS
- Stripe
- Firebase
- Cloud Firestore
- Google sign-in
- Load products from a server-side API
- Sign-in using Google
- Checkout using Stripe
- Store orders in Firebase Cloud Firestore
- Responsive design
- Run
yarn
- Make an environment variable file
.env.local
for running locally- Add an environment variable
NEXTAUTH_URL=http://localhost:3000
- Add an environment variable
- Generate a random secret for the environment variable
NEXTAUTH_SECRET
- Generate two random secrets of length 16 characters e.g. using www.random.org or randomkeygen.com. These keys will be used as as the following environment variables
SERVICE_ENCRYPTION_IV
SERVICE_ENCRYPTION_KEY
- Set up Firebase as described below
- Set up Stripe as described below
- Run
yarn dev
to run locally - Deploy to Vercel (Optional)
- Go to the firebase console
- Add a new project
- In the Firebase console, go to the project settings
- Scroll down to
Your Apps
- Add a web app
- Deselect Firebase hosting
- In the Add Firebase SDK screen, select
use npm
and copy the value of thefirebaseConfig
variable
- In the file
firebase.js
in the repository root, replace the value of thefirebaseConfig
variable with the value you copied
- In the Firebase console, go to the project settings -> Service Accounts -> Generate new private key. This will download a file
- Encrypt the file. You can encrypt the file online using this tool
- Paste the contents of the downloaded file in the tool as the text to be encrypted
- Mode =
CBC
- Key size =
128
bits - IV = value of
SERVICE_ENCRYPTION_IV
env var - Secret Key = value of
SERVICE_ENCRYPTION_KEY
env var - Output Text Format =
Base64
- Save the encrypted content in a file
firebaseServiceAccount.enc.json
in the repository root. The content of the file should be:
{
"encrypted": "<THE BASE64 ENCRPYTED CONTENT>"
}
- In the Firebase console, go to Authentication
- Click
Get Started
if you see it - Under Sign-in method, add Google
- Click Enable
- Provide a public-facing name and a support email
- Click Save
- Click the new Google provider in the list and then
Web SDK configuration
- Copy the value of Web client ID as the
GOOGLE_ID
environment variable - Copy the value of Web client secret as the
GOOGLE_SECRET
environment variable
- Copy the value of Web client ID as the
- Go to the Google Cloud console and then your Firebase project
- On the hamburger navigation menu -> API & Services -> Credentials
- Under OAuth 2.0 Client IDs -> Web client
- Under Authorized redirect URIs
- Add a URI
http://localhost:3000/api/auth/callback/google
- Add for any domains you will be hosting the app on as well. Note that non-localhost URIs must use
https
protocol
- Add a URI
- In the Firebase console, go to Firestore Database
- Click Create Database
- Select Start in test mode. You can use production mode as well
- On the next screen, select the desired region. Best to pick one closest to your geographical location
- Create
- Go the the Stripe dashboard
- Create a new test account
- Go to Developers -> Overview (or API keys)
- Copy the Publishable key. This will go in the
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
env var - Copy the Secret key. This will go in the
STRIPE_SECRET_KEY
env var
- Copy the Publishable key. This will go in the
- Go to Products -> Shipping rates -> Create shipping rate
- Provide some details and save
- Copy the ID under Details
- The ID will go in the
STRIPE_SHIPPING_RATE_ID
env var
- Setup Webhooks as below
Webhooks are needed for Stripe to send payment updates to the application. Different setup is required depending on if you are running the application locally or in a live site (e.g. Vercel).
- Install Stripe CLI
- Run
stripe login
and log in to your account - Run
stripe listen --forward-to localhost:3000/api/webhooks
- The above command will return a secret. Put it as
STRIPE_SIGNING_SECRET
in the.env.local
file
- In the Stripe dashboard. Goto -> Developers -> Webhooks -> Add an endpoint
- Add the endpoint has
<SITE DOMAIN>/api/webooks
- In events, select the
checkout.session.completed
event - Create
- In the newly create webhook, in the
Signing Secret
column, click Reveal and copy the Signing secret as theSTRIPE_SIGNING_SECRET
env var
For running the app locally, create a file .env.local
and put the variables in it as follows:
SERVICE_ENCRYPTION_IV=secret
SERVICE_ENCRYPTION_KEY=secret
GOOGLE_ID=secret
GOOGLE_SECRET=secret
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=notSecret
STRIPE_SECRET_KEY=secret
STRIPE_SIGNING_SECRET=secret
NEXTAUTH_SECRET=secret
NEXTAUTH_URL=http://localhost:3000
SERVICE_ENCRYPTION_IV
The Initialization vector for the AES encryption algorithmSERVICE_ENCRYPTION_KEY
The secrey key for the AES encryption algorithmGOOGLE_SECRET
Google client secret for Sign-in using GoogleGOOGLE_ID
Google client ID for Sign-in using GoogleNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
Publishable key from the Stripe accountSTRIPE_SECRET_KEY
Secret key from the Stripe accountSTRIPE_SIGNING_SECRET
Signing key from Stripe for listening to WebhooksSTRIPE_SHIPPING_RATE_ID
ID of the shipping rate to use. Created in the Stripe dashboardNEXTAUTH_SECRET
Next Auth secret for sigining JWTs. You can provide anything hereNEXTAUTH_URL
This is not required on Vercel. Otherwise it is the URL to the app
- Visit the webiste
- Add items to the basket
- Click the basket icon at the right top navbar
- Click Proceed to Checkout
- Enter fake details. For card see Stripe Details below
- Pay (no payment processing is done with the Stripe test account)
- Go to Returns & Orders in the right navbar and see your order there
- When checking out with Stripe, make sure that you have configured a test Stripe account. Provide fake name and address details. For the payment card, use
4242 4242 4242 4242
as the card number with a random future expiry and424
as the CVV.
The app is ready to be deployment on Vercel. Only the environment variables need to be set up
- The Stripe API only accepts a metadata field of 500 characters and the app is currently putting all the images in the metadata. So Stripe will fail if the combined length of the images of the order is more than 500.
- Group similar items into one and show as quantity in the basket