Skip to content

tigusigalpa/ebay-php

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

eBay PHP/Laravel SDK

eBay PHP SDK

Latest Version License PHP Version Laravel eBay

PHP SDK for eBay API. Supports Trading API (XML) and Commerce API (REST), OAuth 2.0 authentication, 20+ marketplaces. Works as standalone and with Laravel.

📖 Full documentation available on Wiki

Table of Contents

Features

API:

  • Trading API (XML) — orders, listings, categories, GetMyEbaySelling, etc.
  • Commerce API (REST) — inventory, fulfillment, taxonomy, translation
  • Message API (REST) — buyer-seller messaging, conversations, notifications
  • OAuth 2.0 with automatic token refresh
  • 20+ marketplaces (US, UK, DE, FR, AU, etc.)

Code:

  • PHP 8.1+ with native Enums
  • Strict typing
  • Immutable DTOs
  • Fluent interface
  • PSR-4, PSR-7, PSR-12

Laravel:

  • Service Provider + Facade
  • Dependency Injection
  • .env configuration

Requirements

  • PHP 8.1+
  • Guzzle 7.x
  • Laravel 9.x / 10.x / 11.x / 12.x (optional)
  • Composer

Installation

composer require tigusigalpa/ebay-php

For Laravel — publish config:

php artisan vendor:publish --tag=ebay-config

Add credentials to .env:

EBAY_ENVIRONMENT=sandbox

# Sandbox
EBAY_SANDBOX_APP_ID=your-sandbox-app-id
EBAY_SANDBOX_CERT_ID=your-sandbox-cert-id
EBAY_SANDBOX_DEV_ID=your-sandbox-dev-id
EBAY_SANDBOX_RUNAME=your-sandbox-runame

# Production
EBAY_PRODUCTION_APP_ID=your-production-app-id
EBAY_PRODUCTION_CERT_ID=your-production-cert-id
EBAY_PRODUCTION_DEV_ID=your-production-dev-id
EBAY_PRODUCTION_RUNAME=your-production-runame

EBAY_DEFAULT_SITE=US

Get credentials at eBay Developers Program.

Quick Start

Laravel (Facade)

use Tigusigalpa\Ebay\Facades\Ebay;
use Tigusigalpa\Ebay\Enums\Site;

// OAuth URL
$url = Ebay::getConsentUrl();

// Exchange code for tokens
$tokens = Ebay::exchangeCodeForToken($code);

// Get orders
$orders = Ebay::trading()->getOrders([
    'CreateTimeFrom' => now()->subDays(30)->toIso8601String(),
]);

// Switch marketplace
Ebay::setSite(Site::UK)->trading()->getOrders();

Standalone PHP

require_once 'vendor/autoload.php';

use Tigusigalpa\Ebay\Ebay;
use Tigusigalpa\Ebay\Enums\Site;

$ebay = new Ebay([
    'environment' => 'sandbox',
    'sandbox' => [
        'app_id' => 'your-app-id',
        'cert_id' => 'your-cert-id',
        'dev_id' => 'your-dev-id',
        'runame' => 'your-runame',
    ],
    'site' => Site::US,
]);

$orders = $ebay->trading()->getOrders();

Authentication

OAuth 2.0 Flow

1. Get authorization URL:

$consentUrl = Ebay::getConsentUrl(
    scopes: config('ebay.scopes'),
    state: 'your-state-parameter',
    locale: 'en-US'
);

return redirect($consentUrl);

2. Handle callback:

public function callback(Request $request)
{
    $code = $request->get('code');
    $tokenData = Ebay::exchangeCodeForToken($code);
    
    // Store tokens
    auth()->user()->update([
        'ebay_access_token' => $tokenData['access_token'],
        'ebay_access_token_expires_at' => $tokenData['expires_at'],
        'ebay_refresh_token' => $tokenData['refresh_token'],
        'ebay_refresh_token_expires_at' => $tokenData['refresh_token_expires_at'],
    ]);
    
    return redirect()->route('dashboard');
}

3. Use tokens:

$user = auth()->user();

Ebay::setAccessToken($user->ebay_access_token, $user->ebay_access_token_expires_at);
Ebay::setRefreshToken($user->ebay_refresh_token, $user->ebay_refresh_token_expires_at);

// Tokens refresh automatically when expired
$orders = Ebay::trading()->getOrders();

Trading API

Orders

