**[ English ]** | [ 繁體中文 ](./docs/README.zh-TW.md) | [ 简体中文 ](./docs/README.zh-CN.md)

# UCP Shopping Agent

[![WordPress](https://img.shields.io/badge/WordPress-5.8+-blue.svg)](https://wordpress.org/)
[![WooCommerce](https://img.shields.io/badge/WooCommerce-5.0+-purple.svg)](https://woocommerce.com/)
[![PHP](https://img.shields.io/badge/PHP-7.4+-777BB4.svg)](https://php.net/)
[![License](https://img.shields.io/badge/License-GPL2-green.svg)](https://www.gnu.org/licenses/gpl-2.0.html)

**Google Universal Commerce Protocol (UCP) implementation for WooCommerce** — Enable AI agents to discover, browse, and transact with your WooCommerce store through a standardized REST API.

---

## 🌟 Features

### 🔍 Store Discovery
- Standard `/.well-known/ucp` discovery endpoint
- Complete store capability manifest
- Merchant information, currency, locale, and timezone

### 🛍️ Product Catalog
- Browse products with pagination and filtering
- Search by keyword, category, price range
- Get product details by ID or SKU
- Variable products with all variations
- Product images, attributes, and ratings

### 📁 Categories
- Full category hierarchy navigation
- Nested subcategory support
- Products by category with pagination

### 🛒 Persistent Cart
- Create and manage shopping carts
- Add, update, remove cart items
- Support for product variations
- Automatic stock validation
- Cart expiration management

### 💳 Checkout
- Create checkout sessions from carts
- Direct checkout with items
- Shipping and billing address management
- Coupon application
- Order confirmation and creation

### 📦 Orders
- Order listing with filters
- Detailed order information
- Order event timeline tracking
- Payment and shipping status

### 👤 Customer Management
- Create customer profiles
- Update billing/shipping addresses
- Lookup by email

### 🚚 Shipping
- Real-time shipping rate calculation
- Multiple shipping zones support
- Available shipping methods

### ⭐ Reviews
- Product reviews listing
- Review creation
- Rating distribution summary

### 🎟️ Coupons
- Discover available coupons
- Validate coupon codes
- Calculate discounts

### 🔔 Webhooks
- Real-time order event notifications
- HMAC-SHA256 signature verification
- **Retry with exponential backoff** (3 attempts)
- **Automatic failed webhook recovery** via WP-Cron
- **Signing keys exposed in discovery endpoint**
- Events: `order.created`, `order.status_changed`, `order.paid`, `order.refunded`

### 🔐 Authentication
- Secure API key authentication
- Three permission levels: `read`, `write`, `admin`
- Key management via admin interface
- Rate limiting support
- **API key caching** for improved performance

---

## 📋 Requirements

- WordPress 5.8 or higher
- WooCommerce 5.0 or higher
- PHP 7.4 or higher

---

## 🌐 External Services

The following external services are referenced or used by this plugin:

### 1. UCP Schema Registry
- **Service URL:** `https://ucp.dev`
- **Purpose:** Referenced as a protocol namespace identifier in JSON schemas and API responses.
- **Data Sent:** None. This is a passive reference; the plugin does not connect to or send data to this service.
- **Privacy Policy:** N/A (Static documentation site)
- **Terms of Service:** N/A

### 2. Documentation Examples
- **Service URLs:** `https://agent.example`, `https://your-store.com`
- **Purpose:** Used as placeholder URLs in documentation examples and code comments to demonstrate link relations.
- **Data Sent:** None.
- **Privacy Policy:** N/A
- **Terms of Service:** N/A

### 3. User-Configured Webhooks
- **Service URL:** Varies (User configured)
- **Purpose:** Sending real-time order event notifications.
- **Data Sent:** Order details, customer information, and checkout status as JSON payloads.
- **Timing:** Triggered immediately when specific events occur (e.g., order creation) or via WP-Cron for retries.
- **Privacy Policy:** Please refer to the privacy policy of the specific service you configure as a webhook receiver.

---

## 🚀 Installation

1. Download the plugin zip file
2. Go to **WordPress Admin → Plugins → Add New → Upload Plugin**
3. Upload the zip file and click **Install Now**
4. Click **Activate Plugin**
5. Go to **WooCommerce → UCP** to configure settings

---

## ⚙️ Configuration

### Admin Settings

Navigate to **WooCommerce → UCP** in your WordPress admin panel.

#### General Tab
| Setting | Description | Default |
|---------|-------------|---------|
| Enable UCP | Enable/disable UCP API endpoints | Yes |
| Rate Limit | Max requests per minute per API key | 100 |
| Cart Expiry | Hours until inactive cart expires | 24 |
| Checkout Expiry | Minutes until checkout session expires | 30 |
| Enable Logging | Log API requests for debugging | No |

#### API Keys Tab
- Create new API keys with descriptions
- Set permission levels (read/write/admin)
- View existing keys and last access time
- Delete unused keys

#### Discovery Tab
- View your Discovery URL
- Quick start guide
- Available endpoints reference

---

## 🔑 Authentication

### API Key Format
```
key_id:secret
```
Example: `ucp_abc123:saucp_secret_xyz789`

### Authentication Methods

**Header (Recommended)**
```bash
curl -H "X-UCP-API-Key: ucp_abc123:saucp_secret_xyz789" \
  https://your-store.com/wp-json/ucp/v1/products
```

**Query Parameter**
```bash
curl "https://your-store.com/wp-json/ucp/v1/products?ucp_api_key=ucp_abc123:saucp_secret_xyz789"
```

### Permission Levels

| Level | Access |
|-------|--------|
| `read` | Browse products, categories, reviews |
| `write` | Create carts, checkout, orders, customers |
| `admin` | Full access including API key management |

---

## 📡 API Endpoints

### Discovery
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| GET | `/.well-known/ucp` | No | Store discovery manifest |
| GET | `/wp-json/ucp/v1/discovery` | No | Same as above |

### Products
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| GET | `/wp-json/ucp/v1/products` | No | List products |
| GET | `/wp-json/ucp/v1/products/{id}` | No | Get product by ID |
| GET | `/wp-json/ucp/v1/products/search` | No | Search products |
| GET | `/wp-json/ucp/v1/products/sku/{sku}` | No | Get product by SKU |

### Categories
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| GET | `/wp-json/ucp/v1/categories` | No | List categories |
| GET | `/wp-json/ucp/v1/categories/{id}` | No | Get category |
| GET | `/wp-json/ucp/v1/categories/{id}/products` | No | Category products |

### Cart
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/wp-json/ucp/v1/carts` | Write | Create cart |
| GET | `/wp-json/ucp/v1/carts/{id}` | Write | Get cart |
| DELETE | `/wp-json/ucp/v1/carts/{id}` | Write | Delete cart |
| POST | `/wp-json/ucp/v1/carts/{id}/items` | Write | Add item |
| PATCH | `/wp-json/ucp/v1/carts/{id}/items/{key}` | Write | Update item |
| DELETE | `/wp-json/ucp/v1/carts/{id}/items/{key}` | Write | Remove item |
| POST | `/wp-json/ucp/v1/carts/{id}/checkout` | Write | Convert to checkout |

### Checkout
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/wp-json/ucp/v1/checkout/sessions` | Write | Create session |
| GET | `/wp-json/ucp/v1/checkout/sessions/{id}` | Write | Get session |
| PATCH | `/wp-json/ucp/v1/checkout/sessions/{id}` | Write | Update session |
| POST | `/wp-json/ucp/v1/checkout/sessions/{id}/confirm` | Write | Confirm checkout |

### Orders
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| GET | `/wp-json/ucp/v1/orders` | Write | List orders |
| GET | `/wp-json/ucp/v1/orders/{id}` | Write | Get order |
| GET | `/wp-json/ucp/v1/orders/{id}/events` | Write | Order timeline |

### Customers
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/wp-json/ucp/v1/customers` | Write | Create customer |
| GET | `/wp-json/ucp/v1/customers/{id}` | Write | Get customer |
| PATCH | `/wp-json/ucp/v1/customers/{id}` | Write | Update customer |
| GET | `/wp-json/ucp/v1/customers/email/{email}` | Write | Find by email |

### Shipping
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/wp-json/ucp/v1/shipping/rates` | No | Calculate rates |
| GET | `/wp-json/ucp/v1/shipping/methods` | No | List methods |
| GET | `/wp-json/ucp/v1/shipping/zones` | No | List zones |

### Reviews
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| GET | `/wp-json/ucp/v1/reviews` | No | List reviews |
| GET | `/wp-json/ucp/v1/reviews/{id}` | No | Get review |
| POST | `/wp-json/ucp/v1/reviews` | Write | Create review |
| GET | `/wp-json/ucp/v1/reviews/product/{id}/summary` | No | Rating summary |

### Coupons
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| GET | `/wp-json/ucp/v1/coupons` | No | List coupons |
| POST | `/wp-json/ucp/v1/coupons/validate` | No | Validate coupon |
| GET | `/wp-json/ucp/v1/coupons/code/{code}` | No | Get by code |

### API Keys
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/wp-json/ucp/v1/auth/keys` | WP Admin | Create key |
| GET | `/wp-json/ucp/v1/auth/keys` | WP Admin | List keys |
| DELETE | `/wp-json/ucp/v1/auth/keys/{id}` | WP Admin | Delete key |
| GET | `/wp-json/ucp/v1/auth/verify` | Read | Verify key |

---

## 📝 Usage Examples

### 1. Discover Store
```bash
curl https://your-store.com/.well-known/ucp
```

### 2. Browse Products
```bash
curl "https://your-store.com/wp-json/ucp/v1/products?per_page=10&category=15"
```

### 3. Search Products
```bash
curl "https://your-store.com/wp-json/ucp/v1/products/search?q=shirt&min_price=20&max_price=100"
```

### 4. Create Cart & Add Items
```bash
# Create cart
curl -X POST \
  -H "X-UCP-API-Key: YOUR_API_KEY" \
  https://your-store.com/wp-json/ucp/v1/carts

# Add item to cart
curl -X POST \
  -H "X-UCP-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"product_id": 123, "quantity": 2}' \
  https://your-store.com/wp-json/ucp/v1/carts/{cart_id}/items
```

### 5. Checkout Flow
```bash
# Convert cart to checkout
curl -X POST \
  -H "X-UCP-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "shipping_address": {
      "first_name": "John",
      "last_name": "Doe",
      "address_1": "123 Main St",
      "city": "Taipei",
      "country": "TW"
    },
    "billing_address": {...}
  }' \
  https://your-store.com/wp-json/ucp/v1/carts/{cart_id}/checkout

# Confirm checkout
curl -X POST \
  -H "X-UCP-API-Key: YOUR_API_KEY" \
  https://your-store.com/wp-json/ucp/v1/checkout/sessions/{session_id}/confirm
```

---

## 🔔 Webhooks

### Webhook Features (v1.0.2+)

- **Retry Logic**: Failed webhooks automatically retry 3 times with exponential backoff (5s, 10s, 20s)
- **Failed Webhook Recovery**: Undelivered webhooks stored and retried via WP-Cron every 15 minutes
- **Signing Keys**: Discovery endpoint now exposes `signing_keys` for webhook verification

### Webhook Signature Verification

All webhook requests include signature headers:

```
X-UCP-Signature: t=1705234567,v1=<hmac_signature>
X-UCP-Event: order.created
X-UCP-Timestamp: 1705234567
X-UCP-Delivery-ID: <uuid>
```

### Verify Signature (PHP Example)
```php
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_UCP_SIGNATURE'];
$secret = 'your_webhook_secret';

// Parse signature: t=timestamp,v1=hash
preg_match('/t=(\d+),v1=([a-f0-9]+)/', $signature, $matches);
$timestamp = $matches[1];
$received_hash = $matches[2];

// Verify timestamp is within 5 minutes
if (abs(time() - $timestamp) > 300) {
    die('Signature expired');
}

// Verify signature
$message = $timestamp . '.' . $payload;
$expected_hash = hash_hmac('sha256', $message, $secret);

if (hash_equals($expected_hash, $received_hash)) {
    // Valid webhook
    $data = json_decode($payload, true);
}
```

---

## 🗄️ Database Tables

The plugin creates the following custom tables:

| Table | Purpose |
|-------|---------|
| `wp_shopping_agent_ucp_api_keys` | API key storage |
| `wp_shopping_agent_ucp_cart_sessions` | Persistent cart data |
| `wp_shopping_agent_ucp_checkout_sessions` | Checkout session data |
| `wp_shopping_agent_ucp_webhooks` | Webhook configurations |

---

## 🌐 Internationalization

The plugin supports translations. Translation files are located in the `/languages` directory.

- Text Domain: `shopping-agent-with-ucp`
- POT file: `languages/shopping-agent-with-ucp.pot`

---

## 📁 File Structure

```
shopping-agent-with-ucp/
├── shopping-agent-with-ucp.php             # Main plugin file
├── admin/
│   ├── class-shopping-agent-ucp-admin.php    # Admin functionality
│   ├── class-shopping-agent-ucp-settings.php # Settings management
│   └── views/
│       └── settings-page.php                 # Admin UI template
├── includes/
│   ├── api/                                  # REST API controllers
│   │   ├── class-shopping-agent-ucp-rest-controller.php
│   │   ├── class-shopping-agent-ucp-auth.php
│   │   ├── class-shopping-agent-ucp-discovery.php
│   │   ├── class-shopping-agent-ucp-products.php
│   │   ├── class-shopping-agent-ucp-categories.php
│   │   ├── class-shopping-agent-ucp-cart.php
│   │   ├── class-shopping-agent-ucp-checkout.php
│   │   ├── class-shopping-agent-ucp-orders.php
│   │   ├── class-shopping-agent-ucp-customers.php
│   │   ├── class-shopping-agent-ucp-shipping.php
│   │   ├── class-shopping-agent-ucp-reviews.php
│   │   └── class-shopping-agent-ucp-coupons.php
│   ├── models/                               # Data models
│   │   ├── class-shopping-agent-ucp-api-key.php
│   │   └── class-shopping-agent-ucp-cart-session.php
│   ├── webhooks/                             # Webhook handling
│   │   ├── class-shopping-agent-ucp-webhook-manager.php
│   │   └── class-shopping-agent-ucp-webhook-sender.php
│   ├── class-shopping-agent-ucp-activator.php
│   ├── class-shopping-agent-ucp-deactivator.php
│   ├── class-shopping-agent-ucp-loader.php
│   └── class-shopping-agent-ucp-i18n.php
├── assets/
│   ├── css/admin.css
│   └── js/admin.js
└── languages/
    └── wc-ucp-agent.pot
```

---

## 🔧 Hooks & Filters

### Actions
```php
// Webhook delivery failed
do_action('shopping_agent_ucp_webhook_delivery_failed', $webhook, $error);
```

### Filters
```php
// Modify webhook SSL verification
apply_filters('shopping_agent_ucp_webhook_ssl_verify', true);
```

---

## 🛠️ Troubleshooting

### API Returns 404
- Ensure you're using the correct URL: `/wp-json/ucp/v1/...`
- Flush permalinks: **Settings → Permalinks → Save Changes**

### Authentication Fails
- Verify API key format: `key_id:secret`
- Check key permissions match required endpoint access
- Ensure key hasn't been deleted

### Cart/Checkout Expires
- Adjust expiry times in **WooCommerce → UCP → General**
- Default: Cart = 24 hours, Checkout = 30 minutes

---

## 📄 License

This plugin is licensed under the GPL2 license. See [LICENSE](https://www.gnu.org/licenses/gpl-2.0.html) for details.

---

## 👨‍💻 Author

**Roger Deng**

---

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

---

## 📞 Support

For support, please create an issue in the GitHub repository.
