Issue/Bug in Patreon API: last_charge_date empty for ALL patrons since 2020-09-03

Sure; In this post, I go into it in some depth also (along with some recommendations on improvement). The short version of it is that since you won’t be able to depend on charge cents being consistent (Patreon plans to adjust it periodically based on currency fluctuations), we have to check the last charge. If you’re not doing charge up front, current tier is not necessarily what the user has paid for yet, so you can’t trust that current tier value.

Here’s the new algo (Looks like forums don’t support more than two layers for nested bullets, so apologies for the ugly formatting here)

1. Get a list of all pledges from the API
2. Prune out any accounts from that list that don't have a locally linked account
3. For each remaining user:
   i. If the last charge time is a long time ago, they can be skipped (old account)
   ii. Determine whether this user should be further processed to avoid massive future API calls:
      a. If the last charge timestamp significantly differs from last time program was run:
         x.  If the new status is paid, it definitely should be processed
         y.  If it's something else, it's probably safe to skip -- but this logic assumes Patreon does not update last charge time if a charge switches to revoked, which I don't know for sure if that's the case.
	  b. If the last charge timestamp is mostly the same as from last time:
	     x.  If it's the same as the saved status from last time, there hasn't been any change, so user does not need any further reprocessing.
         y.  Otherwise it's a status change, so should be reprocessed.
      c. (Yes, it's kinda top tier BS to be comparing timestamps instead of charge IDs, but working with what we're given... >.<)
   iii.  Hopefully most users have been pruned out at this point, because now we do an API call for each additional user to get their transaction history.
   iv.  Check most recent subscription event.  Fortunately, here we finally have a payment ID and a charged tier ID.  Here we can do the more traditional payment logic, like:
      a.  If it's a new payment in paid status, grant access to any relevant entitlements for a month (to cover the time paid, plus internally I add a bit of buffer when checking this value in case Patreon API is slow the next month)
      b.  If it's an old payment that used to be paid but now is something else, revoke the previously granted entitlements

It usually takes about 3.5 minutes for this algo to run with ~1000 active+former patrons, with small delays between each API call. I run the whole thing every 30 minutes. It’s definitely a lot more API calls than the old method, but it works.

Big caveat: charge time is not the same between the two calls. One is approximate, the other is the true time. (I believe I mention that in my other post, too.)

This all means I had to upgrade half my site to v2 instead of v1, which ended up being a week+ long process of rewriting the code. This time around, I’ve built it so it can run for an extendedly long period of time, and resume if the process dies or needs to be restarted (and it locks itself to ensure two instances aren’t running at the same time). I’m not sure if the code is quite good or general-purpose enough to release one way or another. I’m still working out to find situations where the code produces different entitlement values than the old version of my poller, probably because the new version is faster/can handle the case of someone charging+unpledging before the poller runs/can handle chargebacks/refunds, or possibly just because there’s a bug :sweat_smile:

And if anyone from Patreon is reading, again, recommendations here.

2 Likes