Menu Sidebar


I'm on twitter @dancameron and this is my site so you'll want to read my about page too.

EDD Recurring Payments & Discounts: Solution

As a follow to my EDD Recurring Payments & Discounts: Proposal 1 I’d like to share my solution.

Let me set this up for you first.

Here’s the pricing options for Sprout Invoices.

Screen Shot 2014-09-08 at 3.05.29 PM

Note: the customer pays the “Signup Fee” and the “Price” initially, I’ve written about a proposal to change this already.

The discount is for 25% off and multiple discount codes are created for different events. I did not create a discount per variable price.


The below code will allow for a single discount code to have multiple discount rates based on the variable price the customer is purchasing.

Note: This is live code and can be compared with the variable pricing table above. Also, if I were to release a plugin or needed to use this solution more I wouldn’t hard code the discount, instead it would be calculated based on the discount options.

Don’t stop there (unless you’re not using recurring payments and just wanted to know how to have a single EDD discount code for multiple price discounts based on variable pricing). Otherwise, the discount is going to be applied to recurring rate.

The below code will remove the discount from being applied to the price (AKA recurring fee).

Note: Since these discounts are only for a single download (i.e. #49) I’m checking early.

This last bit will apply the discount to the signup fee by changing it’s fee value.

Note: The new signup fee will have the price applied. In my case  that would make some signup fees a negative number, since our yearly don’t have a signup fee.


You’ll notice that the fees are not updated on AJAX, maybe Pippin can help me with this one since ATM I don’t have the time to dig in enough to explain with authority why. IIRC it has to do with the fees not being applied to the cart_total when AJAX is used. Anyway, I found a refresh of the cart is necessary (as a janky way to get around it).

Since I already have a customer edd_templates/checkout_cart.php I just dropped this at the end.

Note: Thank you to whomever placed triggers in the EDD jQuery functions.

Hope this helps. It took a while to figure this one out and I have a feeling it’s the best route to go. Maybe someone else has a solution.


  1. Which was originally this post but I got out of hand explaining too much 🙂

EDD Recurring Payments & Discounts: Proposal

Pricing a premium plugin is hard. I’ve written publicly about the multiple pricing options for Sprout Invoices and after this weekend at WordCamp LAX talking to a lot of great people, I’ve already concluded improvements to streamline and simplify purchasing are needed. However, the pricing structure won’t change anytime soon, even if EDD discount codes don’t like it.

For the upcoming WordCamp and WPAPPStore promotions I need to apply a percentage discount to Sprout Invoices. Even though I could easily create a Discount with EDD the discount didn’t work as expected. The discount instead of applying to the initial fee (aka sign-up fee + price) it was applied only to the price, which is a major problem for me…

Here are some details…

  • Easy Digital Downloads applies discounts is to the download’s price.
  • Recurring Payments uses fees to apply the “sign up fee” to the download’s total price during checkout.
  • After the discount is applied at checkout it only factors the download’s price, not the total price with the fees applied.
  • The recurring rate is the price.

Do you see the problem? There are a few:

  1. A discount could cause the price of the download to be free, even if it has a recurring fee and instead of charging the customer they’re instead given the download without a recurring payment profile. 1
  2. …[I’ll remember at some point]…
  3. There’s no way to apply a discount to the initial price, instead it’s applied to the recurring fee instead.

That last “problem” is a big one for me. Since I don’t want to allow for a 25% discount for future subscriptions. Instead I need the customer to get their discount today and pay full price on the next term.

I thought I had this worked out after filtering the paypal subscription arguments 2 but it never worked, thankfully to EDD 2.0 changing how fees are calculated I noticed I still had the same problem–discounts were being applied to the recurring rate as well as the initial price.

I’d prefer EDD change how Recurring Payments approaches prices and terms but I understand that backwards compatibility is important, even if the fundamentals are wrong IMHO. When we did recurring fees for GBS the price was what the customer paid today; then there was an option for the term, duration term, and price. That way discounts can be applied to that full initial price without issue.


  1. I forgot where the check is but IIRC EDD is checking the subtotal instead of the total of the cart before deciding the purchase is free.
  2. Don’t use the method linked to filtering the paypal args, it won’t work. Instead read the whole post and use the other code above.

Please don’t “Go Big”, Just be Successful

This tweet really bothered me when I first read it this afternoon.

Personally, I don’t want anyone to be discouraged from going on on their own. I don’t know where we would be without my wife’s support helping me pursue freelance development, I was discouraged and very reluctant at the time.

That said, I highly doubt Justin’s point was to discourage anyone from pursuing freelancing or building a business on their own, suggesting instead to join an agency or a potential competing business. However, when I read “go big”, I see: do something in excess, do something more, build an agency, employ a lot of people, have offices, work your ass off, commit to your business first, profits!, etc..

Obviously this is a loaded issue for me, that’s why a misunderstood tweet has me writing this.

Anyway, It took a while before I realized building something big wasn’t a road to success. Instead I pursued success by focusing on a set goals, ultimately I got there 1, all while not forgetting to continually evaluate my business and being honest enough to change stretch goals.

I’m trying to save myself from writing (and you from reading) a bunch of hyperbolic statements on what true success is and how it’s completely personal. It’s not for the lack of trying either, I just couldn’t figure out an easy way to encourage honest reflection in setting up goals for success, while not limiting a business plan, without sounding contradictory.

By all means “go big”, just don’t feel the need that creating a big business is success.


  1. With a lot help from friends and coincidence.

Stop making me talk about myself!

I was on apply_filters yesterday! I didn’t expect it either.

Not a lot of people know this but I’m extremely nervous when it comes to public speaking. I get really uncomfortable, I mumble out nonsense, and sometimes my mind runs an infinite loop of [What the hell did you just say?!]. That’s what happened yesterday before Brad and Pippin pulled me out of my death spiral. The question was simple: “Why don’t you take a couple of minutes and tell us about yourself? What do you do, where are you from, etc.?”

It’s a common theme for [scare_quotes]entrepreneurs[/scare_quotes] to advise getting your elevator pitch right. I guess I’m an entrepreneur now? Urg…anyway, I don’t have an elevator pitch about myself yet. I’m working on it.

Maybe it’s really not a “elevator pitch”, maybe I just need the confidence to let people know who I am when I’m not face-to-face 1.

This morning I re-wrote my “About” page. Turning it from a page trying to earn respect to a story about my WordPress journey. Which I think is a step in a new start 2.


  1. I’m not crazy! I can talk to people that I don’t already know. Sheesh. I just don’t want to at times 🙂
  2. Saving you from a huge dump of personal self reflective thoughts

Add a NinjaDemo Form on External Domain

At Sprout Apps we’re going to be using the awesome NinjaDemo plugin but we wanted to allow for a demo to be created without directing them to the bland demo site running Twenty Twelve :).

