diff --git a/SETUP_WIZARD_DESIGN.md b/SETUP_WIZARD_DESIGN.md new file mode 100644 index 0000000..21471e8 --- /dev/null +++ b/SETUP_WIZARD_DESIGN.md @@ -0,0 +1,614 @@ +# 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. diff --git a/admin-spa/src/routes/Settings/Payments.tsx b/admin-spa/src/routes/Settings/Payments.tsx index 26a5778..64d9b73 100644 --- a/admin-spa/src/routes/Settings/Payments.tsx +++ b/admin-spa/src/routes/Settings/Payments.tsx @@ -65,21 +65,51 @@ export default function PaymentsPage() { description="Manage how you get paid" onSave={handleSave} > - {/* Test Mode Banner */} - {testMode && ( -
-
- - ⚠️ Test Mode Active - - - No real charges will be processed - -
+ {/* Manual Payment Methods - First priority */} + +
+ {manualMethods.map((method) => ( +
+
+
+
+ +
+
+

{method.name}

+ {method.enabled && ( +

+ Customers can choose this at checkout +

+ )} +
+
+
+ {method.enabled && ( + + )} + toggleManualMethod(method.id)} + /> +
+
+
+ ))}
- )} +
- {/* Payment Providers */} + {/* Payment Providers - Second priority */} - {/* Manual Payment Methods */} - -
- {manualMethods.map((method) => ( -
-
-
-
- -
-
-

{method.name}

- {method.enabled && ( -

- Customers can choose this at checkout -

- )} -
-
-
- {method.enabled && ( - - )} - toggleManualMethod(method.id)} - /> -
-
-
- ))} -
-
- - {/* Payment Settings */} + {/* Payment Settings - Third priority (test mode, capture, etc) */} + {/* Test Mode Banner */} + {testMode && ( +
+
+ + ⚠️ Test Mode Active + + + No real charges will be processed + +
+
+ )} + )} - {/* Content */} -
+ {/* Content - Full width like Orders/Dashboard */} +
{!onSave && (

{title}

@@ -68,13 +68,12 @@ export function SettingsLayout({ )}
)} - {isLoading ? (
) : ( -
{children}
+
{children}
)}