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 Fina Sdk Laravel Package

giorgigrdzelidze/laravel-fina-sdk

A Laravel SDK for integrating the Fina API into PHP applications. It provides configuration, service bindings, and convenient helpers for authenticating and making Fina requests, helping keep your Laravel integration clean, reusable, and maintainable.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package and publish its config (config/fina.php or similar) — this is where the FINA Web API v8.0 base URL, credentials and token storage live.
  2. Point the base URL at the FINA sandbox first. Confirm which config keys hold the bearer token vs. the refresh credentials, and make sure the token cache/store is not array (it must survive between requests, otherwise every request pays a token round-trip).
  3. Read the package's test suite before the source — at 84 tests it is the fastest specification of behaviour. The HTTP tests show exactly which URLs, verbs and headers each resource emits, and the 401 test shows the token-refresh contract.
  4. First real use case: stock visibility. Call the Products resource's rest() and you get { rest: [{ id, store, rest, reserve }] } — one entry per product per store, which is the shape you want for a per-store availability table or a cache warm-up job.
  5. Second use case: single retail sale document. getProductOutSingle($id) returns the product_out_single document with its products[] array — useful for pulling up one receipt/sale for support or reconciliation without a bulk export.

Implementation Patterns

Resolve the client from the container, don't new it. Bind/inject the API client (or use the facade) so tests can swap it. The package already centralises the HTTP layer; duplicating Http::withToken(...) calls around it defeats the guard and the refresh logic.

Treat the response guard as the contract. Every call — including the two new v0.1.3 endpoints — goes through the guard, so a FINA ex payload surfaces as FinaRemoteException rather than as data. Structure your calling code as:

try {
    $levels = $fina->products()->rest();
} catch (FinaRemoteException $e) {
    // business/validation error from FINA (`ex`) or transport failure
    report($e);
    return;
}

Catch FinaRemoteException at the job/controller boundary, not around every call, and let genuine programming errors bubble.

Sync jobs for rest(). The all-products/all-stores payload grows with catalogue size. Pull it in a queued job, then upsert into a product_store_stock table keyed on (product_id, store) so reruns are idempotent. Keep rest and reserve in separate columns — they answer different questions (on-hand vs. committed) and consumers will ask for both.

Fetch documents on demand. getProductOutSingle($id) is a per-document call — use it lazily (an admin "view sale" action, a webhook follow-up), not inside a loop over a date range. If you find yourself looping, you want a bulk endpoint instead.

Don't hand-roll retries around the 401 path. The package refreshes the token on 401 and retries. Adding your own retry wrapper on top risks double-refreshing under concurrency. If you need resilience for 5xx/400, wrap at the job level with backoff and let FinaRemoteException be the trigger.

Test against the guard, not the message. When writing your own feature tests, assert FinaRemoteException is thrown and inspect the exception's payload/context rather than matching FINA's Dutch error strings.

Gotchas and Tips

  • Behaviour change for anyone who was on raw calls. The release notes explicitly call out that these two endpoints were previously reachable only via hand-rolled HTTP. If you wrote that code, the ex case now throws instead of returning the error body as $response->json(). Audit any ad-hoc Http:: calls to getProductsRest / getDocProductOutSingle and delete them.
  • rest() is denormalised. It is not one row per product — it is one row per product-store. Grouping, summing or "is this product in stock anywhere?" logic must aggregate over store. Getting this wrong silently shows the last store's figure.
  • Token refresh concurrency. A 401 refresh is fine for one worker; with N queue workers all hitting expiry simultaneously you can stampede the refresh. Cache the token with a lock (or a short safety margin before expiry) if you run parallel workers.
  • Config cache. After publishing/editing the FINA config, php artisan config:cache in deploy — and remember cached config ignores .env changes, a classic "why is it still hitting sandbox?" moment.
  • Log hygiene. Bearer tokens end up in Http:: debug logs and exception contexts. Scrub Authorization before reporting; FinaRemoteException payloads may echo request context.
  • Extension points. The HTTP client and base URL are typically swappable via the container/config — use that for a fake server in tests and for sandbox/production switching. Check the service provider for the binding before reaching for a fork.
  • Debugging tip. When a call misbehaves, drop to Http::fake() and assert the outgoing URL — the 9 tests added in v0.1.3 (URL/method, bearer token, payload passthrough, ex, 400/500, 401 refresh) are a copyable template for exactly this.
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