feat: Implement centralized module management system
- Add ModuleRegistry for managing built-in modules (newsletter, wishlist, affiliate, subscription, licensing) - Add ModulesController REST API for module enable/disable - Create Modules settings page with category grouping and toggle controls - Integrate module checks across admin-spa and customer-spa - Add useModules hook for both SPAs to check module status - Hide newsletter from footer builder when module disabled - Hide wishlist features when module disabled (product cards, account menu, wishlist page) - Protect wishlist API endpoints with module checks - Auto-update navigation tree when modules toggled - Clean up obsolete documentation files - Add comprehensive documentation: - MODULE_SYSTEM_IMPLEMENTATION.md - MODULE_INTEGRATION_SUMMARY.md - ADDON_MODULE_INTEGRATION.md (proposal) - ADDON_MODULE_DESIGN_DECISIONS.md (design doc) - FEATURE_ROADMAP.md - SHIPPING_INTEGRATION.md Module system provides: - Centralized enable/disable for all features - Automatic navigation updates - Frontend/backend integration - Foundation for addon-module unification
This commit is contained in:
322
SHIPPING_INTEGRATION.md
Normal file
322
SHIPPING_INTEGRATION.md
Normal file
@@ -0,0 +1,322 @@
|
||||
# Shipping Integration Guide
|
||||
|
||||
This document consolidates shipping integration patterns and addon specifications for WooNooW.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
WooNooW supports flexible shipping integration through:
|
||||
1. **Standard WooCommerce Shipping Methods** - Works with any WC shipping plugin
|
||||
2. **Custom Shipping Addons** - Build shipping addons using WooNooW addon bridge
|
||||
3. **Indonesian Shipping** - Special handling for Indonesian address systems
|
||||
|
||||
---
|
||||
|
||||
## Indonesian Shipping Challenges
|
||||
|
||||
### RajaOngkir Integration Issue
|
||||
|
||||
**Problem**: RajaOngkir plugin doesn't use standard WooCommerce address fields.
|
||||
|
||||
#### How RajaOngkir Works:
|
||||
|
||||
1. **Removes Standard Fields:**
|
||||
```php
|
||||
// class-cekongkir.php
|
||||
public function customize_checkout_fields($fields) {
|
||||
unset($fields['billing']['billing_state']);
|
||||
unset($fields['billing']['billing_city']);
|
||||
unset($fields['shipping']['shipping_state']);
|
||||
unset($fields['shipping']['shipping_city']);
|
||||
return $fields;
|
||||
}
|
||||
```
|
||||
|
||||
2. **Adds Custom Destination Dropdown:**
|
||||
```php
|
||||
<select id="cart-destination" name="cart_destination">
|
||||
<option>Search and select location...</option>
|
||||
</select>
|
||||
```
|
||||
|
||||
3. **Stores in Session:**
|
||||
```php
|
||||
WC()->session->set('selected_destination_id', $destination_id);
|
||||
WC()->session->set('selected_destination_label', $destination_label);
|
||||
```
|
||||
|
||||
4. **Triggers Shipping Calculation:**
|
||||
```php
|
||||
WC()->cart->calculate_shipping();
|
||||
WC()->cart->calculate_totals();
|
||||
```
|
||||
|
||||
#### Why Standard Implementation Fails:
|
||||
|
||||
- WooNooW OrderForm uses standard fields: `city`, `state`, `postcode`
|
||||
- RajaOngkir ignores these fields
|
||||
- RajaOngkir only reads from session: `selected_destination_id`
|
||||
|
||||
#### Solution:
|
||||
|
||||
Use **Biteship** instead (see below) or create custom RajaOngkir addon that:
|
||||
- Hooks into WooNooW OrderForm
|
||||
- Adds Indonesian address selector
|
||||
- Syncs with RajaOngkir session
|
||||
|
||||
---
|
||||
|
||||
## Biteship Integration Addon
|
||||
|
||||
### Plugin Specification
|
||||
|
||||
**Plugin Name:** WooNooW Indonesia Shipping
|
||||
**Description:** Indonesian shipping integration using Biteship Rate API
|
||||
**Version:** 1.0.0
|
||||
**Requires:** WooNooW 1.0.0+, WooCommerce 8.0+
|
||||
|
||||
### Features
|
||||
|
||||
- ✅ Indonesian address fields (Province, City, District, Subdistrict)
|
||||
- ✅ Real-time shipping rate calculation
|
||||
- ✅ Multiple courier support (JNE, SiCepat, J&T, AnterAja, etc.)
|
||||
- ✅ Works in frontend checkout AND admin order form
|
||||
- ✅ No subscription required (uses free Biteship Rate API)
|
||||
|
||||
### Implementation Phases
|
||||
|
||||
#### Phase 1: Core Functionality
|
||||
- WooCommerce Shipping Method integration
|
||||
- Biteship Rate API integration
|
||||
- Indonesian address database (Province → Subdistrict)
|
||||
- Frontend checkout integration
|
||||
- Admin settings page
|
||||
|
||||
#### Phase 2: SPA Integration
|
||||
- REST API endpoints for address data
|
||||
- REST API for rate calculation
|
||||
- React components (SubdistrictSelector, CourierSelector)
|
||||
- Hook integration with WooNooW OrderForm
|
||||
- Admin order form support
|
||||
|
||||
#### Phase 3: Advanced Features
|
||||
- Rate caching (reduce API calls)
|
||||
- Custom rate markup
|
||||
- Free shipping threshold
|
||||
- Multi-origin support
|
||||
- Shipping label generation (optional, requires paid Biteship plan)
|
||||
|
||||
### Plugin Structure
|
||||
|
||||
```
|
||||
woonoow-indonesia-shipping/
|
||||
├── woonoow-indonesia-shipping.php
|
||||
├── includes/
|
||||
│ ├── class-shipping-method.php
|
||||
│ ├── class-biteship-api.php
|
||||
│ ├── class-address-database.php
|
||||
│ └── class-rest-controller.php
|
||||
├── admin/
|
||||
│ ├── class-settings.php
|
||||
│ └── views/
|
||||
├── assets/
|
||||
│ ├── js/
|
||||
│ │ ├── checkout.js
|
||||
│ │ └── admin-order.js
|
||||
│ └── css/
|
||||
└── data/
|
||||
└── indonesia-addresses.json
|
||||
```
|
||||
|
||||
### API Integration
|
||||
|
||||
#### Biteship Rate API Endpoint
|
||||
```
|
||||
POST https://api.biteship.com/v1/rates/couriers
|
||||
```
|
||||
|
||||
**Request:**
|
||||
```json
|
||||
{
|
||||
"origin_area_id": "IDNP6IDNC148IDND1820IDZ16094",
|
||||
"destination_area_id": "IDNP9IDNC235IDND3256IDZ41551",
|
||||
"couriers": "jne,sicepat,jnt",
|
||||
"items": [
|
||||
{
|
||||
"name": "Product Name",
|
||||
"value": 100000,
|
||||
"weight": 1000,
|
||||
"quantity": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"object": "courier_pricing",
|
||||
"pricing": [
|
||||
{
|
||||
"courier_name": "JNE",
|
||||
"courier_service_name": "REG",
|
||||
"price": 15000,
|
||||
"duration": "2-3 days"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### React Components
|
||||
|
||||
#### SubdistrictSelector Component
|
||||
```tsx
|
||||
interface SubdistrictSelectorProps {
|
||||
value: {
|
||||
province_id: string;
|
||||
city_id: string;
|
||||
district_id: string;
|
||||
subdistrict_id: string;
|
||||
};
|
||||
onChange: (value: any) => void;
|
||||
}
|
||||
|
||||
export function SubdistrictSelector({ value, onChange }: SubdistrictSelectorProps) {
|
||||
// Cascading dropdowns: Province → City → District → Subdistrict
|
||||
// Uses WooNooW API: /woonoow/v1/shipping/indonesia/provinces
|
||||
}
|
||||
```
|
||||
|
||||
#### CourierSelector Component
|
||||
```tsx
|
||||
interface CourierSelectorProps {
|
||||
origin: string;
|
||||
destination: string;
|
||||
items: CartItem[];
|
||||
onSelect: (courier: ShippingRate) => void;
|
||||
}
|
||||
|
||||
export function CourierSelector({ origin, destination, items, onSelect }: CourierSelectorProps) {
|
||||
// Fetches rates from Biteship
|
||||
// Displays courier options with prices
|
||||
// Uses WooNooW API: /woonoow/v1/shipping/indonesia/rates
|
||||
}
|
||||
```
|
||||
|
||||
### Hook Integration
|
||||
|
||||
```php
|
||||
// Register shipping addon
|
||||
add_filter('woonoow/shipping/address_fields', function($fields) {
|
||||
if (get_option('woonoow_indonesia_shipping_enabled')) {
|
||||
return [
|
||||
'province' => [
|
||||
'type' => 'select',
|
||||
'label' => 'Province',
|
||||
'required' => true,
|
||||
],
|
||||
'city' => [
|
||||
'type' => 'select',
|
||||
'label' => 'City',
|
||||
'required' => true,
|
||||
],
|
||||
'district' => [
|
||||
'type' => 'select',
|
||||
'label' => 'District',
|
||||
'required' => true,
|
||||
],
|
||||
'subdistrict' => [
|
||||
'type' => 'select',
|
||||
'label' => 'Subdistrict',
|
||||
'required' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
return $fields;
|
||||
});
|
||||
|
||||
// Register React component
|
||||
add_filter('woonoow/checkout/shipping_selector', function($component) {
|
||||
if (get_option('woonoow_indonesia_shipping_enabled')) {
|
||||
return 'IndonesiaShippingSelector';
|
||||
}
|
||||
return $component;
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## General Shipping Integration
|
||||
|
||||
### Standard WooCommerce Shipping
|
||||
|
||||
WooNooW automatically supports any WooCommerce shipping plugin that uses standard shipping methods:
|
||||
|
||||
- WooCommerce Flat Rate
|
||||
- WooCommerce Free Shipping
|
||||
- WooCommerce Local Pickup
|
||||
- Table Rate Shipping
|
||||
- Distance Rate Shipping
|
||||
- Any third-party shipping plugin
|
||||
|
||||
### Custom Shipping Addons
|
||||
|
||||
To create a custom shipping addon:
|
||||
|
||||
1. **Create WooCommerce Shipping Method**
|
||||
```php
|
||||
class Custom_Shipping_Method extends WC_Shipping_Method {
|
||||
public function calculate_shipping($package = []) {
|
||||
// Your shipping calculation logic
|
||||
$this->add_rate([
|
||||
'id' => $this->id,
|
||||
'label' => $this->title,
|
||||
'cost' => $cost,
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **Register with WooCommerce**
|
||||
```php
|
||||
add_filter('woocommerce_shipping_methods', function($methods) {
|
||||
$methods['custom_shipping'] = 'Custom_Shipping_Method';
|
||||
return $methods;
|
||||
});
|
||||
```
|
||||
|
||||
3. **Add SPA Integration (Optional)**
|
||||
```php
|
||||
// REST API for frontend
|
||||
register_rest_route('woonoow/v1', '/shipping/custom/rates', [
|
||||
'methods' => 'POST',
|
||||
'callback' => 'get_custom_shipping_rates',
|
||||
]);
|
||||
|
||||
// React component hook
|
||||
add_filter('woonoow/checkout/shipping_fields', function($fields) {
|
||||
// Add custom fields if needed
|
||||
return $fields;
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use Standard WC Fields** - Whenever possible, use standard WooCommerce address fields
|
||||
2. **Cache Rates** - Cache shipping rates to reduce API calls
|
||||
3. **Error Handling** - Always provide fallback rates if API fails
|
||||
4. **Mobile Friendly** - Ensure shipping selectors work well on mobile
|
||||
5. **Admin Support** - Make sure shipping works in admin order form too
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- [WooCommerce Shipping Method Tutorial](https://woocommerce.com/document/shipping-method-api/)
|
||||
- [Biteship API Documentation](https://biteship.com/docs)
|
||||
- [WooNooW Addon Development Guide](ADDON_DEVELOPMENT_GUIDE.md)
|
||||
- [WooNooW Hooks Registry](HOOKS_REGISTRY.md)
|
||||
Reference in New Issue
Block a user