Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Shipping Laravel Package

ghaninia/shipping

ghaninia/shipping is a Laravel package for flexible shipping management. Define shipping methods and rates, calculate delivery costs at checkout, and keep shipping logic clean and configurable through a simple, developer-friendly API.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer and publish the config:

composer require ghaninia/shipping
php artisan vendor:publish --provider="Ghaninia\Shipping\ShippingServiceProvider"

Open the published config/shipping.php first — this is where driver selection, credentials, and defaults live. The package is driver-based, exposing two built-in postage calculators: sefarshi (registered/ordinary mail) and pisthtaz (express mail). You pick the active driver either in config or per-call.

Your first working call is a rate lookup by weight and destination. Consult the README for the exact facade/method signature, but the shape is typically:

use Ghaninia\Shipping\Facades\Shipping;

$cost = Shipping::driver('pisthtaz')->calculate([
    'weight' => 500,        // grams
    'destination' => 'tehran',
]);

Sanity-check the returned value against the official Iran Post tariff tables before trusting it in production — the published numbers can lag behind real rates, and this package had its last release in October 2022.

A good first use case: add a shipping-method selector to your checkout that fetches both sefarshi and pisthtaz prices for the cart's total weight and lets the customer choose.

Implementation Patterns

Wrap the driver in your own service. Don't scatter Shipping::driver(...) calls through controllers. Create a thin application-level class so you can swap the library, add caching, and mock it in tests:

class PostageCalculator
{
    public function options(int $weightGrams, string $destination): array
    {
        return collect(['sefarshi', 'pisthtaz'])
            ->mapWithKeys(fn ($driver) => [
                $driver => Shipping::driver($driver)->calculate([
                    'weight' => $weightGrams,
                    'destination' => $destination,
                ]),
            ])
            ->all();
    }
}

Cache aggressively. Tariffs change slowly but the call may hit a remote service. Cache per (driver, weight-bucket, destination) for a day:

$cacheKey = "postage:{$driver}:{$destination}:{$weightGrams}";
return Cache::remember($cacheKey, now()->addDay(), fn () => Shipping::driver($driver)->calculate([...]));

Round weight into tariff brackets before caching. Postal pricing is banded (e.g. up to 500 g, up to 1 kg). Bucketing keeps your cache-key space small and matches how the carrier actually prices:

$bucketed = (int) (ceil($weightGrams / 500) * 500);

Persist the chosen method on the order, not just the price. Store shipping_driver, shipping_cost, and the weight snapshot at purchase time so historical orders remain accurate when tariffs change later.

Graceful degradation in checkout. Fetch quotes behind a try/catch; if a driver fails, drop that option rather than breaking the whole page. If all drivers fail, fall back to a flat rate or "contact us" option.

Testing. Because this hits an external service, inject your PostageCalculator via the container and bind a fake in tests returning fixed quotes. Never let unit tests make real HTTP calls.

Gotchas and Tips

  • Weight units are ambiguous. Confirm in the source whether weight is grams or kilograms. Iranian post tariffs are usually quoted per-gram bands, but a silent 1000× error is the classic bug here. Add a docblock and an assertion in your wrapper.
  • Unmaintained since Oct 2022. Check it installs cleanly against your Laravel and PHP version; older packages often break on Laravel 10+/PHP 8.2+ due to loose type hints. If composer require complains, check the illuminate/support constraint and consider a fork with a widened constraint.
  • Driver name casing. Driver keys are usually lowercase strings ('sefarshi', 'pisthtaz') — a Shipping::driver('Pishtaz') typo can throw an unhelpful "driver not found" exception. Validate driver values against an allowlist in your form requests.
  • Config caching bites during setup. After editing config/shipping.php, run php artisan config:clear (or config:cache in deploy). Stale cached config is the #1 "my credentials aren't being read" cause.
  • No credentials = no error until runtime. If the driver requires API keys or account details and they're missing, failures often surface as a generic exception deep in the call. Add a boot-time check or a health-check command that fails fast in staging.
  • Wrap exceptions in a domain type. Catch the package's underlying exception and rethrow as your own PostageUnavailableException so your checkout logic isn't coupled to the vendor's namespace — makes swapping the library later trivial.
  • Extension point: custom drivers. If Iran Post adds a new service, look at the driver contract in src/Drivers/ — implementing the same interface and registering it in config is the intended extension path, rather than forking.
  • Verify the tariff source. Since releases are sparse, cross-check the computed figure against the official Iran Post price list periodically; consider asserting a plausible range (0 < cost < someCeiling) so a bad response doesn't silently discount shipping to zero.
  • Log the raw response at debug level during rollout so you can diff the library's interpretation against the carrier's published table when a customer disputes a quote.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums