Skip to main content

PhotoSwipe Pro - License Delivery & Distribution Setup Guide

Overview

This guide explains how to set up automated license delivery and Pro package distribution for paying customers.


✅ What's Implemented

1. License Delivery System

  • ✅ Lemon Squeezy webhook handler (/api/webhooks/lemonsqueezy)
  • ✅ Automated email delivery with license keys
  • ✅ Beautiful HTML email template with installation instructions
  • ✅ Download token generation for secure portal access

2. Pro Package Distribution

  • ✅ Build script to create distributable .tgz package
  • ✅ Secure download endpoint with license validation
  • ✅ Customer portal for license management and downloads
  • ✅ Version management and latest release API

3. Customer Experience

  • ✅ Email with license key + download link
  • ✅ Customer portal login (email + license key)
  • ✅ One-click download of Pro package
  • ✅ Installation guide links
  • ✅ Support contact information

🔧 Setup Instructions

Step 1: Configure Environment Variables

Add these to your production environment (Vercel, Railway, etc.):

# Lemon Squeezy API
LEMON_SQUEEZY_API_KEY=your_ls_api_key_here
LEMON_SQUEEZY_STORE_ID=your_store_id
LEMON_SQUEEZY_PRODUCT_ID=your_product_id
LEMON_SQUEEZY_WEBHOOK_SECRET=your_webhook_secret

# Email Provider (Resend recommended)
EMAIL_PROVIDER=resend
RESEND_API_KEY=re_your_resend_key_here

# Download Security
DOWNLOAD_SECRET=generate_a_random_secret_here

# Site Configuration
SITE_URL=https://photoflowseo.com
ALLOWED_ORIGINS=https://photoflowseo.com,http://localhost:3001

# AI Provider (Optional - for demo/testing)
OPENROUTER_API_KEY=sk-or-v1-...
AI_MODEL=openai/gpt-4o-mini

Step 2: Set Up Lemon Squeezy Product

  1. Create Product in Lemon Squeezy Dashboard:

    • Name: "PhotoSwipe Pro - Site License"
    • Price: $99/year
    • Enable "License Keys" feature
    • Set license key format: pswp_prod_{random}
  2. Configure Webhook:

    • Go to Settings → Webhooks
    • Add webhook URL: https://your-domain.com/api/webhooks/lemonsqueezy
    • Select events:
      • order_created ✅ (required for license delivery)
      • subscription_created
      • subscription_updated
      • subscription_cancelled
      • license_key_created
    • Copy webhook secret and add to env as LEMON_SQUEEZY_WEBHOOK_SECRET
  3. Get API Credentials:

    • Go to Settings → API
    • Create new API key
    • Copy and add to env as LEMON_SQUEEZY_API_KEY
    • Note your Store ID and Product ID

Step 3: Set Up Email Provider (Resend)

Why Resend? Simple API, affordable ($20/mo for 100k emails), great deliverability

  1. Sign up: https://resend.com
  2. Verify your domain:
    • Add DNS records for photoflowseo.com
    • Wait for verification (usually instant)
  3. Create API key:
    • Go to API Keys → Create
    • Copy key and add to env as RESEND_API_KEY
  4. Set FROM address:
    • Update webhook handler: from: 'PhotoSwipe Pro <noreply@photoflowseo.com>'

Alternative: SendGrid, AWS SES, or any SMTP provider


Step 4: Build and Deploy Pro Package

# Build the Pro package
npm run build-pro

# This creates: /releases/photoswipe-pro-5.4.4.tgz