Here’s the solution I came up with:

Add some AJAX handlers on the WPMU demo site running NinjaDemo. I wish NinjaDemo would provide these built in at some point but before that I’d like to see them allow for some attributes to be passed to Ninja_Demo_Shortcodes->try_demo(): add the domain in the form action (home_url()), add some classes to the submit form and change the submit button value.

Modify the allowed domains so that cross domain AJAX requests can be made.

After activating the example plugin above, a shortcode can be used on your main domain (or site you want to add the NinjaDemo form).

Make sure to modify the demo_url!

I know only a few could use this but I hope they find it useful. and Jetpack should lead the way toward standardizing custom post types

I don’t understand why this is an issue. The “lock-in” is only perceived by the theme user, it’s not real, especially when the content is owned. Any theme could add a very basic option and method to convert post type names. The answer should be to build better tools to convert their prospective customers; to help those that might think they’re locked in. It’s good business for Array and others to help convert than to wait and expect others to follow 1.

The real lock-in isn’t custom post type slug names: it’s post_meta 2!


We shouldn’t give up control by imposing any standards on a popular plugin. Jetpack shouldn’t be an authority for standards; as well as s2Member should never be an authority on subscription logic (even if it was extremely popular).

As I wrote in my response CPT slug names really isn’t an issue. If these businesses want to help customers (by converting them into buyers) they need to provide tools to help them convert from older themes. Technically a CPT slug name is probably the easiest thing to change and an interface to migrate is a days worth of work–more importantly it’s a business opportunity.



  1. Not to say that they can’t try to set a standard and build tools to help new customers start running post activation.
  2. Which only gets a mention. Understandably since there’s no true solution.

Javascript new Date() Formats and Offsets

Noticing that new Date( 'July 17, 2014' ).getTime() and new Date( '07/17/2014' ).getTime() will return two different values. The former will have the GMT offset attached while the later will not.

I need to test if this has anything to do with the values of the first are from a string and the second is from a date input type.


See the Pen sdypG by Dan Cameron (@dancameron) on CodePen.

Catching up in the WordPress Community

I have been releasing plugins and themes since the early days (~1.0) and I’ve been doing professional WordPress development for 6 years, but I only recently realized that I’ve become out of loop with the WP community. There’s so many new sub-groups: premium sellers, WP agencies and a ton of shops.

Looking back (beyond 6 years ago) I fit into a few places, I had some popular themes 1 and a surprisingly popular plugin in Search Everything 2. The community was smaller, the “premium” market was just starting and the explosion of WordPress dominating anything but blogs hadn’t hit yet. I could blame the community growth but I can’t.

I really just shut myself out. I stopped releasing code, stopped blogging and participating. This was because I ended up separating community involvement with work/business, and with me working full-time on a premium WordPress plugin I didn’t want to spend any free time on anything related.

Now that I have a more flexible work schedule, since I only need to hold myself accountable, I’ll be able to “give back”. I plan to contribute back to core 3, putting in more time at Stack Exchange (because it’s not just about WordPress) and being involved in my local WP meetup.

It will also be good business to give back at Sprout Apps and the plan is to make the core apps available for free in WP extend. This alone will help prevent me from sheltering myself away from a community I owe a lot to.


  1. All are no-where to be found now.
  2. Search Everything which I sold to Zemanta earlier this year because I was too busy to support it and they promised to make it better.
  3. Trying to contribute back to core has always been a negative experience for me. The next time around I’m going to take a trac issue that needs work but the debate is already over.
Newer Posts
Older Posts

Dan Cameron

I build stuff with WordPress

I'm currently building Sprout Apps to help small businesses and freelancers running WordPress.