Yearly Patrons Accessing All Content

Hi there!
I’ve been using the wordpress Patron Pro app for a while and like it, but recently I started getting yearly patrons. The problem is the patreon plugin doesn’t seem to work for those yearly patrons and allows them to access all the content that should be locked to them.
Is there a way for me to fix this?
The plugin becomes fairly useless if it doesn’t block my lowest tier Patrons from gaining access just because they subscribed for a year.

You can try turning on ‘Active patrons’ setting. The one which says “Require a pledge active at the time…”. This will cause only patrons who were patrons when the content was posted to gain access to that post. Though it may not work for some posts.

The thing is that yearly pledges are not currently supported in the api. I will look into what can be done plugin-side to address that. But for a while things may be like this.

Is there any update on this issue?

Yearly patrons ending up with access to monthly content is an issue that stems from the api and it must be addressed there. When the api provides needed information, it can be fixed on the plugin side as well.

So where do I go to address the api issue? Is there a help forum for that?

This is the help forum - if you wish, you can file a support ticket at Patreon by describing the issue.

So just so I’m clear, you’re saying that there is no way for the plugin to be adjusted to request the appropriate information from the Patreon API to distinguish between annual and monthly patrons? The API itself is developed by Patreon, which is independent from the plugin?

I thought Patreon was able to provide info such as tier IDs with currently entitled tiers if the APIs requests it, and I thought the plugin was involved with the APIs development. But it sounds like Codebard is separate from Patreon and simply provides a coded user interface to interpret the data? I just want to make sure I understand the issue and understand who is responsible for what aspect of this plugin, since I pay money for it and it doesn’t work properly.

Codebard, I’m not sure how your pro plugin is written, but couldn’t you compare last_charge_date and next_charge_date when the patron_status is active_patron, looking for a date that’s greater than 31 days apart or any instance when next_charge_date is null?

Based on API Reference it seems like it should be possible to figure out whether a patron is monthly or annual, even if the API doesn’t explicitly say it.

1 Like

That was my thought too. I understand that the API doesn’t have an option specifically to distinguish between annual and monthly subscribers, but it seems like there’s plenty of other data that you can request and deduce their pledge type based on that.

I’m getting the impression that Codebard doesn’t want to put the work in to fix the issue with the tools available, which is really sad. I enjoyed this plugin while it worked, but it’s no longer worth the money if it doesn’t work properly. And if Codebard is unwilling to update the code to address this glaring problem even for paid pro plugin customers, that’s pretty unfortunate. I hope that changes in the future.

I don’t have annual subscribers to test the API against, but I do know that when I request next_charge_date, the API returns it just fine. The default configuration for the plugins do not request that data though.

Hmm… I’m going to try some stuff with the PHP API package to see if I can figure out an easy way to do this. Gives me an excuse to push new features to my fork of said package, anyways. I’ll post again later tonight when I know more.

Alright, so I’ve done a bunch of testing and a bit of trial and error and have determined that if you request the nested relations of a member from a patreon user you can do basically all of this in a single API call. You have to not only include memberships but also memberships.campaign. From there you have to declare field requests for not only ['member'] but also ['campaign']. And yes, you could, probably, also just include campaign and not call it through the membership, but this way means you are guaranteed to get the campaign of the memberships and not like, their creator account or something odd you have to sort through if you have too many scopes.

The fun part comes when you sort this out. You either need to know your campaign ID, OR, you need to be working within a very limited scope authorization that only requests a user’s details as they pertain to your campaign–which, given privacy concerns in this day in age I recommend anyways.

If you can ID your campaign, the rest falls into place fairly easy. You sort through the ['included'] key’s nested array returned by the call, looking specifically for whichver one has a subkey of ['type'] that is exactly 'campaign' for your campaign (if you only request the minimal amount, this is the only campaign you’ll see for patrons when they do this–your account will return everything because you have full scopes to yourself always). Once you have that you look for that key’s subkey of ['is_monthly'] which if 1 means this is a monthly only Creator, as opposed to an on release Creator.

With that established, we check that the user is still active: ['patron_status'] == 'active'.

And finally, we look at charge dates of the user’s membership to your campaign: ['last_charge_date'] compared against ['next_charge_date'] to see if they’re over a month. You could also probably check if ['next_charge_date] is null if you’ve already verified that this is a monthly pledge. I’d do the date comparison myself, just because I think it’s more reliable.

If you check that these are actually dates and that last_charged_date isn’t null, you could skip the patron status check, I think.

Anyways, from there it is just actually using the result of that comparison to do something.

The thing is that there is some info that differentiates yearly patrons in api returns, but its not certain that those particular bits are going to be permanent fields that can be used in perpetuity - they may be deprecated or changed depending on the situation.

When reliable info is provided by api side on a long term basis, we can build those fields into the calls and rely on them on a long term basis.

If you would like to get around this particular situation for the time being, the various approaches you mentioned may work - you could put hook into the lock_or_not function’s filters, and introduce an additional check using whatever method you see fit.