$xml = Ebay::trading()->getOrders([
    'CreateTimeFrom' => '2024-01-01T00:00:00.000Z',
    'CreateTimeTo' => '2024-12-31T23:59:59.999Z',
    'OrderStatus' => 'Active',
]);

foreach ($xml->OrderArray->Order as $order) {
    $orderId = (string) $order->OrderID;
    $total = (float) $order->Total;
}

Items

// Get item
$item = Ebay::trading()->getItem('123456789');
$title = (string) $item->Item->Title;
$price = (float) $item->Item->SellingStatus->CurrentPrice;

// Create listing
$response = Ebay::trading()->addFixedPriceItem([
    'Title' => 'My Product Title',
    'Description' => 'Product description',
    'PrimaryCategory' => ['CategoryID' => '12345'],
    'StartPrice' => 99.99,
    'Quantity' => 10,
    'Currency' => 'USD',
    'Country' => 'US',
    'Location' => 'New York',
    'DispatchTimeMax' => 3,
    'ShippingDetails' => [
        'ShippingType' => 'Flat',
        'ShippingServiceOptions' => [
            'ShippingService' => 'USPSPriority',
            'ShippingServiceCost' => 5.00,
        ],
    ],
]);

$itemId = (string) $response->ItemID;

Categories

$categories = Ebay::trading()->getCategories([
    'CategorySiteID' => 0,
    'LevelLimit' => 2,
]);

Commerce API

Inventory

// Get
$item = Ebay::commerce()->getInventoryItem('SKU-123');

// Update quantity
Ebay::commerce()->createOrReplaceInventoryItem($sku, [
    'availability' => ['shipToLocationAvailability' => ['quantity' => $newQuantity]],
]);

Fulfillment

$orders = Ebay::commerce()->getFulfillmentOrders([
    'filter' => 'orderfulfillmentstatus:{NOT_STARTED|IN_PROGRESS}',
    'limit' => 50,
]);

Translation

$translated = Ebay::commerce()->translate(
    text: 'Brand New iPhone',
    fromLanguage: 'en',
    toLanguage: 'de',
    context: 'ITEM_TITLE'
);

Category Aspects

$aspects = Ebay::commerce()->getItemAspectsForCategory('0', '12345');

foreach ($aspects['aspects'] as $aspect) {
    echo $aspect['localizedAspectName'];
}

Message API

Get Conversations

use Tigusigalpa\Ebay\Enums\{ConversationType, ConversationStatus};

$result = Ebay::message()->getConversations([
    'conversation_type' => ConversationType::FROM_MEMBERS->value,
    'conversation_status' => ConversationStatus::UNREAD->value,
    'limit' => 25,
]);

foreach ($result['conversations'] as $conversation) {
    echo $conversation->conversationTitle;
    echo $conversation->latestMessage?->messageBody;
}

Send Message

// Start new conversation
$message = Ebay::message()->sendMessage([
    'otherPartyUsername' => 'buyer_username',
    'messageText' => 'Thank you for your question.',
    'reference' => [
        'referenceId' => '123456789',
        'referenceType' => 'LISTING',
    ],
]);

// Reply to conversation
$message = Ebay::message()->sendMessage([
    'conversationId' => 'c1234567890',
    'messageText' => 'Here is the information you requested.',
]);

Manage Conversations

// Mark as read
Ebay::message()->updateConversation([
    'conversationId' => 'c1234567890',
    'conversationType' => ConversationType::FROM_MEMBERS->value,
    'read' => true,
]);

// Archive multiple conversations
$result = Ebay::message()->bulkUpdateConversation([
    'conversations' => [
        [
            'conversationId' => 'c1111111111',
            'conversationType' => ConversationType::FROM_MEMBERS->value,
            'conversationStatus' => 'ARCHIVE',
        ],
    ],
]);

Working with Marketplaces

use Tigusigalpa\Ebay\Enums\Site;

// Set marketplace
Ebay::setSite(Site::UK);
Ebay::setSite(Site::GERMANY);
Ebay::setSite(Site::AUSTRALIA);

// Marketplace information
$site = Site::US;
$site->title();        // "United States"
$site->code();         // "us"
$site->url();          // "https://ebay.com"
$site->locale();       // "en-US"
$site->marketplace();  // "EBAY_US"
$site->currency()->symbol(); // "$"

// Find by code
$site = Site::fromCode('uk');           // Site::UK
$site = Site::fromMarketplace('EBAY_DE'); // Site::GERMANY

