CRM Integration
CRM integrations extend Crm. They usually fetch one or more provider objects, define field-mapping schema for those objects, then send mapped submission data to the CRM after a submission completes.
For a full walkthrough, see Building a CRM Integration from Scratch.
Form Settings Data
Use fetchFormSettings() to fetch the CRM fields Formie can map to. A CRM often has multiple objects, such as contacts, deals, leads, accounts or opportunities.
use verbb\formie\models\IntegrationField;
use verbb\formie\models\IntegrationFormSettings;
public function fetchFormSettings(): IntegrationFormSettings
{
$contactFields = [
new IntegrationField([
'handle' => 'email',
'name' => Craft::t('formie', 'Email'),
'required' => true,
]),
new IntegrationField([
'handle' => 'name',
'name' => Craft::t('formie', 'Name'),
]),
];
$dealFields = [
new IntegrationField([
'handle' => 'title',
'name' => Craft::t('formie', 'Title'),
'required' => true,
]),
];
return new IntegrationFormSettings([
'contact' => $contactFields,
'deal' => $dealFields,
]);
}Form Settings Schema
CRM integrations commonly expose a lightswitch for each object they can map to, followed by a field-mapping schema for that object.
use verbb\formie\base\FormInterface;
use verbb\formie\helpers\SchemaHelper;
protected function defineFormSettingsSchema(FormInterface $form): array
{
$schema = parent::defineFormSettingsSchema($form);
$schema[] = $this->getOptInFieldSchema();
$schema[] = SchemaHelper::lightswitchField([
'name' => 'mapToContact',
'label' => Craft::t('formie', 'Map to Contact'),
'instructions' => Craft::t('formie', 'Whether to map form data to a contact.'),
]);
$schema[] = $this->getIntegrationFieldMappingField([
'name' => 'contactFieldMapping',
'if' => 'mapToContact',
'dataLabel' => 'Contact',
'dataKey' => 'contact',
]);
return $schema;
}Sending Payloads
Use getFieldMappingValues() to resolve each object mapping. When the mapping source contains a Formie field reference, Formie converts the value using the destination IntegrationField type.
use verbb\formie\base\Integration;
use verbb\formie\elements\Submission;
use Throwable;
public function sendPayload(Submission $submission): bool
{
try {
$contactValues = $this->getFieldMappingValues($submission, $this->contactFieldMapping, 'contact');
$response = $this->deliverPayload($submission, 'contacts', [
'contact' => $contactValues,
]);
return $response !== false;
} catch (Throwable $e) {
Integration::apiError($this, $e);
return false;
}
}If your CRM has selectable objects, use IntegrationCollection and pass the selected collection field to your mapping schema. That lets Formie show the right destination fields for the selected CRM object.