ictinnovations/php-crm-connectors

Framework-agnostic PHP library of 21 CRM writeback connectors (Zoho, Pipedrive, Salesforce, Dynamics 365, SugarCRM, SuiteCRM, Freshsales, Copper, Capsule and more) behind one contract.

Maintainers

Package info

github.com/ictinnovations/php-crm-connectors

pkg:composer/ictinnovations/php-crm-connectors

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.1 2026-08-13 19:26 UTC

This package is auto-updated.

Last update: 2026-08-13 19:27:55 UTC


README

One contract, 21 CRM connectors. A framework-agnostic PHP library for pushing contacts and call/campaign outcomes into the CRMs your customers actually use — Zoho, Pipedrive, Salesforce, Dynamics 365, SugarCRM, SuiteCRM, Freshsales, Copper, Capsule, ActiveCampaign, Close, Keap, Zendesk Sell, Monday, Streak, Vtiger, Apptivo, Agile, Creatio, Less Annoying, and YetiForce.

CI Packagist License: MIT

Every connector implements the same interface, so calling code never changes when you add or switch a CRM:

use ICTInnovations\CrmConnectors\ConnectorFactory;

$crm = ConnectorFactory::make('zoho', [
    'client_id'     => getenv('ZOHO_CLIENT_ID'),
    'client_secret' => getenv('ZOHO_CLIENT_SECRET'),
    'refresh_token' => getenv('ZOHO_REFRESH_TOKEN'),
    'module'        => 'Leads',
    'disposition_map' => ['Interested' => 'Qualified', 'Sale' => 'Won'],
]);

$result = $crm->run([
    'phone'      => '+1 (202) 555-0147',
    'first_name' => 'Jane',
    'last_name'  => 'Doe',
    'email'      => 'jane@example.com',
    'campaign_name'   => 'Summer Outreach',
    'disposition'     => 'Interested',   // mapped -> 'Qualified' via disposition_map
    'disposition_crm' => 'Qualified',
    'duration'        => 73,
    'history_comments'=> 'Asked for a callback next week.',
    'time_connect'    => time(),
]);
// => ['remote_id' => '3652...', 'remote_module' => 'Leads']  (upserted + note + call activity)

run() finds the contact (by remote_id, then phone, then email), creates it if missing, applies the disposition, and attaches a note + a call activity — all through each CRM's native API.

What each connector gives you

The full contract (drive a CRM directly if you don't need the campaign orchestration):

$crm->authenticate();
$id = $crm->findContactByPhone('12025550147') ?? $crm->findContactByEmail('jane@example.com');
$id = $id ?? $crm->createContact(['first_name'=>'Jane','last_name'=>'Doe','phone'=>'...','email'=>'...']);
$crm->updateContact($id, [/* CRM-native fields */]);
$crm->createNote($id, ['subject'=>'Call', 'content'=>'...']);
$crm->createActivity($id, ['subject'=>'Call', 'duration'=>73, 'time_connect'=>time()]);

Install

composer require ictinnovations/php-crm-connectors

Requires PHP ≥ 7.4 with ext-curl and ext-json. No framework required — works standalone, in Laravel, Symfony, or any app.

Design

  • Pluggable token cache. OAuth connectors cache access tokens via a TokenStoreInMemoryTokenStore (default) or FileTokenStore ship in the box; implement the interface for Redis/DB.
  • Pluggable logging. Inject a CallableLogger (or wrap PSR-3); defaults to NullLogger.
  • No hidden I/O. Every HTTP call goes through one http() seam — trivial to mock in tests (see tests/ZohoFlowTest.php).
  • Disposition mapping from a plain disposition_map config array, per connector.
use ICTInnovations\CrmConnectors\Support\{FileTokenStore, CallableLogger};

$crm = ConnectorFactory::make('pipedrive', $config,
    new FileTokenStore('/var/cache/crm-tokens.json'),
    new CallableLogger(fn($lvl,$msg) => error_log("[$lvl] $msg")));

Connectors

ConnectorFactory::available() returns them all. Short name → CRM:

Short name CRM Auth
zoho Zoho CRM OAuth2 refresh token
pipedrive Pipedrive API token
salesforce Salesforce OAuth2
dynamics365 Microsoft Dynamics 365 OAuth2
sugarcrm / suitecrm SugarCRM / SuiteCRM OAuth2 password
freshsales Freshsales API key
copper Copper API key
capsule Capsule bearer token
activecampaign ActiveCampaign API key
close Close API key
keap Keap (Infusionsoft) OAuth2 / PAT
zendesksell Zendesk Sell bearer token
monday monday.com API token
streak Streak API key
vtiger Vtiger access key
apptivo Apptivo API key
agile Agile CRM API key
creatio Creatio OAuth2
lessannoying Less Annoying CRM API token
yetiforce YetiForce token

Each connector's config fields are declared in its form() method — see the class under src/Connector/.

Payload shape

run() accepts a partial payload and fills the rest; see docs/PAYLOAD.md for every key.

Testing

composer install
vendor/bin/phpunit          # factory, base, token store, and a mocked Zoho end-to-end flow

Connectors are tested by overriding the single http() seam — no live CRM needed.

Provenance & credits

Extracted and generalized from the CRM integration layer of ICTContact (28 CRM modules in production), by ICT Innovations / ICT Vision. Author: Tahir Almas.

MIT licensed — see LICENSE. Contributions welcome; see docs/PORTING.md to add a CRM.