Stripe: handle the first subscription and webhook event - stripe-payments

My customer join a our subscripton plan at the first time, I create a transaction (called START-transaction) and use Stripe's API to create new subscription and store subscription object return within above transaction.
I also using webhook to catch Stripe's events. My bigest purpose is handle recurring payment (send notification on charge success or fail, and something for customer's interaction). I catch event invoice.payment_succeeded to detect it's a recuring billing. I create a transaction too (call RECURRENCE) and, of couse, I store event object within transaction. (base on subscription information in event invoice.payment_succceeded, I find out relative-START transaction and create a new transaction as long as RECURRENCE)
And the problem exposes, in the first time customer creates plan, there 6 event called back to my system: customer.created; charge.succeeded; invoice.created; invoice.payment_succeeded; customer.card.created; customer.subscription.created. So, my customer have 2-transactiona: 1-START and 1-RECURRENCE at the first time.
Do you suggest me any idea to remove RECURRENCE transaction?
Thank you.

It sounds like you want to be able to tell if the invoice.payment_succeeded event you receive is for the first payment (which you already processed in your "START transaction") or not (in which case you want to process it in a "RECURRENCE transaction").
The simplest way to do this is to look at the event object's request attribute. Because the first invoice is a direct consequence of your subscription creation request, the first invoice.payment_succeeded event will have a non-null value for the request attribute. Subsequent invoices are created in the background by Stripe, and so the events will have a null value for the request attribute.

You can use the Stripe Request's billing_reason to identify if it is a first-time subscription, a recurring payment, or an updated invoice payment. See https://stripe.com/docs/api/invoices/object#invoice_object-billing_reason

Related

payPal subscription transactions not showing up immediately

I'm creating recurring payments through payPal subscriptions flow. On the frontend, I have a button auto-generated by payPal which redirects me to their domain. After that, it correctly returns the subscriptionID; after that, the frontend calls a backend API which should verify that subscriptionID, to check fields such "status" and so on.
In this backend API, I need to store some "paymentID" (one per month, always unique, if the subscription is automatically renewed monthly), which I found to be called "transactionID" on payPal. I use the REST API GET /v1/billing/subscriptions/{id}/transactions, which should returns an object with a field transactions, which should be an array of transactions. The problem is that sometimes, just after the successful payment, this array is empty. If I wait some time (from few ms to minutes), then every subscription has it's own transactions, in the end.
Is there a way to fix this? Or, alternatively, is there something like transactions on the PayPal environment which can uniquely represents a specific payment?
When a subscription starts it takes time for the first transaction to be created.
Instead of querying the subscriptions API, create a webhook to be notified of PAYMENT.SALE.COMPLETEDevents. This will be useful for the initial transaction as well as all future transactions.

Stripe subscription events webhooks are not clear

Say I am letting customers subscribe to a service, as I see it there are 2 events that I need to know about :
The current charge succeeded or failed, so I can congratulate him for joining in.
every next charge (every month) succeeded or failed.
Stripe have too many events, and it's hard to know which one of them to listen to :
invoice.paid - "Occurs whenever an invoice payment attempt succeeds"
charge.succeeded - "occures when a new charge was created" (so what's the difference??)
invoice.payment_succeeded - "Occurs whenever an invoice payment attempt succeeds."
customer.subscription.created - "Occurs whenever a customer is signed up for a new plan."
Now I am aware that a few events can happen for a single API call, but,
What should a developer listen to in order to know that his user successfully subscribed, or failed ? how invoice.paid is different than charge.succeeded ? and how invoice.payment_succeeded is different from those ?
It is too messy, I just need to get a yes or no.
I read the API https://stripe.com/docs/api/events/types
It comes down to what you want to listen for.
charge.succeeded will trigger when an invoice is successfully paid, but it'll also trigger for one-off payments.
invoice.paid will trigger when an invoice is paid but will also trigger if you mark the invoice as paid out of band (e.g. someone pays you in cash)
invoice.payment_succeeded is the same as invoice.paid, but won't trigger if you mark the invoice as paid out of band. If you don't anticipate ever accepting out of band payments, then consider using this event.
customer.subscription.created will trigger when a new subscription is created, which isn't the same as the first invoice being paid (e.g. you can create a subscription with a trial period that won't trigger an invoice paid event immediately).
If your business only works with subscriptions (and not one-off payments) and you don't particularly care about the invoice data, use charge.succeeded. If you use both then it's useful to listen to both events to distinguish between the two.
In your case, you probably only want to listen to invoice.payment_succeeded. When you get the invoice, look at the billing_reason field: https://stripe.com/docs/api/invoices/object#invoice_object-billing_reason
If it's set to subscription_create, then send your congratulatory email. If it's subscription_cycle, then it's because the subscription entered a new billing cycle and the payment succeeded.

What is the best way to update a subscription on the back-end using Stripe's webhooks?

What event should my webhook look for in order to update a customer's subscription in my database? I would assume customer.subscription.updated as it contains the current_period_start and current_period_end items. However, my concern is that customer.subscription.updated is apparently fired an hour or so before invoice.payment_succeeded is fired. I wouldn't want to update a customer's subscription if the payment then failed an hour later.
As duck stated in his/her comment, I think the best way to update a subscription if the payment of the invoice failed or succeeded is to listen to these events:
invoice.payment_succeeded: Occurs whenever an invoice payment attempt succeeds.
invoice.payment_failed: Occurs whenever an invoice payment attempt fails, due either to a declined payment or to the lack of a stored payment method.
Actually this is the way I handle things in production, and it is very effective. I would recommend the Stripe documentation's article Billing Lifecycle and Events, especially the section The subscription lifecycle:
After this first invoice, the following cycle of events repeats every
billing period:
When the subscription approaches its renewal date, an invoice.upcoming event is sent.
When the subscription period elapses, an invoice.created event is sent, indicating the creation of a draft invoice.
About an hour after the invoice is created, it is finalized (changes are no longer permitted), and an invoice.finalized event is
sent. A charge is attempted, and a charge.succeeded event is sent to
indicate that the payment was successful.
An invoice.payment_succeeded event is sent to indicate that the invoice was marked paid.

