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

Laravel Abacus Api Laravel Package

contoweb/laravel-abacus-api

A Laravel API client for Abacus ERP. It simplifies connecting your application to Abacus web services, handling configuration and HTTP requests so you can query ERP data and integrate business records with clean, familiar Laravel code.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require contoweb/laravel-abacus-api

The package is auto-discovered by Laravel. If it ships a config file, publish it and put credentials in .env rather than in code:

php artisan vendor:publish --tag=abacus-api-config

Where to look first, in this order:

  1. src/AbacusClient.php — the entry point; toException() is the status-code switchboard that decides which exception type you get back.
  2. src/Exceptions/ — the full exception hierarchy. As of v0.2.0 it contains AbacusNotFoundException (404) plus the existing mappings for 400, 403 and 429.
  3. config/abacus-api.php (if present) — base URL, credentials, timeouts.
  4. The README for the concrete resource methods exposed by the client.

First use case: resolve the client out of the container and let it throw typed exceptions, then branch on them.

use Contoweb\AbacusApi\AbacusClient;
use Contoweb\AbacusApi\Exceptions\AbacusNotFoundException;

public function __construct(private AbacusClient $abacus) {}

public function show(string $id)
{
    try {
        return $this->abacus->customer($id);
    } catch (AbacusNotFoundException $e) {
        // record genuinely does not exist in Abacus
        return null;
    }
}

Implementation Patterns

Inject, don't instantiate. Bind the client through the container (constructor injection or app(AbacusClient::class)) so config, HTTP client and fakes are interchangeable in tests. Avoid new AbacusClient(...) in application code.

Treat the exception type as the API contract. AbacusClient::toException() is the single place where HTTP status becomes a PHP type. Design your call sites around that mapping rather than inspecting status codes or message strings:

Status Meaning in practice Typical handling
400 Bad payload / rejected input Do not retry. Validate upstream, surface to the user.
403 Auth/permission problem Do not retry. Alert — this is a config or credential bug.
404 Record not found (new in v0.2.0) Treat as "missing in Abacus", reconcile or create.
429 Rate limited Retry with backoff / $release() in a queued job.

Wrap calls in a thin service layer. Put one class between your domain and AbacusClient that logs the method, payload and exception class. When a mapping changes between releases (as it did in v0.2.0), you only audit one file.

Queue-friendly pattern. In jobs, catch rate-limit exceptions and release, catch everything else and fail:

public function handle(AbacusClient $abacus): void
{
    try {
        $abacus->pushInvoice($this->invoice);
    } catch (AbacusRateLimitException $e) {   // maps 429
        $this->release(60);
    }
}

Global rendering for your own API. If you expose Abacus lookups through your own controllers, register a renderable in bootstrap/app.php so a missing upstream record becomes a clean 404 for your consumers instead of a 500:

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(fn (AbacusNotFoundException $e) => response()->json(
        ['message' => 'Not found'], 404
    ));
})

Testing. Fake the underlying HTTP layer (Http::fake([...])) and assert the exception type per status. Add a test per mapped status code — that is exactly the kind of suite that catches a v0.2.0-style mapping change before production does.

Gotchas and Tips

  • v0.2.0 changes 404 behaviour. Previously a 404 surfaced as some other/generic exception; now it is Contoweb\AbacusApi\Exceptions\AbacusNotFoundException. The maintainers call it non-breaking (it is still an exception), but any code that branched on the class or message of the 404 case needs revisiting. Audit catch blocks and instanceof checks for 404 handling.
  • Catch order matters. Put AbacusNotFoundException and the other specific types before any broad catch (\Throwable) or base-package exception, otherwise the new type is dead code.
  • Don't blanket-catch. Swallowing 403 or 429 turns a loud config/rate problem into silent data loss. Let unexpected statuses bubble to Laravel's handler and report() them.
  • Config caching. After changing credentials or base URL in .env, run php artisan config:cache (or config:clear in local dev) — a stale cached config is the most common "it authenticates in tinker but not in the app" cause.
  • Log the upstream payload on failure. The exception alone rarely tells you why Abacus rejected a 400; capture the request body and, where available, the response body in your wrapper.
  • Pin and read the changelog. This is a small package with infrequent releases; the changelog is short enough to read on every bump. Watch for future changes to toException() — that method is the highest-leverage surface in the package.
  • Extension points. If you need custom status handling, prefer decorating your own service around AbacusClient (or rebinding it in a service provider) over forking. Keeping the vendor class untouched makes upgrades trivial.
  • Version-constrain deliberately. Use ^0.2 in composer.json and run your per-status tests after each update; with 0.x versions, minor bumps can carry behavioural changes like this one.
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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route