Fermin Perdomo

Senior Full Stack Engineer | PHP | JavaScript

From Salesforce to Laravel: A Guide to Successful Lead Management Integration

Fermin Perdomo
April 22, 2023

Lead management is an essential part of any business, and it's important to have a system that allows you to manage leads effectively. Many companies use Salesforce as a popular customer relationship management (CRM) software to manage their information. However, if you're using Laravel for your web development, you may wonder how to integrate Salesforce's lead management into your Laravel application.

Prerequisites

  • PHP 8.x and Laravel 9/10/11
  • A Salesforce Developer account
  • Composer
  • Basic knowledge of OAuth flows

1) Create a Salesforce Developer Account

  1. Sign up for a free Salesforce Developer account.
  2. In Salesforce, create a Connected App:
    • Enable OAuth Settings.
    • Add a Callback URL (e.g., https://your-app.test/auth/salesforce/callback).
    • Select scopes like Access and manage your data (api), Perform requests at any time (refresh_token, offline_access).
  3. Copy the Consumer Key and Consumer Secret—you'll need them in Laravel.

2) Install the Salesforce SDK for Laravel

In your Laravel project:

composer require omniphx/forrest

For Laravel >= 5.5, the service provider and alias are auto-discovered.
For earlier versions, add to config/app.php:

'providers' => [
    // ...
    Omniphx\Forrest\Providers\Laravel\ForrestServiceProvider::class,
],

'aliases' => [
    // ...
    'Forrest' => Omniphx\Forrest\Providers\Laravel\Facades\Forrest::class,
];

3) Publish & Configure

Publish the config:

php artisan vendor:publish --provider="Omniphx\Forrest\Providers\Laravel\ForrestServiceProvider"

This creates config/forrest.php where you can choose auth type and tweak settings.

Add these to your .env:

# Salesforce OAuth (Web Server flow)
SF_AUTH_TYPE=WebServer
SF_LOGIN_URL=https://login.salesforce.com
SF_CONSUMER_KEY=your_consumer_key
SF_CONSUMER_SECRET=your_consumer_secret
SF_CALLBACK_URL=https://your-app.test/auth/salesforce/callback

# Optional defaults
SF_API_VERSION=v59.0

Update config/forrest.php to read from envs, e.g.:

'authentication' => env('SF_AUTH_TYPE', 'WebServer'),
'credentials' => [
    'consumerKey'    => env('SF_CONSUMER_KEY'),
    'consumerSecret' => env('SF_CONSUMER_SECRET'),
    'callbackURI'    => env('SF_CALLBACK_URL'),
    'loginURL'       => env('SF_LOGIN_URL', 'https://login.salesforce.com'),
],
'version' => env('SF_API_VERSION', 'v59.0'),

4) Set Up Authentication Routes (Web Server Flow)

Routes (routes/web.php):

use App\Http\Controllers\SalesforceAuthController;

Route::get('/auth/salesforce', [SalesforceAuthController::class, 'login'])
    ->name('salesforce.login');

Route::get('/auth/salesforce/callback', [SalesforceAuthController::class, 'callback'])
    ->name('salesforce.callback');

Controller (app/Http/Controllers/SalesforceAuthController.php):

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Forrest;

class SalesforceAuthController extends Controller
{
    public function login()
    {
        // Redirects user to Salesforce OAuth screen
        return Forrest::authenticate();
    }

    public function callback(Request $request)
    {
        // Handles Salesforce callback and stores encrypted token
        Forrest::callback();

        return redirect()->route('dashboard')
            ->with('status', 'Salesforce connected successfully.');
    }
}

After successful auth, Forrest stores an encrypted token for API calls.

5) Basic Usage: Query Records

Query a record:

$response = Forrest::query("SELECT Id, FirstName, LastName, Company, Email FROM Lead LIMIT 10");
$records  = $response['records'] ?? [];

Handling >2000 records (pagination):
If a query returns more than 2000 records, Salesforce includes nextRecordsUrl:

$records = [];
$response = Forrest::query("SELECT Id, FirstName, LastName, Company, Email FROM Lead");

$records = array_merge($records, $response['records'] ?? []);

while (!empty($response['nextRecordsUrl'])) {
    $response = Forrest::next($response['nextRecordsUrl']);
    $records = array_merge($records, $response['records'] ?? []);
}

6) Retrieve All Leads (Helper Example)

public function fetchAllLeads(): array
{
    $soql = "SELECT Id, FirstName, LastName, Company, Email, Status, CreatedDate FROM Lead";
    $all = [];

    $resp = Forrest::query($soql);
    $all = array_merge($all, $resp['records'] ?? []);

    while (!empty($resp['nextRecordsUrl'])) {
        $resp = Forrest::next($resp['nextRecordsUrl']);
        $all = array_merge($all, $resp['records'] ?? []);
    }

    return $all;
}

7) Create Leads in Salesforce

$data = [
    'FirstName' => 'Jane',
    'LastName'  => 'Doe',
    'Company'   => 'Acme Inc.',
    'Email'     => '[email protected]',
    'Status'    => 'Open - Not Contacted',
];

$response = Forrest::post('sobjects/Lead', $data);

// $response typically contains the new Id and success flag

8) Update or Upsert a Salesforce Lead

Update by Salesforce Id:

$leadId = '00Q5g0000123456AAA';

$data = [
    'Status' => 'Working - Contacted',
    'Company' => 'Acme International',
];

Forrest::patch("sobjects/Lead/{$leadId}", $data);

Upsert using an External ID field:

$externalField = 'External_Id__c';
$externalId    = 'LEAD-12345';

$data = [
    'FirstName' => 'Jane',
    'LastName'  => 'Doe',
    'Company'   => 'Acme Upserted Co.',
    'Status'    => 'Open - Not Contacted',
];

// If a record with External_Id__c = LEAD-12345 exists, it will be updated; otherwise created.
Forrest::patch("sobjects/Lead/{$externalField}/{$externalId}", $data);

Conclusion

You’ve seen how to connect Laravel to Salesforce, authenticate with OAuth, and retrieve, create, update, and upsert leads using the REST API. With this integration, your team can manage Salesforce leads directly from your Laravel application—streamlining workflows for both your users and customers.


Reactions

Loading reactions...
Log in to react to this post.

Comments

Please login to leave a comment.

Newsletter