How I am consuming webhooks to drive website logic

The webhooks documentation is a crap shoot, so I figured how I am currently employing how to grant/remove access; hopefully this can help other developers and also spawn good discussion.

Assumptions:

  • You want to use store their user_id as a primary key, and also use email as their billing (patreon) email
  • members:pledge:create always triggers before members:update
  • You want to grant access for pending payments, but only make them official members once the payment is “Paid”
  • GrantAccess() always creates the account as pending until RemovePendingStatus() is called

Methods:

	GrantAccess(user_id, email)
		// Gives instant access with a status of "PENDING" by default
	RemovePendingStatus(user_id)
		// Removes the "PENDING" status from the access
	RemoveAccess(user_id, when)
		// Removes access starting at `when`
	ChangeEmail(user_id, email)
		// updates the email that was stored when `GrantAccess()` was called

Logic / puesdocode:


	members:pledge:create
		if (`last_charge_status` == "Paid" | "Pending" && currently_entitled_amount_cents > 0)
			GrantAccess(`user_id`, `email`)
			
			if (`last_charge_status` == "Paid")
				RemovePendingStatus(`user_id`)
	members:update		
		ChangeEmail(`user_id`, `email`)
		if (`last_charge_status` == "Paid")
			RemovePendingStatus(`user_id`)
		else if (`last_charge_status` != "Pending") // Will be Declined, Deleted, Refunded, Fraud, Other
			RemoveAccess(`user_id`, now())
	members:pledge:delete
			RemoveAccess(`user_id`, `next_charge_date`)

The main take away is that members:update is the webhook that gets payment updates, and thus should be the main thing driving non-pending access and no-access. You also want to give them some sort of access right away while payment is pending, even if it’s just an email letting them know their you got their patreon sign up and it will be active once payment is posted. Waiting for a “paid” can take multiple days.

This example is meant to be a very simple approach, and does not cover things like if they cancel, let the pledge delete, then re-pledge, or handling the dunning of trying multiple declined payments and finally getting a successful one. It is recommended that access is actually controlled by something like hasAccessUntil date on their account, that way you can turn access on and off to handle these more advanced scenarios where if the date is in the future, or NULL, then they have access.

This post has managed to present more useful info regarding the actual usage of webhooks than any of the official documentation. Thank you very much for your work here @ParoX, well done!

I assume you have had this in production for a bit now, so I have some additional questions if you’d be able to answer them.

  1. I am looking to store, in my own database, each patron’s “paid status”. Furthermore, I am hopeful that this could be done purely through webhooks (member:pledge:update, member:pledge:create, member:pledge:delete), so that I can keep my DB up to date with any new information Patreon has to tell me. From what I have seen though, this seems very prone to errors and the API should instead be used to check, in the moment, the user’s “paid status”. I am wondering what your thoughts are on this and how your implementation has been performing.

  2. Would you say that just watching currently_entitled_amount_cents in the create and update webhooks would be a valid way to determine whether the user should be receiving their reward? Or is listening to last_charge_status necessary — i.e. will Patreon for some reason deem them entitled to something even if their card declines, etc.?

  3. Is there a way to determine which tier or rewards the user has specifically unlocked? We can get the amount they have paid, but I would like to know for certain which reward(s) the paid for tier has unlocked for them. This info doesn’t seem to be provided anywhere but would be very nice for bulletproofing should the tiers/rewards be changed.

  4. Pausing a pledge is apparently a thing. Have you experienced any of these or any problems resulting from them?

  5. It seems that a reward/benefit can be marked as delivered to the user. Is this something that must be marked as completed? If so, do you know of a way to do this programmatically?

  6. You mention a hasAccessUntil field in the last paragraph, but I have been unable to find the field in any of the official documentation. Could you shed some more light on where this field comes from?

  7. Just wondering your overall opinion on using Patreon. From what I have seen, support for developers has been pretty bad and most of the team that used to frequent this forum have been gone for years. It doesn’t provide much confidence in the future of Patreon and worries me regarding any future rug-pulls.

Thanks again for your work here so far! Sorry for the game of 20 questions, but you seem to have some actual answers here :slightly_smiling_face: