WooCommerce Delivery Integration & Automated Tasking
WooCommerce is one of the most flexible e-commerce platforms for delivery automation. With both webhooks and REST API support, you can create seamless integration from order to delivery confirmation – all happening automatically.
This guide provides everything you need to connect your WooCommerce store to our delivery automation system.
Integration Overview: Two Methods Available
WooCommerce supports both webhook (one-way) and REST API (two-way) integration:
Method 1: Webhooks (Simpler, One-Way)
How it works: Your store automatically sends order data to us when triggered
Best for:
- Quick setup without extensive technical knowledge
- Stores wanting automatic task creation
- Businesses comfortable with manual order status updates
Process:
- Customer places order
- You change order status to trigger delivery
- WooCommerce automatically posts order data to us
- We create delivery task
- We notify you via email of delivery progress
- You manually update order status when complete
Method 2: REST API (Advanced, Two-Way)
How it works: We can both read from and write to your WooCommerce store
Best for:
- Fully automated workflow
- Stores wanting automatic order status updates
- Businesses with technical resources for setup
Process:
- Customer places order
- You change order status to trigger delivery
- WooCommerce automatically posts order data to us (OR we monitor for status changes)
- We create delivery task
- We automatically update order status in your store (Dispatched, Completed, Failed)
- Customer sees real-time status in their order history
Recommendation: Start with webhooks (Method 1), upgrade to REST API (Method 2) as you scale.
WooCommerce Integration Capabilities
Built-in WooCommerce Features:
Third-Party Plugins (Optional but Recommended):
- WooCommerce Order Status Manager by SkyVerge – Custom order statuses
- WunderAutomation by Wundermatics – Advanced webhook automation
- Advanced Custom Fields (ACF) – Add custom date fields to orders
Note: We’re not affiliated with these providers – they’re recommended based on successful customer implementations.
JSON Schema: Required Data Format
When sending order data to us (via webhook or API), use this exact JSON structure:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "TheFrozenFoodCourierWooCommerceReceiver",
"description": "The Frozen Food Courier WooCommerce Receiver Webhook Schema",
"type": "object",
"properties": {
"senderID": {
"description": "The Frozen Food Courier Merchant Identifier",
"type": "string",
"$comment": "Obtain your Merchant Code by registering at thefrozenfoodcourier.co.za/register - REQUIRED"
},
"orderID": {
"description": "Order Identifier",
"type": "integer",
"$comment": "Retrieve via {{ order.id }} - REQUIRED"
},
"status": {
"description": "Order Status",
"type": "string",
"$comment": "Retrieve via {{ order.status }} - OPTIONAL (see Custom Order Statuses section)"
},
"number": {
"description": "Order Number",
"type": "string",
"$comment": "Retrieve via {{ order.number }} - OPTIONAL (requires Sequential Order Number Plugin)"
},
"customerEmail": {
"description": "Customer Email",
"type": "string",
"$comment": "Retrieve via {{ order.email }} - REQUIRED"
},
"customerNote": {
"description": "Customer Order Notes",
"type": "string",
"$comment": "Retrieve via {{ order.customer_note }} - OPTIONAL (include if notes contain access instructions)"
},
"billing_firstName": {
"description": "Billing First Name",
"type": "string",
"$comment": "Retrieve via {{ order.billing_first_name }} - REQUIRED"
},
"billing_lastName": {
"description": "Billing Last Name",
"type": "string",
"$comment": "Retrieve via {{ order.billing_last_name }} - REQUIRED"
},
"billing_company": {
"description": "Billing Company Name",
"type": "string",
"$comment": "Retrieve via {{ order.billing_company }} - OPTIONAL"
},
"billing_email": {
"description": "Billing Email",
"type": "string",
"$comment": "Retrieve via {{ order.billing_email }} - REQUIRED"
},
"billing_phone": {
"description": "Billing Phone Number",
"type": "string",
"$comment": "Retrieve via {{ order.billing_phone }} - REQUIRED (should be mobile number for SMS/WhatsApp)"
},
"billing_address1": {
"description": "Billing Address Line 1",
"type": "string",
"$comment": "Retrieve via {{ order.billing_address_1 }} - REQUIRED"
},
"billing_address2": {
"description": "Billing Address Line 2",
"type": "string",
"$comment": "Retrieve via {{ order.billing_address_2 }} - OPTIONAL"
},
"billing_city": {
"description": "Billing City",
"type": "string",
"$comment": "Retrieve via {{ order.billing_city }} - REQUIRED"
},
"billing_state": {
"description": "Billing State/Province",
"type": "string",
"$comment": "Retrieve via {{ order.billing_state }} - REQUIRED"
},
"billing_country": {
"description": "Billing Country",
"type": "string",
"$comment": "Retrieve via {{ order.billing_country }} - OPTIONAL"
},
"billing_postcode": {
"description": "Billing Postal Code",
"type": "string",
"$comment": "Retrieve via {{ order.billing_postcode }} - REQUIRED for address completeness"
},
"shipping_firstName": {
"description": "Shipping First Name",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_first_name }} - OPTIONAL (see Shipping Address section)"
},
"shipping_lastName": {
"description": "Shipping Last Name",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_last_name }} - OPTIONAL (see Shipping Address section)"
},
"shipping_phone": {
"description": "Shipping Phone Number",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_phone }} - OPTIONAL (see Shipping Address section)"
},
"shipping_company": {
"description": "Shipping Company Name",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_company }} - OPTIONAL (see Shipping Address section)"
},
"shipping_address1": {
"description": "Shipping Address Line 1",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_address_1 }} - OPTIONAL (see Shipping Address section)"
},
"shipping_address2": {
"description": "Shipping Address Line 2",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_address_2 }} - OPTIONAL (see Shipping Address section)"
},
"shipping_city": {
"description": "Shipping City",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_city }} - OPTIONAL (see Shipping Address section)"
},
"shipping_state": {
"description": "Shipping State/Province",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_state }} - OPTIONAL (see Shipping Address section)"
},
"shipping_country": {
"description": "Shipping Country",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_country }} - OPTIONAL (see Shipping Address section)"
},
"shipping_postcode": {
"description": "Shipping Postal Code",
"type": "string",
"$comment": "Retrieve via {{ order.shipping_postcode }} - OPTIONAL (see Shipping Address section)"
},
"dispatchReadyDate": {
"description": "Dispatch Ready Date",
"type": "string",
"$comment": "Retrieve via {{ order.acf | key: 'field_xxxx' }} - OPTIONAL (see Dispatch Ready Date section)"
},
"dispatchReadyDateMask": {
"description": "Date Format Mask",
"type": "string",
"$comment": "Enter date mask (example: YYYYMMDD) - OPTIONAL (see Dispatch Ready Date section)"
},
"taskAction": {
"description": "Task Action",
"type": "string",
"$comment": "REQUIRED - Enter either UPDATE or CANCELLED"
}
},
"required": [
"senderID",
"orderID",
"customerEmail",
"billing_firstName",
"billing_lastName",
"billing_email",
"billing_phone",
"billing_address1",
"billing_city",
"billing_state",
"billing_postcode",
"taskAction"
]
}
Understanding Key Fields
Required Fields (Must Be Included)
senderID – Your unique merchant code
- Obtain during registration at thefrozenfoodcourier.co.za/register
- Example:
TFFC-MERCHANT-001
orderID – WooCommerce internal order ID
- Numeric identifier (e.g.,
12345
) - Used to track deliveries back to specific orders
customerEmail – Customer’s email address
- Required for delivery notifications
- Primary contact method
Billing Information – Complete billing details
- Name, email, phone, address
- Used if shipping address not provided
taskAction – What to do with this task
UPDATE
– Create new task or update existingCANCELLED
– Cancel a previously created task
Optional but Recommended Fields
number – Sequential order number
- Human-friendly order reference (e.g.,
ORD-2024-001
) - Requires Sequential Order Number plugin
- Makes tracking easier for you and customers
shipping_* – Shipping address fields
- Preferred for delivery (see Shipping Address section below)
- Falls back to billing if not provided
customerNote – Order notes from customer
- Useful if customer included access instructions
- Example: “Gate code is 1234” or “Leave at back door”
dispatchReadyDate – When order will be ready
- Advanced feature for scheduling
- Requires custom field setup (see section below)
Shipping Address vs Billing Address
How We Handle Addresses
Not all WooCommerce stores require shipping addresses. Our validation process is smart:
If shipping address is provided:
- ✅ We use shipping address for delivery
- ✅ Billing information used for contact details
If shipping address is NOT provided:
- ✅ We automatically use billing address for delivery
- ✅ No manual intervention required
- ✅ Order processes smoothly
Best Practice: Configure your WooCommerce store to collect shipping addresses for physical goods. This ensures:
- Accurate delivery locations
- Billing address remains for invoicing
- Clear separation of purpose
If you sell digital + physical products: Only require shipping address for physical/frozen goods. WooCommerce can conditionally show shipping fields based on cart contents.
Custom Order Statuses
Custom order statuses allow intermediate tracking stages between order placement and completion.
Why Use Custom Statuses?
Without custom statuses:
- Processing → Completed
- No visibility into delivery progress
With custom statuses:
- Processing → Dispatch Ready → Dispatched → Out for Delivery → Completed
- Full visibility into delivery journey
- Better customer communication
Recommended Status Flow
1. DISPATCH READY (slug: wc-dispatch-ready
)
- Order is packed and ready for collection
- Triggers webhook to create delivery task
- We schedule pickup and delivery
2. DISPATCHED (slug: wc-dispatched
)
- We’ve collected the order
- Driver departed with goods
- Customer notified delivery is on the way
3. OUT FOR DELIVERY (slug: wc-out-for-delivery
)
- Driver actively heading to customer
- Real-time tracking active
- Imminent arrival
4. COMPLETED (slug: wc-completed
)
- Delivery successfully completed
- Customer received goods
- Task closed
5. FAILED DELIVERY (slug: wc-failed-delivery
)
- Delivery unsuccessful
- Requires rescheduling
- Customer contacted
Setting Up Custom Statuses
Option 1: WooCommerce Order Status Manager Plugin
- Install Order Status Manager
- Create custom statuses with desired slugs
- Configure status transitions
- Set email triggers (optional)
Option 2: Code (functions.php)
// Register custom order statuses
function register_custom_delivery_statuses() {
register_post_status( 'wc-dispatch-ready', array(
'label' => 'Dispatch Ready',
'public' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Dispatch Ready <span class="count">(%s)</span>', 'Dispatch Ready <span class="count">(%s)</span>' )
));
// Repeat for other statuses...
}
add_action( 'init', 'register_custom_delivery_statuses' );
Important: WooCommerce Analytics
Built-in WooCommerce Analytics only updates when order status = COMPLETED
Implication: If you use custom intermediate statuses (Dispatched, Out for Delivery), revenue won’t show in analytics until you manually change to Completed.
Solutions:
- Use REST API (we auto-update to Completed when delivered)
- Manually update orders to Completed after delivery confirmation
- Use third-party analytics that recognize custom statuses
Dispatch Ready Date (Advanced Feature)
For businesses that need to schedule deliveries in advance, you can add a “Dispatch Ready Date” to orders.
Use Cases
- Meal prep businesses: Meals prepared today, ready for delivery tomorrow
- Scheduled deliveries: Customer chooses delivery date at checkout
- Production schedules: Match delivery to production completion
How to Implement
Step 1: Add Custom Date Field
Use Advanced Custom Fields (ACF) or similar plugin:
- Create field group for “Order” post type
- Add “Date Picker” field
- Name it “Dispatch Ready Date”
- Note the field key (e.g.,
field_abc123
)
Step 2: Include in Webhook Payload
{
"dispatchReadyDate": "{{ order.acf | key: 'field_abc123' }}",
"dispatchReadyDateMask": "YYYY-MM-DD"
}
Step 3: We Schedule Accordingly
When we receive a dispatch ready date:
- Task created immediately (status: PLANNED)
- Collection/delivery scheduled for specified date
- Customer notified with confirmed date
Date Format Masks
Specify the format of your date field so we can parse it correctly:
Your Format | Mask | Example |
---|---|---|
2024-10-15 | YYYY-MM-DD | Standard ISO |
15/10/2024 | DD/MM/YYYY | South African |
15-10-2024 | DD-MM-YYYY | Alternative SA |
2024/10/15 | YYYY/MM/DD | Alternative ISO |
Why the mask is needed: Different systems interpret dates differently. The mask tells us exactly how to read your date format.
Receiving Delivery Status Updates
You have three methods to receive updates on delivery progress:
Method 1: Email Notifications (Simplest)
Setup: Configure during merchant registration
What you receive:
- Task accepted confirmation
- Validation status (if on hold)
- Planned confirmation
- Scheduled notification
- Dispatched notification
- En route notification
- Completed/Failed confirmation
Advantages:
- No technical setup required
- Works immediately
- Permanent record of all deliveries
Limitations:
- Requires manual order status updates
- Customer doesn’t see status in their WooCommerce account
Method 2: REST API (Automatic Updates)
Setup: Requires WooCommerce REST API credentials (read/write)
What happens:
- We automatically update order status in your store
- Customer sees real-time status in order history
- Complete automation loop
Status Updates We Perform:
Our Status | WooCommerce Status | When |
---|---|---|
PLANNED | wc-dispatch-ready or custom | Task in planning |
DISPATCHED | wc-dispatched or custom | Driver departed |
ENROUTE | wc-out-for-delivery or custom | Heading to customer |
COMPLETED | wc-completed | Delivery successful |
FAILED | wc-failed-delivery or custom | Delivery unsuccessful |
Setup Requirements:
- Generate REST API credentials (Settings → Advanced → REST API)
- Grant read/write permissions
- Provide credentials during merchant registration
- Map our statuses to your custom statuses (if using)
Advantages:
- Fully automated
- Real-time customer visibility
- Reduces manual work
- Better customer experience
Method 3: Webhook Response (Semi-Real-Time)
Setup: Create webhook receiver in WooCommerce (requires coding)
How it works:
- We post status updates to your webhook URL
- Your code processes the update
- You update order status programmatically
JSON Response Schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "TheFrozenFoodCourierResponder",
"description": "The Frozen Food Courier Webhook Response Schema",
"type": "object",
"properties": {
"senderID": {
"description": "The Frozen Food Courier Identifier",
"type": "string",
"$comment": "Always: THEFROZENFOODCOURIER"
},
"orderID": {
"description": "Your Order Identifier",
"type": "integer",
"$comment": "Your WooCommerce Order ID"
},
"orderStatus": {
"description": "Delivery Status",
"type": "string",
"$comment": "Statuses: PLANNED, DISPATCHED, ENROUTE, COMPLETED, FAILED"
}
},
"required": [
"senderID",
"orderID",
"orderStatus"
]
}
Advantages:
- Real-time updates
- Custom processing logic
- Full control over status handling
Limitations:
- Requires developer expertise
- More complex setup
Step-by-Step Setup Guide
Quick Start (Webhook Method)
Step 1: Register as Merchant
- Visit thefrozenfoodcourier.co.za/register
- Complete registration
- Receive merchant code
- Note webhook URL provided
Step 2: Install WunderAutomation (Recommended)
- Install WunderAutomation plugin
- Create new workflow
- Trigger: “Order status changed to Dispatch Ready”
- Action: “Send webhook”
- URL: [Provided webhook URL]
- Method: POST
- Content-Type: application/json
Step 3: Configure Webhook Payload
Map WooCommerce fields to our JSON schema:
{
"senderID": "YOUR_MERCHANT_CODE",
"orderID": "{{ order.id }}",
"customerEmail": "{{ order.email }}",
"billing_firstName": "{{ order.billing_first_name }}",
"billing_lastName": "{{ order.billing_last_name }}",
"billing_email": "{{ order.billing_email }}",
"billing_phone": "{{ order.billing_phone }}",
"billing_address1": "{{ order.billing_address_1 }}",
"billing_address2": "{{ order.billing_address_2 }}",
"billing_city": "{{ order.billing_city }}",
"billing_state": "{{ order.billing_state }}",
"billing_postcode": "{{ order.billing_postcode }}",
"taskAction": "UPDATE"
}
Step 4: Test the Integration
- Place test order
- Change status to “Dispatch Ready”
- Verify webhook fires
- Confirm we received task
- Check email for confirmation
Step 5: Go Live
- Process real orders normally
- Change status to “Dispatch Ready” when ready
- Delivery automation handles the rest
Advanced Setup (REST API Method)
Step 1-2: Same as Quick Start
Step 3: Generate REST API Credentials
- WooCommerce → Settings → Advanced → REST API
- Click “Add Key”
- Description: “The Frozen Food Courier Integration”
- User: Select admin user
- Permissions: Read/Write
- Generate API Key
- Save Consumer Key and Consumer Secret
Step 4: Provide API Credentials
- Login to merchant portal
- Settings → Integrations
- Enter Consumer Key and Consumer Secret
- Configure status mapping
- Save
Step 5: Configure Custom Statuses (If Using) Map our statuses to yours:
- Our PLANNED → Your “wc-dispatch-ready”
- Our DISPATCHED → Your “wc-dispatched”
- Our ENROUTE → Your “wc-out-for-delivery”
- Our COMPLETED → Your “wc-completed”
- Our FAILED → Your “wc-failed-delivery”
Step 6: Test End-to-End
- Place test order
- Change status to trigger delivery
- Verify task created
- Check status auto-updates in WooCommerce
- Confirm customer sees status changes
Troubleshooting
Problem: Webhook Not Firing
Check:
- ✓ Webhook URL is correct
- ✓ Order status trigger matches your custom status
- ✓ Webhook is enabled (not paused)
- ✓ WooCommerce webhooks are functioning (test with webhook.site)
Problem: Task Not Created
Check:
- ✓ Merchant code (senderID) is correct
- ✓ Required fields are populated (see JSON schema)
- ✓ JSON format is valid (use JSON validator)
- ✓ customerEmail, billing_phone, and address fields present
View Error Response: Check webhook delivery logs in WooCommerce for our error response explaining what’s missing.
Problem: Order Status Not Updating (REST API)
Check:
- ✓ API credentials are correct
- ✓ API user has admin permissions
- ✓ API permissions set to Read/Write (not just Read)
- ✓ Custom status slugs match exactly
- ✓ Status mapping configured correctly
Problem: Duplicate Tasks Created
Cause: Webhook firing multiple times for same order
Solution:
- We automatically reject duplicate order IDs for safety
- Check webhook trigger conditions (should fire only once per status change)
- Disable automatic retry in webhook configuration
Related Resources
Integration Guides:
- Delivery Automation Overview
- Work Order Processing
- Real-Time Tracking
WooCommerce Documentation:
Recommended Plugins:
Get Help
Technical Support: 📧 hello@thefrozenfoodcourier.co.za
We’re here to help with:
- Integration setup assistance
- Webhook configuration
- REST API implementation
- Custom requirements
- Troubleshooting
Don’t hesitate to reach out – we want your integration to work perfectly!
The Frozen Food Courier – Seamless WooCommerce integration for frozen food delivery