When to register the "payment" event in Stripe webhook

There is the following event from Stripe that shows a charge has went through:
charge.succeeded
https://stripe.com/docs/api/events/types#event_types-charge.succeeded
From this I can generate an invoice receipt and email it to the customer. Easy enough. However, there is zero information about what is charged in that item -- it only shows the amount. More importantly, it doesn't tell me when the subscription start/end is, which I need to tell the customer in the invoice receipt.
I need to get the different items in the subscription that were charged. It seems like I can use this item instead:
invoice.payment_succeeded
https://stripe.com/docs/api/events/types#event_types-invoice.payment_succeeded
This gives the items in the subscription and also the amount_paid, however it doesn't reference the charge object or anything. I'm also concerned that this event seems a bit more abstracted than the charge.succeeeded/refunded event, so it possibly may not capture anything (please correct me if I'm wrong).
For a subscription, which of the above two methods should I use to trigger when I send an invoice email? Why would one be preferred over the other?
For a subscription, which of the above two methods should I use to trigger when I send an invoice email? Why would one be preferred over the other?
You should prefer the invoice.payment_succeeded event, because as you noticed, it refers directly to the invoice from the subscription and thus has much more of the information that you would need to build a receipt email for the payment.
however it doesn't reference the charge object or anything
The event payload is an Invoice object, which has a charge field with the charge ID for the most recent charge on the invoice(which will be what caused the invoice.payment_succeeded event to trigger). You can retrieve that charge to get further information from that if needed.

Is the customer.subscription.updated event raised when a subscription is renewed?

I'm confused about why Stripe's documentation suggests the customer.subscription.updated event is not fired when I believe it should:
A Stripe subscription object has the properties current_period_start and current_period_end which would be updated whenever the customer successfully pays a subscription's invoices ( https://stripe.com/docs/api#subscriptions )
The documentation for the customer.subscription.updated event states that it...
Occurs whenever a subscription changes. Examples would include switching from one plan to another, or switching status from trial to active.
...which would imply that the event would be raised if the current_period_start and current_period_end values change, but it doesn't affirm if it does or it does not in this case.
However this third-party webpage states that it is not raised when a successful renewal is performed ( https://www.masteringmodernpayments.com/stripe-webhook-event-cheatsheet#8 ).
But raising the event just makes sense...
And certainly if applications only needed to monitor a single event type (i.e. customer.subscription.updated) then it would greatly simplify program code without needing to also monitor invoice.payment_succeeded, invoice.created and charge.succeeded.
However the documentation for the Subscription Lifecycle ( https://stripe.com/docs/subscriptions/lifecycle ) makes absolutely no mention of the customer.subscription.updated event at all.
It just seems odd that such an appropriate event is not raised when it should be. The documentation also really doesn't say when the current_period_end and current_period_start values are updated either, which limits their utility.
So in my application, after receiving an invoice.payment_succeeded event, how can my program code determine when the customer's subscription period will end next?
I've verified that customer.subscription.updated is called when the billing period ends.
To do this I intercepted all webhooks that occur at the end of the period (FYI: I used an AWS Lambda function that receives the events from an AWS API Gateway, then puts the events on an SQS queue :))
I agree that the Stripe documentation for the customer.subscription.updated event could be clearer and could cover this use case by saying....
Occurs whenever a subscription changes. Examples would include
when the billing period ends and a new billing period begins, when
switching from one plan to another, or switching status from trial to
active.
(FYI: I would ignore the cheatsheet website altogether. They make only fleeting reference to customer.subscription.updated - In step 8 they are describing (poorly) the use case of "Create a customer with a plan without a trial" which wouldn't create a customer.subscription.updated event because this event only occurs when the subscription is updated, not when it is created. Where they do reference customer.subscription.updated is in context of Step 12 "Invoice charge attempt fails")
In defense of Stripes documentation regarding the lifecycle of a subscription, it does say "the following image shows the lifecycle of the most important events that occur" and I'd say customer.subscription.updated is not an important event in context of creating invoices and making payments.
Some details about how Stripe handles the end of a period:
In my test, Stripe raised the customer.subscription.updated event approximately 2 minutes after the timestamp in the current_period_end property on the subscription. The event has two data objects associated with it. The first is the subscription with the new values on it. The second is a previousAttributes object with the two previous current_period_start and current_period_end values.
Two events were generated simultaneously: customer.subscription.updated and invoice.created (this was the invoice for the period that had just elapsed).
Around an hour after the invoice was created, three events were generated simultaneously: invoice.payment_succeeded, charge.succeeded and invoice.updated.
How you treat the rollover of a billing period vs. the payment status of an invoice is really up to you, and very much depends on your application type. That's the beauty of the Stripe API (and it is a thing of beauty).
In my case, I treat the rollover of a billing period separately to the payment status of an invoice. My application cares about when the billing period rolls over and makes updates to usage based on this, but any payment failures generate alerts & are handled offline.
In summary, you can use customer.subscription.updated to know when the billing period has changed.
customer.subscription.updated is triggered when current_period_start and current_period_end change. These represent the billing period.
When invoice.payment_succeeded happens, it's there that you must update the information on your side (e.g.: subscription period):
https://stripe.com/docs/subscriptions/guide#step-3-sync-with-your-site
Also more info here: https://support.stripe.com/questions/what-events-can-i-see-when-a-subscription-is-renewed

Resources