# 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
<select id="cart-destination" name="cart_destination">
    <option>Search and select location...</option>
</select>
```

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)
