Skip to content

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_management
  • delivery

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.com by default)

Installation Steps

  1. Place the ebay module directory in your Odoo addons path.
  2. Restart the Odoo service.
  3. 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:

  1. Holds the eBay application credentials securely
  2. Redirects the user to eBay's consent screen
  3. Exchanges the authorization code for tokens
  4. Returns the access and refresh tokens to Odoo via callback

Connecting to eBay

  1. Navigate to eBay > Configuration > Instance.
  2. Create a new instance or open the existing one.
  3. Set the Environment to Production or Sandbox.
  4. Verify the OAuth Proxy URL is set (default: https://eb-auth.cloudffl.com).
  5. 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:

  1. Sync Categories -- Click Sync Categories on the instance to import eBay's category taxonomy and your custom store categories.

  2. Sync Policies -- Click Sync Policies to import your eBay business policies (payment, return, and shipping policies). These are required when creating listings.

  3. 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.

  4. Fetch Listings -- Click Fetch Listings to import your existing active eBay listings. This creates ebay.listing records 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

  1. Open a product in Sales > Products.
  2. Navigate to the eBay tab.
  3. Check Use eBay to enable eBay selling.
  4. 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:

  1. Uploads product images via the Trading API
  2. Calls AddItem with the full item specification
  3. Fetches the listing details to store the URL and start date

For Fixed-Price listings, the module uses a three-step Inventory API flow:

  1. Create Inventory Item -- Uploads product data (title, description, condition, aspects, images, availability) to eBay's inventory
  2. Create Offer -- Defines pricing, category, and policies for the listing
  3. Publish Offer -- Makes the listing live on eBay

Multi-Variant Listings

For products with multiple variants, the fixed-price flow extends to:

  1. Create an inventory item for each variant (each with its own SKU)
  2. Create an inventory item group that ties the variants together
  3. 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 EndItem via 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:

  1. Duplicate Check -- Skip if an order with the same client_order_ref (eBay Order ID) already exists.

  2. Customer Matching -- Find an existing partner by ebay_id (eBay username), or create a new one.

  3. Shipping Address -- Extract and normalize the shipping address. If it matches the customer's address, reuse it; otherwise, create a child delivery contact.

  4. 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
  5. Shipping Line -- Create a service line for shipping costs, matched to a shipping service product when available.

  6. 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.

  7. 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

  1. When stock.picking is marked as done and the destination is a customer location, the module checks if the related sale order originated from eBay.
  2. It fetches the eBay order details to obtain line item IDs.
  3. 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:

  1. Verify the OAuth Proxy URL is correct and accessible.
  2. Ensure your Odoo instance's web.base.url system parameter is set to your public URL.
  3. 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:

  1. Payment status filter: Verify that the appropriate payment statuses are enabled (Sync Paid Orders, Sync Pending Orders) on the instance.
  2. Date range: Check the Order Import Range setting. If set to "Since Last Sync," verify the Last Sync timestamp is not too recent.
  3. Cron not running: Ensure the "eBay: get new orders" scheduled action is active.
  4. Token expired: Check the Connection Status on the instance. Reconnect if needed.

Stock Sync Issues

eBay quantity not updating

Possible causes:

  1. "Use Stock Quantity" not enabled: Check that the product has ebay_sync_stock = True.
  2. Listing status: Stock sync only runs for products with status "Active", "Error", or "Out Of Stock".
  3. Quantity unchanged: The module only sends updates when the quantity has actually changed.
  4. Cron not running: Ensure the "eBay: synchronize stock" scheduled action is active.

Image Upload Failures

Images not appearing on eBay listing

Possible causes:

  1. Image too small: The longest side must be at least 500 pixels.
  2. Image too large: Total dimensions (width + height) must not exceed 12,000 pixels, and file size must be under 12 MB.
  3. JPEG mode: JPEG images must be in RGB mode (not CMYK).
  4. 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:

  1. Not an eBay order: The sale order must have an origin starting with "eBay" and a valid client_order_ref.
  2. No tracking number: The delivery must have a carrier_tracking_ref set.
  3. No carrier: The delivery must have a carrier assigned via carrier_id.
  4. Destination: Tracking is only submitted for outgoing deliveries (destination = customer).