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.


  • 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


	GrantAccess(user_id, email)
		// Gives instant access with a status of "PENDING" by default
		// 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:

		if (`last_charge_status` == "Paid" | "Pending" && currently_entitled_amount_cents > 0)
			GrantAccess(`user_id`, `email`)
			if (`last_charge_status` == "Paid")
		ChangeEmail(`user_id`, `email`)
		if (`last_charge_status` == "Paid")
		else if (`last_charge_status` != "Pending") // Will be Declined, Deleted, Refunded, Fraud, Other
			RemoveAccess(`user_id`, now())
			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.