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

Asaas Sdk Php Laravel Laravel Package

jetimob/asaas-sdk-php-laravel

Laravel integration for the Asaas payment gateway that wraps the Asaas PHP SDK with package configuration and service bindings, making it easier to manage customers, payments, subscriptions, and related billing operations in Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This release (v1.9.0.0) adds support for the externalReference field — Asaas' free-form correlation string that lets you attach your own identifier (order UUID, invoice ID, tenant key) to a customer, payment, or subscription and get it echoed back on the object and in webhook payloads. This is the single most useful field for reconciling Asaas records with your local models, so it's worth adopting early.

Minimal setup:

  1. composer require jetimob/asaas-sdk-php-laravel
  2. Publish the config: php artisan vendor:publish --tag=asaas-config (check vendor/jetimob/asaas-sdk-php-laravel/src/Providers for the exact tag if it differs).
  3. Populate .env — typically ASAAS_API_KEY plus an environment/sandbox switch. Confirm the key names against the published config/asaas.php; do not assume.
  4. Point at sandbox first. Asaas sandbox keys are entirely separate from production keys and are not interchangeable.
  5. php artisan config:clear after editing env values.

Where to look first:

  • config/asaas.php — environment, API key, base URI, and any HTTP/timeout options.
  • The package's ServiceProvider and Facade — the facade is the day-to-day entry point.
  • vendor/jetimob/asaas-sdk-php/src — the underlying SDK. The Laravel package is a thin container/facade binding over it, so the entity classes (Customer, Payment, Subscription, Webhook, etc.) and their setters are documented there, not in the Laravel wrapper. This is where you'll confirm that externalReference is exposed as a setter on the entities you care about.

First use case — correlate a charge with a local order:

$payment = Asaas::payments()->create([
    'customer'          => $asaasCustomerId,
    'billingType'       => 'PIX',
    'value'             => 149.90,
    'dueDate'           => now()->addDays(3)->toDateString(),
    'externalReference' => $order->uuid,   // new in v1.9.0.0
]);

Then persist $payment->id locally. You now have a bidirectional link: your UUID on their side, their ID on yours.

Implementation Patterns

Always set externalReference on write, always resolve by it on read. Treat it as your join key. Set it to an immutable identifier (UUID, not an auto-increment ID you might recycle, and not something user-editable). On webhooks, resolve $payload['payment']['externalReference'] → your model rather than maintaining a separate asaas_id lookup table as the only path. Keep the asaas_id column too — you need it for API calls — but the external reference is what survives export/import and manual dashboard creation.

Wrap the SDK in a thin application service. Don't call the facade from controllers or models. A BillingService/AsaasGateway class that maps your domain objects to SDK payloads gives you one place to enforce externalReference, one place to normalise money, and one seam to fake in tests.

Push writes into queued jobs. Charge creation, customer creation, and subscription updates are network calls to a third party. Wrap them in jobs with $tries/backoff. Because externalReference is a natural idempotency hint, your job can check "does a payment with this externalReference already exist?" before creating a duplicate on retry.

Webhook flow. A dedicated route outside auth middleware → verify the asaas-access-token header against your configured secret → persist the raw payload → dispatch a job → respond 200 immediately. Do the actual state transition asynchronously. Asaas retries on non-2xx and can deliver out of order, so make the job idempotent keyed on the event/payment ID.

Reconciliation command. A scheduled asaas:reconcile artisan command that pulls recent payments (filtering or matching on externalReference) and diffs against local state catches the webhooks you missed during deploys. This is the pattern that makes the field pay for itself.

Testing. Bind a fake gateway implementation in the container for feature tests, and reserve real sandbox calls for a small number of integration tests. Don't let the suite depend on network availability.

Gotchas and Tips

  • externalReference is not unique or enforced. Asaas will happily store the same string on ten payments. Uniqueness is your invariant, enforced in your own code. Guard against double-submits in the job/controller, not in the API call.
  • Length and character limits. Confirm the max length in the SDK's validation before you put a long composite key in there; a truncated reference is worse than none. Keep it short and opaque.
  • Echo-back is not universal. Verify per entity that externalReference round-trips in the API response and inside the webhook payload for the specific event you handle — support was added incrementally and may not cover every entity/endpoint at v1.9.0.0.
  • Errors arrive as HTTP 400 with a JSON errors array, not as typed exceptions with useful messages. The SDK throws, but the human-readable reason (e.g. invalid CPF/CNPJ, duplicate charge) lives in the response body. Catch, log the body, and surface a domain error.
  • Sandbox and production keys are distinct and non-portable. A common failure is deploying a sandbox key, or leaving sandbox => true in a cached config. Assert the environment at boot in non-local environments.
  • Config caching bites. config:cache freezes env values; reading env() directly anywhere in your own code alongside this package will silently return null in production.
  • Money and dates. Send values as the SDK expects (decimal, not cents) and dates as Y-m-d. Mixing cents and reais is the classic 100x billing bug.
  • Webhook secret verification is on you. The package does not authenticate inbound webhooks; the shared token check is your responsibility, and the route must be excluded from CSRF.
  • Extension points. The cleanest place to add logging, retries, or tracing is a Guzzle middleware on the underlying HTTP client (rebind/replace the client in a service provider) rather than wrapping every SDK call. For behavioural changes, decorate your own gateway class — avoid forking the vendor package.
  • Upgrade check. When bumping, diff vendor/jetimob/asaas-sdk-php as well as the Laravel wrapper; most feature and breaking surface lives in the underlying SDK, and this package's version bumps can be very small relative to the behaviour change they pull in.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core