diff --git a/CHECKLIST-COMPLIANCE-MERCHANT.md b/CHECKLIST-COMPLIANCE-MERCHANT.md
new file mode 100644
index 0000000..125e0e9
--- /dev/null
+++ b/CHECKLIST-COMPLIANCE-MERCHANT.md
@@ -0,0 +1,43 @@
+# Recesso - Cosa fa l'app vs cosa deve fare il merchant
+
+Ripartizione delle responsabilita' di conformita' (Art. 54-bis + Codice del
+Consumo). L'app copre la FUNZIONE elettronica di recesso; alcuni obblighi restano
+in capo al merchant. Da consegnare col progetto.
+
+---
+
+## 1. Cosa GARANTISCE l'app (automatico, non disattivabile)
+
+- **Pulsante/funzione di recesso sempre accessibile** (footer o dove scelto), **guest**, senza login.
+- Raccolta della **dichiarazione inequivocabile** (nome, n. ordine, email, testo) con **conferma dedicata a 2 step** (nessun dark pattern).
+- Registrazione con **timestamp di TRASMISSIONE** (onere della prova, Art. 54-bis).
+- **Ricevuta su supporto durevole** al consumatore: dichiarazione + timestamp + avviso di legge - **sempre inviata, contenuto legale non modificabile** dal merchant.
+- **Audit log immutabile** delle richieste ed eventi.
+- Coesistenza col reso/rimborso **nativo Shopify** (crea il Reso per gli ordini evasi).
+
+## 2. Cosa il merchant CONFIGURA nell'app (Impostazioni, opzionale)
+
+- Testi email (oggetto/introduzione/nota) - le parti legali restano fisse.
+- Notifica al merchant (on/off + indirizzo email).
+- Tag "Recesso" sull'ordine (on/off).
+- Finestra 14 gg: enforcement on/off + giorni (default 14, calcolata sulla **consegna**).
+- Esclusioni Art. 59 (prodotti/tag non recedibili) + enforcement on/off.
+- **[R1 A6-bis]** Ricevuta differenziata per stato ordine; annullo automatico ordini non evasi; indirizzo reso + spese a carico cliente + istruzioni di reso.
+
+## 3. Cosa il merchant deve fare FUORI dall'app (obblighi propri)
+
+- **Informativa precontrattuale** sul diritto di recesso (Art. 49) nelle pagine/checkout.
+- Mettere a disposizione il **modulo tipo** di recesso (Allegato I, parte B) - coesiste col pulsante.
+- **Emettere il rimborso entro 14 gg** dalla notifica (Art. 56) se non usa l'annullo/rimborso automatico dell'app. Puo' trattenere fino a riconsegna merce o prova di spedizione.
+- Gestire **resi parziali** e rimborsi proporzionali (pannello ordini Shopify).
+- Definire la **politica di reso** (indirizzo, spese, integrita' prodotto) coerente con quanto mostra l'app.
+- **Verifica manuale della data di consegna** se il corriere non trasmette l'evento a Shopify (in tal caso la finestra automatica non blocca).
+- Privacy policy, condizioni di vendita, gestione dati (GDPR) del negozio.
+- Configurare le **esclusioni Art. 59** solo per prodotti realmente esclusi (mala-config = negare il diritto a torto).
+
+## 4. Note
+
+- L'app e' uno **strumento** di conformita', non sostituisce la consulenza legale.
+- Prima del go-live (e soprattutto per la versione pubblica/App Store) consigliata una **review legale**, anche per chiudere i punti ⚠ dottrinali in `ANALISI-REQUISITI-LEGALI.md`.
+- Ambito: **beni B2C online**. Servizi e beni digitali hanno decorrenza/esclusioni diverse (Art. 52/59) - da valutare per merchant fuori scope.
+- Approfondimento stati ordine: `AUDIT-STATI-ORDINE.md`.
diff --git a/app/app/lib/emailTemplate.ts b/app/app/lib/emailTemplate.ts
index 9e233a5..2fd13e4 100644
--- a/app/app/lib/emailTemplate.ts
+++ b/app/app/lib/emailTemplate.ts
@@ -61,11 +61,45 @@ export function renderSubject(subjectTpl: string | null | undefined, vars: Email
return substPlain(tpl, vars).trim() || substPlain(DEFAULT_SUBJECT, vars);
}
+export interface OperationalConfig {
+ state: "unfulfilled" | "shipped" | "delivered";
+ returnAddress?: string | null;
+ atCustomerExpense: boolean;
+ instructions?: string | null;
+}
+
+/** Blocco operativo per stato ordine (A6-bis): annullo (non evaso) o istruzioni reso. */
+function renderOperationalBlock(op: OperationalConfig): string {
+ let inner: string;
+ if (op.state === "unfulfilled") {
+ inner =
+ "Il tuo ordine non risultava ancora spedito: procederemo all'annullamento e al rimborso. Non devi restituire nulla.";
+ } else {
+ const stateWord = op.state === "delivered" ? "consegnato" : "spedito";
+ const addr =
+ op.returnAddress && op.returnAddress.trim()
+ ? `${escHtml(op.returnAddress.trim())}`
+ : "l'indirizzo che ti comunicheremo";
+ const spese = op.atCustomerExpense
+ ? "Le spese di restituzione sono a tuo carico."
+ : "Le spese di restituzione sono a nostro carico.";
+ const instr =
+ op.instructions && op.instructions.trim()
+ ? ` ${nl2br(escHtml(op.instructions.trim()))}`
+ : "";
+ inner = `Il prodotto risulta ${stateWord}. Per ottenere il rimborso, restituisci la merce integra a: ${addr}. ${spese}${instr} Il rimborso sara' disposto dopo il rientro della merce.`;
+ }
+ return `
Questa comunicazione costituisce la ricevuta su supporto durevole ai sensi dell'art. 54-bis del Codice del Consumo. La data e l'ora indicate attestano il momento della trasmissione.