Claude
Skills
Sign in
Back

customer-accounts

Included with Lifetime
$97 forever

Let shoppers register, manage their profile, save multiple addresses, and view their full order history using your platform's built-in customer account system

customer-crmcustomeraccountsregistrationprofileaddress-bookorder-historyauthentication

What this skill does


# Customer Accounts

## Overview

Customer accounts let shoppers save addresses for faster checkout, view order history, track shipments, and manage their profile. Every major e-commerce platform has this built in — Shopify, WooCommerce, and BigCommerce all provide account registration, login, address books, and order history without any custom development. The main decisions are: whether to make accounts optional or required, and whether to extend the platform's default account pages with additional functionality.

## When to Use This Skill

- When enabling customer registration and login on a new storefront
- When customizing the account dashboard with order history and tracking
- When adding an address book to speed up returning customer checkout
- When converting guest checkout users into registered customers
- When adding wishlist or saved-for-later functionality

## Core Instructions

### Step 1: Determine platform and enable customer accounts

| Platform | Account System | Recommended Extension |
|----------|---------------|----------------------|
| **Shopify** | Native customer accounts (classic or new) | Customer Accounts Concierge or Flits for enhanced account pages |
| **WooCommerce** | My Account page (built-in, customizable) | YITH WooCommerce Wishlist; WooCommerce Memberships for gated content |
| **BigCommerce** | Customer account portal (built-in) | Customer Groups for tiered access; LoyaltyLion for loyalty integration |
| **Custom / Headless** | Build with JWT sessions and bcrypt password hashing | Required for complete control over authentication and account UX |

---

### Step 2: Platform-specific setup

---

#### Shopify

Shopify offers two account experiences: **Classic accounts** and the newer **New customer accounts** (available on all plans).

**Enable accounts and choose the experience:**

1. Go to **Settings → Customer accounts**
2. Choose between:
   - **Classic accounts**: traditional email + password login with customizable account pages via Liquid theme
   - **New customer accounts**: passwordless login via email link; Shopify-hosted pages that Shopify controls (faster to set up, less customizable)
3. Set accounts as **Optional** (recommended) or **Required**

**Classic accounts setup:**

1. Enable **Classic accounts** in Settings → Customer accounts
2. The account page appears at `/account` — your theme controls the layout
3. Customize the account page in **Online Store → Themes → Customize → Customer account pages**
4. Key pages: Login, Register, Account overview, Order detail, Addresses

**Making accounts optional (strongly recommended):**
- Always allow guest checkout — never force registration before purchase
- After checkout, show a "Create account to save your details" prompt
- Shopify handles the "convert guest to account" flow automatically when a customer registers with the same email used for a past order

**Extending account pages:**

For enhanced account functionality (wishlist, loyalty points, social login, recent orders with tracking):
- Install **Flits** from the App Store — comprehensive account page customization
- Or install **Customer Accounts Concierge** — adds wishlist, recently viewed, reorder functionality

---

#### WooCommerce

WooCommerce has a built-in **My Account** page that includes order history, addresses, and profile management.

**Set up My Account:**

1. Go to **WooCommerce → Settings → Accounts & Privacy**
2. Configure:
   - **Guest checkout**: check "Allow customers to place orders without an account"
   - **Account creation**: optionally auto-create accounts during checkout
   - **Account erasure**: enable "Allow customers to request account deletion"
3. The My Account page is created automatically at `/my-account/`

**Customize My Account tabs:**

The default tabs are: Dashboard, Orders, Downloads, Addresses, Account details, Logout. Add or remove tabs:
1. Add custom tabs by using the `woocommerce_account_menu_items` filter in your child theme's functions.php, or install a plugin like **YITH WooCommerce Customize My Account Page**
2. Reorder tabs by modifying the array in the filter

**Address book:**

1. Go to **WooCommerce → Settings → Accounts → Allow customers to store multiple addresses**
2. Customers can add/edit multiple addresses in **My Account → Addresses**
3. WooCommerce pre-fills checkout with the default address automatically

**Wishlist:**
- Install **YITH WooCommerce Wishlist** (free/premium)
- Adds a "Add to Wishlist" button on product pages and a wishlist page in My Account

**Converting guest to registered after purchase:**

WooCommerce shows a "Create account" prompt in order confirmation emails automatically when accounts are enabled but optional.

---

#### BigCommerce

BigCommerce has a built-in customer portal.

**Enable and configure:**

1. Go to **Store Setup → Store Settings → Display → Customer Account Access**
2. Set to "Optional" to allow guest checkout
3. Account pages are managed by your theme — customize in the Stencil theme editor

**Customer groups:**

Use customer groups for tiered access, B2B pricing, or member-only categories:
1. Go to **Customers → Customer Groups → Add Group**
2. Set group-specific pricing, category visibility, or shipping rules
3. Assign customers to groups manually or auto-assign based on purchase history

**Address book:**
- Built-in under the customer account portal
- Customers can save multiple addresses and select them at checkout

---

#### Custom / Headless

For headless storefronts, build a complete account system with secure authentication:

```typescript
// lib/auth.ts
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import { z } from 'zod';

const registerSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8).max(128),
  firstName: z.string().min(1).max(100),
  lastName: z.string().min(1).max(100),
  acceptsMarketing: z.boolean().default(false),
});

// POST /api/customers/register
export async function register(req: Request, res: Response) {
  const input = registerSchema.parse(req.body);

  const existing = await db.customers.findByEmail(input.email.toLowerCase());
  if (existing) return res.status(409).json({ error: 'An account with this email already exists' });

  const passwordHash = await bcrypt.hash(input.password, 12);  // Cost factor 12 minimum
  const customer = await db.customers.create({ ...input, email: input.email.toLowerCase(), passwordHash });

  await sendVerificationEmail(customer);
  const token = jwt.sign({ sub: customer.id, type: 'customer' }, process.env.JWT_SECRET!, { expiresIn: '7d' });

  res.status(201).json({ customer: omit(customer, ['passwordHash']), token });
}

// POST /api/customers/login
export async function login(req: Request, res: Response) {
  const { email, password } = req.body;
  const customer = await db.customers.findByEmail(email.toLowerCase());

  // Use the same error for both "not found" and "wrong password" to prevent email enumeration
  if (!customer || !customer.passwordHash) return res.status(401).json({ error: 'Invalid email or password' });
  if (customer.status === 'disabled') return res.status(403).json({ error: 'This account has been disabled' });

  const valid = await bcrypt.compare(password, customer.passwordHash);
  if (!valid) return res.status(401).json({ error: 'Invalid email or password' });

  const token = jwt.sign({ sub: customer.id, type: 'customer' }, process.env.JWT_SECRET!, { expiresIn: '7d' });
  res.json({ customer: omit(customer, ['passwordHash']), token });
}

// Address book CRUD — GET /api/customers/me/addresses
export async function listAddresses(req: AuthRequest, res: Response) {
  const addresses = await db.customerAddresses.findMany({ where: { customerId: req.customerId } });
  res.json({ addresses });
}

// POST /api/customers/me/addresses
export async function addAddress(req: AuthRequest, res: Response) {
  const existing = await db.customerAddresses.findMany({ where: { customerId: req.customerI

Related in customer-crm