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

B24Phpsdk Laravel Package

bitrix24/b24phpsdk

Official PHP library for the Bitrix24 REST API, with two branches: v1 (stable, PHP 8.2–8.4) and v3 (active development, PHP 8.4+, new REST methods, breaking changes). Handles authentication, API calls, and batch requests.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the SDK (use v3 for current projects):

    composer require bitrix24/b24phpsdk:"^3.7"  # v3, PHP 8.4+
    composer require bitrix24/b24phpsdk:"^1.0"  # v1, legacy PHP 8.2-8.4
    

    The 3.7.0 release is additive: new batch scopes, REST v3 incremental user services, Pull/Voximplant/timeman/SonetGroup wrappers, and a portal-domain redirect veto event. No breaking changes are called out in the release notes.

  2. Initialize the service (pick one auth method):

    • Webhook (single-account integrations):
      use Bitrix24\SDK\Services\ServiceBuilderFactory;
      
      $b24Service = ServiceBuilderFactory::createServiceBuilderFromWebhook(
          config('services.bitrix24.webhook_url')
      );
      
    • Local Application (multi-account OAuth):
      use Bitrix24\SDK\Core\Credentials\ApplicationProfile;
      
      $appProfile = ApplicationProfile::initFromArray([
          'CLIENT_ID' => config('services.bitrix24.client_id'),
          'CLIENT_SECRET' => config('services.bitrix24.client_secret'),
          'SCOPE' => 'crm,im,sale,landing', // request only what you need
      ]);
      
      $b24Service = ServiceBuilderFactory::createServiceBuilderFromPlacementRequest(
          \Symfony\Component\HttpFoundation\Request::createFromGlobals(),
          $appProfile
      );
      
  3. First API call (e.g., fetch CRM deals):

    $deals = $b24Service->getMainScope()->crm()->deals()->getDeals();
    

Where to Look First

  • /src/Services/ – service scopes and typed service classes.
  • /examples/ – webhook, local app, and marketplace workflows.
  • /tests/ – integration patterns; use .env.local for credentials.
  • CHANGELOG.md – check before upgrading, especially if you use legacy IMBot, Pull, timeman, or log endpoints.
  • New in 3.7.0: Sale/Landing batch services, REST v3 user history/field-change/metadata services, getPullScope(), Voximplant callback service, and PortalDomainUrlChangingEvent.

First Practical Use Case

For a Laravel app, start with one sync job:

  • Pull CRM deals or Sale payments in chunks.
  • Use batch calls where available to reduce HTTP round-trips.
  • For user sync, prefer the new REST v3 cursor-based user history services over full user-list polling.

Implementation Patterns

1. Service Access and Batch Operations

Use builder methods to chain operations:

$deals = $b24Service
    ->getMainScope()
    ->crm()
    ->deals()
    ->getDeals(['SELECT' => ['ID', 'TITLE', 'AMOUNT']]);

Use generators for large CRM result sets:

foreach ($b24Service->getMainScope()->crm()->deals()->getDealsBatch() as $deal) {
    yield $deal->getId();
}

New in 3.7.0: Sale batch calls. Sale services expose a batch property:

$sale = $b24Service->getSaleScope();

$payments = $sale->payment()->batch->add([
    // payment payloads
]);

$shipments = $sale->shipment()->batch->list([
    // filter/select params
]);

Use this for order/payment/shipment synchronization jobs where you would otherwise issue many individual REST calls. The release covers many Sale entities, including basket properties, cashboxes, deliveries, payments, shipments, properties, statuses, and trade platforms.

New in 3.7.0: Landing batch calls. Landing batch services cover sites, pages, blocks, demos, repo, repo widgets, roles, sys pages, and templates:

$landing = $b24Service->getLandingScope();

$sites = $landing->site()->batch->list([
    'params' => ['limit' => 50, 'offset' => 0],
]);

Landing list batch methods support offset pagination via params.limit and params.offset.

