eBay Integration¶
Full eBay marketplace integration with OAuth 2.0 authentication, listing management via both Trading and Inventory REST APIs, order importing through the Fulfillment API, stock synchronization, and automatic shipping tracking updates.
| Module | ebay |
| Version | 18.0.1.0.1 |
| Category | Sales |
| License | LGPL-3 |
| Author | Longhorn Web Solutions |
Overview¶
The eBay Integration module connects your Odoo 18 instance with eBay's marketplace, providing a complete workflow from product listing through order fulfillment. It uses a dual-API approach: the Trading API handles auction listings and image uploads, while the modern REST Inventory API manages fixed-price listings. Orders are imported via the Fulfillment REST API.
Key capabilities:
- OAuth 2.0 authentication via a Cloudflare Worker proxy (no eBay API keys stored in Odoo)
- List, revise, relist, and end listings for both auction and fixed-price formats
- Multi-variant listing support through the Inventory API
- Import orders from eBay with automatic customer, address, and product matching
- Real-time stock synchronization with out-of-stock handling
- Automatic shipping tracking updates via the Fulfillment API
- Business policy sync (payment, return, and shipping policies)
- Category and shipping service synchronization
Installation & Dependencies¶
Odoo Module Dependencies¶
sale_managementdelivery
Python Dependencies¶
Pillow(for image validation)markupsafe
Prerequisites¶
- Odoo 18.0 Community or Enterprise
- An active eBay seller account
- Access to a Cloudflare Worker OAuth proxy (provided at
https://eb-auth.cloudffl.comby default)
Installation Steps¶
- Place the
ebaymodule directory in your Odoo addons path. - Restart the Odoo service.
- Navigate to Apps, remove the "Apps" filter, search for "eBay", and click Install.
OAuth 2.0 Setup¶
How Authentication Works¶
This module uses OAuth 2.0 for eBay API access. Rather than storing eBay application credentials (App ID, Cert ID, Dev ID) directly in Odoo, authentication is handled through a Cloudflare Worker proxy that securely manages the OAuth flow.
Odoo --> CF Worker Proxy --> eBay OAuth --> CF Worker Proxy --> Odoo Callback
The proxy:
- Holds the eBay application credentials securely
- Redirects the user to eBay's consent screen
- Exchanges the authorization code for tokens
- Returns the access and refresh tokens to Odoo via callback
Connecting to eBay¶
- Navigate to eBay > Configuration > Instance.
- Create a new instance or open the existing one.
- Set the Environment to Production or Sandbox.
- Verify the OAuth Proxy URL is set (default:
https://eb-auth.cloudffl.com). - Click Connect to eBay.
You will be redirected to eBay's authorization page. After granting access, you are returned to Odoo with the tokens automatically stored on the instance record.
Token Lifecycle
- Access Token: Valid for approximately 2 hours. Automatically refreshed by a cron job every 30 minutes.
- Refresh Token: Valid for approximately 18 months. When it expires, you must reconnect via the Connect button.
- Automatic Retry: If an API call receives a 401 response, the module attempts a token refresh and retries once before failing.
Connection Status¶
The Connection Status field on the instance form shows one of:
| Status | Meaning |
|---|---|
| Connected | Tokens are valid and active |
| Token Expired - Will Auto-Refresh | Access token expired but refresh token is valid |
| Refresh Token Expired - Reconnect Required | Both tokens expired; click Connect to eBay again |
| Not Connected | No tokens stored |
Testing the Connection¶
Click Test Connection to verify your credentials. On success, the module fetches and stores:
- Your eBay username
- Account currency, country, and site ID
- Selling privileges status
Disconnecting¶
Click Disconnect to clear all stored OAuth tokens from the instance.
Instance Configuration¶
The instance record controls global eBay settings.
| Setting | Description |
|---|---|
| Instance Name | Descriptive label |
| Company | Associated Odoo company |
| Environment | Production or Sandbox |
| OAuth Proxy URL | Cloudflare Worker URL for OAuth |
| eBay Currency | Currency for eBay transactions |
| Country | Seller's country |
| eBay Website | eBay site (US, UK, DE, etc.) |
| Zip / Location | Seller's postal code and location text |
| Setting | Description |
|---|---|
| Gallery Plus | Enable Gallery Plus for enhanced image display |
| Out Of Stock | Keep listings active when stock reaches zero (sets status to "Out Of Stock" instead of ending) |
| eBay Sales Team | Assign imported orders to a specific CRM sales team |
| Setting | Description |
|---|---|
| Order Import Range | Since Last Sync, or a fixed window (7, 14, 30, 60, 90 days) |
| Sync Paid Orders | Import orders with PAID or PARTIALLY_REFUNDED status (default: enabled) |
| Sync Pending Orders | Import orders with PENDING payment status |
| Last Sync | Timestamp of the last successful order synchronization |
Initial Setup Checklist¶
After connecting to eBay, complete these configuration steps before listing products:
-
Sync Categories -- Click Sync Categories on the instance to import eBay's category taxonomy and your custom store categories.
-
Sync Policies -- Click Sync Policies to import your eBay business policies (payment, return, and shipping policies). These are required when creating listings.
-
Sync Shipping Services -- Click Sync Shipping Services to import available eBay shipping methods. Optionally create Odoo service products for each shipping method to properly record shipping revenue on orders.
-
Fetch Listings -- Click Fetch Listings to import your existing active eBay listings. This creates
ebay.listingrecords that can be linked to Odoo products.
Listing Management¶
Listing Types¶
The module supports two listing types, each using a different eBay API:
| Type | API | Durations |
|---|---|---|
Auction (Chinese) |
Trading API | 3, 5, 7, 10 days |
Fixed Price (FixedPriceItem) |
REST Inventory API | 3, 5, 7, 10, 30 days, or Good 'Til Cancelled |
Configuring a Product for eBay¶
- Open a product in Sales > Products.
- Navigate to the eBay tab.
- Check Use eBay to enable eBay selling.
- Fill in the required fields:
| Field | Description |
|---|---|
| Title | eBay listing title (max 80 characters) |
| Category | Primary eBay category (leaf categories only) |
| Item Condition | Product condition (e.g., New, Used) |
| Listing Type | Auction or Fixed Price |
| Duration | How long the listing runs |
| Payment Policy | eBay payment business policy |
| Return Policy | eBay return business policy |
| Shipping Policy | eBay shipping/fulfillment business policy |
Auction listings:
| Field | Description |
|---|---|
| Starting Price | Opening bid amount |
| Buy It Now Price | Optional immediate purchase price |
Fixed-price listings:
| Field | Description |
|---|---|
| eBay Fixed Price | Sale price on eBay |
| Field | Description |
|---|---|
| Subtitle | Secondary title text (max 55 characters, fees apply) |
| Category 2 | Optional secondary eBay category (fees may apply) |
| Store Category / Store Category 2 | Custom store categories |
| Description | HTML product description |
| Description Template | Odoo mail template for rendering description |
| Allow Best Offer | Let buyers submit offers |
| Private Listing | Hide buyer identity |
| Use Stock Quantity | Sync eBay quantity from Odoo inventory |
| Quantity On eBay | Manual quantity override (when stock sync is off) |
Creating a Listing¶
Click List on eBay from the product form.
For Auction listings, the module:
- Uploads product images via the Trading API
- Calls
AddItemwith the full item specification - Fetches the listing details to store the URL and start date
For Fixed-Price listings, the module uses a three-step Inventory API flow:
- Create Inventory Item -- Uploads product data (title, description, condition, aspects, images, availability) to eBay's inventory
- Create Offer -- Defines pricing, category, and policies for the listing
- Publish Offer -- Makes the listing live on eBay
Multi-Variant Listings¶
For products with multiple variants, the fixed-price flow extends to:
- Create an inventory item for each variant (each with its own SKU)
- Create an inventory item group that ties the variants together
- Create and publish offers for each variant
Each variant maintains its own:
- SKU (
ebay_sku) - Offer ID (
ebay_offer_id) - Quantity and price
- Variation-specific attributes (size, color, etc.)
Revising a Listing¶
Click Revise to update an active listing with changes made in Odoo. The module re-uploads images and updates the listing data through the appropriate API (Trading for auctions, Inventory for fixed-price).
Ending a Listing¶
Click End Listing to remove the listing from eBay.
- Auctions use
EndItemvia the Trading API with reason "NotAvailable" - Fixed-price listings withdraw the offer via the Inventory API
Relisting¶
Click Relist to create a new listing from an ended one. The module rebuilds the item data, uploads fresh images, and publishes through the appropriate API.
Linking Existing Listings¶
To connect an existing eBay listing to an Odoo product, use the Link eBay Listing wizard on the product form. You can link by:
- eBay SKU (Inventory API) -- Fetches the inventory item and offer data from eBay's REST API
- eBay Item ID (Trading API) -- Fetches full item details via
GetItem
Both methods populate the product's eBay fields (title, price, category, policies, condition, quantity) from the live listing data.
Fetched Listings¶
The eBay Listings view (under eBay > Listings) shows all active listings imported from eBay. Each listing record can be linked to an Odoo product either automatically (by matching eBay ID or SKU) or manually.
| Field | Description |
|---|---|
| Status | Linked (connected to a product) or Unlinked |
| eBay Item ID | The listing's unique identifier on eBay |
| SKU | Product SKU from the eBay listing |
| Price / Currency | Current listing price |
| Listing Type | Auction or Fixed Price |
| Quantity | Available quantity on eBay |
Order Importing¶
How Orders Are Imported¶
Orders are fetched using the eBay Fulfillment REST API (/sell/fulfillment/v1/order). The module filters by creation date range and payment status.
Manual Import¶
From the instance record, click Sync Orders. The module imports orders based on the configured import range and payment status filters.
Automatic Import¶
Enable the eBay: get new orders scheduled action. It runs every 15 minutes and imports orders since the last sync timestamp.
Order Processing Flow¶
For each order from eBay:
-
Duplicate Check -- Skip if an order with the same
client_order_ref(eBay Order ID) already exists. -
Customer Matching -- Find an existing partner by
ebay_id(eBay username), or create a new one. -
Shipping Address -- Extract and normalize the shipping address. If it matches the customer's address, reuse it; otherwise, create a child delivery contact.
-
Line Items -- For each line item:
- Match product by
ebay_id(eBay listing ID) - Fallback: match by SKU using a multi-field search (
default_code,sku_code,variant_sku) - If no match: create a new product from the eBay listing title
- Handle multi-variant matching via variation aspects
- Match product by
-
Shipping Line -- Create a service line for shipping costs, matched to a shipping service product when available.
-
Confirmation -- If all products have an eBay URL (fully linked), the order is automatically confirmed and invoiced. Orders with unlinked products remain as draft quotations.
-
Chatter Note -- An internal note is posted with the eBay order summary (buyer, payment status, total, shipping method, line items).
Payment Status Filtering¶
| Setting | Statuses Imported |
|---|---|
| Sync Paid Orders (default) | PAID, PARTIALLY_REFUNDED |
| Sync Pending Orders | PENDING |
Both can be enabled simultaneously.
Order Recovery¶
For recovering missed orders, use the eBay: orders recovery server action. Set date_from and date_to in the action code. Recovered orders are created as draft quotations (not auto-confirmed).
30-Day Limit
eBay's Fulfillment API limits order queries to 30-day windows. The module automatically splits larger date ranges into 30-day chunks and processes them sequentially.
Stock Synchronization¶
How Stock Sync Works¶
When Use Stock Quantity is enabled on a product, the module synchronizes Odoo's virtual_available quantity with the eBay listing.
Sync logic:
| Scenario | Action |
|---|---|
| Stock > 0 and quantity changed | Revise listing with new quantity |
| Stock reaches 0 with Out Of Stock enabled | Revise listing; set status to "Out Of Stock" |
| Stock reaches 0 without Out Of Stock | End listing; set status to "Ended" |
| Stock returns > 0 from "Out Of Stock" with Out Of Stock enabled | Revise listing to restore quantity |
| Stock returns > 0 from "Out Of Stock" without Out Of Stock | Relist the listing |
Sync Queue¶
When an order is imported, the affected products are added to a sync queue. The queue is processed after each order import cycle, updating eBay quantities to reflect the new inventory levels.
Automatic Stock Sync¶
Enable the eBay: synchronize stock scheduled action. It runs hourly and updates all products with ebay_use = True that have changed quantities.
Out Of Stock Control
Enable Out Of Stock on the instance to keep listings active at zero quantity. This preserves listing history, SEO value, and watch counts. When inventory is replenished, the listing automatically becomes active again.
Shipping & Tracking¶
Automatic Tracking Updates¶
When a delivery order is validated (marked as done) for an eBay sale order, the module automatically submits shipping fulfillment information to eBay via the Fulfillment REST API.
What gets submitted:
| Field | Source |
|---|---|
| Line Items | All line items from the eBay order |
| Shipped Date | Current UTC timestamp |
| Tracking Number | From carrier_tracking_ref on the delivery |
| Shipping Carrier | From carrier_id.name on the delivery (cleaned to alphanumeric) |
How It Works¶
- When
stock.pickingis marked as done and the destination is a customer location, the module checks if the related sale order originated from eBay. - It fetches the eBay order details to obtain line item IDs.
- It constructs a shipping fulfillment payload and posts it to
/sell/fulfillment/v1/order/{orderId}/shipping_fulfillment.
Carrier Name Format
The carrier name is sanitized to contain only alphanumeric characters and underscores before being sent to eBay. Ensure your Odoo carrier names are recognizable by eBay (e.g., "USPS", "FedEx", "UPS").
Image Handling¶
Image Requirements¶
eBay enforces the following requirements for product images:
| Requirement | Value |
|---|---|
| Minimum dimension | 500px on longest side |
| Maximum total dimensions | 12,000px (width + height) |
| Maximum file size | 12 MB |
| JPEG mode | Must be RGB |
| Maximum images per listing | 12 |
The module automatically validates images against these requirements before uploading.
Upload Process¶
Images are uploaded via the Trading API's UploadSiteHostedPictures endpoint (there is no REST equivalent). The uploaded URLs are then used in both auction and fixed-price listings.
Categories & Policies¶
eBay Categories¶
Categories are synchronized from eBay's Taxonomy REST API. Two types are supported:
| Type | Source | Description |
|---|---|---|
| eBay Categories | Taxonomy API | Official eBay marketplace categories |
| Store Categories | Trading API GetStore |
Custom categories from your eBay store |
Categories are stored with full hierarchy paths and only leaf categories can be assigned to products.
Business Policies¶
The module syncs three types of business policies from your eBay account:
| Policy Type | API Endpoint | Purpose |
|---|---|---|
| Payment | /sell/account/v1/payment_policy |
How buyers pay |
| Return | /sell/account/v1/return_policy |
Your return terms |
| Shipping | /sell/account/v1/fulfillment_policy |
Shipping options and costs |
Policies Required
You must have business policies configured in your eBay account before they can be synced. Each listing requires all three policy types to be assigned.
Item Conditions¶
Item conditions are automatically imported from eBay's Metadata API during category synchronization. Common conditions include:
| Code | Condition |
|---|---|
| 1000 | New |
| 1500 | New Other |
| 1750 | New with Defects |
| 2500 | Seller Refurbished |
| 3000 | Used - Excellent |
| 4000 | Used - Very Good |
| 5000 | Used - Good |
| 6000 | Used - Acceptable |
| 7000 | For Parts or Not Working |
Scheduled Actions¶
| Cron Job | Interval | Default | Description |
|---|---|---|---|
| eBay: refresh OAuth token | 30 minutes | Active | Refreshes access tokens for all connected instances |
| eBay: get new orders | 15 minutes | Inactive | Imports new orders since last sync |
| eBay: synchronize stock | 1 hour | Inactive | Updates eBay quantities from Odoo inventory |
| eBay: update categories | Daily | Inactive | Syncs eBay category taxonomy |
Token Refresh is Active by Default
The OAuth token refresh cron is the only one enabled by default. It keeps your connection alive by refreshing the access token before it expires.
Server Actions¶
| Action | Description |
|---|---|
| eBay: orders recovery | Manual recovery of missed orders for a specific date range. Edit the action to set date_from and date_to before running. |
Multi-Instance Support¶
The module supports multiple eBay instances, allowing you to manage multiple eBay accounts or environments from a single Odoo database.
Each instance maintains its own:
- OAuth tokens and connection status
- Categories, policies, and shipping services
- Order sync timestamp
- Sync queue
Products and orders are linked to their respective instance via the ebay_instance_id field. Scheduled actions iterate over all active, connected instances.
Troubleshooting¶
OAuth Connection Issues¶
Error: Refresh Token Expired - Reconnect Required
Cause: The eBay refresh token has expired (after approximately 18 months).
Solution: Click Connect to eBay on the instance to start a new OAuth flow. You will be redirected to eBay to re-authorize the application.
Error: Missing tokens in callback
Cause: The OAuth callback did not receive the expected tokens from the proxy.
Solution:
- Verify the OAuth Proxy URL is correct and accessible.
- Ensure your Odoo instance's
web.base.urlsystem parameter is set to your public URL. - Check that the proxy's callback URL can reach your Odoo instance.
Listing Errors¶
Error: The condition is not compatible with the category
Cause: The selected item condition is not valid for the chosen eBay category.
Solution: Sync categories to update condition policies, then select a compatible condition for the category.
Error: Impossible to revise a listing into a multi-variations listing
Cause: eBay does not allow converting a single-item listing to multi-variant.
Solution: End the existing listing and create a new multi-variant listing.
Error: You need to have at least 2 variations
Cause: Multi-variant listings require a minimum of 2 active variants.
Solution: Ensure at least 2 product variants have "Publish On eBay" enabled. To remove a variant, set its quantity to 0 rather than disabling it.
Order Import Issues¶
Orders not importing
Possible causes:
- Payment status filter: Verify that the appropriate payment statuses are enabled (Sync Paid Orders, Sync Pending Orders) on the instance.
- Date range: Check the Order Import Range setting. If set to "Since Last Sync," verify the Last Sync timestamp is not too recent.
- Cron not running: Ensure the "eBay: get new orders" scheduled action is active.
- Token expired: Check the Connection Status on the instance. Reconnect if needed.
Stock Sync Issues¶
eBay quantity not updating
Possible causes:
- "Use Stock Quantity" not enabled: Check that the product has
ebay_sync_stock = True. - Listing status: Stock sync only runs for products with status "Active", "Error", or "Out Of Stock".
- Quantity unchanged: The module only sends updates when the quantity has actually changed.
- Cron not running: Ensure the "eBay: synchronize stock" scheduled action is active.
Image Upload Failures¶
Images not appearing on eBay listing
Possible causes:
- Image too small: The longest side must be at least 500 pixels.
- Image too large: Total dimensions (width + height) must not exceed 12,000 pixels, and file size must be under 12 MB.
- JPEG mode: JPEG images must be in RGB mode (not CMYK).
- No images attached: Ensure images are attached to the product template record (not just set as the main product image).
Shipping Tracking Issues¶
Tracking not submitted to eBay
Possible causes:
- Not an eBay order: The sale order must have an origin starting with "eBay" and a valid
client_order_ref. - No tracking number: The delivery must have a
carrier_tracking_refset. - No carrier: The delivery must have a carrier assigned via
carrier_id. - Destination: Tracking is only submitted for outgoing deliveries (destination = customer).