Building a Printful-Integrated T-Shirt E-Commerce Site: Next.js 14, Stripe Payments, and AWS Infrastructure

This post documents the technical architecture and deployment pipeline for 86dfrom.com, a Printful-integrated t-shirt storefront built with Next.js 14, Stripe payments, and AWS infrastructure. The goal was to create a production-ready e-commerce site with minimal overhead and maximum scalability.

What Was Built

A full-stack t-shirt storefront with the following components:

  • Frontend: Next.js 14 with React Server Components, serving static and dynamic product pages
  • Backend: Next.js API routes handling Printful variant fetching, Stripe payment processing, and order webhooks
  • Infrastructure: Vercel for Next.js hosting, AWS S3 + CloudFront for static assets, Route53 for DNS, ACM for SSL/TLS
  • Payment Processing: Stripe integration with webhook endpoint for order fulfillment
  • Print Fulfillment: Printful API integration for variant management and order routing

Architecture Overview

The site uses a hybrid deployment strategy:

  • Primary domain (86dfrom.com): Hosted on Vercel with full Next.js runtime support for dynamic API routes
  • Redirect domain (86from.com): Lightweight CloudFront distribution with Lambda@Edge redirect function routing traffic to primary domain
  • Static assets: Optimized through Next.js image optimization and Google Fonts caching

Why this approach? Vercel provides automatic HTTPS, global edge caching, and serverless functions out of the box. The redirect domain uses CloudFront + Lambda@Edge because it's cheaper than running a separate Vercel project when you only need HTTP-to-HTTPS redirects. AWS Route53 manages all DNS records for both domains, centralizing DNS management.

Infrastructure Setup

AWS Resources Created

The following AWS resources were provisioned:

  • S3 Bucket: 86dfrom.com-assets — Originally intended for static asset hosting, now primarily used for CloudFront origin configuration and future backup/archive purposes
  • CloudFront Distribution (Primary): Configured as origin for 86dfrom.com, pointing to Vercel's origin with appropriate cache behaviors
  • CloudFront Distribution (Redirect): Dedicated distribution for 86from.com, running a Lambda@Edge function at viewer request to redirect all traffic to the primary domain
  • ACM Certificates: Wildcard certificates for both 86dfrom.com and 86from.com, validated via Route53 DNS CNAME records
  • Route53 Hosted Zone: Single zone managing DNS for both domains, with A records pointing to CloudFront distributions

Why S3 + CloudFront over direct Vercel? While Vercel provides global CDN caching, adding CloudFront in front gives us additional control over cache headers, request/response transformations, and the ability to implement Lambda@Edge functions at the edge. This is particularly useful for the redirect domain, where a simple Lambda function eliminates the need for a full Vercel deployment.

File Structure

The project is organized as follows:

~/Documents/repos/sites/86dfrom.com/
├── site/
│   ├── index.html              (landing page)
│   └── success.html            (post-purchase confirmation)
├── gas/
│   ├── Code.gs                 (Google Apps Script for future automation)
│   ├── appsscript.json         (GAS project config)
│   └── .clasp.json             (clasp deployment metadata)
├── scripts/
│   └── deploy.sh               (S3 + CloudFront deployment script)
└── .env.local                  (local development environment variables)

The core Next.js app remains at /Users/cb/Desktop/86dfrom/ during development, with production code synced to the git repository.

Printful Integration

The Printful API integration is the backbone of product management. The workflow is:

  1. Fetch available product variants from Printful API endpoint using store-specific API key
  2. Filter for the Black t-shirt variant (Bella+Canvas 3001, colors 4016–4020 representing size range)
  3. Store variant IDs in .env.local for use in checkout flow
  4. When a customer purchases, create order via Printful API with variant ID and shipping details

The Printful account is scoped to the "Hello Dangerous" store with full API access across all Printful stores. This allows centralized variant management while maintaining separation from other stores within the same Printful organization.

Stripe Payment Processing

Stripe handles payment processing and order management:

  • Checkout flow: Customer submits form → Next.js API route creates Stripe Session
  • Webhook endpoint: /api/webhook receives payment_intent.succeeded events
  • Order creation: Upon successful payment, webhook route creates order in Printful and records transaction in database
  • Environment variables: STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY stored in Vercel environment variables

Webhook secret management: The webhook signing secret (whsec_...) is obtained from Stripe Dashboard → Developers → Webhooks after initial Vercel deployment. This ensures the webhook endpoint can verify that incoming requests are actually from Stripe, preventing replay attacks.

Deployment Pipeline

Deployments happen in stages:

  1. Code validation: Next.js build must compile cleanly without errors
    npm run build
  2. Environment setup: .env.local populated with:
    • NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
    • STRIPE_SECRET_KEY
    • STRIPE_WEBHOOK_SECRET (after webhook setup)
    • Printful variant IDs
    • Printful API key
  3. Vercel deployment:
    npx vercel@latest --prod
    Environment variables are synced to Vercel project settings before deploy.
  4. DNS configuration: Route53 A records point both domains to their respective CloudFront distributions
  5. Webhook setup: Stripe Dashboard → Developers → Webhooks → Add endpoint pointing to https://86dfrom.com/api/webhook

Key Technical Decisions

  • Next.js 14 over other frameworks: Server Components allow data fetching directly in components without additional middleware. API Routes provide serverless functions without infrastructure overhead. Vercel integration is seamless.