2. Authentication and Portal Domain Redirects

  • The SDK refreshes OAuth tokens on expired-token responses; still handle auth failures in jobs and webhook handlers.
  • For multi-account OAuth, never send credentials or tokens to an untrusted portal domain.

New in 3.7.0: PortalDomainUrlChangingEvent lets you veto a portal redirect before credentials change or tokens are sent:

use Bitrix24\SDK\Core\Events\PortalDomainUrlChangingEvent;
use Bitrix24\SDK\Core\Exceptions\PortalDomainChangeRejectedException;

Event::listen(PortalDomainUrlChangingEvent::class, function (PortalDomainUrlChangingEvent $event) {
    if (! in_array($event->getNewDomain(), config('services.bitrix24.allowed_domains'), true)) {
        $event->deny(); // irreversible
    }
});

Catch PortalDomainChangeRejectedException in the surrounding flow and fail closed.

3. CRUD Patterns

Create:

$deal = $b24Service->getMainScope()->crm()->deals()->addDeal([
    'TITLE' => 'New Deal',
    'AMOUNT' => 1000,
]);

Update:

$deal->setTitle('Updated Deal')->update();

Delete:

$deal->delete();

For Sale and Landing, prefer typed service methods. For bulk updates, use the new batch services rather than looping individual CRUD calls in a job.

4. Event-Driven and Webhook Integrations

Handle webhook events:

$event = $b24Service->getCore()->getWebhookEvent();

switch ($event->getType()) {
    case 'crm.deal.add':
        $deal = $event->getData()['fields'];
        break;
}

For Laravel, route webhook handlers through a controller and dispatch queued jobs:

public function __invoke(Request $request)
{
    $event = $b24Service->getCore()->getWebhookEvent();

    SyncBitrix24Event::dispatch($event->getType(), $event->getData());

    return response()->noContent();
}

5. Incremental User Sync with REST v3 User History

3.7.0 adds REST v3 user history, field-change, and metadata services with cursor-based incremental reads. Use these for user sync instead of full-list polling:

$cursor = Cache::get('b24.user.history.cursor');

$history = $b24Service
    ->getMainScope()
    ->user()
    ->history()
    ->list(['cursor' => $cursor]);

foreach ($history->getItems() as $change) {
    // apply user change locally
}

Cache::put('b24.user.history.cursor', $history->getNextCursor());

Store the cursor per portal/account and advance it only after successful processing. This is a good fit for scheduled Laravel jobs.

6. Laravel Integration

Register a singleton:

// app/Providers/Bitrix24ServiceProvider.php
public function register(): void
{
    $this->app->singleton('bitrix24', function () {
        return ServiceBuilderFactory::createServiceBuilderFromWebhook(
            config('services.bitrix24.webhook_url')
        );
    });
}

Use it in controllers or jobs:

public function syncDeals()
{
    $deals = app('bitrix24')
        ->getMainScope()
        ->crm()
        ->deals()
        ->getDeals();

    // Process deals...
}

For multi-account apps, resolve the service builder per portal/account rather than registering a single global webhook client.

7. Error Handling

Wrap API calls and batch jobs in try/catch:

try {
    $result = $b24Service->getCore()->call('crm.deal.get', ['ID' => 1]);
} catch (\Bitrix24\SDK\Core\Exceptions\ApiException $e) {
    if ($e->getCode() === 401) {
        // Auth/token issue; SDK may auto-refresh, but surface persistent failures
    }

    Log::error('Bitrix24 API error', [
        'code' => $e->getCode(),
        'message' => $e->getMessage(),
    ]);
}

For portal domain changes:

try {
    // OAuth/install flow that may change portal domain
} catch (PortalDomainChangeRejectedException $e) {
    Log::warning('Rejected untrusted portal domain redirect', [
        'exception' => $e,
    ]);

    abort(403);
}

Gotchas and Tips

