new: send alert email when Paybox payment arrives on cancelled order

When a Paybox callback confirms payment on an order with status 4
(Annulé), the payment is still recorded but the order status is no
longer forced to « Préparation ». Instead, an alert email is sent to
``commande@jardinenvie.com`` warning that a refund is likely needed.

New ``AlertePaiementAnnule`` mailable with DB template providing order
ref, amount, customer info and payment reference. New method
``OrderMails::sendCancelledOrderPaymentAlert()`` handles the dispatch.
This commit is contained in:
Valentin Lab
2026-02-20 11:52:03 +01:00
parent 5c10645af7
commit 5325fa1f06
4 changed files with 178 additions and 6 deletions

View File

@@ -0,0 +1,86 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
DB::table('mail_templates')->insert([
'mailable' => 'App\\Mail\\AlertePaiementAnnule',
'subject' => json_encode(['fr' => '[URGENT] Paiement reçu sur commande annulée {{numero_commande}}'], JSON_UNESCAPED_UNICODE),
'html_template' => json_encode(['fr' => $this->getHtmlTemplate()], JSON_UNESCAPED_UNICODE),
'text_template' => json_encode(['fr' => $this->getTextTemplate()], JSON_UNESCAPED_UNICODE),
'created_at' => now(),
'updated_at' => now(),
]);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
DB::table('mail_templates')
->where('mailable', 'App\\Mail\\AlertePaiementAnnule')
->delete();
}
private function getHtmlTemplate(): string
{
return '<table style="min-width: 100%;" width="100%" cellspacing="0" cellpadding="0">'
.'<tbody><tr><td>'
.'<table style="border-collapse: collapse; background-color: #ffffff; margin: 0 auto; width: 600px;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody><tr>'
.'<td style="margin: 0px auto; padding: 32px 0px 24px 4px; vertical-align: top;" align="center">'
.'<a href="https://www.jardinenvie.com/" style="text-decoration: none; color: #000000;">'
.'<img alt="Jardin\'enVie" src="https://boutique.jardinenvie.com/img/logo.png" style="margin: 0px auto; display: block;" width="300" height="138" border="0" /></a></td>'
.'</tr></tbody></table>'
.'<table style="border-collapse: collapse; background-color: #ffffff; margin: 0 auto; width: 600px;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody><tr><td style="margin: 0 auto; padding: 0px; vertical-align: top;">'
.'<table style="border-collapse: collapse; margin: 0 auto; width: 512px;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody>'
.'<tr><td style="font-family: \'Nunito Sans\', Arial, sans-serif; line-height: 40px; color: #c0392b; font-size: 28px; padding: 20px 0px 10px 0px; font-weight: 800; text-align: center;">'
.'&#9888; Paiement sur commande annul&eacute;e</td></tr>'
.'<tr><td style="font-family: \'Nunito Sans\', Arial, sans-serif; line-height: 28px; color: #000000; font-size: 16px; text-align: center; padding: 10px 0 30px 0;">'
.'<p>Un paiement Paybox a &eacute;t&eacute; re&ccedil;u sur une commande <strong>annul&eacute;e</strong>.</p>'
.'<p style="font-size: 20px; font-weight: bold; color: #c0392b; padding: 10px 0;">Un remboursement est probablement n&eacute;cessaire.</p>'
.'<table style="margin: 15px auto; text-align: left; border-collapse: collapse;" cellpadding="8">'
.'<tr><td style="font-weight: bold; padding-right: 15px;">Commande :</td><td>{{numero_commande}}</td></tr>'
.'<tr><td style="font-weight: bold; padding-right: 15px;">Date :</td><td>{{date_commande}}</td></tr>'
.'<tr><td style="font-weight: bold; padding-right: 15px;">Montant :</td><td style="font-size: 18px; font-weight: bold; color: #c0392b;">{{montant}}</td></tr>'
.'<tr><td style="font-weight: bold; padding-right: 15px;">Client :</td><td>{{client_nom}}</td></tr>'
.'<tr><td style="font-weight: bold; padding-right: 15px;">Email :</td><td>{{client_email}}</td></tr>'
.'<tr><td style="font-weight: bold; padding-right: 15px;">R&eacute;f. paiement :</td><td>{{reference_paiement}}</td></tr>'
.'</table>'
.'<p style="padding-top: 15px; color: #666;">Veuillez proc&eacute;der au remboursement du client dans les plus brefs d&eacute;lais.</p>'
.'</td></tr>'
.'</tbody></table>'
.'</td></tr></tbody></table>'
.'<table style="border-collapse: collapse; background-color: #ffffff; margin: 0 auto; width: 600px; text-align: center;" cellspacing="0" cellpadding="0" border="0" align="center">'
.'<tbody><tr><td style="font-family: \'Nunito Sans\', Arial, sans-serif; font-size: 12px; font-weight: 600; line-height: 20px; padding: 16px; color: #999999;">'
.'Jardin\'enVie Artisan Semencier<br />429 route des chaux, 26500 Bourg les Valence - Dr&ocirc;me'
.'</td></tr></tbody></table>'
.'</td></tr></tbody></table>';
}
private function getTextTemplate(): string
{
return "⚠ PAIEMENT SUR COMMANDE ANNULÉE\n\n"
."Un paiement Paybox a été reçu sur une commande annulée.\n"
."Un remboursement est probablement nécessaire.\n\n"
."Commande : {{numero_commande}}\n"
."Date : {{date_commande}}\n"
."Montant : {{montant}}\n"
."Client : {{client_nom}}\n"
."Email : {{client_email}}\n"
."Réf. paiement : {{reference_paiement}}\n\n"
."Veuillez procéder au remboursement du client dans les plus brefs délais.\n\n"
."Jardin'enVie Artisan Semencier\n"
.'429 route des chaux, 26500 Bourg les Valence - Drôme';
}
};