Deploy releases directory:

  • Option A: Commit releases/*.tgz to Git (simple, version-controlled)
  • Option B: Upload to S3/CDN (scalable, faster)
  • Option C: Serve from Vercel static files

For Vercel, the releases/ directory is automatically served as static files.


Step 5: Test the Full Flow

Test Webhook Locally (Using Webhook.site)

  1. Go to https://webhook.site
  2. Copy your unique URL
  3. Configure Lemon Squeezy webhook to point to that URL temporarily
  4. Create a test order in Lemon Squeezy
  5. Verify webhook payload is received
  6. Update webhook URL to your production API

Test Email Delivery

# Start API server
PORT=4001 npm run api

# Simulate webhook event
curl -X POST http://localhost:4001/api/webhooks/lemonsqueezy \
-H 'Content-Type: application/json' \
-d '{
"meta": { "event_name": "order_created" },
"data": {
"attributes": {
"customer_email": "test@example.com",
"user_name": "Test Customer",
"order_number": "12345",
"first_order_item": {
"license_key": "pswp_prod_test123",
"product_name": "PhotoSwipe Pro - Site License"
},
"urls": { "receipt": "https://example.com/receipt" }
}
}
}'

Expected: Email sent to test@example.com with license key


Step 6: Test Download Flow

# Get latest version info
curl http://localhost:4001/api/download/latest

# Download with license key
curl -o photoswipe-pro.tgz "http://localhost:4001/api/download/download/5.4.4?key=pswp_prod_test123"

# Verify tarball
tar -tzf photoswipe-pro.tgz

Step 7: Test Customer Portal

  1. Go to http://localhost:3001/customer-portal
  2. Login with:
  3. Verify you can see license info
  4. Click "Download v5.4.4"
  5. Verify .tgz file downloads successfully

🔄 End-to-End Customer Journey (Production)

1. Customer Purchases

Customer clicks "Buy Now" on /checkout
→ Lemon Squeezy checkout overlay opens
→ Customer enters payment info
→ Order completed

2. License Delivery (Automated)

Lemon Squeezy sends webhook to /api/webhooks/lemonsqueezy
→ Webhook handler verifies signature
→ Extracts license key from order
→ Sends email via Resend to customer
→ Email includes:
- License key: pswp_prod_abc123...
- Download link with secure token
- Installation instructions
- Support contact

3. Customer Receives Email

Subject: Your PhotoSwipe Pro License Key - Order #12345

Hi John Doe,

Thank you for purchasing PhotoSwipe Pro - Site License!

YOUR LICENSE KEY:
pswp_prod_abc123...

[Download PhotoSwipe Pro] [View Receipt]

Quick Start:
1. Download the Pro package
2. Install: npm install ./photoswipe-pro-5.4.4.tgz
3. Initialize with your license key
4. View full guide: https://photoflowseo.com/how-to-use-pro

4. Customer Downloads Package

Option A: From email link (has download token)

Click "Download PhotoSwipe Pro"
→ Redirects to customer portal with ?token=...
→ Auto-authenticated
→ Click "Download v5.4.4"
→ API validates token
→ Streams .tgz file

Option B: Manual portal login

Go to /customer-portal
→ Enter email + license key
→ Click "Access Portal"
→ See license details
→ Click "Download v5.4.4"
→ API validates license key
→ Streams .tgz file

5. Customer Installs

# Customer runs in their project
npm install ./photoswipe-pro-5.4.4.tgz

# Initialize
import { createAiSeoPlugin } from 'photoswipe-pro';

const aiPlugin = createAiSeoPlugin({
licenseKey: 'pswp_prod_abc123...',
baseUrl: '/api/ai'
});

6. License Validation

On first use:
→ Plugin reads license key
→ Validates locally (format, not expired)
→ Shows 14-day grace period
→ Makes remote validation call (optional)
→ Pro features enabled ✅

📧 Email Templates

Purchase Confirmation Email

Location: server/lemonsqueezy/webhook.js

Template includes:

  • ✅ License key (formatted, easy to copy)
  • ✅ Download button with secure token
  • ✅ Receipt link
  • ✅ Quick start guide (3-4 steps)
  • ✅ What's included list
  • ✅ Support links
  • ✅ Order number

Customization: Edit the emailHtml constant in sendLicenseEmail() function.


🔒 Security Features

Webhook Security

  • ✅ HMAC signature verification (SHA-256)
  • ✅ Timing-safe comparison to prevent timing attacks
  • ✅ Environment-based secret configuration

Download Security

  • ✅ License key validation before download
  • ✅ Time-limited download tokens
  • ✅ Rate limiting on API endpoints
  • ✅ No direct file access (streamed through API)

Email Security

  • ✅ No sensitive data in URLs (except signed tokens)
  • ✅ HTTPS-only links in production
  • ✅ SPF/DKIM verification via Resend

🚀 Deployment Checklist

Before Going Live:

  • Set all environment variables in production
  • Configure Lemon Squeezy webhook to production URL
  • Verify email domain in Resend
  • Test webhook with real Lemon Squeezy test mode purchase
  • Verify email is sent and received
  • Test download with real license key
  • Verify customer portal loads and works
  • Check all links in email template point to production URLs
  • Set up monitoring/logging (Sentry, Datadog)
  • Test with different email providers (Gmail, Outlook, etc.)

Post-Launch Monitoring:

  • Monitor webhook endpoint for failures
  • Check email deliverability (open rates, bounces)
  • Track download metrics
  • Monitor license validation API usage
  • Set up alerts for errors

🐛 Troubleshooting

Webhook Not Firing

Symptoms: Customer pays but doesn't receive email

Fixes:

  1. Check Lemon Squeezy webhook logs
  2. Verify webhook URL is correct (https, no typos)
  3. Check webhook signature verification
  4. Look at server logs for errors
  5. Test with ngrok for local debugging:
    ngrok http 4001
    # Use ngrok URL in LS webhook temporarily

Email Not Sending

Symptoms: Webhook fires but email doesn't arrive

Fixes:

  1. Check EMAIL_PROVIDER env var is set to resend
  2. Verify RESEND_API_KEY is correct
  3. Check Resend dashboard for delivery status
  4. Verify domain is verified in Resend
  5. Check spam folder
  6. Look at server logs for email errors

Download Fails

Symptoms: Customer clicks download, gets 404 or 403

Fixes:

  1. Verify releases/ directory exists with .tgz file
  2. Check license validation is working
  3. Verify environment variables are set
  4. Test download endpoint directly with curl
  5. Check file permissions on server

License Validation Fails

Symptoms: Customer has valid key but can't use Pro features

Fixes:

  1. Check LEMON_SQUEEZY_API_KEY is set correctly
  2. Verify license key format matches (pswp_prod_*)
  3. Test validation endpoint directly
  4. Check Lemon Squeezy dashboard for license status
  5. Verify store ID and product ID match

📊 Metrics to Track

Email Metrics (via Resend)

  • Delivery rate
  • Open rate
  • Click-through rate (download button)
  • Bounce rate

Download Metrics

  • Total downloads per license
  • Version distribution
  • Download failures

Support Metrics

  • "Can't find license key" tickets
  • "Download failed" tickets
  • "License invalid" tickets

🔄 Updating the Pro Package

When You Release a New Version:

# 1. Update version in root package.json
npm version 5.5.0

# 2. Build new Pro package
npm run build-pro

# 3. Commit and push
git add releases/photoswipe-pro-5.5.0.tgz
git commit -m "Release PhotoSwipe Pro v5.5.0"
git push

# 4. Deploy to production
vercel --prod

# 5. Email existing customers (optional)
# Use Resend broadcast or Lemon Squeezy customer emails

Existing license keys automatically work with new versions!


💡 Future Enhancements

Short-term:

  • Add license usage analytics (how many sites using each key)
  • Implement domain-based activation limits
  • Add "forgot license key" recovery flow
  • Create admin dashboard for license management

Long-term:

  • Self-service license transfer between domains
  • Upgrade/downgrade flows (Site → Agency)
  • License pooling for Agency customers
  • Automatic update notifications

✅ Status

License Delivery: ✅ Fully implemented
Pro Package Distribution: ✅ Fully implemented
Customer Portal: ✅ Fully implemented
Email Templates: ✅ Fully implemented
Download Security: ✅ Fully implemented

Ready for production: ⚠️ After Lemon Squeezy + Resend configuration


📞 Need Help?

If you encounter issues during setup:

  1. Check server logs for errors
  2. Test each component individually
  3. Use mock mode for development
  4. Contact support@photoflowseo.com