spatie/spatie-price-api
Fetch pricing information from Spatie’s spatie.be API, used internally on Spatie product promotional sites. Includes a simple method to retrieve a price for a purchasable item. Open source but not intended for third-party use.
Installation:
composer require spatie/spatie-price-api
Publish the config file (if needed for customization):
php artisan vendor:publish --provider="Spatie\PriceApi\PriceApiServiceProvider" --tag="config"
First Use Case: Fetch a product price via its ID:
use Spatie\PriceApi\Facades\PriceApi;
$price = PriceApi::getPrice('product-id-123');
Output will be a Spatie\PriceApi\Price object with attributes like amount, currency, and validFrom.
Where to Look First:
config/price-api.php (if published) for API base URL, timeout, and retry logic.Spatie\PriceApi\Facades\PriceApi for direct method calls.PriceApi::getPrice() return type).Price Retrieval:
$price = PriceApi::getPrice('product-slug');
$price = PriceApi::getPrice('product-slug', fallback: 99.99); // Fallback to $99.99 if API fails
$prices = PriceApi::getPrices(['slug1', 'slug2']);
Integration with Eloquent:
// In Product.php
public function getPriceAttribute()
{
return PriceApi::getPrice($this->slug);
}
$price = Cache::remember("price_{$product->slug}", now()->addHours(1), function() use ($product) {
return PriceApi::getPrice($product->slug);
});
Real-Time Updates:
// In a controller or job
event(new \Spatie\PriceApi\Events\PriceUpdated($product->slug));
API Response Handling:
PriceApi::extend(function ($response) {
return new Price(
amount: $response['custom_amount_field'],
currency: $response['currency']
);
});
Rate Limiting:
PriceApi::setRetryOptions([
'max_retries' => 3,
'delay' => 1000, // 1 second
]);
Caching Quirks:
Cache::tags(['prices']) for bulk invalidation:
Cache::tags(['prices'])->flush();
Error Handling:
null or throw exceptions. Handle gracefully:
try {
$price = PriceApi::getPrice('invalid-slug');
} catch (\Spatie\PriceApi\Exceptions\PriceNotFound $e) {
abort(404, 'Product not found or price unavailable.');
}
Currency Mismatches:
use Money\Money;
$money = Money::USD($price->amount);
Testing:
$response = Http::fake([
'api.spatie.be/*' => Http::response(['amount' => 19.99, 'currency' => 'EUR']),
]);
Logging:
PriceApi::setLogger(function ($message) {
\Log::debug($message);
});
Environment-Specific Config:
// config/price-api.php
'url' => env('PRICE_API_URL', 'https://api.spatie.be'),
Performance:
queue to defer price fetches for non-critical paths.Extensions:
Price model to add custom logic:
namespace App\Extensions;
use Spatie\PriceApi\Price;
class ExtendedPrice extends Price {
public function isOnSale()
{
return $this->amount < 50; // Example condition
}
}
Then override the facade binding:
PriceApi::setPriceClass(ExtendedPrice::class);
Documentation:
How can I help you explore Laravel packages today?