Skip to main content
Easy Digital Downloads Documentation
Documentation, Reference Materials, and Tutorials for Easy Digital Downloads

Adding custom code after an order is completed

In Easy Digital Downloads 3.2.0 the after order actions were introduced to replace the deprecated after payment actions. This hook provides developers a way to process intensive actions when a payment completes without affecting the speed and performance of the end user completing the purchase. This is a guide on how to add an after order action.

Introduction to After Order Actions

If you are looking to perform additional actions when an order is marked as ‘completed’ you are encouraged to use the edd_after_order_actions hook instead of the edd_complete_purchase hook. What is the difference between these two hooks?

  • edd_complete_purchase – Runs during the purchase process after the user clicks the ‘Complete Purchase’ button and before the ‘Purchase Confirmation’ page is loaded. This hook should be used for “mission critical” tasks, as it will impact the perceived time it takes for the user to complete their purchase. Examples of using this hook should be tasks like creating license keys, generating subscriptions, or anything that the user is required to have visible on the receipt page.
  • edd_after_order_actions – Runs ~30 seconds after the purchase is completed, via the WP_Cron system. This hook should be used to perform additional API calls, expensive database queries, and tasks that should be considered non-mission critical for the user to complete their purchase. Great examples of this are adding users to mailing lists, calculating stats for a user, updating caches, etc.

What arguments are passed into the hook?

The edd_after_order_actions hook sends three arguments:

  • The order ID as an integer
  • The EDD\Orders\Order object
  • The EDD_Customer object

What order statuses are included in ‘complete’?

Easy Digital Downloads uses the status of complete to mark an order as completed. If you are integrating or using the Recurring Payments extension, the edd_subscription status is also considered a ‘complete’ order. If you only want to run your action for the initial purchase (and ignore subscription renewals) you will need to check the $order->status for a value of complete before continuing with your integration.

Why does this require WP_Cron?

WP_Cron is a background process that your WordPress site uses to complete tasks without impacting the user’s experience viewing your site. When traffic is generated on your site, before the page is done loading, WordPress determines if there are any background tasks that need to be completed. If there are, it will spin up a background process to handle these pending tasks.

What if my host disables WP_Cron?

While we do our best to detect if WP_Cron is working, there may be a case where we cannot propertly detect this. If your host or server has WP_Cron disabled or modified to run at a pre-determined frequency, you may need to disable this feature manually. There is a filter if you choose not to use after action hooks, in which case, EDD will fallback and perform the actions at the time of completion, and avoid the delayed process.

NOTICE: Because this after order actions system is dependent on WP_Cron, it should not be used for things considered ‘mission critical’. It’s simply a way to offload expensive integrations with APIs and large sets of data that do not directly affect the purchase data.

Key points about after order actions

  • Triggers via WP_Cron
  • Able to be disabled via filter (edd_use_after_payment_actions)
  • By default, it is scheduled for 30 seconds after the purchase, but can be changed via a filter.
  • The order’s database table contains a column for the time the actions were completed.

Is there an example?

We’ve created a ‘template’ for integrating with the edd_after_order_actions hook in our WP Code library. It can be viewed here:

Migrating your code from edd_after_payment_actions

If you previously integrated with the edd_after_payment_actions hook, the good news is that migrating to this new, more efficient, hook is pretty easy.

The primary difference is the change from the second parameter. Instead of sending in the payment as an EDD_Payment object, it will send in an Order object.