1. Version and Release Awareness

  • v3 requires PHP 8.4+; v1 remains for legacy PHP 8.2-8.4 systems.
  • 3.7.0 is additive, but check the changelog before upgrading if you rely on legacy IMBot, Pull, timeman, log, Disk, or SonetGroup methods.
  • IMBot deprecations: 3.7.0 documents legacy IMBot method deprecations and replacements. Plan migration if you own chat-bot code.
  • Use ^3.7 for new projects unless you are pinned by PHP version or existing v1 integration.

2. Portal Domain Redirect Veto Is Irreversible

  • PortalDomainUrlChangingEvent::deny() is irreversible.
  • Validate against an allowlist before denying.
  • Catch PortalDomainChangeRejectedException and fail closed.
  • Do not send OAuth tokens or credentials before the domain-change decision has been made.

3. Batch API Quirks

  • Sale batch calls are available through each service’s batch property.
  • Landing batch calls support offset pagination via params.limit and params.offset.
  • Landing batch key conventions differ by entity:
    • lid for landing.landing.update|delete
    • id for landing.site.update|delete
    • code for *.unregister methods
  • Not every endpoint is wrapped. For example, log.comment.delete remains excluded, and some Disk allowed-operation endpoints are still unresolved. Use a raw API call only when you accept the contract risk.
  • Batch responses can contain per-item errors; inspect individual results instead of assuming the whole batch succeeded.

4. Common Debugging Issues

  • 403 Forbidden: confirm the local app scope includes the required module, e.g. crm, sale, landing, im, disk.
  • Token expiry: webhook-only integrations do not have the same refresh flow as OAuth apps. For OAuth apps, persist refreshed tokens per portal.
  • Large datasets: avoid unbounded getDeals() calls. Use filters, SELECT, TOP, or batch/generator methods.
  • Untrusted portal domain: if a redirect is rejected, inspect the exception and the event’s target domain before retrying.

5. Performance Tips

  • Use batch calls for Sale and Landing bulk operations.
  • Use CRM batch generators for large result sets.
  • Use REST v3 cursor-based user history for incremental sync instead of full user-list scans.
  • Add COUNT => false where supported for list queries to reduce payload size.
  • Queue sync jobs and process results in chunks; do not run large batch loops inside a web request.

6. Extension Points

  • Extend \Bitrix24\SDK\Services\AbstractService for undocumented endpoints:
    class CustomService extends AbstractService
    {
        public function customMethod(array $params): array
        {
            return $this->getApiClient()->call('custom.endpoint', $params);
        }
    }
    
  • Inject HTTP middleware through ApiClient for logging, metrics, or tracing.
  • Use the new getPullScope() facade for legacy Pull channel/configuration work.
  • Use the cached Voximplant callback service for voximplant.callback.start.
  • For timeman integrations, note that 3.7.0 adds typed timeman methods with safe ACTIVE=false serialization; preserve that behavior when building payloads manually.

7. Testing Quirks

  • Use .env.local for integration credentials and never commit it.
  • Run targeted integration tests, e.g.:
    make test-integration-scope-crm
    
  • Mock API clients for unit tests:
    $mockClient = new ApiClientMock();
    $mockClient->setResponse('crm.deal.get', ['result' => ['ID' => 1]]);
    
    $service = new CrmService($mockClient);
    
  • For new 3.7.0 features, cover both success and rejection paths: portal domain deny, batch per-item errors, and cursor advancement after failed sync jobs.

8. Configuration Quirks

  • Store webhook URLs, client secrets, and allowlists in environment/config files.
  • Use ngrok or a similar tunnel for local OAuth development.
  • Add an install/callback endpoint for local app OAuth.
  • For multi-account apps, keep portal-specific tokens and cursors keyed by portal domain/member ID.

9. IDE Tips

  • Use a PHP 8.4-aware IDE for v3.
  • Ctrl+Click service methods to inspect typed parameters and return types.
  • Check /examples/ and the changelog when adopting new Sale, Landing, Pull, Voximplant, timeman, SonetGroup, or REST v3 user-history services.
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.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc