Un client nous a demandé, la semaine dernière, de brancher son formulaire de devis Elementor Pro sur un CRM interne qui n’a jamais entendu parler de Zapier. Pas de connecteur tout fait, pas de budget pour un service tiers : il fallait envoyer chaque soumission vers une URL interne, avec un format précis. Bonne nouvelle, Elementor Pro gère ce cas depuis longtemps, à deux niveaux différents.
Le premier niveau est visible dans l’éditeur : l’action « Webhook », disponible dans l’onglet Actions After Submit de n’importe quel formulaire. Le second, plus robuste et surtout personnalisable, consiste à écrire sa propre action PHP en étendant la classe abstraite Action_Base. Nous allons voir les deux, et pourquoi le second l’emporte dès que la logique dépasse un simple POST.
L’action Webhook native, pour aller vite
Dans l’éditeur, sélectionnez le widget Formulaire, ouvrez l’onglet Actions After Submit et cochez Webhook. Un champ URL apparaît : Elementor Pro y envoie une requête POST contenant tous les champs du formulaire, sérialisés en form_fields, accompagnés de métadonnées (IP, user agent, page source).
- Aucune ligne de code n’est nécessaire.
- Le format des données n’est pas configurable : c’est à prendre ou à laisser côté CRM.
- Les erreurs HTTP ne sont pas remontées à l’utilisateur qui soumet le formulaire.
Pour un simple relais vers un outil qui accepte du JSON brut, c’est parfait. Notre client avait besoin d’un format différent, avec un identifiant de contact recalculé côté serveur : il fallait passer à une action personnalisée.
Créer une classe Action_Base
Elementor Pro expose un système d’actions enregistrables, exactement comme les widgets. Chaque action après envoi (Email, Redirect, Webhook…) est une classe qui étend \ElementorPro\Modules\Forms\Classes\Action_Base. Voici le squelette minimal d’une action qui pousse les données vers notre CRM interne :
<?php
use ElementorPro\Modules\Forms\Classes\Action_Base;
use ElementorPro\Modules\Forms\Classes\Form_Record;
use ElementorPro\Modules\Forms\Classes\Ajax_Handler;
class Action_After_Submit_Crm_Maison extends Action_Base {
public function get_name() {
return 'crm_maison';
}
public function get_label() {
return __( 'CRM maison', 'wpm-forms' );
}
public function run( $record, $ajax_handler ) {
$raw_fields = $record->get( 'fields' );
$fields = [];
foreach ( $raw_fields as $id => $field ) {
$fields[ $id ] = $field['value'];
}
$response = wp_remote_post( 'https://crm.interne.test/api/leads', [
'timeout' => 8,
'headers' => [ 'Content-Type' => 'application/json' ],
'body' => wp_json_encode( [
'source' => get_permalink( $record->get( 'post_id' ) ),
'champs' => $fields,
] ),
] );
if ( is_wp_error( $response ) ) {
error_log( 'CRM maison : envoi échoué - ' . $response->get_error_message() );
}
}
public function register_settings_section( $widget ) {}
public function on_export( $element ) {}
}

Trois méthodes sont réellement obligatoires : get_name(), get_label() et run(). Les deux dernières peuvent rester vides si l’action n’ajoute aucun contrôle dans l’éditeur, ce qui est le cas ici puisque l’URL est codée côté serveur.
Enregistrer l’action auprès d’Elementor Pro
Une classe seule ne sert à rien tant qu’elle n’est pas déclarée. Cela se fait via le hook elementor_pro/forms/actions/register, qui reçoit le gestionnaire d’actions en argument :
add_action( 'elementor_pro/forms/actions/register', function( $form_actions_registrar ) {
require_once __DIR__ . '/class-action-crm-maison.php';
$form_actions_registrar->register( new Action_After_Submit_Crm_Maison() );
} );
Une fois ce code déposé dans le thème enfant (ou un petit plugin maison, ce que nous préférons pour ce genre de logique métier), l’action « CRM maison » apparaît dans la liste des Actions After Submit de chaque formulaire, au même titre que Email ou Redirect. Il suffit de la cocher.
Gérer les échecs proprement
Le piège classique : une soumission qui échoue côté CRM sans que personne ne s’en aperçoive, parce que l’utilisateur voit quand même le message de succès d’Elementor. Nous recommandons systématiquement d’ajouter, en plus du error_log(), une notification interne :
- Enregistrer les échecs dans une table dédiée ou un fichier de log tournant.
- Déclencher un e-mail d’alerte à l’équipe si le code HTTP retourné n’est pas 2xx.
- Prévoir un mécanisme de rejeu manuel pour les leads perdus, plutôt que de les laisser disparaître.
Sur un projet e-commerce, nous avons vu deux semaines de demandes de devis se perdre silencieusement parce que le endpoint du CRM avait changé de certificat SSL. Depuis, toute action after submit critique embarque une alerte par e-mail en cas d’échec.
En résumé
L’action Webhook native convient pour un simple relais de données brutes. Dès que la logique se complique — reformatage, calcul d’un identifiant, appel à plusieurs services — la classe Action_Base est le bon outil : elle s’intègre nativement dans l’éditeur, elle est enregistrée une seule fois via elementor_pro/forms/actions/register, et elle vit dans un code versionné plutôt que dans un champ texte de l’interface. Pensez simplement à toujours journaliser les échecs : un formulaire qui « fonctionne » côté visiteur mais ne livre rien côté CRM est le pire des bugs, invisible jusqu’à ce qu’un client s’étonne de ne jamais être rappelé.