`last_charge_status` is delayed

I’m using OAuth2 for users to login into my website.
To verify the user is an actual paying member, I am checking both patron_status and last_charge_status for active_patron and Paid respectively (I’ve noticed in the past that patron_status sometimes did not update for people with declined charges).

However, the last_charge_status field is lagging behind the actual status of the latest charge, I’ve noticed a (relatively consistent) delay of up to 30 minutes.

This delay is even visible in the normal Dashboard. Here’s an example of a new Patron who was still Pending in the overview (which probably uses last_charge_status) but the charge in the history is already paid.


(Excuse the weird format, I can only upload one image due to new user restrictions, so I had to improvise a bit)

The charge of the example above:

{
    "amount_cents": 1875,
    "currency": "SEK",
    "date": "2024-01-20T12:16:01.000+00:00",
    "is_refundable": true,
    "partial_annual_refund_data": { ... },
    "status": "Paid",
    "supported_period_end": "2024-02-01T08:00:00.000+00:00",
    "supported_period_start": "2024-01-01T08:00:00.000+00:00",
    "underlying_charge_id": "...",
    "underlying_charge_type": "patronage_purchase"
}

As you can see, the charge was created at 12:16:01. However my server logs report last_charge_status was still Pending until as late as 12:35:48 (response from a call to https://www.patreon.com/api/oauth2/v2/identity?include=memberships&fields%5Bmember%5D=patron_status%2Cnext_charge_date%2Clast_charge_status):

{
  "data": {
    "attributes": {},
    "id": "...",
    "relationships": {
      "memberships": {
        "data": [
          {
            "id": "...",
            "type": "member"
          }
        ]
      }
    },
    "type": "user"
  },
  "included": [
    {
      "attributes": {
        "last_charge_status": "Pending",
        "next_charge_date": "2024-02-20T00:00:00.000+00:00",
        "patron_status": "active_patron"
      },
      "id": "...",
      "type": "member"
    }
  ],
  "links": {
    "self": "https://www.patreon.com/api/oauth2/v2/user/..."
  }
}

However, the last charge was already paid at the latest by 12:27, which is when the Patron contacted me and I took the screenshots above.
Because I only log failed auth attempts, I don’t know when exactly the status finally updated, but it was outdated for at least 8 minutes. (I re-checked the dashboard at 12:42 and it was finally up-to-date).

If you are having your users log into your app, why arent you using currently_entitled_tiers and currently_entitled_amount_cents to check to what the patron is entitled to without having to deal with payment statuses?

currently_entitled_amount_cents and currently_entitled_tiers do not account for pending charges.

A Patron’s last (and also first) charge has been pending for 5 days but those fields return positive results.
Had I been relying on those fields, this person would’ve gained access without the payment ever going through.


Notice last_charge_date being from Jan 25th and last_charge_status still being Pending.

That is expected behavior. Until all the retries for charging a member are finished, the member is considered a valid member and those two fields should show the tier or amount the user was entitled to before the charging attempts started. This is how it works at patreon.com and following the same pattern at your app unless you have a very specific use case to not do so, would be best.

Sadly bad actors exist and I can’t be so lenient to give someone access for weeks without even paying once. Which is why I want to use last_charge_status to make absolutely sure the payment went through.

But that’s going off-topic, this post is about the fact that last_charge_status lags behind the actual status of the last charge.

That is possible as a payment can pass through, but could be reverted by the payment provider (or the payer’s bank) for any reason. You could try to incorporate that 30 min delay into your flow in case you definitely need to make sure, in case you arent able to revoke access to the patrons whose payment status get reverted etc.