## Point 1: Addon Bridge Pattern ✅ Created ADDON_BRIDGE_PATTERN.md documenting: - WooNooW Core = Zero addon dependencies - Bridge snippet pattern for Rajaongkir compatibility - Proper addon development approach - Hook system usage **Key Decision:** - ❌ No Rajaongkir integration in core - ✅ Provide bridge snippets for compatibility - ✅ Encourage proper WooNooW addons - ✅ Keep core clean and maintainable --- ## Point 2: Calculation Efficiency Audit 🚨 CRITICAL Created CALCULATION_EFFICIENCY_AUDIT.md revealing: **BLOATED Implementation Found:** - 2 separate API calls (/shipping/calculate + /orders/preview) - Cart initialized TWICE - Shipping calculated TWICE - Taxes calculated TWICE - ~1000ms total time **Recommended Solution:** - Single /orders/calculate endpoint - ONE cart initialization - ONE calculation - ~300ms total time (70% faster!) - 50% fewer requests - 50% less server load **This is exactly what we discussed at the beginning:** > "WooCommerce is bloated because of separate requests. We need efficient flow that handles everything at once." **Current implementation repeats WooCommerce's mistake!** **Status:** ❌ NOT IMPLEMENTED YET **Priority:** 🚨 CRITICAL **Impact:** 🔥 HIGH - Performance bottleneck --- ## Point 3: Settings Placement Strategy ✅ Created SETTINGS_PLACEMENT_STRATEGY.md proposing: **No separate "WooNooW Settings" page.** Instead: - Store Logo → WooCommerce > Settings > General - Order Format → WooCommerce > Settings > Orders - Product Settings → WooCommerce > Settings > Products - UI Settings → WooCommerce > Settings > Admin UI (new tab) **Benefits:** - Contextual placement - Familiar to users - No clutter - Seamless integration - Feels native to WooCommerce **Philosophy:** WooNooW should feel like a native part of WooCommerce, not a separate plugin. --- ## Summary **Point 1:** ✅ Documented addon bridge pattern **Point 2:** 🚨 CRITICAL - Current calculation is bloated, needs refactoring **Point 3:** ✅ Settings placement strategy documented **Next Action Required:** Implement unified /orders/calculate endpoint to fix performance bottleneck.
8.4 KiB
Addon Bridge Pattern - Rajaongkir Example
Philosophy
WooNooW Core = Zero Addon Dependencies
We don't integrate specific addons into WooNooW core. Instead, we provide:
- Hook system for addons to extend functionality
- Bridge snippets for compatibility with existing plugins
- Addon development guide for building proper WooNooW addons
Problem: Rajaongkir Plugin
Rajaongkir is a WooCommerce plugin that:
- Removes standard address fields (city, state)
- Adds custom destination dropdown
- Stores data in WooCommerce session
- Works on WooCommerce checkout page
It doesn't work with WooNooW OrderForm because:
- OrderForm uses standard WooCommerce fields
- Rajaongkir expects session-based destination
- No destination = No shipping calculation
Solution: Bridge Snippet (Not Core Integration!)
Option A: Standalone Bridge Plugin
Create a tiny bridge plugin that makes Rajaongkir work with WooNooW:
<?php
/**
* Plugin Name: WooNooW Rajaongkir Bridge
* Description: Makes Rajaongkir plugin work with WooNooW OrderForm
* Version: 1.0.0
* Requires: WooNooW, Rajaongkir Official
*/
// Hook into WooNooW's shipping calculation
add_filter('woonoow_before_shipping_calculate', function($shipping_data) {
// If Indonesia and has city, convert to Rajaongkir destination
if ($shipping_data['country'] === 'ID' && !empty($shipping_data['city'])) {
// Search Rajaongkir API for destination
$api = Cekongkir_API::get_instance();
$results = $api->search_destination_api($shipping_data['city']);
if (!empty($results[0])) {
// Set Rajaongkir session data
WC()->session->set('selected_destination_id', $results[0]['id']);
WC()->session->set('selected_destination_label', $results[0]['text']);
}
}
return $shipping_data;
});
// Add Rajaongkir destination field to OrderForm via hook system
add_action('wp_enqueue_scripts', function() {
if (!is_admin()) return;
wp_enqueue_script(
'woonoow-rajaongkir-bridge',
plugin_dir_url(__FILE__) . 'dist/bridge.js',
['woonoow-admin'],
'1.0.0',
true
);
});
Frontend (bridge.js):
import { addonLoader, addFilter } from '@woonoow/hooks';
addonLoader.register({
id: 'rajaongkir-bridge',
name: 'Rajaongkir Bridge',
version: '1.0.0',
init: () => {
// Add destination search field after shipping address
addFilter('woonoow_order_form_after_shipping', (content, formData, setFormData) => {
// Only for Indonesia
if (formData.shipping?.country !== 'ID') return content;
return (
<>
{content}
<div className="border rounded-lg p-4 mt-4">
<h3 className="font-medium mb-3">📍 Shipping Destination</h3>
<RajaongkirDestinationSearch
value={formData.shipping?.destination_id}
onChange={(id, label) => {
setFormData({
...formData,
shipping: {
...formData.shipping,
destination_id: id,
destination_label: label,
}
});
}}
/>
</div>
</>
);
});
}
});
Option B: Code Snippet (No Plugin)
For users who don't want a separate plugin, provide a code snippet:
// Add to theme's functions.php or custom plugin
// Bridge Rajaongkir with WooNooW
add_filter('woonoow_shipping_data', function($data) {
if ($data['country'] === 'ID' && !empty($data['city'])) {
// Auto-search and set destination
$api = Cekongkir_API::get_instance();
$results = $api->search_destination_api($data['city']);
if (!empty($results[0])) {
WC()->session->set('selected_destination_id', $results[0]['id']);
}
}
return $data;
});
Proper Solution: Build WooNooW Addon
Instead of bridging Rajaongkir, build a proper WooNooW addon:
WooNooW Indonesia Shipping Addon
<?php
/**
* Plugin Name: WooNooW Indonesia Shipping
* Description: Indonesia shipping with Rajaongkir API
* Version: 1.0.0
* Requires: WooNooW 1.0.0+
*/
// Register addon
add_filter('woonoow/addon_registry', function($addons) {
$addons['indonesia-shipping'] = [
'id' => 'indonesia-shipping',
'name' => 'Indonesia Shipping',
'version' => '1.0.0',
'spa_bundle' => plugin_dir_url(__FILE__) . 'dist/addon.js',
'dependencies' => ['woocommerce' => '8.0'],
];
return $addons;
});
// Add API endpoints
add_action('rest_api_init', function() {
register_rest_route('woonoow/v1', '/indonesia/search-destination', [
'methods' => 'GET',
'callback' => function($req) {
$query = $req->get_param('query');
$api = new RajaongkirAPI(get_option('rajaongkir_api_key'));
return $api->searchDestination($query);
},
]);
register_rest_route('woonoow/v1', '/indonesia/calculate-shipping', [
'methods' => 'POST',
'callback' => function($req) {
$origin = $req->get_param('origin');
$destination = $req->get_param('destination');
$weight = $req->get_param('weight');
$api = new RajaongkirAPI(get_option('rajaongkir_api_key'));
return $api->calculateShipping($origin, $destination, $weight);
},
]);
});
Frontend:
// dist/addon.ts
import { addonLoader, addFilter } from '@woonoow/hooks';
import { DestinationSearch } from './components/DestinationSearch';
addonLoader.register({
id: 'indonesia-shipping',
name: 'Indonesia Shipping',
version: '1.0.0',
init: () => {
// Add destination field
addFilter('woonoow_order_form_after_shipping', (content, formData, setFormData) => {
if (formData.shipping?.country !== 'ID') return content;
return (
<>
{content}
<DestinationSearch
value={formData.shipping?.destination_id}
onChange={(id, label) => {
setFormData({
...formData,
shipping: { ...formData.shipping, destination_id: id, destination_label: label }
});
}}
/>
</>
);
});
// Add validation
addFilter('woonoow_order_form_validation', (errors, formData) => {
if (formData.shipping?.country === 'ID' && !formData.shipping?.destination_id) {
errors.destination = 'Please select shipping destination';
}
return errors;
});
}
});
Comparison
Bridge Snippet (Quick Fix)
✅ Works immediately ✅ No new plugin needed ✅ Minimal code ❌ Depends on Rajaongkir plugin ❌ Limited features ❌ Not ideal UX
Proper WooNooW Addon (Best Practice)
✅ Native WooNooW integration ✅ Better UX ✅ More features ✅ Independent of Rajaongkir plugin ✅ Can use any shipping API ❌ More development effort ❌ Separate plugin to maintain
Recommendation
For WooNooW Core:
- ❌ Don't integrate Rajaongkir
- ✅ Provide hook system
- ✅ Document bridge pattern
- ✅ Provide code snippets
For Users:
- Quick fix: Use bridge snippet
- Best practice: Build proper addon or use community addon
For Community:
- Build "WooNooW Indonesia Shipping" addon
- Publish on WordPress.org
- Support Rajaongkir, Biteship, and other Indonesian shipping APIs
Hook Points Needed in WooNooW Core
To support addons like this, WooNooW core should provide:
// Before shipping calculation
apply_filters('woonoow_before_shipping_calculate', $shipping_data);
// After shipping calculation
apply_filters('woonoow_after_shipping_calculate', $rates, $shipping_data);
// Modify shipping data
apply_filters('woonoow_shipping_data', $data);
// Frontend hooks
'woonoow_order_form_after_shipping'
'woonoow_order_form_shipping_fields'
'woonoow_order_form_validation'
'woonoow_order_form_submit'
These hooks already exist in our addon system!
Conclusion
WooNooW Core = Zero addon dependencies
Instead of integrating Rajaongkir into core:
- Provide hook system ✅ (Already done)
- Document bridge pattern ✅ (This document)
- Encourage community addons ✅
This keeps WooNooW core:
- Clean
- Maintainable
- Flexible
- Extensible
Users can choose:
- Bridge snippet (quick fix)
- Proper addon (best practice)
- Build their own
No bloat in core!