WooCommerce Shopping Cart Donation

This article will show you how to Add a Donation input field to WooCommerce cart page, Allowing customers to round their shopping cart to the nearest £ with a donation.

Create an invisible Product for donations

This approach to adding a donation to your WooCommerce basket is possible by creating a product which is not listed in the catalogue, and has a zero-rate tax class.

If you do not know how to add a unlisted product:

  1. Goto Products > Add Product
  2. Set the title “Donation
  3. On the right hand side above the “Publish” button labelled “catalogue visibility“, choose Hidden
  4. In the Product data section set the Product SKU to something unique e.g. ‘checkout-donation‘, under shipping set the shipping class to ‘no shipping‘, if you have taxes enabled under taxes
  5. select ‘none’ and just in case set the tax class to zero-rate.
  6. Finally under the product data section, in the inventory tab, make sure sold individually is checked, as this will mean that only one donation is allowed in the shopping basket at once.

Donation Setup, creating helper functions

Once finished creating the donation product, grab the product id and set it to the global variable DONATE_ID. while we are setting up the project lets add a helper function which we will use to check if a donation has already been added. This function loops through all the items within the shopping basket and check if a product exists with our donation id, if so it returns true.

define('DONATE_ID', 0); // set to the id of your previously created donation product
 
function jc_donation_exsits(){
 
	global $woocommerce;
 
	if( sizeof($woocommerce->cart->get_cart()) > 0){
 
		foreach($woocommerce->cart->get_cart() as $cart_item_key => $values){
 
			$_product = $values['data'];
 
			if($_product->id == DONATE_ID)
				return true;
		}
	}
	return false;
}

Round donation amount to the nearest £x

If you wish to grab the order total and default the donation at a rounded up value, add this function.

function jc_round_donation($total, $value = 10){
 
     $donation = (ceil($total / $value) * $value) - $total;
     return $donation;
}

Add Donation Form

Lets go ahead and add a form to the shopping cart page, we can do this by hooking into “woocommer_cart_contents” and output our donation form if no donation has been previously added.

add_action('woocommerce_cart_contents','jc_woocommerce_after_cart_table');
function jc_woocommerce_after_cart_table(){
 
	global $woocommerce;
	$donate = isset($woocommerce->session->jc_donation) ? floatval($woocommerce->session->jc_donation) : 0;
 
	if(!jc_donation_exsits()){
		unset($woocommerce->session->jc_donation);
	}
 
    // uncomment the next line of code if you wish to round up the order total with the donation e.g. £53 = £7 donation
    // $donate = jc_round_donation($woocommerce->cart->total );
 
	if(!jc_donation_exsits()){
		?>
		<tr class="donation-block">
			<td colspan="6">
				<div class="donation">
					<p class="message"><strong>Add a donation to your order:</strong></p>
					<form action=""method="post">
						<div class="input text">
							<label>Donation (&pound;):</label>
							<input type="text" name="jc-donation" value="<?php echo $donate;?>"/>
						</div>
						<div class="submit">
							<input type="submit" name="donate-btn" value="Add Donation"/>
						</div>
					</form>
				</div>
			</td>
		</tr>
		<?php
	}
}

Processing the donation form

Now we have a form output on the shopping cart, lets process the data. This is possible by hooking into ‘init’ action and checking to see if the ‘jc-donation’ post variable has been sent, if so add a donation to the basket, and set the session value to your donation amount.

Now when you submit the donation form a donation should appear in the list of items in your cart, and the form should hide, if you remove the donation from the basket the form will reappear. But you should notice that the donation in the basket will display the price that was previously set when the product was created.

// capture form data and add basket item
add_action('init','jc_process_donation');
function jc_process_donation(){
 
	global$woocommerce;
 
	$donation = isset($_POST['jc-donation']) && !empty($_POST['jc-donation']) ? floatval($_POST['jc-donation']) : false;
 
	if($donation && isset($_POST['donate-btn'])){
 
		// add item to basket
		$found = false;
 
		// add to session
		if($donation >= 0){
			$woocommerce->session->jc_donation = $donation;
 
			//check if product already in cart
			if( sizeof($woocommerce->cart->get_cart()) > 0){
 
				foreach($woocommerce->cart->get_cart() as $cart_item_key=>$values){
 
					$_product = $values['data'];
 
					if($_product->id == DONATE_ID)
						$found = true;
				}
 
				// if product not found, add it
				if(!$found)
					$woocommerce->cart->add_to_cart(DONATE_ID);
			}else{
				// if no products in cart, add it
				$woocommerce->cart->add_to_cart(DONATE_ID);
			}
		}
	}
}

Getting the donation price

To hook into WooCommerce product prices we use the following action ‘woocommerce_get_price’. If the item matches the donation let’s grab the donation which is stored in the users session.

add_filter('woocommerce_get_price', 'jc_get_price',10,2);
function jc_get_price($price, $product){
 
	global $woocommerce;
 
	if($product->id == DONATE_ID){
		return isset($woocommerce->session->jc_donation) ? floatval($woocommerce->session->jc_donation) : 0;
 
	}
	return $price;
}

Now the cart total and items should display the correct totals.

Leave a Reply

Fields marked with an * are required to post a comment