# Shipping Method Types - WooCommerce Core Structure ## The Two Types of Shipping Methods WooCommerce has TWO fundamentally different shipping method types: --- ## Type 1: Static Methods (WooCommerce Core) **Characteristics:** - No API calls - Fixed rates or free - Configured once in settings - Available immediately **Examples:** - Free Shipping - Flat Rate - Local Pickup **Structure:** ``` Method: Free Shipping ├── Conditions: Order total > $50 └── Cost: $0 ``` **In Create Order:** ``` User fills address → Static methods appear immediately → User selects one → Done! ``` --- ## Type 2: Live Rate Methods (API-based) **Characteristics:** - Requires API call - Dynamic rates based on address + weight - Returns multiple service options - Needs "Calculate" button **Examples:** - UPS (International) - FedEx, DHL - Indonesian Shipping Addons (J&T, JNE, SiCepat) **Structure:** ``` Method: UPS Live Rates ├── API Credentials configured └── On calculate: ├── Service: UPS Ground - $15.00 ├── Service: UPS 2nd Day - $25.00 └── Service: UPS Next Day - $45.00 ``` **In Create Order:** ``` User fills address → Click "Calculate Shipping" → API returns service options → User selects one → Done! ``` --- ## The Real Hierarchy ### Static Method (Simple): ``` Method └── (No sub-levels) ``` ### Live Rate Method (Complex): ``` Method ├── Courier (if applicable) │ ├── Service Option 1 │ ├── Service Option 2 │ └── Service Option 3 └── Or directly: ├── Service Option 1 └── Service Option 2 ``` --- ## Indonesian Shipping Example **Method:** Indonesian Shipping (API-based) **API:** Biteship / RajaOngkir / Custom **After Calculate:** ``` J&T Express ├── Regular Service: Rp15,000 (2-3 days) └── Express Service: Rp25,000 (1 day) JNE ├── REG: Rp18,000 (2-4 days) ├── YES: Rp28,000 (1-2 days) └── OKE: Rp12,000 (3-5 days) SiCepat ├── Regular: Rp16,000 (2-3 days) └── BEST: Rp20,000 (1-2 days) ``` **User sees:** Courier name + Service name + Price + Estimate --- ## UPS Example (International) **Method:** UPS Live Rates **API:** UPS API **After Calculate:** ``` UPS Ground: $15.00 (5-7 business days) UPS 2nd Day Air: $25.00 (2 business days) UPS Next Day Air: $45.00 (1 business day) ``` **User sees:** Service name + Price + Estimate --- ## Address Field Requirements ### Static Methods: - Country - State/Province - City - Postal Code - Address Line 1 - Address Line 2 (optional) ### Live Rate Methods: **International (UPS, FedEx, DHL):** - Country - State/Province - City - **Postal Code** (REQUIRED - used for rate calculation) - Address Line 1 - Address Line 2 (optional) **Indonesian (J&T, JNE, SiCepat):** - Country: Indonesia - Province - City/Regency - **Subdistrict** (REQUIRED - used for rate calculation) - Postal Code - Address Line 1 - Address Line 2 (optional) --- ## The Pattern | Method Type | Address Requirement | Rate Calculation | |-------------|---------------------|------------------| | Static | Basic address | Fixed/Free | | Live Rate (International) | **Postal Code** required | API call with postal code | | Live Rate (Indonesian) | **Subdistrict** required | API call with subdistrict ID | --- ## Implementation in Create Order ### Current Problem: - We probably require subdistrict for ALL methods - This breaks international live rate methods ### Solution: **Step 1: Detect Available Methods** ```javascript const availableMethods = getShippingMethods(address.country); const needsSubdistrict = availableMethods.some(method => method.type === 'live_rate' && method.country === 'ID' ); const needsPostalCode = availableMethods.some(method => method.type === 'live_rate' && method.country !== 'ID' ); ``` **Step 2: Show Conditional Fields** ```javascript // Always show - Country - State/Province - City - Address Line 1 // Conditional if (needsSubdistrict) { - Subdistrict (required) } if (needsPostalCode || needsSubdistrict) { - Postal Code (required) } // Always optional - Address Line 2 ``` **Step 3: Calculate Shipping** ```javascript // Static methods if (method.type === 'static') { return method.cost; // Immediate } // Live rate methods if (method.type === 'live_rate') { const rates = await fetchLiveRates({ method: method.id, address: { country: address.country, state: address.state, city: address.city, subdistrict: address.subdistrict, // If Indonesian postal_code: address.postal_code, // If international // ... other fields } }); return rates; // Array of service options } ``` --- ## UI Flow ### Scenario 1: Static Method Only ``` 1. User fills basic address 2. Shipping options appear immediately: - Free Shipping: $0 - Flat Rate: $10 3. User selects one 4. Done! ``` ### Scenario 2: Indonesian Live Rate ``` 1. User fills address including subdistrict 2. Click "Calculate Shipping" 3. API returns: - J&T Regular: Rp15,000 - JNE REG: Rp18,000 - SiCepat BEST: Rp20,000 4. User selects one 5. Done! ``` ### Scenario 3: International Live Rate ``` 1. User fills address including postal code 2. Click "Calculate Shipping" 3. API returns: - UPS Ground: $15.00 - UPS 2nd Day: $25.00 4. User selects one 5. Done! ``` ### Scenario 4: Mixed (Static + Live Rate) ``` 1. User fills address 2. Static methods appear immediately: - Free Shipping: $0 3. Click "Calculate Shipping" for live rates 4. Live rates appear: - UPS Ground: $15.00 5. User selects from all options 6. Done! ``` --- ## WooCommerce Core Behavior **Yes, this is all in WooCommerce core!** - Static methods: `WC_Shipping_Method` class - Live rate methods: Extend `WC_Shipping_Method` with API logic - Service options: Stored as shipping rates with method_id + instance_id **WooCommerce handles:** - Method registration - Rate calculation - Service option display - Selection and storage **We need to handle:** - Conditional address fields - "Calculate" button for live rates - Service option display in Create Order - Proper address validation --- ## Next Steps 1. Investigate Create Order address field logic 2. Add conditional field display based on available methods 3. Add "Calculate Shipping" button for live rates 4. Display service options properly 5. Test with: - Static methods only - Indonesian live rates - International live rates - Mixed scenarios