Parfois nous avons besoin de forcer le statut des commandes à “Terminée” dès le paiement, voyons comment le faire.
Pour rappel, les statuts de WooCommerce sont les suivants :
Dans le cas particulier de produits virtuels téléchargeables, WooCommerce passe le statut des commandes de “Attente” à “Terminée” car les produits sont automatiquement disponibles par téléchargement.
Mais dans certains cas nous pouvons souhaiter que le statut “Terminée” soit forcé pour le produits non virtuels. Exemple concret, un client qui ne désire pas gérer les commandes dans WooCommerce mais qui veut que les clients puissent repasser une précédente commande. Il faut savoir que lorsqu’une commande passe au statut “Terminée”, WooCommerce propose un bouton pour recommander depuis l’historique.
Moyen de paiement immédiat ou différé ?
En fonction du moyen de paiement sélectionné par le client, le code va être différent.
Pour un paiement immédiat (carte bancaire, Paypal, Stripe, etc.) nous allons filtrer sur woocommerce_payment_complete_order_status.
add_filter( 'woocommerce_payment_complete_order_status', 'rfvc_update_order_status', 10, 2 );
function rfvc_update_order_status( $order_status, $order_id ) {
$order = new WC_Order( $order_id );
if ( 'processing' == $order_status && ( 'on-hold' == $order->status || 'pending' == $order->status || 'failed' == $order->status ) ) {
return 'completed';
}
return $order_status;
}
[/pastacode]
Si le statut passait à “En cours” en venant de “Attente”, “En attente” ou “Échouée”, on renvoi le statut “Terminée” (completed).
A noter que si vous avez de l’argent à perdre, vous pouvez acheter l’extension WooCommerce Order Status Control qui fait la même chose.
Pour les paiements différés (chèque, virement, à la livraison) le filtre précédant ne sera pas déclenché, alors on va placer une action sur woocommerce_thankyou, un crochet de la page de remerciement qui s’affiche en fin de processus de ces moyens de paiement.
add_action( 'woocommerce_thankyou', 'abw_woocommerce_auto_complete_order' );
function abw_woocommerce_auto_complete_order( $order_id ) {
if ( !$order_id ) return;
$order = new WC_Order( $order_id );
$order->update_status( 'completed' );
}
[/pastacode]
On se contente de forcer le statut de la commande, ici pour “Terminée” (completed), mais cela pourrait être pour “En cours” (processing), le statut initial étant “En attente” (on-hold).
Attention aux e-mails ! Dans le cas d’un paiement différé le client va recevoir un e-mail de nouvelle commande et un e-mail de commande terminée… Pour résoudre ce problème, il vous suffit de désactiver l’e-mail de votre choix dans l’onglet E-mails des paramètres de WooCommerce.
Bonjour et merci pour vos articles.
J’ai un soucis de facture pour un règlement différé. Je m’explique:
je crée une commande en “attente de paiement” et génère une facture, puisqu’il faut un numéro de facture pour un organisme qui règle 1 mois plus tard.
Le mois du règlement, 1 mois plus tard, je passe “en terminé”, mais le chiffre se fait sur le mois ou j’ai crée ma commande et non sur le mois ou j’ai passé en “terminé”…
Y a-t-il un moyen d’éviter cela ou peut-être que je fais mail quelque chose.
En vous remerciant
Bonjour
Merci pour cet article. Peut être pourriez vous m’aider pour mon problème. Je vends des produits virtuels, et dans certains cas, le statut reste comme “en cours”, je suis obligée de passer la commande manuellement en statut “terminée”. Ceci est très problématique, surtout si je ne suis pas disponible pour me rendre sur mon tableau de bord et changer le statut.
J’ai vérifié dans mes paramètres, j’ai bien activé le téléchargement dispo après le paiement.
Merci d’avance.
Bonjour Elodie,
Si vos produits sont virtuels ET téléchargeables je n’ai pas d’explication à votre problème, surtout si ce n’est que dans « certains cas ».
A voir s’il n’y a pas une extension qui contrôlerait le statut des commandes.
Nicolas Maillard.
Merci pour votre réponse. Il s’avère que le statut “en attente” de mes produits virtuels ne concerne que les commandes dont le paiement est effectué via paypal. savez vous si un réglage doit ou peut etre fait ? Merci d’avance
Bonjour,
pouvez-vous me confirmer qu’en cas d’erreur sur le paiement ce code ne va pas passer le statut en “Terminé” ?
De ce que je comprends, on teste que le paiement a bien été effectué, on modifie le statut que s’il était en ‘on-hold’, ‘pending’ ou ‘failed’.
Merci par avance de vos retours.
Bonjour Daniel,
Le statut est forcé à « Terminée » si il est sur le point de passer en « En cours » ET qu’il se trouve actuellement en « Attente », « Attente paiement » ou « Echouée ».
Donc s’il est sur le point de passer en « Echouée » il ne sera pas forcé en « Terminée ».
Nicolas.
C’est bien ce qu’il me semblait, merci pour votre réactivité.
Bonjour,
Le dernier post date ici de 2016 mais peut-être continue-t-il d’être suivi.
Sauriez-vous me dire si par rapport aux produits nécessitant un paiements par abonnement (fonctionnalité que j’ai vu avec le module Mercanet de BNP Paribas) il faut laisser le produit acheté à “En cours” pour que les prélèvements suivants puissent se faire aux prochaines échéances ou si la commande peut être marquée comme “Terminée”?
Merci de votre retour :-)
Bonjour Jean-christophe,
La passerelle de Mercanet pour WooCommerce gère les abonnements ?
Normalement la commande doit être dupliquée à chaque échéance car il s’agit d’une nouvelle commande donnant lieu à une éventuelle facturation, le statut devrait être à Terminée si cela fonctionne bien avec une duplication de commande.
Nicolas.
Oui, elle gère les abonnements.
Je vais faire des tests pour voir tout cela ;-)
Merci
Bonjour
Pour info le “add_filter( ‘woocommerce_payment_complete_order_status’, ‘rfvc_update_order_status’, 10, 2 );” génère des avertissements dans notre error_log:
“status was called incorrectly. Order properties should not be accessed directly.”
Alors je me demande, et comme indiqué par WooCommerce ici : https://docs.woocommerce.com/document/automatically-complete-orders/, si seulement la “add_action( ‘woocommerce_thankyou’, ‘custom_woocommerce_auto_complete_order’ );” ne suffit pas ?
D’ailleurs est-ce que ce qui est indiqué par WooCommerce est strictement la même chose que le truc payant : https://woocommerce.com/products/woocommerce-order-status-control/ … ?
Merci
Bonjour Pascal,
Sauf erreur de ma part, si l’on se base sur woocommerce_thankyou cela impose pour un paiement de type carte bancaire que le visiteur revienne sur le site, non ?
Nicolas.
Hello Nicolas
Et bien écoute, depuis que j’ai vu des erreurs en utilisant le « add_filter( ‘woocommerce_payment_complete_order_status’, ‘rfvc_update_order_status’, 10, 2 ); » et donc que je n’utilise que ce WooCommerce donne ici : https://docs.woocommerce.com/document/automatically-complete-orders/ je n’ai aucun soucis avec les paiements de type CB… ils passent bien en statut Terminé…
Même avant de revenir sur le site après paiement ?
Bonjour,
Je viens vers vous car votre tuto est très intéressant. Cependant je cherche une fonctionnalité supplémentaires. Est-il possible de changer le statut de la commande si une certaines catégories de produits ou un certains produits est présent dans le panier de cette commande ?
J’espère avoir été clair.
Dans l’attente de votre réponse,
Cordialement
Bonjour,
Depuis l’objet $order il faut récupérer le contenu de la commande et parcourir les produits, vérifier les critères et appliquer ou non le changement de statut.
Nicolas.
Bonjour,
Merci pour votre retour rapide. Pouvez vous me guider pour récupérer le contenu de la commande, parcourir les produits et vérifier les critères ?
Merci d’avance
Cordialement
Vous guider c’est ce que je viens de faire, après c’est écrire le code :-)
Bonjour
est-il possible de mettre une condition sur un changement de statut ?
ex: je passe manuellement un statut en “pending” et lorsque le client paye je voudrais que son statut passe en “processing”. Sauf qu’à l’heure actuelle il revient en “on-hold”.
Si j’utilise votre code en changeant “complete” par “processing” ça fonctionne mais pour toutes les commandes et pas seulement celle en “pending”
add_action( ‘woocommerce_thankyou’, ‘abw_woocommerce_auto_complete_order’ );
function abw_woocommerce_auto_complete_order( $order_id ) {
if ( !$order_id ) return;
$order = new WC_Order( $order_id );
$order->update_status( ‘processing’ );
}
Si vous avez une idée ?
Merci beaucoup
Laurent
Bonjour,
Y a-t-il un endroit précis dans Function.php où on doit insérer le code?
Je viens de faire le test avec un payement PaiPal et la commande est restée sur “en cours”, il a fallu que je la valide manuellement par la terminer.
Merci pour votre aide.
Cordialement,
Pascal
Bonjour P