Installation Add the bundle to your Laravel project via Composer:
composer require blackboxcode/pando-tax-bundle
Register the bundle in config/app.php under providers:
BlackBoxCode\PandoTaxBundle\PandoTaxBundle::class,
Configuration Publish the default config:
php artisan vendor:publish --provider="BlackBoxCode\PandoTaxBundle\PandoTaxBundle" --tag="config"
Update config/pando_tax.php with your Pando API credentials and environment settings.
First Use Case: Fetching Tax Rates
Inject the PandoTaxService into a controller or service:
use BlackBoxCode\PandoTaxBundle\Services\PandoTaxService;
public function __construct(private PandoTaxService $pandoTax) {}
public function getTaxRateForLocation(string $location) {
$rate = $this->pandoTax->getTaxRate($location);
return response()->json($rate);
}
Tax Rate Lookup
Use PandoTaxService to fetch tax rates dynamically:
$rate = $this->pandoTax->getTaxRate('New York, NY');
// Returns: ['rate' => 8.875, 'jurisdiction' => 'New York State']
Bulk Tax Calculations Process multiple locations efficiently:
$locations = ['San Francisco, CA', 'Chicago, IL'];
$taxRates = $this->pandoTax->getTaxRates($locations);
Integration with Eloquent
Attach tax logic to models (e.g., Order):
public function calculateTax() {
$this->tax_rate = $this->pandoTax->getTaxRate($this->shipping_address);
$this->tax_amount = $this->subtotal * ($this->tax_rate / 100);
}
Caching Strategies Cache responses to reduce API calls:
$rate = Cache::remember("tax_rate_{$location}", now()->addHours(1), function() use ($location) {
return $this->pandoTax->getTaxRate($location);
});
try {
return $this->pandoTax->getTaxRate($location);
} catch (\Exception $e) {
return config('pando_tax.fallback_rate');
}
API Rate Limits Monitor API call limits (default: 100 requests/minute). Implement exponential backoff for retries:
$this->pandoTax->setRetryPolicy(new \BlackBoxCode\PandoTaxBundle\Policies\ExponentialBackoff());
Location Format Sensitivity
Pando expects strict location formats (e.g., "City, State"). Sanitize inputs:
$cleanLocation = preg_replace('/[^a-zA-Z, ]/', '', $rawLocation);
Time Zone Handling Tax rates may vary by jurisdiction and time (e.g., holiday rates). Ensure your server’s timezone matches Pando’s:
date_default_timezone_set(config('pando_tax.timezone'));
Dependency Injection Avoid singleton pitfalls. Bind the service to the container explicitly:
$this->app->bind(PandoTaxService::class, function ($app) {
return new PandoTaxService($app['config']['pando_tax']);
});
Enable Logging
Configure the PandoTaxLogger in config/pando_tax.php:
'logging' => [
'enabled' => true,
'channel' => 'single',
],
Logs will appear in storage/logs/pando_tax.log.
Mocking for Tests Use a mock service in tests:
$mock = Mockery::mock(PandoTaxService::class);
$mock->shouldReceive('getTaxRate')->andReturn(['rate' => 10.0]);
$this->app->instance(PandoTaxService::class, $mock);
Custom Tax Calculators
Extend the TaxCalculator interface:
class CustomTaxCalculator implements TaxCalculator {
public function calculate(float $amount, array $taxRate): float {
// Custom logic (e.g., tiered rates)
return $amount * ($taxRate['rate'] / 100) + 1.5; // Flat fee
}
}
Register it in the bundle’s config:
'calculator' => BlackBoxCode\PandoTaxBundle\Calculators\CustomTaxCalculator::class,
Event Listeners
Listen for TaxRateUpdated events to sync with external systems:
Event::listen(\BlackBoxCode\PandoTaxBundle\Events\TaxRateUpdated::class, function ($event) {
// Sync to database or third-party service
});
API Response Transformers
Override the TaxRateTransformer to customize response data:
$this->pandoTax->setTransformer(new class implements TaxRateTransformer {
public function transform(array $rawData): array {
return [
'rate' => $rawData['rate'],
'jurisdiction_id' => $rawData['jurisdiction']['id'],
];
}
});
How can I help you explore Laravel packages today?