WooCommerce – ein PDF als Anhang in den Bestell-Emails mitsenden

Wie kann man dem Kunden ein PDF oder mehrere PDF-Dateien wie z.B. AGB oder Widerrufsbelehrung als Anhang in der WooCommerce Bestell-Email mitsenden? Das geht auch ohne Plugin mit einer Funktion in der functions.php des Themes.

Die PDF-Dateien wie AGB und Widerruf kann man dazu direkt im Theme-Ordner ablegen, in meinem Beispiel z.B. unter [wp-content/themes/deintheme/woocommerce/…]. Je nachdem, ob man ein Main-Theme oder ein Child-Theme benutzt, unterscheidet sich der Aufruf des URL-Pfads:

  • Main-Theme: get_template_directory()
  • Childtheme:   get_stylesheet_directory()

Im Beispiel hier unten wird ein Child-Theme benutzt, hier liegen die Dateien “AGB.pdf” und “Widerrufsformular.pdf” also im Ordner [/wp-content/themes/child-theme/woocommerce/…].

Die Zeilen mit // vorne dran sind Kommentare bzw. auskommentierte Funktionen. Diese können bei Bedarf als alternative Funktion genutzt werden. Ein Check verhindert kaputte Anhänge und loggt fehlende Dateien in die WooCommerce-Logs (WooCommerce → Status → Protokolle).

1. Der Code für die Ablage der PDFs im Child-Theme-Ordner

/**
 * WooCommerce: Rechtliche PDF-Dokumente (AGB, Widerrufsbelehrung)
 * als Anhang an Bestell-E-Mails mitsenden.
 *
 * Die PDF-Dateien liegen fest im Child-Theme-Ordner unter /woocommerce/,
 * z.B. wp-content/themes/child-theme/woocommerce/AGB.pdf
 *
 * Kein Plugin nötig – nutzt den WooCommerce-Standard-Filter
 * woocommerce_email_attachments.
 */

/**
 * Liefert den Pfad zum Theme-Unterordner, in dem die PDFs liegen.
 *
 * get_stylesheet_directory() zeigt immer auf das AKTIVE Theme
 * (bei einem Child-Theme also dessen Ordner, nicht das Parent-Theme).
 * Falls du kein Child-Theme nutzt, hier stattdessen
 * get_template_directory() verwenden.
 *
 * @return string Absoluter Serverpfad, z.B. .../child-theme/woocommerce
 */
function rd_legal_pdf_directory() {
	return get_stylesheet_directory() . '/woocommerce';
}

/**
 * Definiert, welche PDF-Dateien an welche WooCommerce-E-Mails
 * angehängt werden sollen.
 *
 * Struktur: E-Mail-ID => Liste der Dateinamen (relativ zu rd_legal_pdf_directory()).
 * Eine Übersicht gängiger E-Mail-IDs findest du in den Kommentaren unten.
 *
 * @return array
 */
function rd_legal_pdf_attachment_map() {
	return array(
		'customer_processing_order' => array(
			'AGB.pdf',
			'Widerrufsformular.pdf',
		),

		// Weitere Beispiele, bei Bedarf einkommentieren und anpassen:
		// 'customer_completed_order' => array( 'AGB.pdf' ),
		// 'new_order'                => array( 'AGB.pdf', 'Widerrufsformular.pdf' ),

		// Alle verfügbaren Standard-E-Mail-IDs von WooCommerce:
		// new_order, cancelled_order, failed_order, order_on_hold,
		// customer_processing_order, customer_on_hold_order,
		// customer_completed_order, customer_refunded_order,
		// customer_invoice, customer_note, customer_reset_password,
		// customer_new_account
	);
}

/**
 * Hängt die konfigurierten PDF-Dateien an die passende(n)
 * WooCommerce-E-Mail(s) an.
 *
 * @param array         $attachments Bisherige Anhänge (Dateipfade).
 * @param string        $email_id    ID der aktuell versendeten E-Mail.
 * @param WC_Order|null $order       Bestellobjekt (kann bei Nicht-Order-Mails null sein).
 * @return array
 */
add_filter( 'woocommerce_email_attachments', 'rd_attach_legal_pdfs_to_email', 10, 3 );
function rd_attach_legal_pdfs_to_email( $attachments, $email_id, $order ) {

	$attachment_map = rd_legal_pdf_attachment_map();

	// Für diese E-Mail-ID ist nichts konfiguriert -> nichts tun.
	if ( empty( $attachment_map[ $email_id ] ) ) {
		return $attachments;
	}

	$pdf_directory = rd_legal_pdf_directory();

	foreach ( $attachment_map[ $email_id ] as $filename ) {

		$file_path = trailingslashit( $pdf_directory ) . $filename;

		if ( file_exists( $file_path ) ) {
			$attachments[] = $file_path;
		} else {
			// Fehlende Datei loggen, damit man es merkt, statt dass
			// die PDF einfach stillschweigend fehlt.
			if ( function_exists( 'wc_get_logger' ) ) {
				wc_get_logger()->warning(
					sprintf( 'PDF-Anhang nicht gefunden: %s', $file_path ),
					array( 'source' => 'rd-legal-pdf-attachments' )
				);
			}
		}
	}

	return $attachments;
}

2. Alternativ Code für Ablage der PDFs direkt in der Mediathek

Man kann die PDFs anstatt im Theme-Ordner auch direkt per Datei-Manager oder FTP/SFTP in den Uploads-Ordner (wp-content/uploads/) legen. Welche Methode man bevorzugt, bleibt einem selbst überlassen. Der Code sieht dann so aus:

