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