Adding an Easy Digital Downloads custom payment status

The core Easy Digital Downloads plugin includes pretty much any payment or order status you’d need to sell a downloadable product:

  • Pending
  • Complete
  • Refunded
  • Failed
  • Abandoned
  • Revoked

Easy Digital Downloads custom payment status: core statuses
Core statuses

Orders will be created as ‘pending’ if they’re awaiting payment, and be set to completed once they’re paid since products are delivered automatically. Because your shop doesn’t need to worry about shipping, etc., there aren’t typically other fulfillment or payment statuses needed for order management.

While these should meet the needs of most shops, you may want to add your own status to this list. For example, what if you’re using EDD to sell services? You may need a status to designate that an invoice has been paid, or that a project is in progress.

This tutorial will walk through how to add an Easy Digital Downloads custom payment status for use in your store. We’ll also include some advanced tips to completely integrate your new status(es) into your workflow.

Add an Easy Digital Downloads custom payment status

Adding a new payment status to your store takes only a few lines of code since there’s an edd_payment_statuses filter to make this very simple for us.

I’m going to use two new statuses throughout this tutorial (“Invoice Paid” and “Project in progress”) for my hypothetical services website.

To add these statuses, we’ll use this snippet to include them in the array of available payment statuses. You can add as many payment statuses as needed — you’ll only need a new id / slug and name for each. Note the id you create, as you’ll have to use this to reference your order status elsewhere (if you follow other parts of this tutorial).

