baks-dev/ozon-products
Laravel/PHP 8.4+ пакет для интеграции с Ozon Products: управление продукцией, синхронизация и обмен данными с маркетплейсом Ozon. Устанавливается через Composer, включает PHPUnit-тесты.
Installation:
composer require baks-dev/ozon-products
php artisan vendor:publish --provider="BaksDev\OzonProducts\OzonProductsServiceProvider" --tag="config"
config/ozon-products.php) for API credentials and settings.Configuration:
.env with Ozon API credentials:
OZON_CLIENT_ID=your_client_id
OZON_CLIENT_SECRET=your_client_secret
OZON_SANDBOX=false # Set to true for testing
config/ozon-products.php:
'api' => [
'base_url' => env('OZON_API_URL', 'https://api.ozon.ru'),
'timeout' => 30,
],
'models' => [
'product' => \App\Models\Product::class, // Your Eloquent model
],
First Use Case: Sync a single product to Ozon:
use BaksDev\OzonProducts\Facades\OzonProducts;
$product = \App\Models\Product::find(1);
$ozonProduct = OzonProducts::syncProduct($product);
Product model has fields matching Ozon’s API requirements (e.g., title, description, price, sku).Verify:
Bulk Sync:
OzonProducts::syncProducts(\App\Models\Product::where('needs_sync', true)->get());
Queued Sync (for large catalogs):
\App\Models\Product::where('needs_sync', true)->each(function ($product) {
SyncOzonProduct::dispatch($product);
});
SyncOzonProduct) extending ShouldQueue.Event-Driven Sync: Listen for product updates and trigger syncs:
\App\Models\Product::observe(OzonProductsObserver::class);
OzonProductsObserver to hook into saved, updated, or deleted events.$product = \App\Models\Product::find(1);
OzonProducts::updateInventory($product, ['quantity' => 50]);
$products = \App\Models\Product::where('inventory_needs_update', true)->get();
OzonProducts::batchUpdateInventory($products);
$orders = OzonProducts::getOrders(['status' => 'new']);
OzonProducts::updateOrderStatus($orderId, 'shipped');
Route::post('/ozon-webhook', [OzonWebhookController::class, 'handle']);
public function handle(Request $request) {
$payload = $request->json()->all();
OzonProducts::handleWebhook($payload);
}
OzonProducts::handleWebhook() to process specific events (e.g., product_updated, order_canceled).Product model includes Ozon-specific fields:
class Product extends Model
{
protected $casts = [
'ozon_id' => 'integer',
'external_seller_id' => 'string',
'price' => 'float',
'quantity' => 'integer',
];
protected $fillable = [
'title', 'description', 'sku', 'price', 'quantity', 'ozon_id', 'external_seller_id',
];
}
public function getOzonAttributes()
{
return [
'name' => $this->title,
'description' => $this->description,
'price' => $this->price,
'sku' => $this->sku,
'quantity' => $this->quantity,
];
}
OzonProductsServiceProvider to handle token refresh:
'auth' => [
'client_id' => env('OZON_CLIENT_ID'),
'client_secret' => env('OZON_CLIENT_SECRET'),
'token_url' => 'https://auth.ozon.ru/token',
'refresh_token' => env('OZON_REFRESH_TOKEN'),
],
OzonProducts::refreshAuthToken();
try {
OzonProducts::syncProduct($product);
} catch (\BaksDev\OzonProducts\Exceptions\OzonApiException $e) {
\Log::error('Ozon sync failed: ' . $e->getMessage());
$this->retrySync($product);
}
php bin/phpunit --group=ozon-products
$mockHandler = \Mockery::mock(\GuzzleHttp\Handler\MockHandler::class);
$mockHandler->shouldReceive('handle')
->once()
->andReturn(new \GuzzleHttp\Psr7\Response(200, [], '{"id": 123}'));
$response = OzonProducts::get('products/search', ['text' => 'test']);
OzonProducts::getClient()->getEmitter()->getMiddlewareStack()
->push(\App\Http\Middleware\LogOzonRequests::class);
external_seller_id, delivery_cost). Missing or incorrectly named fields cause validation errors.Product model against Ozon’s API docs and use accessors to map fields:
public function getExternalSellerIdAttribute()
{
return $this->ozon_seller_id ?? 'default_seller_id';
}
OzonProducts::syncProducts($products, ['batch_size' => 5]);
OzonProducts::getClient()->getEmitter()->getMiddlewareStack()
->push(\BaksDev\OzonProducts\Middleware\RateLimitMiddleware::class);
401 Unauthorized errors.OZON_REFRESH_TOKEN is set in .env.php artisan ozon:refresh-token
OzonProducts::getClient()->getEmitter()->getMiddlewareStack()
->push(\App\Http\Middleware\LogTokenRefresh::class);
public function updateFromOzon(array $ozonData)
{
$this->price = $ozonData['price'] ?? $this->price;
$this->quantity = $ozonData['quantity'] ?? $this->quantity;
$this->save();
}
upsert for conflict resolution:
\DB::table('products')->upsert(
$ozonData,
How can I help you explore Laravel packages today?