Docs
Integration Examples
Integration Examples
Real-world examples and code samples for integrating with the Evon API.
This guide provides practical examples and integration patterns for common use cases with the Evon API.
Lead Capture Form Integration
HTML Form with JavaScript
Create a lead capture form that submits to the Evon API:
<!DOCTYPE html>
<html>
<head>
<title>Lead Capture Form</title>
</head>
<body>
<form id="leadForm">
<div>
<label for="firstName">First Name:</label>
<input type="text" id="firstName" name="firstName" required>
</div>
<div>
<label for="lastName">Last Name:</label>
<input type="text" id="lastName" name="lastName" required>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="phone">Phone:</label>
<input type="tel" id="phone" name="phone" required>
</div>
<button type="submit">Submit</button>
</form>
<script>
const API_KEY = 'your_api_key_here';
const API_BASE = 'https://dev.api.evoncrm.com';
document.getElementById('leadForm').addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const leadData = {
firstName: formData.get('firstName'),
lastName: formData.get('lastName'),
email: formData.get('email'),
phone: formData.get('phone'),
locale: 'EN_US'
};
try {
const response = await fetch(`${API_BASE}/api/leads`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(leadData)
});
const result = await response.json();
if (response.ok) {
alert('Lead submitted successfully!');
e.target.reset();
} else {
alert(`Error: ${result.error}`);
}
} catch (error) {
alert('Network error. Please try again.');
}
});
</script>
</body>
</html>React Integration
React Hook for API Calls
import { useState, useCallback } from 'react';
const useEvonAPI = () => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const API_KEY = process.env.REACT_APP_EVON_API_KEY;
const API_BASE = 'https://dev.api.evoncrm.com';
const makeRequest = useCallback(async (endpoint, options = {}) => {
setLoading(true);
setError(null);
try {
const response = await fetch(`${API_BASE}${endpoint}`, {
...options,
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
...options.headers,
},
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || 'API request failed');
}
return data;
} catch (err) {
setError(err.message);
throw err;
} finally {
setLoading(false);
}
}, [API_KEY]);
const createLead = useCallback(async (leadData) => {
return makeRequest('/api/leads', {
method: 'POST',
body: JSON.stringify(leadData),
});
}, [makeRequest]);
const getOrganization = useCallback(async () => {
return makeRequest('/organization');
}, [makeRequest]);
return {
loading,
error,
createLead,
getOrganization,
makeRequest,
};
};
// Usage in component
const LeadForm = () => {
const { createLead, loading, error } = useEvonAPI();
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
phone: '',
});
const handleSubmit = async (e) => {
e.preventDefault();
try {
const result = await createLead(formData);
alert('Lead created successfully!');
setFormData({ firstName: '', lastName: '', email: '', phone: '' });
} catch (err) {
// Error is handled by the hook
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="First Name"
value={formData.firstName}
onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}
required
/>
<input
type="text"
placeholder="Last Name"
value={formData.lastName}
onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}
required
/>
<input
type="email"
placeholder="Email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
required
/>
<input
type="tel"
placeholder="Phone"
value={formData.phone}
onChange={(e) => setFormData({ ...formData, phone: e.target.value })}
required
/>
<button type="submit" disabled={loading}>
{loading ? 'Submitting...' : 'Submit'}
</button>
{error && <div style={{ color: 'red' }}>{error}</div>}
</form>
);
};WordPress Plugin Integration
PHP Integration for WordPress
<?php
/**
* Evon API Integration for WordPress
*/
class EvonAPI {
private $api_key;
private $base_url = 'https://dev.api.evoncrm.com';
public function __construct($api_key) {
$this->api_key = $api_key;
}
private function make_request($endpoint, $method = 'GET', $data = null) {
$url = $this->base_url . $endpoint;
$args = [
'method' => $method,
'headers' => [
'X-API-Key' => $this->api_key,
'Content-Type' => 'application/json',
],
'timeout' => 30,
];
if ($data) {
$args['body'] = json_encode($data);
}
$response = wp_remote_request($url, $args);
if (is_wp_error($response)) {
throw new Exception('Request failed: ' . $response->get_error_message());
}
$status_code = wp_remote_retrieve_response_code($response);
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if ($status_code !== 200 && $status_code !== 201) {
throw new Exception($data['error'] ?? 'API request failed');
}
return $data;
}
public function create_lead($lead_data) {
return $this->make_request('/api/leads', 'POST', $lead_data);
}
public function get_organization() {
return $this->make_request('/organization');
}
}
// Hook into Contact Form 7 submission
add_action('wpcf7_mail_sent', 'evon_handle_contact_form_submission');
function evon_handle_contact_form_submission($contact_form) {
$api_key = get_option('evon_api_key');
if (!$api_key) return;
$submission = WPCF7_Submission::get_instance();
$posted_data = $submission->get_posted_data();
$lead_data = [
'firstName' => $posted_data['first-name'] ?? '',
'lastName' => $posted_data['last-name'] ?? '',
'email' => $posted_data['email'] ?? '',
'phone' => $posted_data['phone'] ?? '',
'locale' => 'EN_US'
];
try {
$evon_api = new EvonAPI($api_key);
$result = $evon_api->create_lead($lead_data);
// Log success
error_log('Evon lead created: ' . json_encode($result));
} catch (Exception $e) {
// Log error
error_log('Evon API error: ' . $e->getMessage());
}
}
// Admin settings page
add_action('admin_menu', 'evon_admin_menu');
function evon_admin_menu() {
add_options_page(
'Evon API Settings',
'Evon API',
'manage_options',
'evon-api-settings',
'evon_settings_page'
);
}
function evon_settings_page() {
if (isset($_POST['evon_api_key'])) {
update_option('evon_api_key', sanitize_text_field($_POST['evon_api_key']));
echo '<div class="notice notice-success"><p>Settings saved!</p></div>';
}
$api_key = get_option('evon_api_key', '');
?>
<div class="wrap">
<h1>Evon API Settings</h1>
<form method="post">
<table class="form-table">
<tr>
<th scope="row">API Key</th>
<td>
<input type="text" name="evon_api_key" value="<?php echo esc_attr($api_key); ?>" class="regular-text" />
<p class="description">Enter your Evon API key from the dashboard.</p>
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<?php
}
?>Advanced Form Tracking
Complete Form with Conversion Tracking
class EvonFormTracker {
constructor(apiKey, options = {}) {
this.apiKey = apiKey;
this.baseUrl = options.baseUrl || 'https://dev.api.evoncrm.com';
this.sessionId = null;
}
async createSession(formData = {}) {
try {
const response = await fetch(`${this.baseUrl}/api/forms/session`, {
method: 'POST',
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
formTitle: formData.title || 'Lead Form',
formDescription: formData.description || 'Website lead capture',
locale: formData.locale || 'EN_US',
link: window.location.href
})
});
const result = await response.json();
if (response.ok) {
this.sessionId = result.data.sessionId;
return result;
}
throw new Error(result.error);
} catch (error) {
console.error('Failed to create form session:', error);
throw error;
}
}
async submitForm(formData, conversionData = {}) {
if (!this.sessionId) {
throw new Error('No active session. Call createSession() first.');
}
try {
const payload = {
sessionId: this.sessionId,
data: formData,
eventName: conversionData.eventName || 'form_submit',
conversionValue: conversionData.value || 0,
currency: conversionData.currency || 'USD',
userAgent: navigator.userAgent,
ipAddress: await this.getClientIP(),
fbp: this.getFacebookPixel(),
fbc: this.getFacebookClickId()
};
const response = await fetch(`${this.baseUrl}/api/forms/data`, {
method: 'POST',
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
const result = await response.json();
if (response.ok) {
return result;
}
throw new Error(result.error);
} catch (error) {
console.error('Failed to submit form:', error);
throw error;
}
}
async getClientIP() {
try {
const response = await fetch('https://api.ipify.org?format=json');
const data = await response.json();
return data.ip;
} catch {
return null;
}
}
getFacebookPixel() {
// Extract Facebook browser pixel from cookie
const match = document.cookie.match(/_fbp=([^;]+)/);
return match ? match[1] : null;
}
getFacebookClickId() {
// Extract Facebook click ID from URL or cookie
const urlParams = new URLSearchParams(window.location.search);
const fbc = urlParams.get('fbclid');
return fbc ? `fb.1.${Date.now()}.${fbc}` : null;
}
}
// Usage example
const formTracker = new EvonFormTracker('your_api_key_here');
document.getElementById('leadForm').addEventListener('submit', async (e) => {
e.preventDefault();
try {
// Create session if not exists
if (!formTracker.sessionId) {
await formTracker.createSession({
title: 'Product Interest Form',
description: 'Customer showing interest in our products'
});
}
// Collect form data
const formData = new FormData(e.target);
const leadData = {
firstName: formData.get('firstName'),
lastName: formData.get('lastName'),
email: formData.get('email'),
phone: formData.get('phone'),
product: formData.get('product')
};
// Submit with conversion tracking
const result = await formTracker.submitForm(leadData, {
eventName: 'lead_generation',
value: 50.00, // Lead value
currency: 'USD'
});
// Show success message
alert('Thank you! Your information has been submitted.');
e.target.reset();
// Track in Google Analytics if available
if (typeof gtag !== 'undefined') {
gtag('event', 'form_submit', {
event_category: 'engagement',
event_label: 'lead_form'
});
}
} catch (error) {
alert('There was an error submitting your information. Please try again.');
console.error('Form submission error:', error);
}
});Error Handling Best Practices
Robust Error Handling
class EvonAPIClient {
constructor(apiKey, options = {}) {
this.apiKey = apiKey;
this.baseUrl = options.baseUrl || 'https://dev.api.evoncrm.com';
this.retryAttempts = options.retryAttempts || 3;
this.retryDelay = options.retryDelay || 1000;
}
async request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
const config = {
...options,
headers: {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json',
...options.headers,
},
};
for (let attempt = 1; attempt <= this.retryAttempts; attempt++) {
try {
const response = await fetch(url, config);
const data = await response.json();
if (response.ok) {
return data;
}
// Handle specific error cases
switch (response.status) {
case 400:
throw new ValidationError(data.error, data.details);
case 401:
throw new AuthenticationError(data.error);
case 403:
throw new AuthorizationError(data.error);
case 404:
throw new NotFoundError(data.error);
case 409:
throw new ConflictError(data.error);
case 429:
// Rate limit - wait before retry
if (attempt < this.retryAttempts) {
const resetTime = response.headers.get('X-RateLimit-Reset');
const waitTime = resetTime ?
(resetTime * 1000) - Date.now() :
this.retryDelay * attempt;
await this.sleep(waitTime);
continue;
}
throw new RateLimitError(data.error);
case 500:
// Server error - retry with exponential backoff
if (attempt < this.retryAttempts) {
await this.sleep(this.retryDelay * Math.pow(2, attempt - 1));
continue;
}
throw new ServerError(data.error);
default:
throw new APIError(`HTTP ${response.status}: ${data.error}`);
}
} catch (error) {
if (error instanceof TypeError && error.message.includes('fetch')) {
// Network error
if (attempt < this.retryAttempts) {
await this.sleep(this.retryDelay * attempt);
continue;
}
throw new NetworkError('Network connection failed');
}
if (attempt === this.retryAttempts) {
throw error;
}
}
}
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Custom error classes
class APIError extends Error {
constructor(message) {
super(message);
this.name = 'APIError';
}
}
class ValidationError extends APIError {
constructor(message, details) {
super(message);
this.name = 'ValidationError';
this.details = details;
}
}
class AuthenticationError extends APIError {
constructor(message) {
super(message);
this.name = 'AuthenticationError';
}
}
class AuthorizationError extends APIError {
constructor(message) {
super(message);
this.name = 'AuthorizationError';
}
}
class NotFoundError extends APIError {
constructor(message) {
super(message);
this.name = 'NotFoundError';
}
}
class ConflictError extends APIError {
constructor(message) {
super(message);
this.name = 'ConflictError';
}
}
class RateLimitError extends APIError {
constructor(message) {
super(message);
this.name = 'RateLimitError';
}
}
class ServerError extends APIError {
constructor(message) {
super(message);
this.name = 'ServerError';
}
}
class NetworkError extends APIError {
constructor(message) {
super(message);
this.name = 'NetworkError';
}
}Testing Your Integration
Unit Tests with Jest
// evon-api.test.js
import { EvonAPI } from './evon-api';
// Mock fetch
global.fetch = jest.fn();
describe('EvonAPI', () => {
let api;
beforeEach(() => {
api = new EvonAPI('test-api-key');
fetch.mockClear();
});
test('should create lead successfully', async () => {
const mockResponse = {
success: true,
data: {
id: 'lead-123',
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com'
}
};
fetch.mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
});
const leadData = {
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com',
phone: '+1-555-123-4567'
};
const result = await api.createLead(leadData);
expect(fetch).toHaveBeenCalledWith(
'https://dev.api.evoncrm.com/api/leads',
expect.objectContaining({
method: 'POST',
headers: expect.objectContaining({
'X-API-Key': 'test-api-key',
'Content-Type': 'application/json'
}),
body: JSON.stringify(leadData)
})
);
expect(result).toEqual(mockResponse);
});
test('should handle validation errors', async () => {
const mockError = {
error: 'Datos inválidos',
details: [
{
path: ['email'],
message: 'Email inválido'
}
]
};
fetch.mockResolvedValueOnce({
ok: false,
status: 400,
json: async () => mockError
});
const invalidLeadData = {
firstName: 'John',
lastName: 'Doe',
email: 'invalid-email',
phone: '+1-555-123-4567'
};
await expect(api.createLead(invalidLeadData))
.rejects
.toThrow('Datos inválidos');
});
});These examples provide a solid foundation for integrating the Evon API into various applications and platforms. Remember to always handle errors gracefully, implement proper retry logic, and follow security best practices when storing API keys.