function sww_add_edd_payment_statuses( $payment_statuses ) {
    $payment_statuses['invoice_paid']   = 'Invoice Paid';
    $payment_statuses['in_progress']    = 'Project in progress';

    return $payment_statuses;   
add_filter( 'edd_payment_statuses', 'sww_add_edd_payment_statuses' );

And we’re done smile . I did mean easy — that’s all you have to do to start using a new payment status in your EDD shop. You can now use these statuses from the ‘Edit Payment’ Screen.

Easy Digital Downloads custom payment status: new statuses
New Statuses added

With that said, you may want to integrate it into your management scheme a bit more. For example, what if you want to bulk-update payment statuses, or include these in your earnings reports? We can do that, but it’ll require a bit more code.

EDD custom payment statuses: Bulk actions

Let’s first talk about adding these new statuses to our bulk payment history actions. If you’re processing several orders a day, you may be managing them in bulk. EDD includes several core bulk actions that you can use to select multiple orders, then update the status.

Easy Digital Downloads custom payment status: core bulk actions
Core Bulk Actions

We have a couple of very well-placed filters and actions that will let us add our new statuses to this list. First, we’ll use the edd_payments_table_bulk_actions filter. This will add new statuses into the dropdown for use on the Payment History screen. However, I’m going to insert them into this list before “Resend Email Receipts” rather than on the end so they’re grouped with other status changes.

To do so, we’ll need to loop through the existing statuses, then insert ours after the one we want; in this case, it will be after the “Set To Cancelled” action (though you can use a different one).

* Adds bulk actions to the bulk action dropdown on "Payment History" screen
function sww_edd_bulk_status_dropdown( $actions ) {

$new_bulk_status_actions = array();

// Loop through existing bulk actions
foreach ( $actions as $key => $action ) {

$new_bulk_status_actions[ $key ] = $action;

// Add our actions after the "Set To Cancelled" action
if ( 'set-status-cancelled' === $key ) {
$new_bulk_status_actions['set-status-paid']         = 'Set To Invoice Paid';
$new_bulk_status_actions['set-status-in-progress']  = 'Set To In Progress';
// Add a $new_bulk_status_actions[key] = value; for each status you've added (in the order you want)

return $new_bulk_status_actions;
add_filter( 'edd_payments_table_bulk_actions', 'sww_edd_bulk_status_dropdown' );

This will now insert our two new statuses into the bulk actions list so they can be selected for orders.

Easy Digital Downloads custom payment status: new bulk action
New bulk action

Now our payment statuses will be included in the bulk actions dropdown, but there’s a slight problem: they won’t do anything yet, because they’re not tied to an order change.

We need to take one more step to ensure that the right action is executed when this bulk action is used. That’s where the edd_payments_table_do_bulk_action action will help us out. We’ll add our actions here so that they’re performed when selected in this dropdown.

* Adds bulk actions to update orders when performed
function sww_edd_bulk_status_action( $id, $action ) {

if ( 'set-status-paid' === $action ) {
edd_update_payment_status( $id, 'invoice_paid' );

if ( 'set-status-in-progress' === $action ) {
edd_update_payment_status( $id, 'in_progress' );

add_action( 'edd_payments_table_do_bulk_action', 'sww_edd_bulk_status_action', 10, 2 );

Now we’re cooking with gas.

When we select a couple of existing orders, we’ll be able to use the bulk actions we’ve added into our dropdown.

Easy Digital Downloads custom payment status: bulk action 1
Apply a bulk action

When this action is applied, the payment statuses will also be updated for each of these orders as a result.

Easy Digital Downloads custom payment status: bulk changes applied
Bulk Changes applied

EDD custom payment statuses: Reporting

If you’ve inserted statuses that would be between a “paid” and “complete” status, you’ll probably want to include them in your earnings reports. While an “Invoice sent” action shouldn’t be included, an “Invoice paid” order should certainly be counted in our earnings along with those that have completed statuses.

We’ll need to use two more filters to include our new statuses in the reports: the edd_get_earnings_by_date_args filter and the edd_get_sales_by_date_args filter.

This filter includes the arguments for what should be included in reports, and the post status argument is what we’ll need to update (as each payment status is saved as the WordPress post status for the order). Because both of my new statuses represent orders that have already been paid, I’ll want to include them in earnings reports and will merge in two new post statuses for our two new payment statuses.

* Adds our custom statuses to earnings and sales reports
function sww_edd_earnings_reporting_args( $args ) {

$args['post_status'] = array_merge( $args['post_status'], array( 'invoice_paid', 'in_progress' ) );

return $args;
add_filter( 'edd_get_earnings_by_date_args', 'sww_edd_earnings_reporting_args' );

function sww_edd_sales_reporting_args( $args ) {

$args['post_status'] = array_merge( $args['post_status'], array( 'invoice_paid', 'in_progress' ) );

return $args;
add_filter( 'edd_get_sales_by_date_args', 'sww_edd_sales_reporting_args' );

Now all revoked, completed, invoice paid, and in progress orders will be accounted for in your earnings reports so you have a more accurate reporting overview with your custom statuses.

Taking it further: Payment history screen

There’s a final thing we can do to integrate our Easy Digital Downloads custom payment statuses into our store. If you’d like to filter orders based on our new statuses, we can include this ability in the Payment History screen.

We’ll use the edd_payments_table_views filter, but these must be valid post statuses to use this filter effectively (to actually be able to filter orders by our new status rather that just include a dummy link). As a result, we’ll need to register our new statuses, then add them to the Payment History page.

The only thing we can’t do here is include the counts for these order statuses, as we’d have to do a bit of hacking to include the post status count for our custom statuses.

* Registers our new statuses as post statuses so we can use them in Payment History navigation
function sww_register_post_type_statuses() {

// Payment Statuses
register_post_status( 'invoice_paid', array(
'label'                     => _x( 'Invoice Paid', 'Invoice paid payment status', 'sww-edd' ),
'public'                    => true,
'exclude_from_search'       => false,
'show_in_admin_all_list'    => true,
'show_in_admin_status_list' => true,
'label_count'               => _n_noop( 'Invoice Paid <span class="count">(%s)</span>', 'Invoice Paid <span class="count">(%s)</span>', 'sww-edd' )
) );
register_post_status( 'in_progress', array(
'label'                     => _x( 'Project in progress', 'In progress payment status', 'sww-edd' ),
'public'                    => true,
'exclude_from_search'       => false,
'show_in_admin_all_list'    => true,
'show_in_admin_status_list' => true,
'label_count'               => _n_noop( 'In progress <span class="count">(%s)</span>', 'In progress <span class="count">(%s)</span>', 'sww-edd' )
)  );
add_action( 'init', 'sww_register_post_type_statuses' );

* Adds our new payment statuses to the Payment History navigation
function sww_edd_payments_new_views( $views ) {

$views['invoice_paid']  = sprintf( '<a href="%s">%s</a>', add_query_arg( array( 'status' => 'invoice_paid', 'paged' => FALSE ) ), 'Invoice paid' );
$views['in_progress']   = sprintf( '<a href="%s">%s</a>', add_query_arg( array( 'status' => 'in_progress', 'paged' => FALSE ) ), 'In progress' );

return $views;

add_filter( 'edd_payments_table_views', 'sww_edd_payments_new_views' );

Now that we’ve (1) added these as valid post statuses (just like other core payment statuses) and (2) added them to our Payment History screen, they’ll be displayed along with other order statuses.

Easy Digital Downloads custom payment status: new statuses
Filter by new status

Clicking on our order status link will filter orders to show only those with the desired status.


What happens if you remove this code? Your order will still exist, but won’t have a status set. This means that it won’t be included in reporting, etc., so you’d probably want to change it to a core status if you decide to remove this code at some point in the future.

Easy Digital Downloads custom payment status: no status
No status set

I have a gist here of all of the code in this article if you want to copy / change it and add all of the features above into your site. This should completely integrate your new Easy Digital Downloads custom payment status entirely into your order workflow.

Beka Rice
Beka Rice is the Head of Product at Jilt. She works on app improvements, integration plugins, helping merchants improve recovery campaigns, and shares tutorials on reducing abandonment or improving recovery on our blog.