dts/ebay-sdk
dts/ebay-sdk is a PHP library that wraps eBay's APIs in a clean, object-oriented client. It helps Laravel and PHP developers integrate listings, orders, and marketplace data without hand-rolling XML or HTTP requests.
Start by deciding whether you should be here at all. dts/ebay-sdk is officially deprecated in favor of dts/ebay-sdk-php. If you're greenfield, install the successor instead — it's the only line that receives updates and covers eBay's REST APIs (Browse, Inventory, Fulfillment, Marketing). Only follow the steps below if you've inherited a codebase already pinned to this package.
Minimal steps
composer require dts/ebay-sdk. Because it's unmaintained, commit the lockfile; a transitive composer update on a shared dependency (Guzzle, PSR interfaces) is the most common way an old eBay integration silently breaks.appId, certId, devId, plus a user token for Trading calls. Sandbox and production credentials are entirely separate — do not mix them.use DTS\eBaySDK\Trading\Services\TradingService;
$service = new TradingService([
'credentials' => [
'appId' => config('services.ebay.app_id'),
'certId' => config('services.ebay.cert_id'),
'devId' => config('services.ebay.dev_id'),
],
'sandbox' => app()->environment('local'),
'siteId' => \DTS\eBaySDK\Constants\SiteIds::EBAY_US,
'apiVersion' => '...',
]);
$request = new \DTS\eBaySDK\Trading\Types\GetItemRequestType();
$request->ItemID = '1234567890';
$response = $service->getItem($request);
if ($response->ack === 'Failure') {
// iterate $response->Errors
}
Where to look first: the generated Types directory for the request/response class matching the operation name, and the service class's method list. The operation name in eBay's API docs maps almost 1:1 to a camelCase method (GetMyeBaySelling → getMyeBaySelling). First use case: a read-only GetItem or GetMyeBaySelling in sandbox to confirm credentials, site ID, and token before you touch anything that writes.
TradingService (and any Shopping/Finding services) as singletons in a ServiceProvider, fed from config/services.php. Constructing services inline scatters credential handling across the codebase and makes sandbox/production switching error-prone.EbayRepository-style class that accepts your domain input, builds the request type, calls the service, checks ack, and returns either a mapped model or throws a domain exception. Do not let GetItemResponseType objects bleed into controllers or Blade views — they're deeply nested and change shape between API versions.ack, not HTTP status. Trading returns HTTP 200 with Failure or PartialFailure. A successful transport means nothing about the operation. Centralize the check:$ack = $response->ack;
if ($ack === 'Failure' || $ack === 'PartialFailure') {
$errors = collect($response->Errors ?? [])
->map(fn ($e) => "{$e->ErrorCode}: {$e->LongMessage}");
throw new EbayException($errors->implode('; '));
}
PageNumber while $response->HasMoreItems (or compare PageNumber to PaginationResult->TotalNumberOfPages). Do not assume a fixed page size; eBay caps it per operation.AddFixedPriceItem should be queued jobs, not a loop in a request. eBay rate-limits aggressively and a single failure mid-loop leaves partial state; record each ItemID as you go so retries are idempotent.ack plus a few key fields, not the full object graph. For unit tests, wrap the service behind your repository interface and fake it; mocking the SDK's generated types is not worth the effort.dts/ebay-sdk-php as a parallel workstream; treat every new feature here as temporary. The namespace and service/config shapes are similar enough that migration is mostly mechanical, but the REST coverage is genuinely new work.UnknownPropertyException means a typo, not a missing feature. The generated types are strict — $request->ItemId instead of $request->ItemID throws. When an operation "doesn't accept" a field you expect, check the generated type first; the SDK reflects eBay's WSDL, not your memory of the docs.null when absent. Use isset() / null-safe access; assuming an array or object exists is the top source of production fatals.siteId changes behavior, not just currency. Category IDs, shipping services, and item specifics are site-specific. A misconfigured siteId produces validation errors that look like bad data.ErrorCode around 932/16110-class) from business errors so you don't retry a dead token forever.sandbox => true swaps the endpoint globally; a stale apiVersion can drop fields from older responses. Keep both in config and log the effective values at boot in non-production.How can I help you explore Laravel packages today?