I am using STRIPE for credit card payments in my Asp.net Application. Application have an monthly subscription plan. First time when user subscribe the webhook event 'customer.subscription.created' fired. my question is what happened which events will be fired when next month subscription is renewed ? Can anyone tell me the flow on subscription renewal webhook events?
Thanks
The webhook 'invoice.payment_succeeded' actually does distinguish between the first charge of a new subscription and subsequent renewal charges.
The webhook sends an invoice object, which includes 'billing_reason' - the possible values of which are noted in the Stripe Docs - The Invoice object:
billing_reason
(string)
"Indicates the reason why the invoice was created.
subscription_cycle indicates an invoice created by a subscription advancing into a new period. subscription_create indicates an invoice created due to creating a subscription. subscription_update indicates an invoice created due to updating a subscription. subscription is set for all old invoices to indicate either a change to a subscription or a period advancement. manual is set for all invoices unrelated to a subscription (for example: created via the invoice editor). The upcoming value is reserved for simulated invoices per the upcoming invoice endpoint."
If billing_reason == 'subscription_cycle' the webhook is for a subscription
renewal.
If billing_reason == 'subscription_create' the webhook is for a brand new subscription.
Renewing Subscriptions:
When a customer's subscription is renewed in Stripe a number of things happen, each with a corresponding event:
An invoice is created - invoice.created
The subscription billing period is updated - customer.subscription.updated
After an hour (giving you time to add any additional charges) Stripe attempts to charge the customer.
Given payment is successful an invoice.payment_succeeded event is raised.
The way to handle these events within your own application is to register a webhook; a HTTP endpoint that Stripe will send details of the event to.
Find the customer subscription using the Stripe identifier (included in the event payload).
Retrieve the subscription details from the Stripe API.
Update our subscription's CurrentPeriodStart and CurrentPeriodEnd with the Stripe subscription's period_start and period_end.
Create a customer invoice using the details from the Stripe event.
As well as customer.subscription.created you will also receive a invoice.created followed by invoice.payment_succeeded (or invoice.payment_failed)
From the documentation:
If you are using webhooks, Stripe will wait one hour after they have all succeeded to attempt to pay the invoice; the only exception here is on the first invoice, which gets created and paid immediately when you subscribe a customer to a plan.
So, this means, invoice.created event will also fire next month.
Stripe will then wait an hour before charging the customers card, then firing charge.succeeded (if the charge is succeeded) or charge.failed (if the charge fails)
The hour wait is to allow invoice items to be added to the invoice if you so wish.
See my answer on this question for more information on why you might need to do that...
You would want to watch for a invoice.payment_succeeded event:
Have a look at: https://stripe.com/docs/api#event_types
This event is triggered any time an invoice is paid. A charge.succeeded event also occurs, but the difference is that invoice.payment_succeeded only occurs for payments on invoices, whereas charge.succeeded also occurs for standalone charges.
There is no event distinction between the first charge on a subscription and a recurring one, although the logic you store on your end (e.g., when the subscription was created, when it
expires, etc.) should help you disambiguate them.
Related
I have a client offering free products and they want to bypass customers having to enter customer details but they rely on the transaction id to record orders from their QAD system connected via WooCommerce API.
My goal is to set a default transaction ID in the case that there is not one set from stripe or other payment methods. More specifically setting a transaction id to "FREESAMPLE" when someone checks out using Cash on Delivery.
This one is a little more complex and I didn't find anything on stack exchange for resolving this question.
I set up the payment method Cash on Delivery to only be available when the cart total is Zero dollars.
This worked, but Now they are not getting the order information in their QAD system due to not having the transaction ID.
I looked up the documentation for WooCommerce API about utilizing the transaction id field in orders and didn't find much in the way of setting a default option or an option for a payment method that doesn't generate a transaction ID from a third party payment gateway like Stripe.
I have a high traffic WooCommerce Subscriptions site. I need to call a 3rd party API every time an order is generated and send information about the customer (if they still have an active subscription or not), this includes new and renewal orders.
For this purpose I choose the "woocommerce_subscription_status_updated" hook. It fires every time a subscription changes state, lets me know what the current state is and then I can send that info to the API.
The issue is that when a subscription gets renewed successfully, this hook is fired twice (once if the renewal fails). Subscription get changed from "active" to "on-hold" and then "on-hold" to "active" (this is how Wc Subscription renews a subscription).
The API gets called twice even though it did not needed to. What would be a better way to implement this?
I think you can set a CRON with storing the last checked date time and get a list of data whose status are updated since the last time and call an API in some interval through CRON if it works for you.
So I'm using an API to receive payment notifications,
I don't really care what's in the notification I just want paypal to notify the API when a payment has been made and execute my own code.
So first off is this even going to work?
I put the URL for the API in the Instant Payment Notification under my account settings. My account is still new because I sent a test payment and it didn't work, do held payments not notify the IPN?
If the payment is held within PayPal it will notify via IPN, yes. You will be able to see such held payments by logging into www.paypal.com and viewing the activity. There will also be a "pendingreason" value in the IPN, to notify you of why it is held.
Note that if at transaction time a "notify_url" is set by the integration (many older shopping carts do this), that URL will be used in place of whatever is set at the account level in www.paypal.com. Whatever was set at transaction time has precedence.
--
If an order is "on hold" by your shopping cart (pending payment), PayPal will not send any notification as nothing has taken place within its system (except maybe a checkout attempt that was clicked on but not finished for whatever reason)
I want to test my application's handling of webhook events from stripe when a subscription payment has been made (or failed). Here is what I've tried so far:
Set up a new subscription
Update user's credit card to be the one that can be added to an account, but will fail to actually be charged
Change the trial end date to be in one second
Wait a few seconds expecting the webhook to be sent
However, According to the documentation:
If you have configured webhooks, the invoice will wait until one hour after the last webhook is successfully sent (or the last webhook times out after failing).
One hour is a long time to wait, since I am trying to do this as part of an automated integration test suite.
One suggestion (from IRC) is to fake out the webhook request, so that my integration test sends the event, instead of Stripe sending it. However, since Stripe doesn't include any sort of HMAC in the webhooks, I can't trust the data in the payload. So, my application just takes the event ID from the webhook payload and fetches the event from the Stripe API:
If security is a concern, or if it's important to confirm that Stripe sent the webhook, you should only use the ID sent in your webhook and should request the remaining details from the API directly.
This will obviously not work if I am trying to inject fake events for my test (by design).
What are the best practices for testing this sort of scenario?
It seems there isn't a perfect way to do this. As suggested by #koopajah in a comment, I added a configuration value in my application that will disable fetching the event from Stripe, and instead just trust the event data in the webhook. This allows me to test my flow in almost the same way as it would work on production, since the event data in the webhook and the event fetched from Stripe are identical (assuming it is an authentic webhook request :)
Unless/until Stripe includes an HMAC signature in the webhook request to authenticate that it came from them, I think this is the best way to solve the problem.
One hour is a long time to wait, since I am trying to do this as part of an automated integration test suite.
You can shorten the wait by going to the invoice and selecting the "Charge customer" button, as shown below.
I have an asp.net application
The User can purchase items and/or upgrade an existing service. I use PayPal to handle payments.
When the order is placed I put the order details into a table as a record. I also do this so that if the User revisits my page I check a flag in that table to tell them whether payment has been received.
If not received then I display a message on my web page telling them they have requested and upgrade and that we are currently waiting for payment.
I also disable any future purchases for that User so that they do not upgrade twice (or more).
Now, it occurs to me that when the User is redirected to PayPal to make that purchase that a payment could fail or they could close the web page.
In that case then the User would not be able to ever upgrade unless they send me a support email.
What is best practice? Wait for a time period to elapse and if no payment then allow User to try again or stick with the support email route?
If it is best to wait for a period of time what is an acceptable period of time to wait for?
I am using the post back of Form values method to imitate payment to PayPal:
https://www.paypal.com/cgi-bin/webscr
What you can do.
Each time the user is ready to leave your page and move to paypal to pay, you create
Clone of their order
A new unique ID connected with that cloned order.
So, if one order if fail, at any time the user come back is find a new set "Order"+"Unique ID". With that 2 elements can make a final payment.
You may end up with two or tree or more cloned orders, but from my experience because this is what I really do, is rare, and its safe for your customer and you.
Also please note that paypal is accept only one unique id for each order. If one ID is fail, then you must create a new one anyway.
The unique id you send to paypal go to the invoice parametre.
The manual for all parametres is this pdf - PayPal Payments Standard Intergration Guide... and there are more pdf for paypal...