Stop Hardcoding Pricing: Fetch It Dynamically from Your Provider’s API

📖 2 minutes read

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.

Daryle De Silva

VP of Technology

11+ years building and scaling web applications. Writing about what I learn in the trenches.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *