Files
WooNooW/SHIPPING_METHOD_TYPES.md
dwindown 8bebd3abe5 docs: Flag emoji strategy + Tax design + Shipping types
##  Issue #1: Flag Emoji Strategy (Research-Based)

Your comprehensive research revealed:
- Chrome on Windows does NOT render flag emojis
- Flags work for country selection (expected UX)
- Flags problematic for summary cards (political sensitivity)

**Action Taken:**
-  Removed flag from Store summary card
-  Changed to: "📍 Store Location: Indonesia"
-  Kept flags in dropdowns (country, currency)
-  Professional, accessible, future-proof

**Pattern:**
- Dropdowns: 🇮🇩 Indonesia (visual aid)
- Summary: 📍 Indonesia (neutral, professional)
- Shipping zones: Text only (clean, scalable)

##  Issue #2: Tax Settings Design

Created TAX_SETTINGS_DESIGN.md with:
- Toggle at top to enable/disable
- **Predefined rates based on store country**
- Indonesia: 11% (PPN) auto-shown
- Malaysia: 6% (SST) auto-shown
- Smart! No re-selecting country
- Zero learning curve

**User Flow:**
1. Enable tax toggle
2. See: "🇮🇩 Indonesia: 11% (Standard)"
3. Done! Tax working.

**For multi-country:**
1. Click "+ Add Tax Rate"
2. Select Malaysia
3. Auto-fills: 6%
4. Save. Done!

##  Issue #3: Shipping Method Types

Created SHIPPING_METHOD_TYPES.md documenting:

**Type 1: Static Methods** (WC Core)
- Free Shipping, Flat Rate, Local Pickup
- No API, immediate availability
- Basic address fields

**Type 2: Live Rate Methods** (API-based)
- UPS, FedEx, DHL (International)
- J&T, JNE, SiCepat (Indonesian)
- Requires "Calculate" button
- Returns service options

**Address Requirements:**
- International: Postal Code (required)
- Indonesian: Subdistrict (required)
- Static: Basic address only

**The Pattern:**
```
Static → Immediate display
Live Rate → Calculate → Service options → Select
```

**Next:** Fix Create Order to show conditional fields

## Documentation Added:
- TAX_SETTINGS_DESIGN.md
- SHIPPING_METHOD_TYPES.md

Both ready for implementation!
2025-11-10 11:23:42 +07:00

6.4 KiB

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

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

// 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

// 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