# Setup Wizard Design Document ## Overview A guided onboarding experience for new WooNooW stores, helping merchants configure essential settings in 5-10 minutes. ## Goals 1. **Fast Setup** - Get store operational in < 10 minutes 2. **Smart Defaults** - Pre-configure based on location/industry 3. **Progressive** - Can skip and complete later 4. **Educational** - Teach key concepts without overwhelming --- ## Wizard Flow (5 Steps) ### Step 1: Store Basics (2 min) **Purpose:** Essential store identity **Fields:** - Store name (required) - Store email (required) - Country (required) → Auto-detects currency, timezone - Industry (optional) → Suggests products/categories **Smart Defaults:** - Currency from country - Timezone from country - Language from browser **Skip:** ❌ Cannot skip (required for operation) --- ### Step 2: Payments (2 min) **Purpose:** Enable at least one payment method **Options:** 1. **Quick Start (Recommended)** - Enable manual methods (Bank Transfer, COD) - "Set up Stripe later" button 2. **Connect Payment Provider** - Stripe (OAuth flow) - PayPal (OAuth flow) - Other providers **Smart Defaults:** - Bank Transfer: Enabled - Cash on Delivery: Enabled if physical products **Skip:** ⚠️ Warning: "Customers won't be able to checkout" --- ### Step 3: Shipping (2 min) **Purpose:** Configure basic shipping **Options:** 1. **Simple Shipping** - Flat rate for domestic - Flat rate for international - Free shipping threshold (optional) 2. **Advanced Setup** - Multiple zones - Calculated rates - Carrier integrations **Smart Defaults:** - Domestic zone: Country from Step 1 - Flat rate: $10 (or currency equivalent) **Skip:** ⚠️ Warning: "Only for digital products" --- ### Step 4: Taxes (1 min) **Purpose:** Basic tax compliance **Options:** 1. **Auto-calculate** (Recommended) - Based on customer location - Standard rates from database 2. **Manual rates** - Set fixed percentage - Per-country rates 3. **No taxes** - For tax-exempt stores **Smart Defaults:** - Auto-calculate: ON - Tax rate from country (e.g., 10% for Indonesia VAT) **Skip:** ✅ Can skip (configure later) --- ### Step 5: First Product (3 min) **Purpose:** Create sample product to test checkout **Options:** 1. **Create Sample Product** (Recommended) - Pre-filled with dummy data - Can edit or delete later - Helps test checkout flow 2. **Import Products** - CSV upload - WooCommerce import 3. **Skip for now** - Add products later **Smart Defaults:** - Sample product based on industry from Step 1 **Skip:** ✅ Can skip --- ## Technical Architecture ### Frontend Components ``` /routes/Setup/ ├── index.tsx # Wizard container ├── StepProgress.tsx # Progress indicator (1/5, 2/5, etc) ├── steps/ │ ├── StoreBasics.tsx │ ├── Payments.tsx │ ├── Shipping.tsx │ ├── Taxes.tsx │ └── FirstProduct.tsx └── Complete.tsx # Success screen ``` ### Backend API ```php // REST API Endpoints POST /woonoow/v1/setup/store-basics POST /woonoow/v1/setup/payments POST /woonoow/v1/setup/shipping POST /woonoow/v1/setup/taxes POST /woonoow/v1/setup/first-product POST /woonoow/v1/setup/complete // Option to track wizard state update_option('wnw_setup_completed', true); update_option('wnw_setup_step', 3); // Current step ``` ### State Management ```typescript // Zustand store for wizard state interface SetupState { currentStep: number; completed: boolean; data: { storeBasics: StoreBasicsData; payments: PaymentsData; shipping: ShippingData; taxes: TaxesData; firstProduct: ProductData; }; goToStep: (step: number) => void; saveStep: (step: string, data: any) => Promise; completeSetup: () => Promise; } ``` --- ## Payment Provider Integration ### Architecture **Problem:** How to support payment addons (Stripe, PayPal, Xendit, Midtrans, etc)? **Solution:** WordPress filter hooks + React components ### Backend: Payment Provider Registry ```php 'bacs', 'name' => 'Bank Transfer (BACS)', 'type' => 'manual', 'enabled' => true, 'icon' => 'banknote', ], [ 'id' => 'cod', 'name' => 'Cash on Delivery', 'type' => 'manual', 'enabled' => true, 'icon' => 'banknote', ], ]; /** * Filter: Allow addons to register payment providers * * @param array $providers List of payment providers * * Example addon usage: * add_filter('woonoow_payment_providers', function($providers) { * $providers[] = [ * 'id' => 'stripe', * 'name' => 'Stripe Payments', * 'type' => 'gateway', * 'description' => 'Accept Visa, Mastercard, Amex', * 'icon' => 'credit-card', * 'enabled' => false, * 'connected' => false, * 'setup_url' => admin_url('admin.php?page=wc-settings&tab=checkout§ion=stripe'), * 'component_url' => plugins_url('build/stripe-settings.js', __FILE__), * 'fees' => '2.9% + $0.30 per transaction', * ]; * return $providers; * }); */ return apply_filters('woonoow_payment_providers', $providers); } /** * Get provider configuration */ public static function get_provider_config(string $provider_id): array { $providers = self::get_providers(); foreach ($providers as $provider) { if ($provider['id'] === $provider_id) { return $provider; } } return []; } /** * Save provider settings */ public static function save_provider_settings(string $provider_id, array $settings): bool { // Save to WooCommerce payment gateway settings $gateway = WC()->payment_gateways()->payment_gateways()[$provider_id] ?? null; if ($gateway) { foreach ($settings as $key => $value) { $gateway->update_option($key, $value); } return true; } return false; } } ``` ### REST API Endpoint ```php 'GET', 'callback' => [self::class, 'get_providers'], 'permission_callback' => [self::class, 'check_permission'], ]); register_rest_route('woonoow/v1', '/payments/providers/(?P[a-zA-Z0-9_-]+)', [ 'methods' => 'POST', 'callback' => [self::class, 'save_provider'], 'permission_callback' => [self::class, 'check_permission'], ]); } public static function get_providers(WP_REST_Request $request) { $providers = PaymentProviderRegistry::get_providers(); return rest_ensure_response($providers); } public static function save_provider(WP_REST_Request $request) { $provider_id = $request->get_param('id'); $settings = $request->get_json_params(); $success = PaymentProviderRegistry::save_provider_settings($provider_id, $settings); if ($success) { return rest_ensure_response(['success' => true]); } return new WP_Error('save_failed', 'Failed to save provider settings', ['status' => 500]); } } ``` ### Frontend: Dynamic Provider Loading ```typescript // src/routes/Settings/Payments.tsx import { useQuery } from '@tanstack/react-query'; import { api } from '@/lib/api'; export default function PaymentsPage() { // Fetch providers from API (includes addon providers) const { data: providers = [], isLoading } = useQuery({ queryKey: ['payment-providers'], queryFn: () => api.get('/payments/providers'), }); return ( {/* Manual Methods */} {providers .filter(p => p.type === 'manual') .map(provider => ( ))} {/* Payment Gateways */} {providers .filter(p => p.type === 'gateway') .map(provider => ( ))} ); } ``` ### Addon Example: Stripe Integration ```php 'stripe', 'name' => 'Stripe Payments', 'type' => 'gateway', 'description' => 'Accept Visa, Mastercard, Amex, and more', 'icon' => 'credit-card', 'enabled' => $stripe_settings['enabled'] === 'yes', 'connected' => !empty($stripe_settings['publishable_key']), 'setup_url' => admin_url('admin.php?page=wc-settings&tab=checkout§ion=stripe'), 'component_url' => plugins_url('build/stripe-settings.js', __FILE__), 'fees' => '2.9% + $0.30 per transaction', 'test_mode' => $stripe_settings['testmode'] === 'yes', ]; return $providers; }); ``` --- ## Shipping Methods Integration ### Backend: Shipping Method Registry ```php get_shipping_methods(); $zone_methods = []; foreach ($methods as $method) { $zone_methods[] = [ 'id' => $method->id, 'instance_id' => $method->instance_id, 'title' => $method->title, 'enabled' => $method->enabled === 'yes', 'method_id' => $method->id, 'settings' => $method->instance_settings, ]; } $zones_data[] = [ 'id' => $zone['id'], 'name' => $zone['zone_name'], 'regions' => $zone['formatted_zone_location'], 'methods' => $zone_methods, ]; } /** * Filter: Allow addons to modify shipping zones * * @param array $zones_data List of shipping zones with methods * * Example addon usage: * add_filter('woonoow_shipping_zones', function($zones) { * // Add custom shipping method to each zone * foreach ($zones as &$zone) { * $zone['methods'][] = [ * 'id' => 'custom_shipping', * 'title' => 'Custom Shipping', * 'enabled' => true, * 'component_url' => plugins_url('build/custom-shipping.js', __FILE__), * ]; * } * return $zones; * }); */ return apply_filters('woonoow_shipping_zones', $zones_data); } /** * Get available shipping methods (for adding to zones) */ public static function get_available_methods(): array { $wc_methods = WC()->shipping()->get_shipping_methods(); $methods = []; foreach ($wc_methods as $method) { $methods[] = [ 'id' => $method->id, 'title' => $method->method_title, 'description' => $method->method_description, ]; } /** * Filter: Allow addons to register custom shipping methods */ return apply_filters('woonoow_available_shipping_methods', $methods); } } ``` ### REST API Endpoint ```php 'GET', 'callback' => [self::class, 'get_zones'], 'permission_callback' => [self::class, 'check_permission'], ]); register_rest_route('woonoow/v1', '/shipping/methods', [ 'methods' => 'GET', 'callback' => [self::class, 'get_methods'], 'permission_callback' => [self::class, 'check_permission'], ]); } public static function get_zones(WP_REST_Request $request) { $zones = ShippingMethodRegistry::get_zones(); return rest_ensure_response($zones); } public static function get_methods(WP_REST_Request $request) { $methods = ShippingMethodRegistry::get_available_methods(); return rest_ensure_response($methods); } } ``` ### Frontend: Dynamic Shipping Loading ```typescript // src/routes/Settings/Shipping.tsx import { useQuery } from '@tanstack/react-query'; import { api } from '@/lib/api'; export default function ShippingPage() { // Fetch zones from API (includes addon methods) const { data: zones = [], isLoading } = useQuery({ queryKey: ['shipping-zones'], queryFn: () => api.get('/shipping/zones'), }); return ( {/* Shipping Zones */} {zones.map(zone => ( ))} ); } ``` --- ## Implementation Timeline ### Phase 1: Foundation (Week 1) - [ ] Create PaymentProviderRegistry.php - [ ] Create ShippingMethodRegistry.php - [ ] Add REST API endpoints - [ ] Update Payments.tsx to use API - [ ] Update Shipping.tsx to use API ### Phase 2: Setup Wizard (Week 2) - [ ] Create wizard UI components - [ ] Implement 5-step flow - [ ] Add smart defaults - [ ] Add skip logic - [ ] Create completion screen ### Phase 3: Addon Support (Week 3) - [ ] Document filter hooks - [ ] Create example addons - [ ] Test with real payment gateways - [ ] Test with shipping plugins ### Phase 4: Polish (Week 4) - [ ] Add animations/transitions - [ ] Improve error handling - [ ] Add help documentation - [ ] User testing & feedback --- ## Success Metrics 1. **Setup Time** - < 10 minutes average 2. **Completion Rate** - > 80% complete wizard 3. **Payment Setup** - > 90% enable at least one method 4. **Shipping Setup** - > 70% configure shipping 5. **First Sale** - < 24 hours after setup --- ## Future Enhancements 1. **AI-Powered Suggestions** - Detect industry from store name - Suggest products based on industry - Recommend payment methods by country 2. **Video Tutorials** - Embedded help videos - Step-by-step guides 3. **Templates** - Pre-configured setups by industry - "Fashion Store", "Digital Products", etc. 4. **Import Wizards** - Import from Shopify - Import from WooCommerce - Import from CSV --- ## Questions & Answers ### Q: How do payment addons register themselves? **A:** Use the `woonoow_payment_providers` filter hook to add providers to the list. The addon provides metadata (name, icon, fees) and optionally a React component URL for custom settings UI. ### Q: Can addons have custom settings UI? **A:** Yes! Addons can provide a `component_url` that points to a React component. WooNooW will dynamically load and render it in the settings page. ### Q: How does the wizard handle incomplete setup? **A:** The wizard saves progress at each step. Users can exit and resume later. A dashboard banner reminds them to complete setup. ### Q: Can merchants skip the wizard? **A:** Yes, but they'll see a persistent banner until they complete essential steps (store basics, at least one payment method). ### Q: How do we handle payment gateway OAuth flows? **A:** Payment addons provide a `setup_url` that can be an OAuth redirect. After completion, the addon updates its connection status via the API.