batteryincluded/batteryincluded-php-sdk
The official PHP SDK for the BatteryIncluded API. Requires PHP 8.2+, installs via Composer, and lets you sync products and other resources, with extensible DTOs for adding custom shop-specific fields.
Installation
composer require batteryincluded/batteryincluded-php-sdk
Ensure your project uses PHP 8.2+.
First Use Case: Sync a Product
use BatteryIncludedSdk\Dto\ProductBaseDto;
use BatteryIncludedSdk\Client\ApiClient;
use BatteryIncludedSdk\Client\CurlHttpClient;
use BatteryIncludedSdk\Service\SyncService;
$product = new ProductBaseDto('1');
$product->setName('Test Product');
$product->setPrice(19.99);
$apiClient = new ApiClient(
new CurlHttpClient(),
'https://api.batteryincluded.io/api/v1/collections/',
'YOUR_COLLECTION_ID',
'YOUR_API_KEY'
);
$syncService = new SyncService($apiClient);
$result = $syncService->syncFullElements($product);
Where to Look First
examples/ for ready-to-use workflows (e.g., sync_full_product_and_blogs.php).Dto/ for base classes (ProductBaseDto, BlogBaseDto) to extend.Syncing Data
SyncService for full updates (syncFullElements) or partial updates (syncPartialElements).$syncService->syncFullElements($product1, $product2, $blog);
Searching and Browsing
BrowseService with BrowseSearchStruct for queries:
$searchStruct = new BrowseSearchStruct();
$searchStruct->setQuery('laptop');
$searchStruct->addFilter('type', 'PRODUCT');
$results = $browseService->browse($searchStruct);
Extending DTOs
ProductBaseDto or BlogBaseDto to add custom fields:
class CustomProductDto extends ProductBaseDto {
private ?string $material;
public function jsonSerialize(): array {
return array_merge_recursive(
parent::jsonSerialize(),
['_PRODUCT' => ['material' => $this->material]]
);
}
}
Mixed Collections
$syncService->syncFullElements($product, $blog);
$searchStruct->addFilter('type', 'BLOG');
try {
$result = $syncService->syncFullElements($product);
} catch (\Exception $e) {
\Log::error('Sync failed: ' . $e->getMessage());
}
X-RateLimit-* to avoid throttling.API_KEY and COLLECTION_ID in Laravel’s .env:
BATTERYINCLUDED_API_KEY=your_key_here
BATTERYINCLUDED_COLLECTION_ID=your_collection_id
Then inject them via config or service container.Null Field Handling
null values in jsonSerialize() to avoid sending empty keys:
array_filter($jsonDto, static fn($value) => $value !== null)
ID Collisions
PRODUCT-1, BLOG-1). Ensure your local IDs are unique per type to avoid conflicts.Type-Specific Field Access
type field before accessing nested data (_PRODUCT, _BLOG):
if ($document['type'] !== 'PRODUCT') {
throw new \InvalidArgumentException('Expected PRODUCT type');
}
API Key Permissions
syncPartialElements first to avoid full overwrites.CurlHttpClient to log requests/responses:
class DebugHttpClient extends CurlHttpClient {
public function request(string $method, string $url, array $data = []): array {
\Log::debug('Request: ' . json_encode(compact('method', 'url', 'data')));
$response = parent::request($method, $url, $data);
\Log::debug('Response: ' . json_encode($response));
return $response;
}
}
$validated = $request->validate([
'name' => 'required|string|max:255',
'price' => 'required|numeric|min:0',
]);
$product->setName($validated['name']);
Custom HTTP Clients
CurlHttpClient with Guzzle or Symfony’s HttpClient for advanced features (retries, middleware):
use Symfony\Contracts\HttpClient\HttpClientInterface;
$httpClient = \Symfony\Contracts\HttpClient\HttpClient::create();
$apiClient = new ApiClient($httpClient, ...);
Event Dispatching
event(new ProductSynced($product, $result));
EventServiceProvider.Queue Sync Jobs
SyncProductJob::dispatch($product)->onQueue('batteryincluded');
ShouldQueue interface for SyncService.Webhook Integration
webhook package to listen for BatteryIncluded webhooks (e.g., sync confirmation):
Route::post('/batteryincluded-webhook', [WebhookController::class, 'handle']);
api/v1/collections/. Override via dependency injection:
$apiClient = new ApiClient($httpClient, 'https://custom-api.batteryincluded.io/v2/collections/');
/shops/{id}/collections), extend ApiClient to support path parameters.syncPartialElements for incremental updates (e.g., stock changes) instead of full syncs.BrowseService responses in Laravel’s cache:
$cacheKey = 'batteryincluded_search_' . md5($searchStruct->getQuery());
return Cache::remember($cacheKey, now()->addHours(1), fn() => $browseService->browse($searchStruct));
How can I help you explore Laravel packages today?