FleetConnector OptimoRoute Documentation
Complete guide to installing, configuring, and using the WooCommerce to OptimoRoute integration plugin
Ready to automate your WooCommerce deliveries with OptimoRoute?
Purchase the WordPress plugin for just €199/year. Unlimited orders, premium support included.
Installation
1.1 System requirements
Before installing the WooCommerce to OptimoRoute plugin, ensure your system meets these requirements:
- WordPress 6.0 or higher: Tested up to WordPress 6.9
- WooCommerce 7.0 or higher: Must be installed and activated (tested up to WooCommerce 11.1)
- PHP 7.4 or higher: Required for modern PHP features
- An OptimoRoute account with the Web Service API enabled: The WS API is available on all OptimoRoute plans and during the trial. Only administrator users can enable it and view the API key.
- A FleetConnector license: The license key is activated in the plugin settings. Orders are not sent to OptimoRoute without a valid license.
- WooCommerce High-Performance Order Storage (HPOS): Fully supported. The plugin works with both HPOS and the legacy post-based order storage.
1.2 Installation steps
Purchase and Download
Purchase the WooCommerce to OptimoRoute plugin from our website for €199/year. You'll receive a download link and license key via email.
Upload to WordPress
Navigate to Plugins → Add New → Upload Plugin in your WordPress admin.
Activate Plugin
After upload completes, click "Activate Plugin". FleetConnector OptimoRoute automatically creates its activity log table and schedules a daily log clean-up.
Activate License
Go to WooCommerce → FleetConnector OptimoRoute and enter your license key in the License section to activate the integration.
Connect OptimoRoute
In OptimoRoute, enable the Web Service API and copy the API key. Paste it in the plugin settings, click "Test Connection" and save. See section 2.2 for details.
1.3 Where to find the plugin
After activation, FleetConnector OptimoRoute adds two pages to the WooCommerce menu. Both require the manage_woocommerce capability (shop managers and administrators).
FleetConnector OptimoRoute
License, connection and all settings.
WooCommerce → FleetConnector OptimoRoute
FCO Dashboard
Statistics, activity log, retry and CSV export.
WooCommerce → FCO Dashboard
The Plugins screen also shows "Settings" and "Documentation" links below FleetConnector OptimoRoute.
Configuration
All settings live on one page: WooCommerce → FleetConnector OptimoRoute. The license is activated separately; every other card is saved with the "Save All Settings" button at the bottom of the page.
2.1 License
FleetConnector licenses are managed through Lemon Squeezy. Your license key was sent to your email after purchase.
Activate your license
- Go to WooCommerce → FleetConnector OptimoRoute
- Paste your key in the "License Key" field of the License card
- Click "Activate License"
- The page reloads and shows "License Active"
Good to know
- • The activation is registered under your site's domain name.
- • The license is re-validated once a week in the background. A temporary network problem never disables the integration; only an explicitly invalid or expired license does.
- • "Deactivate" releases the activation slot, so you can use the key on another site.
- • A key for another FleetConnector product is refused with "This license key belongs to another FleetConnector product."
2.2 OptimoRoute connection
Step 1: Get your OptimoRoute API key
- Log in to OptimoRoute with an administrator user
- Go to Administration → Settings → Account → WS API
- Enable the API to generate your key
- Copy the API key
Step 2: Configure in WooCommerce
- In WordPress admin, go to WooCommerce → FleetConnector OptimoRoute
- Find the "OptimoRoute Connection" card
- Paste your key in the "OptimoRoute API Key" field
- Click "Test Connection" (this works before saving, it uses the key in the field)
- Click "Save All Settings" at the bottom of the page
2.3 Automatic order sending
Automatically send orders to OptimoRoute
When enabled, orders are sent to OptimoRoute when they reach one of the selected statuses.
Default: Enabled
When disabled, you can still send orders manually with the order actions and bulk actions (see Chapter 3).
Send orders when the status changes to:
Choose one or more WooCommerce order statuses (including custom statuses). An order is only sent once; later status changes don't create it again.
✓ Processing (Default)
The order is paid and ready to be delivered. Best for most shops.
Completed or a custom status
Use this when orders are packed first and only then handed over for route planning.
Only send orders that need a delivery
Skips orders without shippable products and orders with local pickup (shipping methods local_pickup, pickup_location and local_pickup_plus).
Default: Disabled
Enable this if you sell virtual or downloadable products, or offer local pickup.
Send orders in the background (recommended)
Uses the WooCommerce Action Scheduler so checkout is never slowed down by the OptimoRoute API. Temporary errors are retried automatically.
2.4 Synchronization
Automatically sync order changes to OptimoRoute
When an order that was already sent is saved, the changes are sent to OptimoRoute.
How updates work:
- • Address, items, notes and delivery date changes are sent to OptimoRoute
- • An update is only sent when the data actually changed (the plugin compares a fingerprint of the last payload)
- • Updates use the MERGE operation, so fields your dispatcher edited in OptimoRoute are kept
- • Orders that are already delivered, failed or cancelled in OptimoRoute are not changed
- • WooCommerce orders with status Cancelled, Refunded, Failed or in the trash are not synced
Default: Enabled
Remove the OptimoRoute order when the WooCommerce order is cancelled
When enabled, cancelling a WooCommerce order deletes the linked order in OptimoRoute. Default: Disabled.
2.5 Order details sent to OptimoRoute
These settings control the fields of the OptimoRoute order. See section 6.3 for the complete field mapping.
| Setting | Options | Default | Description |
|---|---|---|---|
| Order type | Delivery, Pickup, Task | Delivery | Sent as type (D, P or T). |
| Priority | Low, Medium, High, Critical | Medium | Sent as priority (L, M, H or C). |
| Service time per stop (minutes) | Number | 5 | Time the driver spends at the address. Leave at 0 to use the default duration of your OptimoRoute account. |
| Load (vehicle capacity) | Do not send a load, Number of items, Total weight of the products | Do not send a load | Sent as Load 1 (load1). OptimoRoute compares it with the vehicle capacity, so use the same unit as in OptimoRoute. |
| Send the customer phone number | On / Off | On | Lets drivers call the customer and is used for SMS notifications. |
| Send the customer email address | On / Off | On | Used for email notifications. |
| Add the ordered products to the driver instructions | On / Off | On | Lists every product with quantity and product options. |
| Add payment information to the driver instructions | On / Off | On | Shows the amount to collect for cash on delivery orders, otherwise the payment method. |
| Customer notifications by OptimoRoute | Use the OptimoRoute account setting, Don't notify, Email, SMS, Email and SMS | Use the OptimoRoute account setting | Sent as notificationPreference. Notifications are only sent when order tracking is set up in OptimoRoute. |
| Order number prefix (optional) | Text, e.g. WEB- | Empty | Added in front of the WooCommerce order number in OptimoRoute. Useful when several shops use the same OptimoRoute account. |
2.6 Address geocoding
OptimoRoute converts the address into a location on the map. The plugin sends the full address on one line, including state and country name, for the best result. These options decide what happens when OptimoRoute is not completely sure about the address.
Accept partial address matches (Default: Enabled, recommended)
For example when the house number addition is unknown to the map provider. The order is created and OptimoRoute's warning is added to the WooCommerce order as a note ("OptimoRoute warning: ... Please check the address in OptimoRoute."). Sent as acceptPartialMatch.
Accept addresses with multiple matches (uses the first match) (Default: Disabled)
When OptimoRoute finds several locations for the address, the first one is used instead of returning an error. Sent as acceptMultipleResults.
Create the order even when the address cannot be found (Default: Disabled)
The order is created without a valid location and must be fixed in OptimoRoute before it can be planned. Sent as storeInvalid.
2.7 Delivery date & time window
OptimoRoute requires a date for every order. The delivery date chosen by the customer is sent as the OptimoRoute order date, and a chosen time slot (e.g. "09:00 - 12:00") is sent as the time window.
Delivery date plugin
Auto-detect (Default)
Checks the fields of all supported plugins below
Order Delivery Date for WooCommerce (Tyche)
Lite and Pro versions (_orddd_lite_timestamp, _orddd_timestamp, orddd_timestamp)
Iconic WooCommerce Delivery Slots
jckwds_date_ymd, jckwds_timestamp, jckwds_date, _jckwds_date
Other plugin using a "delivery_date" field
_delivery_date, delivery_date, _iconic_delivery_date, _wc_delivery_date, ywcdd_order_delivery_date, _ywcdd_order_delivery_date
Custom field
Enter the order meta key that holds the delivery date in "Custom field name" (for example _delivery_date). Supported formats: timestamp, YYYY-MM-DD or DD-MM-YYYY.
When no delivery date is found
Used when the order has no delivery date, or when the chosen date lies in the past.
Use the next business day (Mon-Fri)
Default. Saturday and Sunday are skipped.
Use tomorrow
Always the next calendar day.
Use today
For same-day delivery.
Time window
Time slots are read from these order fields: jckwds_timeslot, _jckwds_timeslot, _orddd_time_slot, _orddd_lite_time_slot, orddd_time_slot, _delivery_time, delivery_time and ywcdd_order_slot_from. Both 24-hour ("09:00 - 12:00") and am/pm notation are understood.
Use a default time window when the customer didn't choose a time slot
When enabled, the From/Until times below are sent as the time window for orders without a time slot.
From / Until
Earliest and latest time for the delivery
Format: HH:MM (24-hour)
2.8 Display & advanced
Show a OptimoRoute status column in the orders list
Adds an "OptimoRoute" column next to the order status in WooCommerce → Orders (see section 3.6).
Default: Enabled
Enable debug logging
Writes detailed information to WooCommerce → Status → Logs (source: fleetconnector-optimoroute). Errors, warnings and important events are always logged, even when debug logging is off.
Default: Disabled
Enable it temporarily while troubleshooting. Your OptimoRoute API key is never written to the logs.
Danger Zone
At the bottom of the settings page you'll find two irreversible actions:
Switch OptimoRoute account → "Remove all OptimoRoute links"
Removes the link between your WooCommerce orders and OptimoRoute, so orders can be sent to a new account. Nothing is deleted in OptimoRoute. Large shops may need to click the button again to continue ("... orders cleaned up so far. Click the button again to continue.").
Clear Activity Logs
Clears all FleetConnector OptimoRoute activity logs from the dashboard.
Features
FleetConnector OptimoRoute sends orders automatically, but also gives you full manual control from the orders list and the order screen.
3.1 Safe, duplicate-free order sending
Orders are sent with OptimoRoute's create_order method, using two different operations:
SYNC: first send
Creates the order, or replaces an existing order with the same order number. A retry after a timeout can therefore never create a duplicate order.
MERGE: updates
Updates the order by its OptimoRoute ID and only changes the fields the plugin sends, so fields edited by your dispatcher in OptimoRoute are kept. Only sent when something relevant changed.
After a successful first send:
- • The OptimoRoute ID, order number and delivery date are stored on the order
- • The order gets the note "Order sent to OptimoRoute (WEB-1234) for [date]."
- • The OptimoRoute status starts as "Unscheduled"
- • A warning from OptimoRoute (such as a partial address match) is added as an extra order note
3.2 Background processing and automatic retries
With "Send orders in the background" enabled, every API call for an order (create, update, delete and fetching delivery details) is queued in the WooCommerce Action Scheduler as fco_process_order in the group fleetconnector-optimoroute. Only one pending action per order and action type is queued.
Retry schedule for temporary errors
1 min
1st retry
5 min
2nd retry
15 min
3rd retry
Temporary errors are network timeouts, HTTP 429 and 5xx responses, and the OptimoRoute codes ERR_TOO_MANY_CONNECTIONS, ERR_INTERNAL and ERR_OPT_RUNNING. Other errors (for example an address that can't be found) are not retried, because retrying wouldn't help.
3.3 Order actions (single order)
Open any order and use the "Order actions" dropdown in the right column. Order actions run immediately, so you see the result right away.
Send to OptimoRoute
Shown when the order has not been sent yet. Creates the order in OptimoRoute (also when automatic sending is disabled or the status doesn't match).
Update order in OptimoRoute
Shown when the order was already sent. Always pushes the current order data, even if nothing changed.
Remove from OptimoRoute
Shown when the order was already sent. Deletes the OptimoRoute order and removes the link, so the order can be sent again later. Orders on a live plan are protected (see section 2.4).
3.4 Bulk actions
Send or update many orders at once from WooCommerce → Orders (works with HPOS and legacy order storage).
How to use bulk actions
- Go to WooCommerce → Orders
- Check the boxes next to the orders you want to process
- Select "Send to OptimoRoute" or "Update in OptimoRoute" from the Bulk Actions dropdown
- Click "Apply"
- A notice confirms how many orders are being processed and how many were skipped
What happens during bulk processing:
- • Send to OptimoRoute skips orders that were already sent and orders that don't need a delivery
- • Update in OptimoRoute skips orders that were not sent yet, and only sends orders whose data changed
- • With background processing, the orders are queued and sent within moments
- • All results are logged in the FCO Dashboard
3.5 OptimoRoute Delivery meta box
When editing any WooCommerce order, the "OptimoRoute Delivery" meta box in the side column shows everything the plugin knows about the delivery. Empty rows are hidden.
Information displayed
- OptimoRoute order: The order number in OptimoRoute (e.g. WEB-1234)
- Status: Unscheduled, Scheduled, On route, Driver at the address, Delivered, Failed, Rejected or Cancelled
- Delivery date: The date sent to OptimoRoute
- Driver: Name of the driver
- Stop: Stop number on the driver's route
- Planned arrival: Live estimate or planned time of arrival
- Completed at: When the driver completed the order
- Driver note: Note entered by the driver in the OptimoRoute app
- Proof of delivery: Signature and number of photos
- Sent / Last update: When the order was sent and last updated
- Open delivery tracking →: Link to the OptimoRoute tracking page (when order tracking is set up in OptimoRoute)
- Last error: The most recent error, shown in red
3.6 OptimoRoute status column
The "OptimoRoute" column appears right after the order status column in the orders list. Hover over an icon to see the details.
Status indicators
Delivered
Sent to OptimoRoute (tooltip shows the current status, e.g. Scheduled)
Failed, rejected or cancelled in OptimoRoute
Sending failed (tooltip shows the error)
Not sent, or no delivery required
3.7 Driver instructions
The OptimoRoute notes field is filled with clear instructions for the driver. HTML is stripped and the text is limited to 2,000 characters.
Example
Order #1234 Customer note: Please ring the bell twice Items: 2x T-shirt (Size: M, Color: Blue) 1x Gift card Collect payment on delivery: €45.00
- The customer note is included when the customer left one
- Products and their options are included when "Add the ordered products to the driver instructions" is enabled
- For cash on delivery orders the amount to collect is shown; for other orders "Payment: [payment method]"
Delivery Status Sync
OptimoRoute has no webhooks. Instead, FleetConnector OptimoRoute regularly asks OptimoRoute what happened and updates your WooCommerce orders. There is nothing to set up in OptimoRoute.
4.1 Status sync settings
Find these in the "Delivery Status Sync" card on the settings page.
Sync delivery status from OptimoRoute
Default: Enabled. Turns the background jobs described below on or off. Status sync also needs a saved API key and a valid license.
Order status when delivered
For example "Completed", so the customer receives the WooCommerce "order completed" email.
Default: Do not change status
Order status when the delivery failed or was rejected
Choose any WooCommerce status (including custom statuses), or leave it unchanged.
Default: Do not change status
Save driver name, stop number and planned arrival time on the order
Default: Enabled. Shown in the OptimoRoute Delivery meta box.
Email the OptimoRoute tracking link to the customer
Default: Disabled. Adds the tracking link as a customer note ("Track your delivery: ..."), which WooCommerce sends by email. Sent once, as soon as OptimoRoute provides the link and before the delivery is completed. Requires order tracking in OptimoRoute.
Sync now
Runs both sync jobs immediately and reports the result, e.g. "Status sync finished: 3 new event(s) processed, 2 order(s) updated." The time of the last sync is shown next to the button ("Last sync: ...").
4.2 How the sync works
Two recurring jobs run in the WooCommerce Action Scheduler (group fleetconnector-optimoroute). They are created automatically when status sync is enabled and an API key is saved, and removed when you turn status sync off.
Every 5 minutes: driver events
fco_poll_events
Reads new events from the OptimoRoute mobile app with get_events. A cursor (tag) is remembered, so every event is processed only once. Events that arrive late (for example when a driver was offline) never overwrite a newer status.
Every hour: reconciliation
fco_reconcile_statuses
Checks all open orders created in the last 21 days that were sent to OptimoRoute with get_completion_details. This catches cancelled orders and anything the event feed didn't report.
4.3 Processed driver events
The plugin finds the WooCommerce order by its OptimoRoute ID (or order number) and handles these events:
1 start_service
When triggered: The driver arrives and starts working on the order.
- OptimoRoute status is set to "Driver at the address"
- Driver name is saved (if enabled)
2 success
When triggered: The driver marks the order as completed.
- Order note "OptimoRoute: order delivered by [driver]."
- WooCommerce status changes to "Order status when delivered" (if set)
- Completion time is saved; proof of delivery, driver note and tracking link are fetched right after
- Logged in the FCO Dashboard as "Status sync"
3 failed / rejected
When triggered: The delivery attempt failed, or the driver rejected the order.
- Order note "OptimoRoute: delivery failed by [driver]." or "OptimoRoute: order rejected by [driver]."
- WooCommerce status changes to "Order status when the delivery failed or was rejected" (if set)
- Completion time is saved; the driver's note and proof of delivery are fetched right after
- Logged in the FCO Dashboard as a failed "Status sync"
4 start_time_changed
When triggered: The planned arrival time of the order changed.
- The new planned arrival time is saved on the order
4.4 OptimoRoute statuses and what happens in WooCommerce
| OptimoRoute status | Shown as | Effect on the WooCommerce order |
|---|---|---|
| unscheduled | Unscheduled | Set when the order is created in OptimoRoute |
| scheduled | Scheduled | Driver, stop number, planned arrival and tracking link are fetched |
| on_route | On route | Driver, stop number, planned arrival and tracking link are fetched |
| servicing | Driver at the address | Status saved on the order |
| success | Delivered | Order note, optional status change, proof of delivery saved |
| failed | Failed | Order note, optional status change, driver note saved |
| rejected | Rejected | Order note, optional status change, driver note saved |
| cancelled | Cancelled | Order note "OptimoRoute: order cancelled." (the WooCommerce status is not changed) |
4.5 Delivery details stored on the order
After a final status (and when an order becomes scheduled), the plugin fetches the details with get_completion_details and get_scheduling_info:
Driver and stop number
Who delivers the order and at which stop of the route.
Planned arrival
The live arrival estimate when available, otherwise the scheduled time.
Driver note
The note the driver entered in the proof of delivery form.
Proof of delivery
Whether a signature was captured and how many photos were taken.
Completion time
When the driver completed the order.
Tracking link
The OptimoRoute customer tracking page (requires order tracking in OptimoRoute).
Dashboard
The FleetConnector OptimoRoute Dashboard provides complete visibility into all WooCommerce to OptimoRoute activity.
5.1 Accessing the dashboard
Access the dashboard by navigating to:
There is also a "Dashboard" link at the top of the settings page. The unfiltered first page refreshes itself every 60 seconds.
5.2 Statistics overview
At the top of the dashboard, you'll see six statistics cards based on the activity log:
Total Actions
All logged actions
Successful
Actions that succeeded
Failed
Actions that failed
Pending
Actions still waiting
Today
Actions logged today
This Week
Actions since Monday
5.3 Activity log and filters
The activity log shows every create, update, delete and status sync action, 50 entries per page, newest first.
Filters
- Status: All Statuses, Success, Failed, Pending
- Action: All Actions, Create, Update, Delete, Status sync
- Date range: From and To date
- Click "Filter" to apply, "Reset" to clear all filters
Log columns
- ID: Log entry number
- Order: WooCommerce order (clickable link to the order)
- OptimoRoute Order: The order number in OptimoRoute
- Action: Create, Update, Delete or Sync
- Status: Success, Failed or Pending
- Message: What happened, with the error message in red for failures
- Date: When the action took place
- Actions: "Retry" (failed create and update actions) and "Details"
5.4 Details and retry
Details
"Details" opens a window with the exact request sent to OptimoRoute ("Request Data") and the response ("Response Data"), formatted as JSON. This is the quickest way to see why OptimoRoute refused an order.
How to retry
- Filter the log on status "Failed"
- Fix the cause (for example the shipping address of the order)
- Click "Retry" and confirm
- The order is sent (or updated) immediately and the page reloads
5.5 Export to CSV
Export your activity log to CSV for analysis, reporting, or record-keeping.
How to export
- Select the filters you want (status, action, date range)
- Click the "Export CSV" button
- The filtered results download as fleetconnector-optimoroute-logs-YYYY-MM-DD.csv
5.6 Log retention and WooCommerce logs
Activity log (FCO Dashboard)
Entries older than 90 days are removed by a daily clean-up. Developers can change the period with the fco_log_retention_days filter.
Technical log
API errors, retries and sync results are written to WooCommerce → Status → Logs with the source fleetconnector-optimoroute. Enable debug logging for more detail.
Technical Details
Understanding how FleetConnector OptimoRoute works behind the scenes.
6.1 How the integration works
FleetConnector OptimoRoute connects WooCommerce to the OptimoRoute Web Service API using WordPress hooks, the WooCommerce Action Scheduler and direct HTTPS requests.
WooCommerce → OptimoRoute flow
Order reaches a trigger status (e.g. Processing); the plugin hooks into woocommerce_order_status_changed
The order is checked (not sent yet, needs a delivery) and queued as fco_process_order
Address, delivery date, time window and instructions are collected and the payload is built
The payload is sent to POST /create_order with operation SYNC
The OptimoRoute ID, order number and delivery date are saved to the order meta and the action is logged
Later order edits (woocommerce_update_order) are sent with operation MERGE when the payload changed
6.2 OptimoRoute API endpoints
Base URL: https://api.optimoroute.com/v1. The API key is passed as the key query parameter on every request. Requests time out after 30 seconds.
| Method | Endpoint | Used for |
|---|---|---|
| GET | /get_routes | Test Connection (read-only, today's date) |
| POST | /create_order | Create (operation SYNC) and update (operation MERGE with the OptimoRoute id) |
| POST | /delete_orders | Remove an order (by id, forceDelete false) |
| GET | /get_events | Driver events every 5 minutes (after_tag cursor, up to 10 pages per run) |
| POST | /get_completion_details | Status, proof of delivery, driver note and tracking link (up to 500 orders per request) |
| GET | /get_scheduling_info | Driver name, stop number and planned arrival of one order |
6.3 Data sent to OptimoRoute
How WooCommerce order data maps to OptimoRoute order fields:
| OptimoRoute field | WooCommerce source |
|---|---|
| operation | SYNC on first send, MERGE for updates |
| id | Updates only: the stored OptimoRoute ID |
| orderNo | Order number prefix + WooCommerce order number (e.g. WEB-1234) |
| type | Order type setting: D (Delivery), P (Pickup) or T (Task) |
| date | Customer's delivery date (YYYY-MM-DD); otherwise the fallback: next business day, tomorrow or today. Always sent, because OptimoRoute requires it. |
| location.address | Shipping address (billing as fallback) on one line: street, postcode + city, state, country name |
| location.locationName | Shipping name (billing as fallback), as "Company - Name" when a company is set, otherwise "Order 1234" |
| location.acceptPartialMatch | "Accept partial address matches" setting |
| location.acceptMultipleResults | "Accept addresses with multiple matches" setting |
| location.storeInvalid | Only sent (true) when "Create the order even when the address cannot be found" is enabled |
| duration | "Service time per stop (minutes)"; not sent when 0 (OptimoRoute account default is used) |
| timeWindows | [{twFrom, twTo}] from the customer's time slot, or the default time window when enabled |
| priority | Priority setting: L, M, H or C |
| load1 | Number of items, or total product weight (in your store's weight unit); only when a load mode is selected |
| phone | Shipping phone (billing phone as fallback), converted to international E.164 format using the calling code of the address country |
| Billing email (only when valid) | |
| notificationPreference | dont_notify, email, sms or both; not sent when "Use the OptimoRoute account setting" is selected |
| notes | Driver instructions: order number, customer note, items and payment info (max. 2,000 characters) |
Example payload (first send)
{
"operation": "SYNC",
"orderNo": "WEB-1234",
"type": "D",
"date": "2026-09-29",
"location": {
"address": "Keizersgracht 123, 1015 CJ Amsterdam, Netherlands",
"locationName": "Jane Doe",
"acceptPartialMatch": true,
"acceptMultipleResults": false
},
"notes": "Order #1234\n\nItems:\n2x T-shirt (Size: M)\n\nPayment: Credit card",
"duration": 5,
"timeWindows": [
{
"twFrom": "09:00",
"twTo": "12:00"
}
],
"priority": "M",
"load1": 2,
"phone": "+31612345678",
"email": "jane.doe@example.com",
"notificationPreference": "email"
}
6.4 Order meta keys
The plugin stores its data as WooCommerce order meta (HPOS compatible). Use these keys in your own code or exports.
| Meta key | Description |
|---|---|
| _optimoroute_id | OptimoRoute order ID (the link between both systems) |
| _optimoroute_order_no | Order number used in OptimoRoute |
| _optimoroute_created | When the order was sent |
| _optimoroute_updated | When the order was last updated |
| _optimoroute_status | OptimoRoute status (unscheduled, scheduled, on_route, servicing, success, failed, rejected, cancelled) |
| _optimoroute_delivery_date | Date sent to OptimoRoute (YYYY-MM-DD) |
| _optimoroute_last_error | Most recent error message |
| _optimoroute_tracking_url | Customer tracking link |
| _optimoroute_payload_hash | Fingerprint of the last payload (used to skip unchanged updates) |
| _optimoroute_driver_name | Driver name |
| _optimoroute_stop_number | Stop number on the route |
| _optimoroute_scheduled_at | Planned arrival time |
| _optimoroute_completed_at | Completion time |
| _optimoroute_driver_note | Note entered by the driver |
| _optimoroute_pod | Proof of delivery: array with signature (true/false) and photos (count) |
| _optimoroute_event_ts | Timestamp of the last applied driver event (out-of-order protection) |
| _optimoroute_retry_{action} | Retry counter per action (create, update, delete, refresh) |
6.5 Developer hooks and filters
Developers can customize FleetConnector OptimoRoute with WordPress filters and actions. Add them to your child theme's functions.php or a small custom plugin.
Available filters
| Filter | Arguments | Description |
|---|---|---|
| fco_order_payload | $payload, $order | The complete OptimoRoute order payload. Use it to add skills, vehicleFeatures, customFields, assignedTo, etc. |
| fco_order_update_payload | $payload, $order | The MERGE payload for updates (includes the OptimoRoute id) |
| fco_order_no | $order_no, $order | The OptimoRoute order number (only for orders not sent yet) |
| fco_force_delete | false, $order | Return true to also delete orders on a live plan |
| fco_order_needs_delivery | $needs_delivery, $order | Decide whether an order needs a delivery |
| fco_delivery_date | $date, $order | The delivery date (YYYY-MM-DD) |
| fco_delivery_date_meta_keys | $keys, $order | Order meta keys that are checked for a delivery date |
| fco_time_window | $window, $order | The time window: array with start and end (HH:MM), or null |
| fco_time_slot_meta_keys | $keys, $order | Order meta keys that are checked for a time slot |
| fco_recipient_name | $name, $order | The location name |
| fco_address_parts | $parts, $order | The address parts (address_1, address_2, postcode, city, state, country) |
| fco_full_address | $address, $order | The single-line address sent for geocoding |
| fco_phone | $phone, $order | The formatted phone number |
| fco_phone_country_code | $calling_code, $country | The calling code used for national phone numbers |
| fco_instruction_lines | $lines, $order | The lines of the driver instructions |
| fco_load | $load, $order | The load value (null = not sent) |
| fco_excluded_shipping_methods | $methods | Shipping methods that don't need a delivery (default: local_pickup, pickup_location, local_pickup_plus) |
| fco_log_retention_days | 90 | Days to keep activity logs (0 disables the clean-up) |
| fco_lemonsqueezy_product_id | $product_id | Lemon Squeezy product ID the license must belong to |
Available actions
| Action | Arguments | Runs when |
|---|---|---|
| fco_order_created | $id, $order, $response | The order was created in OptimoRoute |
| fco_order_updated | $id, $order, $response | The order was updated in OptimoRoute |
| fco_order_deleted | $id, $order | The order was removed from OptimoRoute |
| fco_order_create_failed fco_order_update_failed fco_order_delete_failed |
$order, $error | An API action failed ($error is a WP_Error) |
| fco_order_status_success fco_order_status_failed fco_order_status_rejected fco_order_status_cancelled |
$order, $data | A final OptimoRoute status was applied to the order |
| fco_event_start_service fco_event_success fco_event_failed fco_event_rejected fco_event_start_time_changed |
$order, $event | A driver event was processed for the order |
Examples
fco_order_payload
Add skills and custom fields to the OptimoRoute order. Skills and custom fields must already exist in OptimoRoute, otherwise OptimoRoute refuses the order.
add_filter('fco_order_payload', function ($payload, $order) {
// Only drivers with the "COOLING" skill can deliver chilled products
if ($order->get_meta('_contains_chilled_products') === 'yes') {
$payload['skills'] = array('COOLING');
}
// Custom field "shop" must be defined in OptimoRoute first
$payload['customFields'] = array(
'shop' => 'Webshop',
);
return $payload;
}, 10, 2);
fco_order_no
Use your own order number format in OptimoRoute. The number is stored when the order is first sent, so already sent orders keep their number.
add_filter('fco_order_no', function ($order_no, $order) {
return 'SHOP1-' . $order->get_order_number();
}, 10, 2);
fco_delivery_date_meta_keys
Read the delivery date from a meta key of a delivery date plugin that isn't supported out of the box.
add_filter('fco_delivery_date_meta_keys', function ($keys, $order) {
$keys[] = '_my_plugin_delivery_date';
return $keys;
}, 10, 2);
fco_order_status_success
Run your own code when OptimoRoute reports a delivered order.
add_action('fco_order_status_success', function ($order, $data) {
$order->add_order_note('Delivered - thank-you email scheduled.');
}, 10, 2);
6.6 Scheduled jobs
| Hook | Scheduler | Interval | Purpose |
|---|---|---|---|
| fco_process_order | Action Scheduler | On demand | Create, update, delete or refresh one order (with retries) |
| fco_poll_events | Action Scheduler | Every 5 minutes | Read driver events (cursor stored in the option fco_events_tag) |
| fco_reconcile_statuses | Action Scheduler | Every hour | Reconcile open orders of the last 21 days |
| fco_cleanup_logs | WP-Cron | Daily | Remove activity logs older than the retention period |
| fco_weekly_license_check | WP-Cron | Weekly | Re-validate the license |
All Action Scheduler jobs use the group fleetconnector-optimoroute. The time of the last status sync is stored in the option fco_last_status_sync; all settings are stored as options with the prefix fco_.
6.7 Database structure
FleetConnector OptimoRoute creates one custom table for the activity log. The table is created on activation and upgraded automatically after plugin updates.
Table: {prefix}fco_logs (e.g. wp_fco_logs)
| Column | Type | Description |
|---|---|---|
| id | BIGINT(20) UNSIGNED | Primary key |
| order_id | BIGINT(20) UNSIGNED | WooCommerce order ID |
| remote_id | VARCHAR(255) | OptimoRoute order number |
| action | VARCHAR(50) | create, update, delete or sync |
| status | VARCHAR(50) | success, failed or pending |
| message | TEXT | Human-readable message |
| request_data | LONGTEXT | JSON-encoded request payload |
| response_data | LONGTEXT | JSON-encoded API response |
| error_message | TEXT | Error message for failed actions |
| created_at | DATETIME | Timestamp |
| updated_at | DATETIME | Last change |
6.8 Deactivation and uninstall
Deactivate
Stops all scheduled jobs (license check, log clean-up and all Action Scheduler jobs of the plugin). Settings, logs and order data are kept.
Delete (uninstall)
- • Releases the license activation slot
- • Deletes all fco_ options and transients
- • Clears all scheduled jobs
- • Drops the {prefix}fco_logs table
Troubleshooting
Common issues and their solutions when using the WooCommerce to OptimoRoute integration.
7.1 Common issues
"OptimoRoute rejected the API key"
Solutions:
- Check in OptimoRoute under Administration → Settings → Account → WS API that the API is still enabled
- If the key was regenerated, copy the new key into the plugin settings
- Make sure the key was copied completely (the plugin removes spaces automatically)
- Click "Test Connection" and then "Save All Settings"; the notice disappears after the next successful request
Orders not sent to OptimoRoute
Solutions:
- Check that your license is active (License card shows "License Active")
- Verify "Automatically send orders to OptimoRoute" is enabled and the order status is one of the selected statuses
- Orders are only sent when the status changes to a selected status; for existing orders use the order action or bulk action
- With "Only send orders that need a delivery" enabled, virtual products and local pickup orders are skipped (the meta box says "This order does not require a delivery.")
- Check WooCommerce → Status → Scheduled Actions for pending or failed fco_process_order actions
- Check the FCO Dashboard and the "Last error" in the order's meta box
Address geocoding errors
Solutions:
- Check that the shipping address is complete (street and house number, postcode, city, country)
- Look for typos or extra text in the address fields
- ERR_LOC_GEOCODING_PARTIAL: enable "Accept partial address matches" (recommended)
- ERR_LOC_GEOCODING_MULTIPLE: make the address more specific, or enable "Accept addresses with multiple matches"
- ERR_LOC_GEOCODING: correct the address and click "Retry" in the dashboard, or enable "Create the order even when the address cannot be found" and fix the location in OptimoRoute
- An order note "OptimoRoute warning: ..." means the order was created, but the address should be checked in OptimoRoute
Delivery status not syncing
Solutions:
- Check that "Sync delivery status from OptimoRoute" is enabled, an API key is saved and the license is active
- Check WooCommerce → Status → Scheduled Actions for fco_poll_events and fco_reconcile_statuses (group fleetconnector-optimoroute). Pending actions that never run usually mean WP-Cron isn't running; set up a real server cron job if DISABLE_WP_CRON is set
- Driver events only exist for routes that were dispatched to the drivers' mobile app. Orders outside the dispatched plan are updated by the hourly reconciliation
- Only orders created in the last 21 days are reconciled
- Click "Sync now" on the settings page to run the sync immediately and see the result
- Check WooCommerce → Status → Logs (source fleetconnector-optimoroute) for "Event polling failed" or "Status reconciliation failed"
"OptimoRoute is currently planning routes" (ERR_OPT_RUNNING)
Solutions:
- OptimoRoute doesn't accept changes while a route optimization is running. This is a temporary error
- Automatic actions are retried after 1, 5 and 15 minutes
- For manual actions, wait until planning has finished and try again
Another order with the same order number is overwritten
Solutions:
- New orders are sent with the SYNC operation, which replaces an existing OptimoRoute order with the same orderNo. This prevents duplicates, but also means order numbers must be unique in your OptimoRoute account
- When several shops (or other systems) use the same OptimoRoute account, set a unique "Order number prefix" per shop, or use the fco_order_no filter
Order can't be removed from OptimoRoute
Solutions:
- Orders on a live (dispatched) plan are protected and can't be deleted through the API; remove the order from the route in OptimoRoute
- If the order was already deleted in OptimoRoute, the plugin simply removes the link
- Developers can allow deleting orders on a live plan with the fco_force_delete filter
Order changes don't reach OptimoRoute
Solutions:
- Verify "Automatically sync order changes to OptimoRoute" is enabled
- Orders that are Delivered, Failed, Rejected or Cancelled in OptimoRoute can no longer be changed
- Updates are skipped when the data sent to OptimoRoute didn't change; use "Update order in OptimoRoute" to force an update
- If the order was deleted in OptimoRoute, the link is removed with the note "The order no longer exists in OptimoRoute. The link was removed; you can send it again."
7.2 OptimoRoute error codes
These error codes appear in the FCO Dashboard, in order notes and in the WooCommerce logs.
| Code | Meaning | Retried automatically |
|---|---|---|
| AUTH_KEY_UNKNOWN | The API key is invalid (regenerated or API disabled). Shows the admin notice. | No |
| ERR_LOC_GEOCODING | OptimoRoute could not find this address. | No |
| ERR_LOC_GEOCODING_MULTIPLE | Multiple locations found for this address. | No |
| ERR_LOC_GEOCODING_PARTIAL | Only a partial match was found for this address. | No |
| WAR_LOC_GEOCODING_PARTIAL | Warning, not an error: the order was created with a partial match. Added to the order as a note. | n/a |
| ERR_TOO_MANY_CONNECTIONS | Too many simultaneous requests. OptimoRoute allows at most 5 concurrent requests per account. | Yes |
| ERR_OPT_RUNNING | OptimoRoute is currently planning routes. | Yes |
| ERR_INTERNAL | Temporary error at OptimoRoute. | Yes |
| ERR_ORD_NOT_FOUND | The order no longer exists in OptimoRoute. On update the link is removed so you can send it again; on delete it counts as removed. | No |
7.3 Getting support
If you can't resolve an issue using this documentation, we're here to help.
Before Contacting Support
Please gather the following information:
- WordPress version and WooCommerce version
- PHP version (visible in WooCommerce → Status)
- FleetConnector OptimoRoute plugin version
- Screenshot of error message or unexpected behavior
- Relevant entries from the FCO Dashboard ("Details") and WooCommerce → Status → Logs
- Order ID of affected order (if applicable)
How to Contact Us
Email Support
Send an email to support@fleetconnector.app or use our contact form
Response time: Within 24 hours on business days
Premium Support Included
Your FleetConnector OptimoRoute license includes priority email support and updates for one year.
7.4 Additional resources
OptimoRoute API Documentation
optimoroute.com/api: Official OptimoRoute Web Service API reference
WooCommerce Documentation
woocommerce.com/documentation: WooCommerce guides and tutorials
WooCommerce to OptimoRoute integration
Integration overview: Features, use cases and pricing
Launch announcement
Read the blog post: Why we built the WooCommerce to OptimoRoute integration
HPOS delivery integrations
WooCommerce HPOS and delivery integrations: What High-Performance Order Storage means for your delivery plugins