# WooNooW Indonesia Shipping (Biteship Integration) ## Plugin Specification **Plugin Name:** WooNooW Indonesia Shipping **Description:** Simple Indonesian shipping integration using Biteship Rate API **Version:** 1.0.0 **Requires:** WooNooW 1.0.0+, WooCommerce 8.0+ **License:** GPL v2 or later --- ## Overview A lightweight shipping plugin that integrates Biteship's Rate API with WooNooW SPA, providing: - ✅ Indonesian address fields (Province, City, District, Subdistrict) - ✅ Real-time shipping rate calculation - ✅ Multiple courier support (JNE, SiCepat, J&T, AnterAja, etc.) - ✅ Works in both frontend checkout AND admin order form - ✅ No subscription required (uses free Biteship Rate API) --- ## Features Roadmap ### 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 # Main plugin file ├── includes/ │ ├── class-shipping-method.php # WooCommerce shipping method │ ├── class-biteship-api.php # Biteship API client │ ├── class-address-database.php # Indonesian address data │ ├── class-addon-integration.php # WooNooW addon integration │ └── Api/ │ └── AddressController.php # REST API endpoints ├── admin/ │ ├── class-settings.php # Admin settings page │ └── views/ │ └── settings-page.php # Settings UI ├── admin-spa/ │ ├── src/ │ │ ├── components/ │ │ │ ├── SubdistrictSelector.tsx # Address selector │ │ │ └── CourierSelector.tsx # Courier selection │ │ ├── hooks/ │ │ │ ├── useAddressData.ts # Fetch address data │ │ │ └── useRateCalculation.ts # Calculate rates │ │ └── index.ts # Addon registration │ ├── package.json │ └── vite.config.ts ├── data/ │ └── indonesia-areas.sql # Address database dump └── README.md ``` --- ## Database Schema ```sql CREATE TABLE `wp_woonoow_indonesia_areas` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `biteship_area_id` varchar(50) NOT NULL, `name` varchar(255) NOT NULL, `type` enum('province','city','district','subdistrict') NOT NULL, `parent_id` bigint(20) DEFAULT NULL, `postal_code` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`), KEY `biteship_area_id` (`biteship_area_id`), KEY `parent_id` (`parent_id`), KEY `type` (`type`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` --- ## WooCommerce Shipping Method ```php id = 'woonoow_indonesia_shipping'; $this->instance_id = absint($instance_id); $this->method_title = __('Indonesia Shipping', 'woonoow-indonesia-shipping'); $this->supports = array('shipping-zones', 'instance-settings'); $this->init(); } public function init_form_fields() { $this->instance_form_fields = array( 'api_key' => array( 'title' => 'Biteship API Key', 'type' => 'text' ), 'origin_subdistrict_id' => array( 'title' => 'Origin Subdistrict', 'type' => 'select', 'options' => $this->get_subdistrict_options() ), 'couriers' => array( 'title' => 'Available Couriers', 'type' => 'multiselect', 'options' => array( 'jne' => 'JNE', 'sicepat' => 'SiCepat', 'jnt' => 'J&T Express' ) ) ); } public function calculate_shipping($package = array()) { $origin = $this->get_option('origin_subdistrict_id'); $destination = $package['destination']['subdistrict_id'] ?? null; if (!$origin || !$destination) return; $api = new WooNooW_Biteship_API($this->get_option('api_key')); $rates = $api->get_rates($origin, $destination, $package); foreach ($rates as $rate) { $this->add_rate(array( 'id' => $this->id . ':' . $rate['courier_code'], 'label' => $rate['courier_name'] . ' - ' . $rate['service_name'], 'cost' => $rate['price'] )); } } } ``` --- ## REST API Endpoints ```php 'GET', 'callback' => 'get_provinces' )); register_rest_route('woonoow/v1', '/indonesia-shipping/calculate-rates', array( 'methods' => 'POST', 'callback' => 'calculate_rates' )); ``` --- ## React Components ```typescript // admin-spa/src/components/SubdistrictSelector.tsx export function SubdistrictSelector({ value, onChange }) { const [provinceId, setProvinceId] = useState(''); const [cityId, setCityId] = useState(''); const { data: provinces } = useQuery({ queryKey: ['provinces'], queryFn: () => api.get('/indonesia-shipping/provinces') }); return (