# Frontend Next Checkout

> Next.js e-commerce checkout: CheckoutClient, persisted draft store, RHF+Zod form, shipping, delivery slots, Stripe/Tabby/Tamara payments, order creation. Use when building or modifying checkout flow, payment, or order creation.

- Skill: `xmuhameed/frontend-next-checkout` (Agent Skill)
- Install (CLI): `npx skillmds@latest add xmuhameed/frontend-next-checkout`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xmuhameed/frontend-next-checkout/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: xmuhameed (https://skillmd.com/u/xmuhameed)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/xmuhameed/frontend-next-checkout

---


# Checkout Flow

## Routes

| Route | Mode |
|-------|------|
| `/[locale]/checkout` | `CheckoutClient mode="cart"` |
| `/[locale]/checkout/[orderId]` | `CheckoutClient mode="order"` (resume draft) |

`SiteChrome` hides header/footer on checkout paths.

## Architecture

```
features/checkout/  (or app/[locale]/checkout/)
├── CheckoutClient.tsx
├── store/checkout.store.ts      # Zustand persist: diaflower_new_checkout_draft
├── hooks/useCheckoutForm.ts     # RHF + Zod
├── hooks/useCheckoutPersistence.ts  # Debounced server sync
├── components/shipping/
├── components/delivery/
├── components/payment/
└── utils/payment-providers.ts
```

## Form (RHF + Zod)

```typescript
const form = useForm({
  resolver: zodResolver(checkoutFormSchema),
  mode: 'onBlur',
});
// Conditional refinements: recipient vs sender, address modes
```

## Persisted Draft Store

```typescript
// Zustand persist — form state, draftOrderId, payment method, shipping costs
persist(..., { name: 'diaflower_new_checkout_draft' })
```

Auto-save: debounced 1.5s → `OrderService.createNewCheckoutDraft` / `updateNewCheckoutDraft`

## Checkout Sections (order)

1. Express checkout (Stripe Apple/Google Pay)
2. Login prompt (guest checkout allowed)
3. Sender / Recipient info
4. Address picker (existing or new)
5. Delivery date + slot
6. Payment method selector
7. Order summary + promo code

## Payment Providers

| Provider | Files |
|----------|-------|
| Stripe card | `StripeCardSection.tsx`, `PayNowButton.tsx` |
| Stripe Express | `ExpressCheckoutButtons.tsx` |
| Tabby BNPL | `services/tabby.service.ts`, `useBnplEligibility` |
| Tamara BNPL | `services/tamara.service.ts` |
| COD | `utils/cod.ts` — region-gated |

`usePaymentProviders` merges server config + env fallbacks.

## Order Creation

```typescript
const result = await OrderService.createOrder(payload);
// Returns clientSecret (Stripe) or redirect URL (BNPL)
```

## Order Success

`/order-success` — clears cart, coupon, checkout draft; fires `trackPurchase` with dedup event ID.

## Region Checks

`shipping-compatibility.ts` — remove incompatible cart items before order.
`RegionConflictValidator` — block intl locale with local-only products.

## Env

`NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY`, `NEXT_PUBLIC_TABBY_*`, `NEXT_PUBLIC_API_BASE_URL`

