La gestion d’un site e-commerce nécessite souvent d’intégrer ou de développer des outils supplémentaires de gestion et d’interaction avec le client. Parmi les actions nécessaires, la relance du client peut s’avérer très utile, notamment en cas de vente de services ou de produits, nécessitant la transmission de documents ou d’informations complémentaires pour le traitement de la commande.
Dans cet article, nous allons créer un système simple permettant au gestionnaire d’une boutique en ligne Woocommerce d’envoyer manuellement un message de relance client depuis une page d’une commande. Ce type de module pourra être intégré directement à la création de la boutique en ligne ou permettre une évolution du skite e-commerce sans frais supplémentaire.
Interface d’envoi d’e-mail personnalisé
La première chose à faire pour envoyer une relance au client d’une boutique Woocommerce est de créer un formulaire permettant d’envoyer l’e-mail en tâche de fond, incluant un champ de texte <textarea> ainsi qu’un bouton simple d’envoi.
Nous allons donc commencer par créer une metaboxe spécifique aux pages de commande Woocommerce, chargée d’afficher ces éléments HTML, et d’intégrer un script jQuery afin d’écouter l’action utilisateur et d’émettre une requête AJAX pour effectuer l’envoi d’e-mail en question, en récupérant les données du client.
Voici à quoi resemblera notre metabox d’envoi d’e-mail de relance client ainsi que de la réponse serveur à la requête AJAX émise depuis la page de commande Woocommerce :
WordPress propose traditionnellement une API permettant d’intégrer en back-office des champs de saisie ou autres éléments d’interface utilisateur. Cette API WordPress est encore valide y compris sur l’éditeur Gutenberg.
Nous utiliserons donc ici le hook add_meta_boxes ainsi que la fonction WordPress add_meta_box pour créer la zone de métadonnées au sein de l’éditeur, et y présenter un champ de saisie :
function jst_order_screen_add_metaboxes($post_id, $post ) {
add_meta_box(
‘jst_email_file_upload_needed’,
__( 'Envoi relance e-mail de téléchargement de fichiers' ),
[ $this, 'permis_conduire_email_file_upload_needed' ],
'shop_order',
'side',
'high'
);
}
function jst_email_file_upload_needed( $post ) {
wp _nonce_fiels('pdcnfileuploadneeded', ‘pdcnfileuploadneeded_nce’ );
?>
<div class="jst-email-files-upload-needed">
<p><textarea id=”jst-email-files-upload-needed-txt” class=”email-files-upload-needed-txt”></textarea><p>
<button id="jst-email-files-upload-needed-btn" class="button button-small button-secondary">
<?php _e( 'Envoyer relance fichiers client', 'jst' ); ?>
</button>
</div>
<div id="jst-email-files-upload-needed-result"></div>
<?php
}
add_action( 'add_meta_boxes', array( $this, 'jst_order_screen_add_metaboxes' ), 10, 2 );
Ici, j’appelle avec le hook add_metaboxes, la fonction jst_order_screen_add_metaboxes() chargée de créer une zone de métadonnée sur la page d’édition. Cette fonction callback fait elle-même appel à ma fonction interne jst_email_file_upload_needed(), chargée d’afficher le, ou les champs de saisie, un bouton d’envoi d’e-mail et un champ permettant de saisir un contenu personnalisé.
L’inspection de la page de commande après cette intégration nous montre que la structure HTML de ce module est bien ajoutée à la page de commande Woocommerce :
Enregistrement du script AJAX et transmission des données de commande
Le script Javasctipt permettant d’écouter l’action utilisateur et de transmettre au serveur notre requête AJAX, doit être enregistré sur WordPress afin qu’il soit appelé spécifiquement sur les nos pages d’édition de commande Woocommerce.
Afin de cibler la page d’édition de commande Woocommerce, nous pouvons utiliser le hook woocommerce_admin_order_data_after_shipping_address permettant d’afficher à peu près tout ce que l’on veut sur la page HTML, après la zone d’adresse d’envoi, et présentant l’avantage de bénéficier de l’objet de commande en paramètre de la fonction callback.
Je l’utilise ici pour enregistrer et présenter un script sur la page d’administration WordPress, ainsi que pour enregistrer des données qui lui seront transmises telles que l’adresse URL AJAX ainsi que l’action permettant d’écouter le bon hook AJAX de WordPress.
N.B. nous pourrions aussi utiliser le hook admin_enqueue_script et récupérer l’objet global $order.
Au sein de cette fonction de rappel, nous importons le script dans le document HTML à l’aide de la fonction WordPress wp_enqueue_script().
function jst_shop_order_enqueue_scripts( $order ){
wp_register_script(
'jst-email-clientfiles-upload-nedded',
plugins_url(
'assets/js/jst-email-clientfiles-upload-nedded.js',
__FILE__
),
[ 'jquery' ],
true
);
wp_localize_script(
jst-email-clientfiles-upload-nedded',
'clientFileUploadNeededParams',
[
'ajax_url' => admin_url( 'admin-ajax.php' ),
'clientFileUploadNeededAction' => 'client_file_upload_email',
'orderId' => $order->get_id(),
'nce' => $uplneddedemailnce
]
) ;
wp_enqueue_script( jst-email-clientfiles-upload-nedded' );
);
add_action( ‘woocommerce_admin_order_data_after_shipping_address’, ‘jst_shop_order_enqueue_scripts’ ) ;
Script AJAX d’interception d’action utilisateur sur l’interface Woocommerce
Il nous reste maintenant à récupérer dans notre script les données « localisées », et écouter les événements utilisateurs afin de déclencher notre appel AJAX au clic sur le bouton de notre metabox.
Un bref retour sur l’enregistrement de notre script nous donne une indication sur la librairie Javascript jQuery utilisée pour le développement de ce script.
N.B. Vous noterez l’utilisation d’une affectation par destructuration (décomposition) d’objet pour récupérer et d’exposer les données localisées.
(function($){
$(document).ready(function(){
let params = clientFileUploadNeededParams;
let {
ajax_url,
clientFileUploadNeededAction,
orderId
} = params,
nce = $(‘.pdcnfileuploadneeded_nce ).val();
$('body').on('click', 'button# jst-email-files-upload-needed-btn, function(e){
e.preventDefault();
$('# jst-email-files-upload-needed-result ').css({'display' : 'none' } );
let $emailContent = $(‘# jst-email-files-upload-needed-txt’).val();
$.ajax({
url: ajax_url,
type: 'POST',
data : {
'action': clientFileUploadNeededAction,
'order_id': orderId,
'nce': nce,
‘emailContent’ : $emailContent
},
success : function( response ){
if( response ){
response = JSON.parse( response );
response = response[0] .replace(/\n/g, '<br>\n').replace(/\r/g, '<br>\n');
}else{
response = 'Aucune réponse du mailer Woocommerce';
}
$('# jst-email-files-upload-needed-result’)
.html( '<span id="jst-email-files-upload-needed-result__inner">' + response + '</span>' )
.fadeIn().delay(3000).fadeOut();
}
});
});
});
})(jQuery);
La bibliothèque jQuery nous permet de récupérer simplement les valeurs de champs hidden et textarea, ainsi que d’écouter l’événement « clic » pour lancer une requête AJAX.
Votre devis en 48 H chrono !
Demandez à être rappelé !
Nous préciserons ensemble votre projet
de vive voix
Une fois notre requête AJAX émise, notre dernière tâche consistera à écouter la requête AJAX sur WordPress afin de procéder à l’envoi e-mail depuis notre serveur.
N.B. Nous modifions ici le contenu du champ texte à renvoyer au serveur afin d’y préserver les sauts de ligne. La réponse incluant le message envoyé, nous le modifions à nouveau à l’aide d’une expression régulière avant de renvoyer le message sur l’interface utilisateur.
Interception de la requête AJAX avec WordPress
Sur WordPress, l’interception des requêtes AJAX s’effectue à l’aide des hooks wp_ajax_{$action} et wp_ajax_nopriv_{$action} pour lesquelles {$action} correspond à la valeur de la varialble « action » passée au sein de $_POST.
Notre fonction va donc se décompose en 2 temps :
Nous commençons par sécuriser notre module en vérifiant que le nonce récupéré correspond bien à celui passé avec notre formulaire.
Nous testons ensuite l’existence du numéro de commande permettant d’envoyer un e-mail au client comprenant un lien vers la page de commande Woocommerce du client. Notre fonction renvoie à notre script un message qui sera affiché en retour en page de commande :
function ajax_client_file_upload_email() {
if( ! wp_verify_nonce( $_POST[ 'nce'], 'pdcnfileuploadneeded' ) )
{
wp_die( json_encode( array( 'notice'=>__('Authorisation invalide', 'jst') ) ) );
}
if( isset( $_POST[ 'order_id' ] ) )
{
$order_id = intval( $_POST[ 'order_id' ] );
$order = wc_get_order( $order_id );
$emailContent = filter_input( INPUT_POST, 'emailContent', FILTER_SANITIZE_STRING );
$msg = $this->send_client_file_upload_email( $order, $order_id, $emailContent ) ? __( 'L\'e-mail de relance a bien été envoyé au client :<br />'.$emailContent, 'jst' ) : 'L\’Email de relance n\'a pu être envoyé au client';
wp_die( json_encode( [ $msg ] ) );
}else{
wp_die( json_encode( [ 'N° de commande absent ou invalide, l\'email n\'a pu être envoyé au client' ] ) );
}
exit;
}
Nous décomposons ici la fonction d’interception de la requête AJAX et la fonction d’envoi de l’e-mail proprement dite.
N.B. Notez au passage l’utilisation de la fonction PHP filter_input avec le flag FILTER_SANITIZE_STRING qui nous permet de conserver les sauts de lignes éventuels dans le contenu envoyé via le champ textarea.
Afin d’utiliser le système et le modèle d’e-mail de la boutique en ligne, nous récupérons le mailer interne de Woocommerce avec WC()->mailer() :
function send_client_file_upload_email( $order, $order_id, $emailContent ){
$from = 'Concepteur-Developpeur-Web.Fr'; // Nom émetteur
$from_email = 'contact@concepteur-developpeur-web.fr'; // Reply-to email
$to = $order->get_billing_email();
$mailer = WC()->mailer(); //Load WC Mailer
$headers = "Content-Type: text/html\r\n";
$headers .= "Reply-to: $from < $from_email > \r\n";
$subject = sprintf( 'Commande N° %1$d en attente des téléchargements de vos fichiers', $order_id );
$message = sprintf( '<h1>Commande N° %1$d en attente de vos téléchargements de fichiers.</h1>', $order_id ); // Définition du titre de l’e-mail, vous pourriez proposer un champ spécifique dans la metabox
$order_url = sprintf(
home_url( '%1$s%2$d/' ),
'/mon-compte/view-order/',
$order_id
);
$message .= empty( $emailContent ) ? sprintf( '<p>Bonjours,<br />Nous sommes toujours en attente de vos documents pour pouvoir taiter votre commande.</p><p>Merci d\'utilisser <a href="%1$s">le formulaire de téléchargement de votre commande</a> pour nous faire parvenir les fichiers requis dans les plus brefs délais.</p><p>Permis-Conduire.net</p>', $order_url ) : $emailContent;
$message = '<html><head></head><body>'. $message .'</body></html>';
$message = $mailer->wrap_message( __( 'Documents en attente' ), $message );
$email_is_sent = $mailer->send( $to, $subject, $message, $headers );
return $email_is_sent;
}
add_action( 'wp_ajax_client_file_upload_email', [ $this, 'ajax_client_file_upload_email' ] );
N.B. Notez l’intégration conditionnelle du contenu de l’e-mail envoyé, en fonction – ou non – de la présence d’un message utilisateur.
L’utilisation de WC()->mailer() nous permet de bénéficier du modèle Woocommerce et de faciliter ainsi son intégration sur la plateforme e-commerce.
Préférez la création d’un plugin WordPress pour l’intégration de fonctionnalités additionnelles Woocommerce
Un dernier conseil si vous souhaitez intégrer vous-mêmes ce type de module sur votre site WordPress :
S’il est tout à fait possible d’utiliser le fichier functions.php de votre thème WordPress pour intégrer ce type de fonctionnalité, cela la rendra dépendante de votre thème courant. Je vous conseille donc vivement de créer un plugin à cet effet, et d’utiliser des méthodes de classes pour vos différentes fonctions.