EDD_Fees Class

The  EDD_Fees class can be used to add arbitrary fees to the shopping cart, both positive and negative (discount) fees. For example, you could add a special 10% off fee automatically for all registered users that have a certain user role, or add a "handling" fee for all products inside of a certain category. The options are limitless.

This class is only available in EDD v1.5+

Fees are stored as session variables, which means once they're set for a user they'll persist until either the user checks out or they're removed by some code based on a decision or setting.

Types of fees

Fees can have two types:

fee
This is just what it sounds like, an additional cost or discount added to the subtotal of purchases.
item
This is a fee that is not associated with anything else, think of it like a temporary product made up on the spot. Currently used for Wallet deposits for example.

Note: negative fees always set no_tax to true.

add_fee()

Adding an expense or giving a discount are both considered adding fees, despite the fact that one of them is removing money.

Adding a fee is done with code similar to this:

function pw_set_admin_discount() {
    // check to see the customer is a site admin
    if( current_user_can( 'manage_options' ) ) {
	// find 20% of the total
        $amount = edd_get_cart_subtotal() * 0.20;

	// flip the 20% from a positive number to a negative number
        $amount = $amount * -1;

	// Add the fee, sending the amount, the reason printed to the front end, and the handle
        EDD()->fees->add_fee( $amount, 'You are an admin special!', 'admin_special' );
    }
}
// run this code on site init
add_action( 'init', 'pw_set_admin_discount' );

This example automatically adds a 20% discount if the current user is an admin.

Here's another example that adds a handling fee:

function pw_add_handling_fee() {
	// Add a $10 handling fee no matter what
	EDD()->fees->add_fee( '10', 'Handling Fee', 'handling_fee' );
}
add_action( 'init', 'pw_add_handling_fee' );

The first parameter is the fee amount, the second parameter is the label (as shown on the checkout/purchase history screens), and the third parameter is the fee ID.

Here's a screenshot of both of the above examples being applied at the same time:

The above examples were for simply adding arbitrary fees, but add_fees() can also take the following arguments:

$args = array(
	'price_id'    => $price_id,
	'amount'      => $amount,
	'label'       => $label,
	'id'          => $id,
	'type'        => $type,
	'no_tax'      => false,
	'download_id' => 0
);

remove_fee()

To remove a fee, simply pass the fee ID (third parameter above) to the remove_fee() method:

function pw_remove_handling_fee() {
	EDD()->fees->remove_fee( 'handling_fee' );
}
add_action( 'init', 'pw_remove_handling_fee' );

Other Methods

In addition to simply adding and removing fees there are a number of methods for working with fees on the back end.

has_fees( string $type = 'fee'  )

This method simply checks to see if any fees exist.  Defaults to the fee type, but can accept item as well.

Example:

if ( EDD()->fees->has_fees() ) {
	echo 'yep, we can haz fees!';
}

Returns: true or false.

get_fees( string $type = 'fee', integer $download_id = 0  )

This method will get an array of all existing fees.  It can be limited by type and/or download id.

Example

The  Simple Shipping extension is a perfect example of how the EDD_Fees class can be used.

$fees = EDD()->fees->get_fees();

Returns something like this:

Array
(
    [handling_fee] => Array
        (
            [amount]      => 11.00
            [label]       => Handling Fee
            [type]        => fee
            [no_tax]      => 
            [download_id] => 0
            [price_id]    =>
        )

    [admin_special] => Array
        (
            [amount]      => -2
            [label]       => You are an admin special!
            [type]        => fee
            [no_tax]      => 
            [download_id] => 0
            [price_id]    =>
        )

    [tophers_fee] => Array
        (
            [amount]      => 42.00
            [label]       => Topher's fee
            [no_tax]      => 
            [type]        => fee
            [download_id] => 114
            [price_id]    =>
        )

)
get_fee( string $id = ''  )

This method will get an array of a specific fee, identified by the name it was given when it was created.  

Example: 

$my_custom_fee = EDD()->fees->get_fee( 'my_custom_fee' );

Returns something like this:

 Array
(
    [amount] => 42.00
    [label] => The Final Fee
    [no_tax] => 
    [type] => fee
    [download_id] => 114
)
type_total( string $type = 'fee'  )

This method calculate the total for a specific type of fee.  The types supported are 'fee' and 'item'.

Example: 

$item_total = EDD()->fees->type_total( 'item' );

Returns an number like 51.00

total( integer $download_id = 0  )

This method calculate the total for all fees OR all fees specifically attached to a given download.

Note: If a product has fees and variable prices, The fee will only be applied once per transaction, NOT once per item.

Example:

$total = EDD()->fees->total();

$total = EDD()->fees->total( '42' );

In the example above, the first would return a number like 51.00 that is the sum of all fees.

The second example would return a number like 51.00 that is the sum of all fees tied specifically to the Download with the ID of 42.

record_fees( array $payment_meta, array $payment_data )

This method records the fee information about a specific transaction.  It should never be called directly.