batteryincluded/batteryincluded-php-sdk
PHP 8.2+ SDK for the BatteryIncluded API. Install via Composer and use provided examples to call endpoints. Includes DTOs for syncing products and supports extending ProductBaseDto to send custom shop fields (e.g., keywords, material, color) in payloads.
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?