/**
 * WooCommerce: Rechtliche PDF-Dokumente (AGB, Widerrufsbelehrung)
 * als Anhang an Bestell-E-Mails mitsenden.
 *
 * Die PDF-Dateien liegen direkt im Uploads-Root, z.B.
 * wp-content/uploads/AGB.pdf
 *
 * Kein Plugin nötig – nutzt den WooCommerce-Standard-Filter
 * woocommerce_email_attachments.
 */

/**
 * Liefert den Serverpfad zum WordPress-Uploads-Verzeichnis
 * (Basisordner der Mediathek, i.d.R. wp-content/uploads).
 *
 * @return string Absoluter Serverpfad.
 */
function rd_legal_pdf_directory() {
	$upload_dir = wp_upload_dir();
	return $upload_dir['basedir'];
}

/**
 * Definiert, welche PDF-Dateien an welche WooCommerce-E-Mails
 * angehängt werden sollen.
 *
 * Struktur: E-Mail-ID => Liste der Dateinamen (relativ zu rd_legal_pdf_directory()).
 *
 * @return array
 */
function rd_legal_pdf_attachment_map() {
	return array(
		'customer_processing_order' => array(
			'AGB.pdf',
			'Widerrufsbelehrung.pdf',
		),

		// Weitere Beispiele, bei Bedarf einkommentieren und anpassen:
		// 'customer_completed_order' => array( 'AGB.pdf' ),
		// 'new_order'                => array( 'AGB.pdf', 'Widerrufsbelehrung.pdf' ),

		// Alle verfügbaren Standard-E-Mail-IDs von WooCommerce:
		// new_order, cancelled_order, failed_order, order_on_hold,
		// customer_processing_order, customer_on_hold_order,
		// customer_completed_order, customer_refunded_order,
		// customer_invoice, customer_note, customer_reset_password,
		// customer_new_account
	);
}

/**
 * Hängt die konfigurierten PDF-Dateien an die passende(n)
 * WooCommerce-E-Mail(s) an.
 *
 * @param array         $attachments Bisherige Anhänge (Dateipfade).
 * @param string        $email_id    ID der aktuell versendeten E-Mail.
 * @param WC_Order|null $order       Bestellobjekt (kann bei Nicht-Order-Mails null sein).
 * @return array
 */
add_filter( 'woocommerce_email_attachments', 'rd_attach_legal_pdfs_to_email', 10, 3 );
function rd_attach_legal_pdfs_to_email( $attachments, $email_id, $order ) {

	$attachment_map = rd_legal_pdf_attachment_map();

	// Für diese E-Mail-ID ist nichts konfiguriert -> nichts tun.
	if ( empty( $attachment_map[ $email_id ] ) ) {
		return $attachments;
	}

	$pdf_directory = rd_legal_pdf_directory();

	foreach ( $attachment_map[ $email_id ] as $filename ) {

		$file_path = trailingslashit( $pdf_directory ) . $filename;

		if ( file_exists( $file_path ) ) {
			$attachments[] = $file_path;
		} else {
			// Fehlende Datei loggen, damit man es merkt, statt dass
			// die PDF einfach stillschweigend fehlt.
			if ( function_exists( 'wc_get_logger' ) ) {
				wc_get_logger()->warning(
					sprintf( 'PDF-Anhang nicht gefunden: %s', $file_path ),
					array( 'source' => 'rd-legal-pdf-attachments' )
				);
			}
		}
	}

	return $attachments;
}

Hinweis: Lädt man die PDFs stattdessen über die normale WordPress-Mediathek hoch (Medien → Neu hinzufügen), landen sie je nach WordPress-Einstellung entweder automatisch im Uploads-Root oder in einem Jahr/Monat-Unterordner (z.B. /uploads/2024/07/AGB.pdf) statt. Der Dateipfad im Code muss dann ggf. entsprechend angepasst werden.

Statt: $file_path = trailingslashit( $pdf_directory ) . $filename; müsste man dann den Unterordner mit angeben z.B.: $file_path = trailingslashit( $pdf_directory ) . ‘2025/07/’ . $filename;

Wichtig: Beide Varianten (PDFs in Theme-Ordner und Mediathek) sollten nicht gleichzeitig in derselben functions.php aktiv sein, da beide dieselben Funktionsnamen verwenden – das würde einen Fatal Error auslösen. Im Zweifel eine der beiden Funktionen umbenennen, falls beide Methoden parallel benötigt werden.

Die WooCommerce email IDs

WooCommerce verschickt je – nach Bestellstatus – unterschiedliche E-Mails an den Administrator und Kunden. Diese werden über den Wert $email_ids im Code angesteuert. So kann man steuern, an welche WooCommerce E-Mails die PDF-Dateien angehängt werden sollen.

  • new_order
  • customer_on_hold_order
  • customer_processing_order
  • customer_refund_order
  • customer_refunded_order
  • customer_partially_refunded_order
  • cancelled_order
  • failed_order
  • customer_reset_password
  • customer_invoice
  • customer_new_account
  • customer_note

6 Kommentare zu „WooCommerce – ein PDF als Anhang in den Bestell-Emails mitsenden“

  1. Kann man da auch einstellen, dass es das nur bei bestimmten Emails versendet? Ich habe 2 Kurse bei denen es eine bestimmte PDF mit verschicken soll. Ist das über PHP möglich?

    Antworten
    • Das ist etwas sehr speziell, aber theoretisch möglich über die product ID der Kurse und einen weiteren “Conditional Logic” Filter im Code. Wenn Sie dazu einen Kostenvoranschlag haben möchten, können Sie mich gerne kontaktieren. Vielen Dank für Ihr Verständnis!

      Antworten

Schreibe einen Kommentar