Files
WooNooW/RAJAONGKIR_INTEGRATION.md
Dwindi Ramadhana 786e01c8f6 feat(shipping): searchable state fields and addon hook
1. Admin OrderForm: Changed billing & shipping state from Select to
   SearchableSelect for better UX (consistent with country field)

2. OrdersController: Replaced Rajaongkir-specific hardcoded session
   handling with generic filter hook:
   do_action('woonoow/shipping/before_calculate', $shipping, $items)

3. Added RAJAONGKIR_INTEGRATION.md with:
   - Hook documentation
   - Code snippet to bridge Rajaongkir with WooNooW
   - Frontend integration examples
   - Troubleshooting guide
2026-01-08 11:00:55 +07:00

5.8 KiB

Rajaongkir Integration with WooNooW

This guide explains how to bridge the Rajaongkir shipping plugin with WooNooW's admin order form and checkout flow.


The Challenge

Rajaongkir doesn't use standard WooCommerce address fields. Instead of using city and state, it requires a destination ID from its own Indonesian location database.

Standard WooCommerce Flow:

Country → State → City → Postcode

Rajaongkir Flow:

Country (ID) → Destination ID (subdistrict level)

WooNooW Integration Hook

WooNooW provides a hook that fires before shipping calculation. This allows plugins like Rajaongkir to set session variables or prepare any data they need.

Hook: woonoow/shipping/before_calculate

do_action( 'woonoow/shipping/before_calculate', $shipping_data, $items );

Parameters:

  • $shipping_data (array) - The shipping address from frontend:
    • country - Country code (e.g., 'ID')
    • state - State code
    • city - City name
    • postcode - Postal code
    • address_1 - Street address
    • address_2 - Additional address (optional)
      • Any custom fields added by addons
  • $items (array) - Cart items being shipped

Code Snippet: Rajaongkir Bridge

Add this code to your theme's functions.php or via a code snippets plugin:

<?php
/**
 * Bridge Rajaongkir plugin with WooNooW shipping calculation.
 * 
 * This code listens for WooNooW's shipping hook and sets the
 * Rajaongkir session variables it needs to calculate rates.
 */
add_action( 'woonoow/shipping/before_calculate', function( $shipping, $items ) {
    // Only process for Indonesia
    if ( empty( $shipping['country'] ) || $shipping['country'] !== 'ID' ) {
        // Clear Rajaongkir session for non-ID countries
        WC()->session->__unset( 'selected_destination_id' );
        WC()->session->__unset( 'selected_destination_label' );
        return;
    }

    // Check if destination_id is provided by frontend
    if ( ! empty( $shipping['destination_id'] ) ) {
        WC()->session->set( 'selected_destination_id', $shipping['destination_id'] );
        WC()->session->set( 'selected_destination_label', $shipping['destination_label'] ?? $shipping['city'] );
        return;
    }

    // Fallback: Try to lookup destination from city name
    // This requires the Rajaongkir database lookup
    $destination = rajaongkir_lookup_destination( $shipping['city'], $shipping['state'] );
    if ( $destination ) {
        WC()->session->set( 'selected_destination_id', $destination['id'] );
        WC()->session->set( 'selected_destination_label', $destination['label'] );
    }
}, 10, 2 );

/**
 * Helper: Lookup Rajaongkir destination by city/state name.
 * 
 * This is a simplified example. Implement based on your Rajaongkir data structure.
 */
function rajaongkir_lookup_destination( $city, $state ) {
    // Query the Rajaongkir location database
    // This depends on how your Rajaongkir plugin stores location data
    
    // Example using transient/option storage:
    $locations = get_option( 'cekongkir_destinations', [] );
    
    foreach ( $locations as $location ) {
        if ( 
            stripos( $location['city'], $city ) !== false ||
            stripos( $location['district'], $city ) !== false
        ) {
            return [
                'id' => $location['id'],
                'label' => $location['label'],
            ];
        }
    }
    
    return null;
}

Frontend Integration (Optional)

To add a proper Rajaongkir destination selector to WooNooW's admin order form, you need to:

1. Register Custom Address Fields

add_filter( 'woonoow/checkout/address_fields', function( $fields ) {
    // Only for Indonesia
    if ( WC()->customer && WC()->customer->get_shipping_country() === 'ID' ) {
        $fields['destination_id'] = [
            'type' => 'hidden',
            'required' => true,
        ];
        $fields['destination_selector'] = [
            'type' => 'custom',
            'component' => 'RajaongkirDestinationSelector',
            'label' => __( 'Destination', 'woonoow-rajaongkir' ),
            'required' => true,
        ];
    }
    return $fields;
} );
add_action( 'woonoow/admin/enqueue_scripts', function() {
    wp_enqueue_script(
        'woonoow-rajaongkir',
        plugins_url( 'assets/js/woonoow-integration.js', __FILE__ ),
        [ 'woonoow-admin' ],
        '1.0.0',
        true
    );
    
    wp_localize_script( 'woonoow-rajaongkir', 'WNW_RAJAONGKIR', [
        'ajaxUrl' => admin_url( 'admin-ajax.php' ),
        'nonce' => wp_create_nonce( 'rajaongkir_search' ),
    ] );
} );

Testing

  1. Install and configure Rajaongkir plugin
  2. Add the code snippet above
  3. Go to WooNooW → Orders → Create New Order
  4. Add a product
  5. Set country to Indonesia
  6. Fill in city/state (or use destination selector if implemented)
  7. Click "Calculate Shipping"
  8. Verify Rajaongkir rates appear

Troubleshooting

Rates not appearing?

  1. Check browser DevTools Network tab for /shipping/calculate response

  2. Look for debug object in response:

    {
      "methods": [...],
      "debug": {
        "packages_count": 1,
        "cart_items_count": 1,
        "address": { ... }
      }
    }
    
  3. Verify Rajaongkir session is set:

    error_log( 'destination_id: ' . WC()->session->get( 'selected_destination_id' ) );
    

Session not persisting?

Make sure WooCommerce session is initialized before the hook runs. The hook fires during REST API calls where session may not be initialized by default.