WooCommerce: Split Revenue On Specific Products

Well, this is one of those “steal my setup” tutorials – because I’m going to share the system I use to generate commission/split revenue records when specific products (which are the result of business partnerships) are purchased on the Business Bloomer WooCommerce website.

Let me explain. Imagine an online course that comes with an owner (Mary) and a teacher (John). Mary and John have a 50/50 split revenue agreement: whenever the online course is purchased, Mary must notify John of such a purchase, and log a 50% commission/referral in the system. John will then have access to the dashboard where there are stats, total amount due, and can then request a payment/withdrawal at the end of the month.

Another example, which is the one that also applies to my WooCommerce Mini-Plugins business. In this case, there is Business Bloomer (Rodolfo, the owner), and a plugin developer (XYZ, the coder). If our agreement is to split revenue equally, Rodolfo must log the earnings that XYZ generated for each WooCommerce sale, so that XYZ can manually request a payment based on the due amount.

So, to recap, when a WooCommerce product is purchased, how do we generate a record of the “partner” earnings somewhere, so that they can access and check their total?

1) Install AffiliateWP plugin

Note 1: you can also use custom code to create your simplified commission log system, or use a different affiliate plugin for WooCommerce, as long as you’re allowed to programmatically create a referral/commission for your partner/affiliate. AffiliateWP comes with the handy affiliate_wp()->referrals->add() function, and that’s all we need to log the purchase and calculate the split revenue.

Note 2: because we’re using an affiliate plugin in “private mode”, you don’t need to enable the affiliate sign up page, affiliate registration and whatever is publicly available. We will be using the affiliate program in the background.

2) Manually add your partner as an affiliate

Go to WordPress Dashboard > AffiliateWP > Affiliates > Add New and enter the username of your split revenue partner. The user must already exist in WordPress before adding them as an affiliate, so make sure you’ve previously registered them under Users.

You can leave referral type and referral rate to their default values as we will override these later inside the code.

3) Display AffiliateWP area @ WooCommerce My Account custom tab

When the affiliate logs in, you can use my snippet to add a custom tab to the WooCommerce My Account page, so that they can check their stats and earnings.

Inside the tab content function as per the above snippet (part #4), you can use the following PHP to show the AffiliateWP affiliate area conditionally:

if ( affwp_is_affiliate() ) {
	echo do_shortcode( '[affiliate_area]' );
}

4) PHP Snippet: programmatically generate an AffiliateWP referral when a product is purchased

This is the core of the customization. When a new order is placed, we loop through the order products, and if the “split revenue product” is in there, we automatically generate a referral for our affiliate:

Affiliate ID = 82 has just received a new referral! This is done automatically, thanks to the snippet below, when their product is purchased on Business Bloomer.

You will need:

  • the product ID (123 in the example below) – this is the product that, if purchased, will generate a commission
  • the split revenue rate (50% in the example below) – this is how much the partner is due on each sale
  • the affiliate ID (13 in the example below) – this is the affiliate that will receive the commission
/**
 * @snippet       Generate AffiliateWP Referral With a WooCommerce Order
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @compatible    WooCommerce 8
 * @community     https://businessbloomer.com/club/
 */

add_action( 'woocommerce_order_status_completed', 'bbloomer_add_pending_referral_to_product_affiliate', 9999 );

function bbloomer_add_pending_referral_to_product_affiliate( $order_id ) {
	$order = wc_get_order( $order_id );
	$items = $order->get_items();
	foreach ( $items as $item_id => $product ) {
		if ( $product['product_id'] == 123  ) { // PRODUCT ID
			$amount = $product['line_total'] / 2; // 50% REVENUE
			$affiliate_id = 13; // AFFILIATE ID
			$reference = $item_id;
			$existing = affwp_get_referral_by( 'reference', $reference, 'woocommerce' );
			if ( ! is_wp_error( $existing ) && ( 'paid' === $existing->status || 'unpaid' === $existing->status ) ) {
				return;
			}
			$referral_id = affiliate_wp()->referrals->add(
				array(
					'affiliate_id' => $affiliate_id,
					'reference' => $reference,
					'description' => $product['name'],
					'status' => 'pending',
					'amount' => $amount,
					'context' => 'woocommerce',
				)
			);
			affwp_set_referral_status( $referral_id, 'unpaid' );
		}
	}
}

On purchase, a referral will be generated and set to “UNPAID” status. Whenever you pay the partner, you can set it to “PAID”.

You can also automatically reject unpaid AffiliateWP commissions whenever there is a refund or the order is cancelled:

add_action( 'woocommerce_order_status_completed_to_refunded', 'bbloomer_revoke_referral', 9999 );
add_action( 'woocommerce_order_status_completed_to_cancelled', 'bbloomer_revoke_referral', 9999 );
add_action( 'wc-completed_to_trash', 'bbloomer_revoke_referral', 9999 );

function bbloomer_revoke_referral( $order_id ) {
	$order = wc_get_order( $order_id );
	$items = $order->get_items();
	foreach ( $items as $item_id => $product ) {
		if ( $product['product_id'] == 123 ) {
			$reference = $item_id;
			$referral = affwp_get_referral_by( 'reference', $reference, 'woocommerce' );
			if ( is_object( $referral ) && 'unpaid' === $referral->status ) {
				affwp_set_referral_status( $referral->referral_id, 'rejected' );
			}
		}
	}
}

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

4 thoughts on “WooCommerce: Split Revenue On Specific Products

  1. Hey Rodolfo,

    Thank you for sharing this! If we had enabled the Affiliate Product Rates extension for AffiliateWP active, and we set User A to be 50% for a handful of specific products could we comment out both the:

    if ( $product['product_id'] == 123  ) { // PRODUCT ID" and "$amount = $product['line_total'] / 2; // 50% REVENUE

    lines? Would it pull the correct rates for the products accordingly?

    1. Not sure, please test on staging!

  2. Hi Rodolfo,

    Thank you for your excellent article. What should we do if we have more than 600 products and want the split revenue to apply to all of them? Is there a way to use ‘ALL’ in the product ID field or a similar method instead of entering all 600 product IDs individually?

    1. Hey Chris! You just need to remove this line, and the relative closing curly bracket a few rows below:

      if ( $product['product_id'] == 123  ) { // PRODUCT ID

      In this way it will work for all products

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

Your email address will not be published. Required fields are marked *