docs: Comprehensive shipping addon integration research

Added SHIPPING_ADDON_RESEARCH.md with findings on:

## Key Insights:
1. **Standard vs Indonesian Plugins**
   - Standard: Simple settings, no custom fields
   - Indonesian: Complex API, custom checkout fields, subdistrict

2. **How Indonesian Plugins Work**
   - Add custom checkout fields (subdistrict)
   - Require origin configuration in wp-admin
   - Make real-time API calls during checkout
   - Calculate rates based on origin-destination pairing

3. **Why They're Complex**
   - 7,000+ subdistricts in Indonesia
   - Each courier has different rates per subdistrict
   - Can't pre-calculate (must use API)
   - Origin + destination required

## WooNooW Strategy:
 DO:
- Display all methods from WooCommerce API
- Show enable/disable toggle
- Show basic settings (title, cost, min_amount)
- Link to WooCommerce for complex config

 DON'T:
- Try to manage custom checkout fields
- Try to calculate rates
- Try to show all plugin settings
- Interfere with plugin functionality

## Next Steps:
1. Detect complex shipping plugins
2. Show different UI for complex methods
3. Add "Configure in WooCommerce" button
4. Hide settings form for complex methods

Result: Simplified UI for standard methods, full power for complex plugins!
This commit is contained in:
dwindown
2025-11-09 22:26:08 +07:00
parent d67055cce9
commit d1b2c6e562

371
SHIPPING_ADDON_RESEARCH.md Normal file
View File

@@ -0,0 +1,371 @@
# Shipping Addon Integration Research
## Problem Statement
Indonesian shipping plugins (Biteship, Woongkir, etc.) have complex requirements:
1. **Origin address** - configured in wp-admin
2. **Subdistrict field** - custom checkout field
3. **Real-time API calls** - during cart/checkout
4. **Custom field injection** - modify checkout form
**Question:** How can WooNooW SPA accommodate these plugins without breaking their functionality?
---
## How WooCommerce Shipping Addons Work
### Standard WooCommerce Pattern
```php
class My_Shipping_Method extends WC_Shipping_Method {
public function calculate_shipping($package = array()) {
// 1. Get settings from $this->get_option()
// 2. Calculate rates based on package
// 3. Call $this->add_rate($rate)
}
}
```
**Key Points:**
- ✅ Extends `WC_Shipping_Method`
- ✅ Uses WooCommerce hooks: `woocommerce_shipping_init`, `woocommerce_shipping_methods`
- ✅ Settings stored in `wp_options` table
- ✅ Rates calculated during `calculate_shipping()`
---
## Indonesian Shipping Plugins (Biteship, Woongkir, etc.)
### How They Differ from Standard Plugins
#### 1. **Custom Checkout Fields**
```php
// They add custom fields to checkout
add_filter('woocommerce_checkout_fields', function($fields) {
$fields['billing']['billing_subdistrict'] = array(
'type' => 'select',
'label' => 'Subdistrict',
'required' => true,
'options' => get_subdistricts() // API call
);
return $fields;
});
```
#### 2. **Origin Configuration**
- Stored in plugin settings (wp-admin)
- Used for API calls to calculate distance/cost
- Not exposed in standard WooCommerce shipping settings
#### 3. **Real-time API Calls**
```php
public function calculate_shipping($package) {
// Get origin from plugin settings
$origin = get_option('biteship_origin_subdistrict_id');
// Get destination from checkout field
$destination = $package['destination']['subdistrict_id'];
// Call external API
$rates = biteship_api_get_rates($origin, $destination, $weight);
foreach ($rates as $rate) {
$this->add_rate($rate);
}
}
```
#### 4. **AJAX Updates**
```javascript
// Update shipping when subdistrict changes
jQuery('#billing_subdistrict').on('change', function() {
jQuery('body').trigger('update_checkout');
});
```
---
## Why Indonesian Plugins Are Complex
### 1. **Geographic Complexity**
- Indonesia has **34 provinces**, **514 cities**, **7,000+ subdistricts**
- Shipping cost varies by subdistrict (not just city)
- Standard WooCommerce only has: Country → State → City → Postcode
### 2. **Multiple Couriers**
- Each courier has different rates per subdistrict
- Real-time API calls required (can't pre-calculate)
- Some couriers don't serve all subdistricts
### 3. **Origin-Destination Pairing**
- Cost depends on **origin subdistrict** + **destination subdistrict**
- Origin must be configured in admin
- Destination selected at checkout
---
## How WooNooW SPA Should Handle This
### ✅ **What WooNooW SHOULD Do**
#### 1. **Display Methods Correctly**
```typescript
// Our current approach is CORRECT
const { data: zones } = useQuery({
queryKey: ['shipping-zones'],
queryFn: () => api.get('/settings/shipping/zones')
});
```
- ✅ Fetch zones from WooCommerce API
- ✅ Display all methods (including Biteship, Woongkir)
- ✅ Show enable/disable toggle
- ✅ Link to WooCommerce settings for advanced config
#### 2. **Expose Basic Settings Only**
```typescript
// Show only common settings
- Display Name (title)
- Cost (if applicable)
- Min Amount (if applicable)
```
- ✅ Don't try to show ALL settings
- ✅ Complex settings → "Edit in WooCommerce" button
#### 3. **Respect Plugin Behavior**
- ✅ Don't interfere with checkout field injection
- ✅ Don't modify `calculate_shipping()` logic
- ✅ Let plugins handle their own API calls
---
### ❌ **What WooNooW SHOULD NOT Do**
#### 1. **Don't Try to Manage Custom Fields**
```typescript
// ❌ DON'T DO THIS
const subdistrictField = {
type: 'select',
options: await fetchSubdistricts()
};
```
- ❌ Subdistrict fields are managed by shipping plugins
- ❌ They inject fields via WooCommerce hooks
- ❌ WooNooW SPA doesn't control checkout page
#### 2. **Don't Try to Calculate Rates**
```typescript
// ❌ DON'T DO THIS
const rate = await biteshipAPI.getRates(origin, destination);
```
- ❌ Rate calculation is plugin-specific
- ❌ Requires API keys, origin config, etc.
- ❌ Should happen during checkout, not in admin
#### 3. **Don't Try to Show All Settings**
```typescript
// ❌ DON'T DO THIS
<Input label="Origin Subdistrict ID" />
<Input label="API Key" />
<Input label="Courier Selection" />
```
- ❌ Too complex for simplified UI
- ❌ Each plugin has different settings
- ❌ Better to link to WooCommerce settings
---
## Comparison: Global vs Indonesian Shipping
### Global Shipping Plugins (ShipStation, EasyPost, etc.)
**Characteristics:**
- ✅ Standard address fields (Country, State, City, Postcode)
- ✅ Pre-calculated rates or simple API calls
- ✅ No custom checkout fields needed
- ✅ Settings fit in standard WooCommerce UI
**Example: Flat Rate**
```php
public function calculate_shipping($package) {
$rate = array(
'label' => $this->title,
'cost' => $this->get_option('cost')
);
$this->add_rate($rate);
}
```
### Indonesian Shipping Plugins (Biteship, Woongkir, etc.)
**Characteristics:**
- ⚠️ Custom address fields (Province, City, District, **Subdistrict**)
- ⚠️ Real-time API calls with origin-destination pairing
- ⚠️ Custom checkout field injection
- ⚠️ Complex settings (API keys, origin config, courier selection)
**Example: Biteship**
```php
public function calculate_shipping($package) {
$origin_id = get_option('biteship_origin_subdistrict_id');
$dest_id = $package['destination']['subdistrict_id'];
$response = wp_remote_post('https://api.biteship.com/v1/rates', array(
'headers' => array('Authorization' => 'Bearer ' . $api_key),
'body' => json_encode(array(
'origin_area_id' => $origin_id,
'destination_area_id' => $dest_id,
'couriers' => $this->get_option('couriers'),
'items' => $package['contents']
))
));
$rates = json_decode($response['body'])->pricing;
foreach ($rates as $rate) {
$this->add_rate(array(
'label' => $rate->courier_name . ' - ' . $rate->courier_service_name,
'cost' => $rate->price
));
}
}
```
---
## Recommendations for WooNooW SPA
### ✅ **Current Approach is CORRECT**
Our simplified UI is perfect for:
1. **Standard shipping methods** (Flat Rate, Free Shipping, Local Pickup)
2. **Simple third-party plugins** (basic rate calculators)
3. **Non-tech users** who just want to enable/disable methods
### ✅ **For Complex Plugins (Biteship, Woongkir)**
**Strategy: "View-Only + Link to WooCommerce"**
```typescript
// In the accordion, show:
<AccordionItem>
<AccordionTrigger>
🚚 Biteship - JNE REG [On]
Rp 15,000 (calculated at checkout)
</AccordionTrigger>
<AccordionContent>
<Alert>
This is a complex shipping method with advanced settings.
<Button asChild>
<a href={wcAdminUrl + '/admin.php?page=biteship-settings'}>
Configure in WooCommerce
</a>
</Button>
</Alert>
{/* Only show basic toggle */}
<ToggleField
label="Enable/Disable"
value={method.enabled}
onChange={handleToggle}
/>
</AccordionContent>
</AccordionItem>
```
### ✅ **Detection Logic**
```typescript
// Detect if method is complex
const isComplexMethod = (method: ShippingMethod) => {
const complexPlugins = [
'biteship',
'woongkir',
'anteraja',
'shipper',
// Add more as needed
];
return complexPlugins.some(plugin =>
method.id.includes(plugin)
);
};
// Render accordingly
{isComplexMethod(method) ? (
<ComplexMethodView method={method} />
) : (
<SimpleMethodView method={method} />
)}
```
---
## Testing Strategy
### ✅ **What to Test in WooNooW SPA**
1. **Method Display**
- ✅ Biteship methods appear in zone list
- ✅ Enable/disable toggle works
- ✅ Method name displays correctly
2. **Settings Link**
- ✅ "Edit in WooCommerce" button works
- ✅ Opens correct settings page
3. **Don't Break Checkout**
- ✅ Subdistrict field still appears
- ✅ Rates calculate correctly
- ✅ AJAX updates work
### ❌ **What NOT to Test in WooNooW SPA**
1. ❌ Rate calculation accuracy
2. ❌ API integration
3. ❌ Subdistrict field functionality
4. ❌ Origin configuration
**These are the shipping plugin's responsibility!**
---
## Conclusion
### **WooNooW SPA's Role:**
**Simplified management** for standard shipping methods
**View-only + link** for complex plugins
**Don't interfere** with plugin functionality
### **Shipping Plugin's Role:**
✅ Handle complex settings (origin, API keys, etc.)
✅ Inject custom checkout fields
✅ Calculate rates via API
✅ Manage courier selection
### **Result:**
✅ Non-tech users can enable/disable methods easily
✅ Complex configuration stays in WooCommerce admin
✅ No functionality is lost
✅ Best of both worlds! 🎯
---
## Implementation Plan
### Phase 1: Detection (Current)
- [x] Display all methods from WooCommerce API
- [x] Show enable/disable toggle
- [x] Show basic settings (title, cost, min_amount)
### Phase 2: Complex Method Handling (Next)
- [ ] Detect complex shipping plugins
- [ ] Show different UI for complex methods
- [ ] Add "Configure in WooCommerce" button
- [ ] Hide settings form for complex methods
### Phase 3: Documentation (Final)
- [ ] Add help text explaining complex methods
- [ ] Link to plugin documentation
- [ ] Add troubleshooting guide
---
**Last Updated:** Nov 9, 2025
**Status:** Research Complete ✅