karim-tao/pipedrive-laravel
A Laravel wrapper for the Pipedrive CRM API, making it easy to manage deals, leads, contacts, organizations, and activities from your PHP application. Provides a simple, expressive interface for authenticating and querying Pipedrive endpoints.
composer require karim-tao/pipedrive-client:^0.2. The 0.2 line depends on karim-tao/pipedrive-client ^0.2, so pin both together to avoid signature drift..env (PIPEDRIVE_CLIENT_ID, PIPEDRIVE_CLIENT_SECRET, PIPEDRIVE_REDIRECT_URI) and publish the package config (php artisan vendor:publish --tag=pipedrive-config).config/pipedrive.php, the service provider binding, and the Token value object / model — that is where auth state lives and where the 0.2.0 rename matters.use KarimTao\Pipedrive\Token;
use KarimTao\Pipedrive\Pipedrive;
$token = Token::fromArray($storedToken); // or hydrate from your own model
$deals = app(Pipedrive::class)
->withToken($token->accessToken, $token->expiresAt, $token->refreshToken, $token->baseUrl)
->deals()
->all(['status' => 'open', 'limit' => 100]);
baseUrl is carried on the token.access_token, refresh_token, expires_at, and base_url on your own model (usually per-user or per-tenant). Never recompute the API host — persist whatever Pipedrive returned and pass it back through withToken().expiresAt before dispatching work; refresh proactively (a minute or two of slack) and persist the new access/refresh pair. Put this in a RefreshPipedriveToken job or a middleware so queue workers and HTTP requests share the same logic.withToken() argument makes this clean — one row per connected company, each with its own base_url. Wrap access in a PipedriveForCompany resolver so callers never touch raw tokens.start, limit) in a while loop with a cursor stored on the job, so retries resume rather than restart.auth middleware, validate the webhook signature/basic auth from config, then push the payload onto a queue. Never call back into the API synchronously from the webhook handler.Http::fake() with URL patterns keyed to the baseUrl you configured. Assert that your code passes the correct baseUrl for non-default tenants — that is the easiest regression to miss after 0.2.0.DealsGateway, PersonsGateway). It keeps Pipedrive's DTO shapes out of your domain code and makes the eventual upgrade to ^0.3 a one-file change.Token::apiDomain() is now Token::baseUrl(). Any call site, accessor, or Blade/JSON serialisation referencing apiDomain will break. Grep the codebase for apiDomain before upgrading.withToken($accessToken, $expiresAt, $refreshToken = null, $baseUrl = null) — $baseUrl is the new fourth positional argument. If you were passing three arguments positionally you are fine, but if you had a wrapper or named arguments, update them. Prefer named arguments here to make future signature additions harmless.$baseUrl is nullable: passing null should fall back to the default API host. That is correct for single-tenant installs but silently wrong for companies on a non-default data centre — you will get 401s that look like auth bugs. Log the resolved base URL when debugging.api_domain, add a migration renaming it to base_url and backfill. Keeping the old column "just in case" invites two sources of truth.$expiresAt is consumed by the client, so pass the real expiry (Carbon or timestamp as the package expects) rather than null; otherwise the client cannot signal a stale token and you get a 401 mid-job.->withDelay()/backoff on 429 with a longer sleep than you think you need, and cap queue concurrency per company.method, resolved baseUrl, status, and Pipedrive's x-request-id — support tickets move much faster with that ID.^0.2 and read the release notes for each patch — the 0.1 → 0.2 jump shows this package is still willing to rename public API, so pin the minor and upgrade deliberately.How can I help you explore Laravel packages today?