|
| 1 | +# Account Checkout Next.js Example |
| 2 | + |
| 3 | +This example showcases how to implement an **account checkout** flow with **Elastic Path Commerce Cloud** in a Next.js application with server-side authentication. |
| 4 | + |
| 5 | +[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Felasticpath%2Fcomposable-frontend%2Ftree%2Fmain%2Fexamples%2Fnext-account-checkout&env=NEXT_PUBLIC_EPCC_CLIENT_ID,NEXT_PUBLIC_EPCC_ENDPOINT_URL,NEXT_PUBLIC_PASSWORD_PROFILE_ID,NEXT_PUBLIC_APP_URL&project-name=ep-next-account-checkout) |
| 6 | + |
| 7 | +> **Heads-up:** This project can be considered a **hybrid** of the [Shopper Accounts Authentication Example](../shopper-accounts-authentication) and [Guest Checkout SPA Example](../spa-guest-checkout). It combines account authentication with cart management and checkout—providing a more secure, server-side approach to e-commerce checkout flows. |
| 8 | +
|
| 9 | +Key capabilities demonstrated: |
| 10 | + |
| 11 | +1. **Account Authentication** – secure login with server-side token management using HttpOnly cookies. |
| 12 | +2. **User Login** – complete authentication flow with EPCC's account members API. |
| 13 | +3. **Protected Account Pages** – route protection ensuring authenticated access to account features. |
| 14 | +4. **Session Management** – automatic token refresh and secure session handling with cookies. |
| 15 | +5. **Cart Persistence** – automatically creates / retrieves a cart via the Shopper SDK with account association. |
| 16 | +6. **Account Checkout Form** – captures billing & shipping addresses with account token security: |
| 17 | + • _Same as billing_ toggle |
| 18 | + • Optional _Delivery Instructions_ field (shipping only) |
| 19 | + • **Server-side validation** and checkout processing |
| 20 | +7. **Order Creation** – converts a cart to an order using account tokens for enhanced security. |
| 21 | +8. **Shipping Options** – integrated shipping selection with real-time pricing updates. |
| 22 | +9. **Event-driven Cart Refresh** – broadcasts a `cart:updated` custom event so any part of the app can update after operations. |
| 23 | +10. **Centralized API Client Configuration** – server-side API calls with consistent authentication patterns. |
| 24 | + |
| 25 | +> **Security Considerations:** Unlike the SPA guest checkout example, this is a Next.js implementation. This is because account checkout necessarily uses account tokens. Account tokens have elevated permissions compared to implicit tokens, so using them server-side only via Next.js server actions, is safer. |
| 26 | +
|
| 27 | +--- |
| 28 | + |
| 29 | +## Project Structure |
| 30 | + |
| 31 | +``` |
| 32 | +next-account-checkout/ |
| 33 | +├── src/ |
| 34 | +│ ├── app/ |
| 35 | +│ │ ├── (auth)/ # Authentication pages (login/register/password-reset) |
| 36 | +│ │ ├── account/ # Account management pages |
| 37 | +│ │ ├── api/webhooks/ # Webhook endpoints for notifications |
| 38 | +│ │ ├── actions.ts # Server actions for cart/checkout operations |
| 39 | +│ │ ├── layout.tsx # Root layout with CartProvider |
| 40 | +│ │ └── page.tsx # Main page with product grid + cart |
| 41 | +│ ├── components/ |
| 42 | +│ │ ├── cart-provider.tsx # Initializes / persists cart with account context |
| 43 | +│ │ ├── cart-view.tsx # Cart listing, promo codes & shipping options |
| 44 | +│ │ ├── checkout-view.tsx # Account checkout form (billing + shipping) |
| 45 | +│ │ ├── product-grid.tsx # Product display with add-to-cart |
| 46 | +│ │ └── ui.tsx # Reusable UI components |
| 47 | +│ └── lib/ |
| 48 | +│ ├── auth.ts # Authentication helpers |
| 49 | +│ ├── auth-client.tsx # Client-side auth context |
| 50 | +│ └── api-client.ts # Server-side API client configuration |
| 51 | +└── README.md # ← you are here |
| 52 | +``` |
| 53 | + |
| 54 | +## How It Works |
| 55 | + |
| 56 | +### 1. Account Authentication & Cart Initialization |
| 57 | + |
| 58 | +The app combines account authentication with cart management. On app load, if a user is authenticated, their account token is used to create/retrieve a cart with enhanced permissions: |
| 59 | + |
| 60 | +```tsx |
| 61 | +// src/components/cart-provider.tsx |
| 62 | +useEffect(() => { |
| 63 | + initializeCart() // Uses account token if available |
| 64 | +}, []) |
| 65 | +``` |
| 66 | + |
| 67 | +Account tokens provide elevated security compared to implicit tokens, enabling secure checkout operations. |
| 68 | + |
| 69 | +### 2. Server-Side Cart Operations |
| 70 | + |
| 71 | +All cart operations use Next.js server actions with account token authentication: |
| 72 | + |
| 73 | +```ts |
| 74 | +// src/app/actions.ts |
| 75 | +export async function addToCart(productId: string, quantity: number = 1) { |
| 76 | + // Server-side operation with account token security |
| 77 | +} |
| 78 | +``` |
| 79 | + |
| 80 | +### 3. Account Checkout Form |
| 81 | + |
| 82 | +`CheckoutView` manages a structured form state using direct SDK types: |
| 83 | + |
| 84 | +```ts |
| 85 | +{ |
| 86 | + customer: { email }, |
| 87 | + billing_address: { first_name, last_name, line_1, city, region, postcode, country }, |
| 88 | + shipping_address: { first_name, last_name, line_1, city, region, postcode, country, instructions }, |
| 89 | + sameAsBilling: true |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +The form uses SDK field names directly with `satisfies` validation for type safety. |
| 94 | + |
| 95 | +### 4. Shipping Integration |
| 96 | + |
| 97 | +Shipping options are managed as custom cart items, for example purposes: |
| 98 | + |
| 99 | +```ts |
| 100 | +const SHIPPING_OPTIONS = [ |
| 101 | + { id: "standard", name: "Standard Shipping", price_cents: 500 }, |
| 102 | + { id: "express", name: "Express Shipping", price_cents: 1500 }, |
| 103 | +] |
| 104 | +``` |
| 105 | + |
| 106 | +### 5. Secure Order Creation |
| 107 | + |
| 108 | +Account checkout uses the account token: |
| 109 | + |
| 110 | +```ts |
| 111 | +await checkoutWithAccountToken({ |
| 112 | + cartId, |
| 113 | + customer: form.customer, |
| 114 | + billing_address: form.billing_address, |
| 115 | + shipping_address: finalShippingAddress, |
| 116 | +}) |
| 117 | +``` |
| 118 | + |
| 119 | +### 6. Event-Driven Updates |
| 120 | + |
| 121 | +After successful operations, the app broadcasts cart updates: |
| 122 | + |
| 123 | +```ts |
| 124 | +window.dispatchEvent(new Event("cart:updated")) |
| 125 | +``` |
| 126 | + |
| 127 | +Any listeners automatically refresh their data, ensuring UI consistency. |
| 128 | + |
| 129 | +--- |
| 130 | + |
| 131 | +## Running the Example Locally |
| 132 | + |
| 133 | +1. **Install deps** (from the repo root): |
| 134 | + |
| 135 | +```bash |
| 136 | +pnpm i # or npm install / yarn |
| 137 | +``` |
| 138 | + |
| 139 | +2. **Set environment variables** – create a `.env.local` file in `examples/next-account-checkout`: |
| 140 | + |
| 141 | +``` |
| 142 | +NEXT_PUBLIC_EPCC_ENDPOINT_URL=https://euwest.api.elasticpath.com |
| 143 | +NEXT_PUBLIC_EPCC_CLIENT_ID=your_client_id |
| 144 | +NEXT_PUBLIC_PASSWORD_PROFILE_ID=your_password_profile_id |
| 145 | +NEXT_PUBLIC_APP_URL=http://localhost:3000 |
| 146 | +``` |
| 147 | + |
| 148 | +3. **Start Next.js dev server**: |
| 149 | + |
| 150 | +```bash |
| 151 | +pnpm --filter next-account-checkout dev |
| 152 | +``` |
| 153 | + |
| 154 | +4. **Set up password profile** in your EPCC account to enable authentication. |
| 155 | + |
| 156 | +### Authentication Flow |
| 157 | + |
| 158 | +## Key Components |
| 159 | + |
| 160 | +- `CartProvider`: Initializes cart with account context and manages authentication state |
| 161 | +- `CartView`: Displays cart contents, shipping options, and promotion code management |
| 162 | +- `CheckoutView`: Account checkout form with server-side validation |
| 163 | +- `ProductGrid`: Product display with secure add-to-cart operations |
| 164 | +- Server Actions: Secure cart/checkout operations using account tokens |
| 165 | + |
| 166 | +## Authentication Flow |
| 167 | + |
| 168 | +1. **Login**: Users authenticate via account member API |
| 169 | +2. **Token Storage**: Account tokens stored in HttpOnly cookies (server-side only) |
| 170 | +3. **Cart Association**: Cart operations use account tokens for enhanced security |
| 171 | +4. **Protected Checkout**: Checkout requires authentication and uses account privileges |
| 172 | +5. **Session Management**: Automatic token refresh and secure session handling |
| 173 | + |
| 174 | +## Security Considerations |
| 175 | + |
| 176 | +- **Account tokens** provide elevated permissions compared to implicit tokens |
| 177 | +- **Server-side operations** prevent token exposure to client |
| 178 | +- **HttpOnly cookies** protect against XSS attacks |
| 179 | +- **Server actions** ensure secure cart/checkout processing |
| 180 | +- **Form validation** performed on both client and server |
| 181 | + |
| 182 | +## Learn More |
| 183 | + |
| 184 | +To learn more about EPCC account authentication, visit the [Elastic Path documentation](https://documentation.elasticpath.com/commerce-cloud/docs/developer/authentication/index.html). |
0 commit comments