// List on multiple marketplaces
foreach ([Site::UK, Site::GERMANY, Site::FRANCE] as $site) {
    Ebay::setSite($site)->trading()->addFixedPriceItem($itemData);
}

Enums and DTOs

Package uses PHP 8.1 Enums for type safety:

use Tigusigalpa\Ebay\Enums\{Site, Currency, ListingStatus, OrderStatus, PaymentStatus, ListingType};

// Currency
$currency = Currency::USD;
$currency->symbol();      // "$"
$currency->htmlEntity();  // "$"
$currency->title();       // "US Dollar"

// Listing Status
$status = ListingStatus::ACTIVE;
$status->title();         // "Active"
$status->description();

// Listing Type
$listingType = ListingType::FIXED_PRICE;
$listingType->description(); // "Buy It Now format with a fixed price"

DTOs

use Tigusigalpa\Ebay\Http\Resources\{Order, Item};

$xml = Ebay::trading()->getOrders();
foreach ($xml->OrderArray->Order as $orderXml) {
    $order = Order::fromXml($orderXml);
    
    echo $order->orderId;
    echo $order->total;
    echo $order->orderStatus->title();
}

// Convert to array
$array = $order->toArray();

Error Handling

use Tigusigalpa\Ebay\Exceptions\{EbayApiException, AuthenticationException, InvalidConfigurationException};

try {
    $orders = Ebay::trading()->getOrders();
} catch (AuthenticationException $e) {
    Log::error('eBay auth failed', [
        'error_code' => $e->getErrorCode(),
        'message' => $e->getMessage(),
    ]);
} catch (EbayApiException $e) {
    foreach ($e->getErrors() as $error) {
        echo $error['code'] . ': ' . $error['message'];
    }
} catch (InvalidConfigurationException $e) {
    Log::error('Invalid eBay configuration', ['message' => $e->getMessage()]);
}

Optimization

Caching

// config/ebay.php
'cache' => [
    'enabled' => true,
    'ttl' => 3600,
],

Rate Limiting

RateLimiter::attempt('ebay-api', $perMinute = 5000, function() {
    // API calls
});

Queues

dispatch(new SyncEbayOrdersJob($dateRange));
dispatch(new UpdateInventoryJob($products));

Batch Processing

$itemIds = ['123', '456', '789'];
foreach ($itemIds as $itemId) {
    $items[] = Ebay::trading()->getItem($itemId);
    usleep(100000); // Rate limiting
}

Testing

composer test

# Unit tests only
./vendor/bin/phpunit tests/Unit

# Feature tests only
./vendor/bin/phpunit tests/Feature

FAQ

How to get API credentials?

Register at eBay Developers Program, create application and get App ID, Cert ID, Dev ID, RuName.

Can I use for dropshipping?

Yes. Package is suitable for order automation, inventory, and listings.

What's the difference between Trading API and Commerce API?

  • Trading API (XML) — legacy API for core operations (listings, orders, categories)
  • Commerce API (REST) — modern REST API for inventory, fulfillment, and new features

How to switch to production?

Set EBAY_ENVIRONMENT=production in .env and add production credentials.

How to handle rate limits?

Use Laravel Rate Limiter or add usleep() between requests.

Troubleshooting

"Missing required configuration"

Check that all credentials are set in .env:

EBAY_SANDBOX_APP_ID=your-app-id
EBAY_SANDBOX_CERT_ID=your-cert-id
EBAY_SANDBOX_DEV_ID=your-dev-id
EBAY_SANDBOX_RUNAME=your-runame

OAuth token expired

Package refreshes tokens automatically. Ensure refresh token is set:

Ebay::setRefreshToken($refreshToken, $expiresAt);

XML parsing errors

Enable logging in config/ebay.php:

'logging' => ['enabled' => true],

Support

eBay Documentation

Contributing

git clone https://github.com/tigusigalpa/ebay-php.git
cd ebay-php
composer install
composer test
composer check-style

Requirements:

  • PSR-12
  • Tests for new features
  • PHPDoc with links to eBay API docs
  • Strict typing

License

MIT. See LICENSE.

Author

Igor Sazonov

Changelog

See CHANGELOG.md.

About

Modern Laravel/PHP 8.1+ package for eBay API integration with full OAuth 2.0 support. Features native Enums, Trading & Commerce API clients, type-safe DTOs, automatic token refresh, and multi-marketplace support. Built with SOLID principles, PSR standards, and comprehensive documentation. Laravel 9-12 compatible with Service Provider and Facade.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages