Home / eCommerce / AffiliateWP – Affiliate Referrals CSV Export
Duplicate Snippet

Embed Snippet on Your Site

AffiliateWP – Affiliate Referrals CSV Export

Adds a "Download Referrals CSV" button to the Affiliate Area referrals tab. When WooCommerce is active, the exported file includes full order details -- customer name, email, items ordered, and order total alongside commission data.

Code Preview
php
<?php
/**
 * Plugin Name: AffiliateWP - Affiliate Referrals CSV Export
 * Description: Adds a "Download Referrals CSV" button to the Affiliate Area referrals tab.
 *              When WooCommerce is active, the export includes full order details
 *              (customer name, email, items ordered, order total) alongside commission data.
 * Version:     1.0.0
 *
 * PRIVACY NOTE: This export gives affiliates access to customer names, email addresses,
 * and order contents. That is intentional for fulfillment workflows where affiliates
 * handle distribution. If your affiliates should NOT see customer PII, remove the
 * customer name and email columns from the WooCommerce branch below.
 *
 * INSTALLATION: Paste this file into wp-content/mu-plugins/ as a standalone file,
 * or copy the two functions (without the plugin header) into your theme's functions.php.
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
/**
 * Adds the "Download Referrals CSV" button above the referrals table
 * in the classic Affiliate Area.
 *
 * Hook: affwp_referrals_dashboard_before_table (passes $affiliate_id)
 */
add_action( 'affwp_referrals_dashboard_before_table', 'affwp_custom_referrals_export_button' );
function affwp_custom_referrals_export_button( $affiliate_id ) {
	$export_url = wp_nonce_url(
		add_query_arg( 'affwp_export_referrals', '1' ),
		'affwp_export_referrals_' . absint( $affiliate_id ),
		'_affwp_export_nonce'
	);
	?>
	<p style="margin-bottom: 12px;">
		<a href="<?php echo esc_url( $export_url ); ?>" class="affwp-button">
			<?php esc_html_e( 'Download Referrals CSV', 'affiliate-wp' ); ?>
		</a>
	</p>
	<?php
}
/**
 * Handles the CSV export request.
 *
 * Security: verifies the affiliate is logged in, validates the nonce,
 * and only returns referrals belonging to the currently logged-in affiliate.
 * Affiliates cannot export another affiliate's data.
 */
add_action( 'init', 'affwp_custom_handle_referrals_export' );
function affwp_custom_handle_referrals_export() {
	if ( ! isset( $_GET['affwp_export_referrals'] ) ) {
		return;
	}
	// Must be an active affiliate.
	if ( ! affwp_is_affiliate() ) {
		wp_die( esc_html__( 'You must be an active affiliate to export referrals.', 'affiliate-wp' ) );
	}
	$affiliate_id = affwp_get_affiliate_id();
	// Validate nonce — ties the download link to this specific affiliate.
	$nonce = isset( $_GET['_affwp_export_nonce'] )
		? sanitize_text_field( wp_unslash( $_GET['_affwp_export_nonce'] ) )
		: '';
	if ( ! wp_verify_nonce( $nonce, 'affwp_export_referrals_' . $affiliate_id ) ) {
		wp_die( esc_html__( 'Security check failed. Please return to your affiliate area and try again.', 'affiliate-wp' ) );
	}
	// Fetch all referrals for this affiliate, newest first.
	// NOTE: -1 fetches all records. If you have affiliates with thousands of referrals,
	// consider adding a date range filter here to keep exports manageable.
	$referrals = affiliate_wp()->referrals->get_referrals(
		[
			'affiliate_id' => $affiliate_id,
			'number'       => -1,
			'status'       => [ 'paid', 'unpaid', 'rejected' ],
			'orderby'      => 'date',
			'order'        => 'DESC',
		]
	);
	// Send download headers — prevents browser caching of the file.
	nocache_headers();
	header( 'Content-Type: text/csv; charset=utf-8' );
	header( 'Content-Disposition: attachment; filename="referrals-' . gmdate( 'Y-m-d' ) . '.csv"' );
	$output = fopen( 'php://output', 'w' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen
	$is_woocommerce = class_exists( 'WooCommerce' );
	// Write the column header row.
	if ( $is_woocommerce ) {
		fputcsv(
			$output,
			[ 'Date', 'Order ID', 'Customer Name', 'Customer Email', 'Items Ordered', 'Order Total', 'Commission Earned', 'Status' ]
		);
	} else {
		fputcsv(
			$output,
			[ 'Date', 'Reference', 'Description', 'Amount', 'Status' ]
		);
	}
	foreach ( $referrals as $referral ) {
		// WooCommerce branch: pull full order details from the order record.
		if ( $is_woocommerce && ! empty( $referral->reference ) ) {
			$order = wc_get_order( absint( $referral->reference ) );
			if ( $order instanceof WC_Abstract_Order ) {
				// Build a readable item list, e.g. "Blue Hydrangea x2 | Lavender x1".
				$items = [];
				foreach ( $order->get_items() as $item ) {
					$items[] = $item->get_name() . ' x' . $item->get_quantity();
				}
				fputcsv(
					$output,
					[
						$referral->date_i18n( 'datetime' ),
						$referral->reference,
						$order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
						$order->get_billing_email(),
						implode( ' | ', $items ),
						$order->get_total(),
						$referral->amount,
						affwp_get_referral_status_label( $referral ),
					]
				);
				continue;
			}
		}
		// Fallback row — used for non-WooCommerce referrals or if the order is not found.
		fputcsv(
			$output,
			[
				$referral->date_i18n( 'datetime' ),
				$referral->reference,
				$referral->description,
				$referral->amount,
				affwp_get_referral_status_label( $referral ),
			]
		);
	}
	fclose( $output ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
	exit;
}

Comments

Add a Comment