# ShipStation Integration Guide

## Overview

This document describes the ShipStation integration implemented in this Next.js application. The integration automatically creates orders in ShipStation after successful Stripe payments and handles shipment notifications via webhooks.

## Architecture

```
Customer Payment → Stripe → Webhook → WooCommerce → ShipStation
                                    ↓
                            Order Created & Synced
                                    ↓
ShipStation Ships Order → Webhook → WooCommerce Status Updated
```

### Status Lifecycle

```
pending → processing → shipped → completed
          ↑            ↑
          |            |
    Stripe Payment   ShipStation Ships
```

## Environment Variables

Add these to your `.env.local` file:

```env
# ShipStation API Configuration
SHIPSTATION_API_KEY=45df243c25724253a8085b39e81c26c2
SHIPSTATION_API_SECRET=a99e4153d60a453685936dfd87b1d2bf
SHIPSTATION_WEBHOOK_SECRET=optional_secret_for_webhook_validation
```

## Implementation Details

### 1. Payment Success Flow

**File**: `app/api/stripe/webhook/route.ts`

When a payment succeeds (`payment_intent.succeeded`):

1. ✅ Verify payment intent and fetch WooCommerce order
2. ✅ Validate amount matches
3. ✅ Update order status to "processing"
4. ✅ Store Stripe payment metadata
5. **⭐ NEW: Create order in ShipStation**
6. **⭐ NEW: Store ShipStation order ID in metadata**
7. ✅ Clear customer cart
8. ✅ Log completion

**Metadata Fields Added**:
- `_shipstation_order_id`: ShipStation's internal order ID
- `_shipstation_order_number`: Order number (same as WooCommerce ID)
- `_shipstation_synced_at`: ISO timestamp of successful sync
- `_shipstation_sync_error`: Error message if sync fails (for manual retry)
- `_shipstation_sync_error_at`: Timestamp of sync failure

### 2. ShipStation Order Mapping

**File**: `lib/shipstation.ts`

**WooCommerce → ShipStation Mapping**:

| WooCommerce Field | ShipStation Field | Notes |
|-------------------|-------------------|-------|
| `order.id` | `orderNumber` | Used for idempotency |
| Current timestamp | `orderDate` | Payment success time |
| `"processing"` | `orderStatus = "awaiting_shipment"` | Always set to awaiting_shipment |
| `billing.email` | `customerEmail` | Customer identifier |
| `billing` address | `billTo` | Formatted address |
| `shipping` address | `shipTo` | Formatted address |
| `line_items[].product_id` | `items[].sku` | **Using product_id as SKU** |
| `line_items[].name` | `items[].name` | Product name |
| `line_items[].quantity` | `items[].quantity` | Quantity |
| `line_items[].total / quantity` | `items[].unitPrice` | Calculated unit price |
| `order.total` | `amountPaid` | Total order amount |
| `shipping_lines[].total` | `shippingAmount` | Shipping cost |

### 3. Idempotency Protection

The integration checks for existing `_shipstation_order_id` metadata before creating orders:

- ✅ **First attempt**: Creates order in ShipStation
- ✅ **Subsequent attempts**: Skips creation, returns existing order ID
- ✅ **Prevents duplicates**: Even if webhook retries

### 4. Error Handling

**Graceful Degradation**:
- ❌ If ShipStation API fails, the payment webhook still succeeds
- ✅ Order is marked "processing" in WooCommerce
- ✅ Error stored in `_shipstation_sync_error` metadata
- ✅ Admin can identify failed syncs and retry manually

**Common Errors**:
- `401 Unauthorized`: Check API credentials
- `Rate limit exceeded`: Reduce request frequency
- `Network timeout`: ShipStation API may be slow/down
- `Invalid address`: Check address validation

### 5. Shipment Notification Flow

**File**: `app/api/shipstation/webhook/route.ts`

When ShipStation ships an order:

1. ✅ ShipStation sends webhook to `/api/shipstation/webhook`
2. ✅ Extract WooCommerce order ID from `order_number`
3. ✅ Fetch order from WooCommerce
4. ✅ Verify order is in "processing" status
5. ✅ Update status to "shipped"
6. ✅ Store tracking metadata:
   - `_tracking_number`
   - `_shipping_carrier`
   - `_shipped_date`
7. ✅ Add customer note with tracking information

**Webhook Events Handled**:
- `SHIP_NOTIFY`: Order has been shipped
- `ITEM_SHIPPED`: Individual items shipped (same handling)
- `ORDER_NOTIFY`: Order notification (logged only)
- `ITEM_ORDER_NOTIFY`: Item order notification (logged only)

### 6. Custom Order Status: "shipped"

**File**: `lib/woo.ts`

Added support for "shipped" status:

```typescript
// Check if order can be paid
canBePaid(order): order.status === "pending"

// Check if order is paid
isPaid(order): ["processing", "shipped", "completed", "on-hold"]

// Check if order is shipped (NEW)
isShipped(order): ["shipped", "completed"]
```

**Note**: If WooCommerce doesn't have a custom "shipped" status registered, it may fall back to "completed". Consider installing a plugin like "WooCommerce Order Status Manager" to add custom statuses.

## Testing

### Local Testing Setup

1. **Install ngrok** (for webhook testing):
   ```bash
   ngrok http 3000
   ```

2. **Update environment variables** with ngrok URL (for local testing only)

3. **Configure ShipStation webhooks**:
   - Go to ShipStation → Settings → API Settings → Webhooks
   - Add webhook URL: `https://your-ngrok-url.ngrok.io/api/shipstation/webhook`
   - Select events: `SHIP_NOTIFY`, `ITEM_SHIPPED`

4. **Configure Stripe webhooks** (if not already done):
   - Add webhook URL: `https://your-ngrok-url.ngrok.io/api/stripe/webhook`
   - Events: `payment_intent.succeeded`, `payment_intent.payment_failed`

### Test Payment Flow

1. **Create test order in WooCommerce**
2. **Process payment through checkout**:
   ```bash
   npm run dev
   # Navigate to checkout page
   # Use Stripe test card: 4242 4242 4242 4242
   ```

3. **Verify order creation in ShipStation**:
   - Check ShipStation dashboard
   - Order should appear with status "Awaiting Shipment"
   - Order number matches WooCommerce order ID

4. **Check WooCommerce metadata**:
   - `_shipstation_order_id`: Should contain ShipStation order ID
   - `_shipstation_synced_at`: Should have timestamp

### Test Shipment Flow

1. **Mark order as shipped in ShipStation**:
   - Add tracking number
   - Select carrier
   - Mark as shipped

2. **Verify webhook received**:
   - Check application logs for "Webhook event received"
   - Type should be "SHIP_NOTIFY"

3. **Verify WooCommerce order updated**:
   - Status should be "shipped"
   - Metadata should include:
     - `_tracking_number`
     - `_shipping_carrier`
     - `_shipped_date`
   - Customer note should include tracking info

### Testing Error Scenarios

#### Test Invalid Credentials

1. Temporarily set invalid `SHIPSTATION_API_KEY`
2. Process test payment
3. **Expected**:
   - Payment succeeds in Stripe
   - Order status = "processing" in WooCommerce
   - Metadata contains `_shipstation_sync_error`
   - Logs show authentication error

#### Test Network Failure

1. Set `SHIPSTATION_API_KEY` to invalid endpoint (simulate network issue)
2. Process test payment
3. **Expected**:
   - Same as above - graceful degradation

#### Test Duplicate Order

1. Process payment (creates order in ShipStation)
2. Manually trigger webhook again with same payment intent
3. **Expected**:
   - No duplicate order created
   - Logs show "Order already synced to ShipStation"

## Monitoring & Debugging

### Check Order Sync Status

**Query WooCommerce API**:
```bash
curl https://your-site.com/wp-json/wc/v3/orders/123 \
  -u consumer_key:consumer_secret
```

Look for metadata:
- `_shipstation_order_id`: Present = synced successfully
- `_shipstation_sync_error`: Present = sync failed

### Check Logs

**Application logs** (check console or log aggregator):
```
[shipstation] Creating order in ShipStation
[shipstation] Successfully created order in ShipStation
[v0] Order payment completed
```

**Failed sync**:
```
[shipstation] Failed to create order in ShipStation
[v0] Order marked for manual ShipStation sync
```

### Manual Retry Failed Orders

1. **Identify failed orders**:
   - Query WooCommerce for orders with `_shipstation_sync_error` metadata
   - No `_shipstation_order_id` present

2. **Retry options**:
   - **Option A**: Manually create order in ShipStation UI
   - **Option B**: Build admin tool to retry sync programmatically
   - **Option C**: Fix error and re-trigger webhook (requires Stripe dashboard)

## Security Considerations

✅ **Backend-Only**: All ShipStation API calls from server (never client)

✅ **Credentials**: Stored in environment variables only

✅ **Rate Limiting**: Applied to webhook endpoints (100 req/min)

✅ **Validation**: Zod schemas validate all webhook payloads

✅ **Idempotency**: Prevents duplicate order creation

✅ **Audit Trail**: All actions logged with order context

✅ **Graceful Degradation**: Payment succeeds even if ShipStation fails

## Production Deployment

### Pre-Deployment Checklist

- [ ] Environment variables set in production (Vercel/hosting provider)
- [ ] ShipStation API credentials verified
- [ ] Webhook URLs configured in ShipStation dashboard
- [ ] Custom "shipped" status created in WooCommerce (optional)
- [ ] Monitoring/alerting configured for ShipStation sync failures
- [ ] Test payment processed successfully
- [ ] Test shipment notification received

### Post-Deployment Verification

1. **Process test order** in production
2. **Verify ShipStation order** created
3. **Mark as shipped** in ShipStation
4. **Verify WooCommerce status** updated
5. **Monitor logs** for 24 hours
6. **Check for failed syncs**

## Webhook URLs

**Production URLs** (replace with your domain):

```
Stripe Webhook:
https://your-domain.com/api/stripe/webhook

ShipStation Webhook:
https://your-domain.com/api/shipstation/webhook
```

## API Rate Limits

**ShipStation API Limits**:
- 40 requests per minute (standard)
- 200 requests per minute (enterprise)

**Current Implementation**:
- 1 API call per order (create order)
- Idempotency prevents retry storms
- Webhook rate limited to 100/min

## Future Enhancements

### Potential Improvements

1. **Retry Queue**: Automatically retry failed syncs
2. **SKU Mapping**: Fetch actual SKUs from WooCommerce products
3. **Bulk Sync**: Sync existing orders to ShipStation
4. **Admin Dashboard**: View sync status and retry failed orders
5. **Webhooks Signature**: Validate ShipStation webhook signatures
6. **Advanced Shipping**: Support multiple packages, custom carriers
7. **Tracking Page**: Customer-facing tracking page
8. **Email Notifications**: Send tracking emails via custom handler
9. **Analytics**: Track shipping performance metrics
10. **Multi-Store**: Support multiple WooCommerce/ShipStation stores

## Troubleshooting

### Orders Not Appearing in ShipStation

1. Check `_shipstation_sync_error` metadata in WooCommerce
2. Verify API credentials are correct
3. Check ShipStation API status page
4. Review application logs for error details
5. Test API credentials manually with cURL

### Shipment Webhooks Not Received

1. Verify webhook URL is correct in ShipStation
2. Check webhook is enabled for `SHIP_NOTIFY` event
3. Test webhook manually from ShipStation dashboard
4. Check application logs for received webhooks
5. Verify firewall/security rules allow ShipStation IPs

### Order Status Not Updating to "Shipped"

1. Check if "shipped" status exists in WooCommerce
2. Review webhook payload in logs
3. Verify order is in "processing" status
4. Check for WooCommerce API errors in logs

## Support

For issues related to:
- **ShipStation API**: Contact ShipStation support
- **Stripe Webhooks**: Check Stripe dashboard webhook logs
- **WooCommerce Integration**: Review WooCommerce REST API docs
- **Application Issues**: Check application logs and error tracking

## References

- [ShipStation API Documentation](https://www.shipstation.com/docs/api/)
- [ShipStation Webhooks Guide](https://www.shipstation.com/docs/api/webhooks/)
- [Stripe Webhooks](https://stripe.com/docs/webhooks)
- [WooCommerce REST API](https://woocommerce.github.io/woocommerce-rest-api-docs/)




