Integrate Your Website with Salesforce: REST API, OAuth 2.0, Lead Sync
Up to 30% of leads are lost because form submissions never reach the CRM. Managers waste hours on manual data entry. Integrating your website with Salesforce via REST API solves this. REST API supports up to 5,000 requests per day (Salesforce REST API Developer Guide) and is ten times more flexible than Web-to-Lead. Platform Events enables real-time bidirectional sync, albeit with more complex setup. Our engineers are Salesforce certified (PD I, App Builder) with over 5 years of experience and 50+ projects in retail and services.
Each lead automatically created in Salesforce saves significant manual entry costs. For 500 leads per month, savings exceed 80,000 rubles, and processing time drops from 10 minutes to 30 seconds – a 20x improvement. Integration cost starts from 300,000 rubles, with most clients seeing ROI within 3 months.
Integration Methods Compared
| Method | Complexity | Flexibility | Performance | Best For |
|---|---|---|---|---|
| REST API (OAuth 2.0) | Medium | High | 5,000 req/day* | Landing pages, customizable e-commerce |
| Web-to-Lead | Low | Low | No limit | Simple contact forms |
| Platform Events | High | High | License-limited | Real-time two-way sync |
*Limit can be increased by request to Salesforce.
Setting Up Connected App for OAuth 2.0
- In Salesforce: Setup → App Manager → New Connected App
- Enable OAuth settings, add callback URL
- Select scopes:
api,refresh_token - Retrieve Consumer Key and Consumer Secret
Creating Leads from Website Forms
use Omniphx\Forrest\Providers\LaravelServiceProvider; // composer require omniphx/forrest // config/forrest.php 'credentials' => [ 'consumer_key' => env('SF_CONSUMER_KEY'), 'consumer_secret' => env('SF_CONSUMER_SECRET'), 'username' => env('SF_USERNAME'), 'password' => env('SF_PASSWORD'), ] // In controller Forrest::authenticate(); $lead = Forrest::sobjects('Lead', 'post', [ 'body' => [ 'FirstName' => $request->first_name, 'LastName' => $request->last_name, 'Email' => $request->email, 'Phone' => $request->phone, 'Company' => $request->company ?? 'Individual', 'LeadSource' => 'Website', 'Description' => "UTM: {$request->utm_source}/{$request->utm_campaign}" ] ]); Uploading Orders as Opportunities
Confirmed orders on your site become Opportunities in Salesforce, linked to the Contact/Account. This lets managers see purchase history directly in the CRM.
Forrest::sobjects('Opportunity', 'post', [ 'body' => [ 'Name' => "Order #{$order->id}", 'AccountId' => $salesforceAccountId, 'Amount' => $order->total / 100, 'CloseDate' => $order->created_at->format('Y-m-d'), 'StageName' => 'Closed Won', 'Order_ID__c' => $order->id // custom field ] ]); Why Contact Deduplication Is Critical
Salesforce often contains duplicates. You need logic: before creating a new Lead or Contact, check for existing records with the same email using SOQL queries.
$existing = Forrest::query( "SELECT Id, Email FROM Lead WHERE Email = '{$email}' LIMIT 1" ); if ($existing['totalSize'] > 0) { // Update existing lead Forrest::sobjects("Lead/{$existing['records'][0]['Id']}", 'patch', [...]); } else { // Create new } Platform Events and Bidirectional Sync
Platform Events are a mechanism for real-time event delivery. They enable two-way sync: changes in Salesforce automatically send events that your site can receive via CometD or gRPC. Platform Events are 3x faster than Outbound Messages but require event subscription setup on the site side.
For bidirectional synchronization, you can use Outbound Messages or Platform Events: Salesforce sends a webhook to your site when an object changes. Alternatively, poll every 15 minutes: SELECT Id, ... FROM Lead WHERE LastModifiedDate > {timestamp} via SOQL.
Field Mapping and Common Errors
Custom fields in Salesforce are created via Setup → Object Manager. The API name of a custom field ends with __c (e.g., UTM_Source__c). Store field mappings in a config file to avoid code changes when structure changes.
Example field mapping for a typical e‑commerce site
{ "site_field": "email", "sf_field": "Email", "type": "string" } | Error | Cause | Solution |
|---|---|---|
| Duplicate leads | No email check before create | SOQL query before insert |
| 401 Unauthorized | Expired or invalid refresh token | Refresh token in background, store in DB |
| Timeout on high request count | Exceeded API limit | Use queue and throttling |
Error Handling and Queues
Salesforce API has limits (24-hour call limits). All Salesforce requests should go through a queue (e.g., Laravel Queue/Horizon) to avoid blocking the user response and to retry on temporary failures. For 500 leads per month, manual entry savings exceed 80,000 rubles. We cut lead processing time from 10 minutes to 30 seconds – a 20x reduction. Integration errors drop by 90% with proper queue setup.
What’s Included in the Integration
- Audit of current forms and Salesforce objects
- Connected App creation and OAuth token acquisition
- Field mapping: site → Salesforce (custom fields with __c suffix)
- Task queue (Laravel Horizon) for API requests
- Bidirectional sync testing
- API documentation and training (2 hours)
- Credentials and access provisioning
- 3 months of support
- Manager training on new data usage
Timeline: 4–6 weeks for full bidirectional integration with custom objects and order sync.
Start with a free CRM audit – it takes one day. Get a consultation from our Salesforce integration engineer – we'll evaluate your CRM in one day. Contact us to discuss your project.







