Stripe Webhooks: check if object changed - stripe-payments

I am integrating Stripe webhooks in a webapp to implement subscriptions using Stripe Billing. The webapp has a frontend and backend.
When a subscription is started or canceled the frontend directly communicates with the backend and everything happens by synchronously calling the Stripe API.
For example, to cancel a subscription, this is the flow:
the user taps on a button in the frontend
frontend calls my app backend to cancel the sub
backend calls the stripe api to actually cancel the sub
backend updates the saved subscription object in its own db
Here comes the "problem": after some seconds a customer.subscription.deleted webhook calls comes at my backend telling me to update the subscription I just saved. I want to avoid the double-save for performance reasons and was wondering if these stripe objects have some kind of signature or update count to check if they have changed with respect to the previous version.
I think it's quite common to use webhooks only for out-of-band updates, so this use case should be supported.

There is not an "update" count or signature for each state of a Subscription. One alternative might be to skip updating your Subscription object in the database directly when processing the request from your own front end to your backend. Instead you could depend primarily on the event notification from Stripe to update your database. This way, you're only updating the database once and if you need to make changes directly from the Stripe dashboard for some reason, those will still propagate to your backend.
I also wanted to note that you should build your webhook event handler to be idempotent by checking the ID of the event before processing as occasionally Stripe will send the same event more than once even if acknowledged successfully.
https://stripe.com/docs/webhooks/best-practices#event-handling

Related

Google IAP In App Purchase auto-renewing subscriptions Webhook for Subscription update / cancellation in NodeJS

Is there any way to implement a Webhook for automatic update of subscriptions on server side, in nodejs for example, for situations such as: the user renewed or canceled his subscription?
Currently I save the subscription data in my Database after purchase and use the Google Developers API to verify that it has been renewed or canceled when necessary.
However, for some Administrator routines I need to check all subscriptions at once and this includes calling the Google API for each one. This process is slow and can take a long time.
I could create a method that checks and updates all subscriptions according to the Google API response, and leave this process running through a Cronjob every day at night. I believe it will work, but a server-side Webhook would be the ideal solution.
Something which automatically notifies my server as soon as there is a change to a subscription so that I can update it in my DB immediately.
Found the answer. We can use Google Cloud Platform (GCP) to subscribe to topics and receive real-time notifications when a subscription change.
All steps are described in detail in their documentation: https://developer.android.com/google/play/billing/getting-ready#configure-rtdn

If I cancel user's subscription manually in Stripe dashboard, should a webhook endpoint I set up on my web server be notified of that?

I am currently in test mode with Stripe.
I cancelled a users subscription is Stripe dashboard, but the webhook I set up on my site's web server (which uses Laravel Cashier) does not fire i.e. the subscription data is unaffected on my site's web server.
I thought this should happen. The webhook is otherwise tested and working.
Whenever a subscription is canceled, the event customer.subscription.deleted will be generated on your account and sent to your webhook endpoint (assuming it listens for it). This is true whether the subscription is canceled automatically after too many failures, via the API or manually in the dashboard.
You can easily confirm this in the dashboard by looking at the Events section for your customer and see this event.
It's likely an issue in the configuration for your webhook or the code server-side with Cashier.
For testing: also make sure, that you set "cancel subscription immediately" instead of at the end of the billing period otherwise it won't fire instantly.
You could also test it with a test clock properly :)

How to make an Approval step in Azure Logic app calling my own APIs similar to office365 approval connector?

I wanna build a small workflow using Azure Logic Apps that contains an "Approval" step, which is simply an API call in my own system, similar to office 365 approval connector.
However, from what I found on the internet, the only way to make a long running task in Azure Logic Apps is to use Webhooks.
In Webhooks, I could not set a value to the parameter I created "Bool-Approved".. so, How can I check it later in a condition step?
The other possible solution maybe is to use Swagger to have an "Bool-Approved" parameter. However, it does not support long running action!
What's the possible solution for me?
As you mentioned, the way to do it is to use the Webhook action, and for that you need to implement the Subscribe/Unsubscribe pattern described here. The webhook action will allow you to get any payload (via an HTTP Post) from the instance-based webhook you are subscribing to.
The points below are a summary of this blog post:
https://www.mexia.com.au/correlation-identifier-pattern-on-logic-apps/
To implement the Subscribe/Unsubscribe Webhook pattern you need to consider:
Subscription store: A database to store the unique message Id and the
instance-based callback URL provided by the webhook action.
Subscribe and Start Request Processing API: this is a RESTful API that is in charge of starting the processing of the request and storing the
subscription.
Unsubscribe and Stop Request Processing API: this is another RESTful API that is only going to be called if the webhook action on the main workflow times out. This API is in charge of stopping the processing and deleting the subscription from the store.
Instance-based webhook: this webhook is to be triggered by your own custom approval event. Once triggered, your webhook is in charge of getting the instance-based callback URL from the store and invoking it. After making the call back to the main workflow instance, the subscription is to be deleted. This is the webhook that is in charge of sending the payload you require to the waiting webhook action in your Logic App.
The subsequent actions will be able to use that response body, so you can implement your conditions, etc.
You can follow the blog post mentioned above to see a detailed example and get more details on how to implement it.
make you api return HTTP code 200 if the response if "ok" and 400 if the response is "not ok". This way you can force logic app to behave the way you need it to behave..

Stripe: "charge.succeeded" webhook not firing for connected account. Wrong event type name?

I suppose that a fundamental question I really ought to be asking, before I get into the details below, might be:
As a vendor/service-provider with a standalone Stripe account that's been connected to a platform account, is it possible for me to set up a webhook that will be called when the platform makes a successful charge on my behalf?
In any case, that's what I'm trying to do, with a webhook that I set up on the recipient account, configured to be called for any of the following events:
Test invocations of the webhook from my dashboard cause it to fire as expected.
But when when I create a charge through the platform, setting destination to reference the connected account, the webhook doesn't fire -- even though the charge is successfully created, along with an accompanying event, in the connected account.
One big fat clue -- that I don't know how to interpret -- is that the type of the event shown in the dashboard's "Events & Webhooks" tab isn't charge.succeeded or charge.captured -- it's payment.created (!).
But:
there's no event type with that name listed in the webhook configuration menu;
nor, as far as I can tell, does the API define a payment object type (and indeed, the type of the object referenced in the event is charge):
So:
Is this just a naming glitch in the API implementation that Stripe simply needs to fix?
Or is there some more fundamental problem that I'm failing to grasp with the idea of setting a webhook on a connected standalone account that I own?
(Or am I just doin' it wrong?)
At the moment, the payment.created event is not visible in the list of selectable events, so you'd have to check "Send me all events" when creating the webhook endpoint in order to receive those.
extending Dmitry's comment in the post, I was able to solve it by adding my endpoint and webhook event type to Endpoints receiving events from your account section in the Stripe dashboard.
The other section called Endpoints receiving events from Connect applications is for events with a Connect Account associated with it. The event object will have an account property, as long as it is an event generated from a Connect Account. These events will go in the Endpoints receiving events from Connect applications section of the Webhooks page in the Dashboard.

How to identify Stripe webhooks type?

I am using Stripe and I need to understand how to only process webhooks that are generated by Stripe behind the scenes. When my server sends something to Stripe (new subscription, new individual charge) Stripe will generate events that are sent via the webhooks I provide. Well, I don't need to process those since it will create a mess. I only want to process Stripe generated webhooks in situations like: failed charge at subscription renewal, manual modifications via the Stripe dashboard, refunds generated in the dashboard, etc).
I went through the events generated and I cannot find anything that would make a difference from those my API calls generate or those generated behind the scenes.
Is there something I am missing?
Update
- API call: event has a request id
- Stripe behind the scenes: event has null request_id
- Stripe dashboard: event has a request id (This still remains a problem)
If I discard all webhook events that are not null I will also discard Stripe dashboard events. I need to process Stripe behind the scenes and also Stripe dashboard generated events.
First of all, Stripe currently does not support identifying the incoming webhook event type. Looking in the Dashboard I indeed can see what initiated the event (API, Dashboard or Automatic) but Stripe's people said they don't support it.
However, there is a workaround. For anyone struggling with this I will describe what I did. An automatic Stripe generated event is easy to differentiate. It contains a null request field. Any other type of event will have a request id (ex: re_123h2kj18321hjk3218). The problem remains with differentiating between API and Stripe Dashboard generated requests. Therefore, the solution is to capture the request id for every request generated by the API. Whenever a webhook arrives to your server, you check for the request field NOT to be in the Storage System (DB, etc) OR that the request is null. This means that the event was generated by either the Dashboard or Automatically by Stripe (subscription renewal).
Steps:
Hook into the CurlClient provided by Stripe. Extend that class and
override the request() method. The request method returns the
response generated by Stripe servers. Capture the headers of the
response which would contain a Request-id. Store that in your
Storage (in my case a DB)
In your configuration files you need to specify that Stripe should use your own CurlClient. ApiRequestor::setHttpClient(new CurlClient()); (I've named my CurlClient too but you can name it whatever)
When a webhook arrives, you have three options to identify the type:
Automatic: if the event has a request=null
Dashboard: the request is not null and the request is not in you Storage
API: you're left with one situation. The request is not null but exists in your DB
As you can see, there's quite a lot of work for something really easy. All Stripe needs to do is provide another field in their webhook event name something like request-type with three options (api, automatic, dashboard). They already have this build but they don't allow it to be shown in the webhook event.
On the event object documentation, you'll see the request property documented. This property is set whenever the event came from an API request. Otherwise, if it's null it means there was no API request associated with it and it was what we call an Automatic event in the dashboard.
You need to discard any event where request is not null on your end!

Resources