# 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 ``` 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)