If you’re integrating with a service that has dynamic pricing (shipping carriers, payment processors, cloud APIs), you might hardcode the rates in your config:
// config/shipping.php
return [
'rates' => [
'express' => ['base' => 5.99, 'per_kg' => 0.89],
'standard' => ['base' => 2.99, 'per_kg' => 0.45],
],
];
The problem: Rates change frequently. You’re constantly updating config files, redeploying, and risking stale prices shown to customers.
Better approach: Fetch pricing dynamically from the provider’s API and cache it:
// app/Services/ShippingPricingService.php
class ShippingPricingService
{
public function getRates(): array
{
return Cache::remember('shipping_rates', now()->addHour(), function () {
$response = Http::withToken(config('shipping.api_key'))
->get('https://api.shippingprovider.example/v1/rates');
return $response->json('rates');
});
}
public function calculateCost(string $method, float $weight): float
{
$rates = $this->getRates();
$rate = $rates[$method];
return $rate['base'] + ($weight * $rate['per_kg']);
}
}
Now your cost calculations always use current pricing, without manual config updates:
// Before: Hardcoded config (stale pricing risk)
$cost = config("shipping.rates.express.base")
+ ($weight * config("shipping.rates.express.per_kg"));
// After: Dynamic pricing (always current)
$cost = app(ShippingPricingService::class)->calculateCost('express', $weight);
Cache strategy: 1-hour TTL is usually fine for pricing data – it doesn’t change minute-to-minute. If the provider updates rates, your app picks them up within an hour. No deploys needed.
Bonus: Some providers let you pass per-request pricing overrides. If your tracking package supports runtime config, you can pass the fetched rates directly:
// Hypothetical cost tracker with runtime pricing override
CostTracker::calculate(
method: 'express',
weight: $weight,
pricingOverride: $this->shippingPricing->getRates()['express']
);
When NOT to do this: If the API is slow or unreliable, fetch pricing asynchronously via a scheduled job and store it in your database. Then your app reads from the DB instead of hitting the API every hour.
Leave a Reply