fix(rajaongkir): correct API method name and remove premature country check

Root causes fixed:
1. API method: search_destination_api() not search_destination()
2. Field filter: removed country check that failed before user selection
3. Field now always added if store sells to Indonesia

The woocommerce_checkout_fields filter now:
- Checks if Rajaongkir is active
- Checks if Indonesia is in allowed countries
- Always adds field (frontend will show/hide based on country)
This commit is contained in:
Dwindi Ramadhana
2026-01-08 14:38:52 +07:00
parent 906ad38a36
commit f6b778c7fc

View File

@@ -17,24 +17,6 @@ Before using this integration:
--- ---
## How It Works
```
┌─────────────────┐ ┌───────────────────┐ ┌──────────────────┐
│ Customer types │ → │ /rajaongkir/ │ → │ SearchableSelect │
│ "Bandung" │ │ destinations API │ │ shows results │
└─────────────────┘ └───────────────────┘ └──────────────────┘
┌─────────────────┐ ┌───────────────────┐ ┌──────────────────┐
│ Rajaongkir uses │ ← │ Hook sets WC │ ← │ Customer selects │
│ session to get │ │ session data │ │ destination │
│ shipping rates │ │ │ │ │
└─────────────────┘ └───────────────────┘ └──────────────────┘
```
---
## Code Snippet ## Code Snippet
Add this to **Code Snippets** or **WPCodebox**: Add this to **Code Snippets** or **WPCodebox**:
@@ -78,10 +60,17 @@ function woonoow_rajaongkir_search_destinations($request) {
} }
// Use Rajaongkir's API class for the search // Use Rajaongkir's API class for the search
// NOTE: Method is search_destination_api() not search_destination()
$api = Cekongkir_API::get_instance(); $api = Cekongkir_API::get_instance();
$results = $api->search_destination(['keyword' => $search]); $results = $api->search_destination_api($search);
if (is_wp_error($results)) { if (is_wp_error($results)) {
error_log('Rajaongkir search error: ' . $results->get_error_message());
return [];
}
if (!is_array($results)) {
error_log('Rajaongkir search returned non-array: ' . print_r($results, true));
return []; return [];
} }
@@ -89,8 +78,8 @@ function woonoow_rajaongkir_search_destinations($request) {
$formatted = []; $formatted = [];
foreach ($results as $r) { foreach ($results as $r) {
$formatted[] = [ $formatted[] = [
'value' => (string) $r['id'], 'value' => (string) ($r['id'] ?? ''),
'label' => $r['label'], // "Province, City, District" 'label' => $r['label'] ?? $r['text'] ?? '',
]; ];
} }
@@ -99,7 +88,8 @@ function woonoow_rajaongkir_search_destinations($request) {
} }
// ============================================================ // ============================================================
// 2. Add destination field to checkout fields (SPA-aware) // 2. Add destination field to checkout fields
// Always add for Indonesia zone (no premature country check)
// ============================================================ // ============================================================
add_filter('woocommerce_checkout_fields', function($fields) { add_filter('woocommerce_checkout_fields', function($fields) {
// Check if Rajaongkir is active // Check if Rajaongkir is active
@@ -107,42 +97,29 @@ add_filter('woocommerce_checkout_fields', function($fields) {
return $fields; return $fields;
} }
// Get country from various sources // Check if store sells to Indonesia (check allowed countries)
$country = ''; $allowed = WC()->countries->get_allowed_countries();
if (!isset($allowed['ID'])) {
// From WC customer object
if (WC()->customer) {
$country = WC()->customer->get_shipping_country();
}
// From REST API request body (for SPA context)
if (defined('REST_REQUEST') && REST_REQUEST) {
$json = file_get_contents('php://input');
if ($json) {
$data = json_decode($json, true);
if (isset($data['shipping']['country'])) {
$country = $data['shipping']['country'];
}
}
}
// Only add field for Indonesia or when country not yet determined
if ($country && $country !== 'ID') {
return $fields; return $fields;
} }
// Add searchable destination field // Add searchable destination field
// The frontend will show/hide based on selected country
$fields['shipping']['shipping_destination_id'] = [ $fields['shipping']['shipping_destination_id'] = [
'type' => 'searchable_select', 'type' => 'searchable_select',
'label' => __('Destination (Province, City, Subdistrict)', 'woonoow'), 'label' => __('Destination (Province, City, Subdistrict)', 'woonoow'),
'required' => true, 'required' => false, // Not required initially, SPA will manage this
'priority' => 85, // After country/state, before postcode 'priority' => 85,
'class' => ['form-row-wide'], 'class' => ['form-row-wide'],
'placeholder' => __('Search destination...', 'woonoow'), 'placeholder' => __('Search destination...', 'woonoow'),
// WooNooW-specific: API endpoint configuration // WooNooW-specific: API endpoint configuration
'search_endpoint' => '/woonoow/v1/rajaongkir/destinations', 'search_endpoint' => '/woonoow/v1/rajaongkir/destinations',
'search_param' => 'search', 'search_param' => 'search',
'min_chars' => 2, 'min_chars' => 2,
// Custom attribute to indicate this is for Indonesia only
'custom_attributes' => [
'data-show-for-country' => 'ID',
],
]; ];
return $fields; return $fields;
@@ -173,14 +150,13 @@ add_action('woonoow/shipping/before_calculate', function($shipping, $items) {
?? null; ?? null;
if (empty($destination_id)) { if (empty($destination_id)) {
// No destination selected yet
return; return;
} }
// Set session for Rajaongkir // Set session for Rajaongkir
WC()->session->set('selected_destination_id', intval($destination_id)); WC()->session->set('selected_destination_id', intval($destination_id));
// Also set label if provided (for display purposes) // Also set label if provided
$label = $shipping['destination_label'] $label = $shipping['destination_label']
?? $shipping['shipping_destination_id_label'] ?? $shipping['shipping_destination_id_label']
?? ''; ?? '';
@@ -196,33 +172,20 @@ add_action('woonoow/shipping/before_calculate', function($shipping, $items) {
--- ---
## Field Configuration Options
The `searchable_select` field type supports:
| Option | Description |
|--------|-------------|
| `type` | `'searchable_select'` for API-backed search |
| `search_endpoint` | REST API endpoint path |
| `search_param` | Query parameter name (default: 'search') |
| `min_chars` | Minimum characters before search (default: 2) |
| `placeholder` | Input placeholder text |
---
## Testing ## Testing
### 1. Test the API Endpoint ### 1. Test the API Endpoint
```bash After adding the snippet:
curl "https://yoursite.com/wp-json/woonoow/v1/rajaongkir/destinations?search=bandung" ```
GET /wp-json/woonoow/v1/rajaongkir/destinations?search=bandung
``` ```
Should return: Should return:
```json ```json
[ [
{"value": "1234", "label": "Jawa Barat, Bandung, Kota"}, {"value": "1234", "label": "Jawa Barat, Bandung, Kota"},
{"value": "1235", "label": "Jawa Barat, Bandung, Kabupaten"} ...
] ]
``` ```
@@ -234,49 +197,49 @@ Should return:
4. "Destination" field should appear 4. "Destination" field should appear
5. Type 2+ characters to search 5. Type 2+ characters to search
6. Select a destination 6. Select a destination
7. Click "Calculate Shipping" or proceed 7. Rajaongkir rates should appear
8. Rajaongkir rates should appear
--- ---
## Troubleshooting ## Troubleshooting
### Destination field not appearing? ### API returns empty?
Check if: Check `debug.log` for errors:
- Country is set to Indonesia
- Rajaongkir plugin is active
- Snippet has no syntax errors
Debug in PHP:
```php ```php
add_action('woocommerce_checkout_init', function() { // Added logging in the search function
$fields = WC()->checkout()->get_checkout_fields(); error_log('Rajaongkir search error: ...');
error_log('Shipping fields: ' . print_r(array_keys($fields['shipping'] ?? []), true));
});
``` ```
### Search returns empty? Common issues:
- Invalid Rajaongkir API key
- Rajaongkir plugin not active
- API quota exceeded
```php ### Field not appearing?
// Add to the search endpoint
error_log('Rajaongkir search: ' . $search);
error_log('Results: ' . print_r($results, true));
```
### Rajaongkir rates not appearing? 1. Ensure snippet is active
2. Check if store sells to Indonesia
3. Check browser console for JS errors
### Rajaongkir rates not showing?
1. Check session is set: 1. Check session is set:
```php ```php
add_action('woonoow/shipping/before_calculate', function($shipping) { add_action('woonoow/shipping/before_calculate', function($shipping) {
error_log('Destination ID in shipping data: ' . print_r($shipping, true)); error_log('Shipping data: ' . print_r($shipping, true));
error_log('Session destination: ' . WC()->session->get('selected_destination_id'));
}, 5); }, 5);
``` ```
2. Check Rajaongkir debug: 2. Check Rajaongkir is enabled in shipping zone
- Enable debug in Rajaongkir settings
- Check `debug.log` for Rajaongkir messages ---
## Known Limitations
1. **Field visibility**: Currently field always shows for checkout. Future improvement: hide in React when country ≠ ID.
2. **Session timing**: Must select destination before calculating shipping.
--- ---