# Rajaongkir Integration Issue ## Problem Discovery Rajaongkir plugin **doesn't use standard WooCommerce address fields** for Indonesian shipping calculation. ### How Rajaongkir Works: 1. **Removes Standard Fields:** ```php // class-cekongkir.php line 645 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 // Adds Select2 dropdown for searching locations ``` 3. **Stores in Session:** ```php // When user selects destination via AJAX WC()->session->set('selected_destination_id', $destination_id); WC()->session->set('selected_destination_label', $destination_label); ``` 4. **Triggers Shipping Calculation:** ```php // After destination selected WC()->cart->calculate_shipping(); WC()->cart->calculate_totals(); ``` ### Why Our Implementation Fails: **OrderForm.tsx:** - Uses standard fields: `city`, `state`, `postcode` - Rajaongkir ignores these fields - Rajaongkir only reads from session: `selected_destination_id` **Backend API:** - Sets `WC()->customer->set_shipping_city($city)` - Rajaongkir doesn't use this - Rajaongkir reads: `WC()->session->get('selected_destination_id')` **Result:** - Same rates for all provinces ❌ - No Rajaongkir API hits ❌ - Shipping calculation fails ❌ --- ## Solution ### Backend (✅ DONE): ```php // OrdersController.php - calculate_shipping method if ( $country === 'ID' && ! empty( $shipping['destination_id'] ) ) { WC()->session->set( 'selected_destination_id', $shipping['destination_id'] ); WC()->session->set( 'selected_destination_label', $shipping['destination_label'] ); } ``` ### Frontend (TODO): Need to add Rajaongkir destination field to OrderForm.tsx: 1. **Add Destination Search Field:** ```tsx // For Indonesia only {bCountry === 'ID' && (
{ setDestinationId(id); setDestinationLabel(label); }} />
)} ``` 2. **Pass to API:** ```tsx shipping: { country: bCountry, state: bState, city: bCity, destination_id: destinationId, // For Rajaongkir destination_label: destinationLabel // For Rajaongkir } ``` 3. **API Endpoint:** ```tsx // Add search endpoint GET /woonoow/v1/rajaongkir/search?query=bandung // Proxy to Rajaongkir API POST /wp-admin/admin-ajax.php action=cart_search_destination query=bandung ``` --- ## Rajaongkir Destination Format ### Destination ID Examples: - `city:23` - City ID 23 (Bandung) - `subdistrict:456` - Subdistrict ID 456 - `province:9` - Province ID 9 (Jawa Barat) ### API Response: ```json { "success": true, "data": [ { "id": "city:23", "text": "Bandung, Jawa Barat" }, { "id": "subdistrict:456", "text": "Bandung Wetan, Bandung, Jawa Barat" } ] } ``` --- ## Implementation Steps ### Step 1: Add Rajaongkir Search Endpoint (Backend) ```php // OrdersController.php public static function search_rajaongkir_destination( WP_REST_Request $req ) { $query = sanitize_text_field( $req->get_param( 'query' ) ); // Call Rajaongkir API $api = Cekongkir_API::get_instance(); $results = $api->search_destination_api( $query ); return new \WP_REST_Response( $results, 200 ); } ``` ### Step 2: Add Destination Field (Frontend) ```tsx // OrderForm.tsx const [destinationId, setDestinationId] = useState(''); const [destinationLabel, setDestinationLabel] = useState(''); // Add to shipping data const effectiveShippingAddress = useMemo(() => { return { country: bCountry, state: bState, city: bCity, destination_id: destinationId, destination_label: destinationLabel, }; }, [bCountry, bState, bCity, destinationId, destinationLabel]); ``` ### Step 3: Create Destination Search Component ```tsx // components/RajaongkirDestinationSearch.tsx export function RajaongkirDestinationSearch({ value, onChange }) { const [query, setQuery] = useState(''); const { data: results } = useQuery({ queryKey: ['rajaongkir-search', query], queryFn: () => api.get(`/rajaongkir/search?query=${query}`), enabled: query.length >= 3, }); return ( setQuery(e.target.value)} /> {results?.map(r => ( {r.text} ))} ); } ``` --- ## Testing ### Before Fix: 1. Select "Jawa Barat" → JNE REG Rp31,000 2. Select "Bali" → JNE REG Rp31,000 (wrong! cached) 3. Rajaongkir dashboard → 0 API hits ### After Fix: 1. Search "Bandung" → Select "Bandung, Jawa Barat" 2. ✅ Rajaongkir API hit 3. ✅ Returns: JNE REG Rp31,000, JNE YES Rp42,000 4. Search "Denpasar" → Select "Denpasar, Bali" 5. ✅ Rajaongkir API hit 6. ✅ Returns: JNE REG Rp45,000, JNE YES Rp58,000 (different!) --- ## Notes - Rajaongkir is Indonesia-specific (country === 'ID') - For other countries, use standard WooCommerce fields - Destination ID format: `type:id` (e.g., `city:23`, `subdistrict:456`) - Session data is critical - must be set before `calculate_shipping()` - Frontend needs autocomplete/search component (Select2 or similar)