Back to projects

nestjs shopify

A simple NestJS API integrated with Shopify

Last updated: March 30, 2026
Project Preview nestjs-shopify
TypeScript 96.5%JavaScript 3.0%Dockerfile 0.5%

Documentation

πŸ›οΈ Shopify Orders Webhook Integration (NestJS + Drizzle + Docker)

This project is an API developed using NestJS with Drizzle ORM and PostgreSQL, designed to integrate with the Shopify API. It handles OAuth authentication for Shopify stores and receives order creation webhooks (orders/create).

Table of Contents

Technologies Used

  • NestJS - A progressive Node.js framework for building efficient, reliable, and scalable server-side applications.
  • Drizzle ORM - Type-safe operations on the database.
  • Shopify API - Shopify’s REST/GraphQL APIs used for OAuth authentication and order webhooks.
  • Ngrok - Tunnel to expose your local API to the internet.
  • PostgreSQL - Relational database for data persistence.
  • Docker - Containerization for the application and database.
  • Zod - TypeScript-first schema and data validation.

Prerequisites

Before getting started, make sure you have:

Setting Up a Public Domain (Ngrok or Alternative)

To receive Shopify webhooks and OAuth callbacks, your local API must be accessible from the internet. Ngrok is recommended for this.

  1. Install Ngrok and run:

    ngrok http 3000

    Replace 3000 with the port your NestJS app uses if different (e.g., ngrok http 3333).

  2. Copy the HTTPS URL generated by ngrok (e.g., https://abcd1234.ngrok.io).

  3. Update your project configuration:

    • In your .env file, set:

      HOST=https://abcd1234.ngrok.io
  4. You will use this URL in your Shopify app configuration in the next step.

Initial Setup on Shopify

Now that you have a public domain, follow these steps to create and configure your Shopify app:

  1. Go to Shopify Partners and log in or create an account.

  2. Create a custom app:

    • Navigate to Apps β†’ Create app β†’ Custom App.
    • Choose a name, for example: Webhook Orders App.
  3. Generate credentials:

    • Copy the API Key (Client ID) and API Secret and save them in your .env file (see Project Configuration).
  4. Configure your app URLs using the ngrok URL:

    • Set App URL to:

      https://abcd1234.ngrok.io/auth/shopify
    • Set Redirect URL to:

      https://abcd1234.ngrok.io/auth/shopify/redirect
  5. Create a development store to test your app:

    • In the Shopify Partners dashboard, go to Stores β†’ Add store β†’ Create development store.
    • Enter a store name and confirm.
  6. Install your custom app in the development store:

    • In your Shopify Partners dashboard, go to Apps and open your custom app.
    • Then go to Distribution and select Custom domain.
    • Enter your test store domain (e.g., store-name.myshopify.com).
    • Use the installation link generated by Shopify to install the app into your test store. This link typically looks like:
    https://{store-name}.myshopify.com/admin/oauth/authorize?client_id={API_KEY}&scope={SCOPES}&redirect_uri={REDIRECT_URI}
    • Open this link in your browser and confirm the app installation in your test store.

Tip: You can always update the ngrok URL in Shopify and your .env file if you restart ngrok and get a new domain.

Project Configuration

  1. Create a .env file based on .env.example:
# Server Configuration
PORT=3000 # HTTP server port
 
# Database Connection
DATABASE_HOST=db                  # e.g., database service name in docker-compose.yml
DATABASE_USER=postgres            # your DB username
DATABASE_PASSWORD=postgres        # your DB password
DATABASE_PORT=5432                # default PostgreSQL port
DATABASE_NAME=nestshop            # your DB name
# Format: postgresql://USER:PASSWORD@DATABASE_HOST:PORT/DATABASE_NAME?schema=public
DATABASE_URL=postgresql://postgres:postgres@db:5432/nestshop?schema=public
 
# Shopify App Credentials
SHOPIFY_API_KEY=your_api_key_here
SHOPIFY_API_SECRET=your_api_secret_here
SHOPIFY_SCOPES=read_products,write_orders
SHOPIFY_API_VERSION=2025-07 # Shopify API version
 
# Public App URL (Ngrok or Custom Domain)
HOST=https://your-ngrok-subdomain.ngrok-free.app
  1. (Optional) If you want to view the saved data using Drizzle Studio, create a .env.studio file:
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/nestshop?schema=public

Note: The URL is similar to the one in .env, but the DATABASE_HOST changes from db to localhost so Drizzle Studio can connect locally.

Running the Project

You can run the project in two ways: via Docker (recommended for isolated environments) or locally with Node.js and Docker only for the database.

Option 1: Using Docker

Recommended for isolated development environments.

From the project root, run:

docker-compose up --build

This will build and start both the API and the PostgreSQL database.

To stop containers later:

docker-compose down

Option 2: Using Node.js/NPM (Local Development)

  1. Install dependencies:
npm install
  1. Start the PostgreSQL database container:
docker-compose up -d db

Make sure port 5432 is free on your machine to avoid conflicts. Note: db is the service name defined for the database in the docker-compose.yml file. The default port for the db service is 5432, as it uses PostgreSQL.

  1. Update your .env and .env.studio to use localhost in DATABASE_URL:
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/nestshop?schema=public
  1. Apply database migrations locally:
npm run db:migrate
  1. Run the API server in development mode:
npm run start:dev

API Endpoints

You can explore and test the available API endpoints using the documentation below.

The default base URL is usually one of the following, depending on your setup:

  • Local: http://localhost:3000
  • Ngrok: https://your-ngrok-subdomain.ngrok.io
  • Custom domain: https://your-custom-domain.com

Available endpoints:

MethodEndpointDescription
GET/healthVerifies if the API is running properly.
GET/auth/shopifyStarts the Shopify OAuth authentication flow.
GET/auth/shopify/redirectHandles the OAuth redirect after authentication.
POST/webhooks/orders/createReceives Shopify order creation webhooks.
GET/ordersRetrieves all saved orders with details.
GET/orders/:shopDomainRetrieves all saved orders from a specific Shopify domain.

Testing the Integration

  1. Access your test store admin panel:
https://admin.shopify.com/store/your-test-store-name
  1. Create a product and place an order.

  2. Shopify will send order creation webhooks automatically to your public API URL:

POST https://abcd1234.ngrok.io/webhooks/orders/create
  1. To verify if the webhook was received:

    • Check your API logs for webhook request entries.
    • Use the GET /orders or GET /orders/shopDomain endpoints to confirm the order data is saved.

Supported Webhooks

Currently, this project only listens to:

  • orders/create: Receives information about new orders placed in the store.

(Optional) Viewing Saved Data in the Database

If you created a .env.studio file and configured the DATABASE_URL for Drizzle Studio, you can view the saved data by running the following command from the project root in a new terminal:

npm run db:studio

Then open Drizzle Studio at https://local.drizzle.studio in your browser.

Project Structure

src/
β”œβ”€β”€ auth/                 # OAuth authentication module with Shopify
β”‚   └── dto/              # Data Transfer Objects used by the auth methods
β”‚   ...
β”œβ”€β”€ common/               # Shared code
β”‚   β”œβ”€β”€ dto/              # Reusable DTOs shared across modules (e.g., Shopify Webhooks)
β”‚   β”œβ”€β”€ interceptors/     # Reusable interceptors (e.g., HMAC validation)
β”‚   └── mapper/           # Functions to transform and map external data (e.g., Shopify β†’ DB format)
β”œβ”€β”€ drizzle/              # Drizzle ORM configuration
β”‚   β”œβ”€β”€ migrations/       # Database migration files
β”‚   β”œβ”€β”€ schema/           # Database table schemas
β”‚   └── types/            # TypeScript types related to the database
β”‚   ...
β”œβ”€β”€ env/                  # Environment variable validation using zod
β”œβ”€β”€ orders/               # View information about orders saved in the system
β”œβ”€β”€ webhooks/             # Shopify webhooks receiving and handling module
β”œβ”€β”€ app.module.ts
β”œβ”€β”€ main.ts
.env
.env.studio
docker-compose.yml
Dockerfile

Note:

The core flow of the app mainly happens within the auth and webhooks modules, which handle authentication and webhook processing respectively.

Author

Made by Marcos Antonio.

  • πŸ’» Full Stack developer dedicated to building complete solutions by combining modern, functional user interfaces with robust back-end architectures.
  • πŸš€ Always open to feedback, collaboration, or ideas for improvement!
  • πŸ“« Feel free to connect with me on LinkedIn or check out more of my projects here on GitHub.