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.
Related
So i have following situation going:
User makes purchase request (And transaction is sent to google
analytics with 0 value).
After some time Operator confirms purchase (And transaction is updated and revenue is set to according amount)
This works like a charm so far. The Problem is the fact that when updated transaction is sent, it also, somehow, updates where transaction was sent from. for ex... if referral user made a purchase, before update i can see transactions next to referral users but after update it disappears from there since operator is not referral user. this is just one downside. Next being the fact that website has two domains, but one actual website, so if user made a transaction from domain2, after operator updates transaction, i cant see it in the "domain2 view" since operators log in "domain1".
so, how can i make it so that only revenue updates and it doesnt touch anything else?
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 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.
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...
With a paypal like system it's easy to track the transaction with the auto-return setting and ?utm_nooverride=1 parameter, since after the payment the user is redirected back to the site.
But what if we have a system with delayed payments?
User adds to cart, checkout, but he just pays for the transaction tomorrow.
Is it possible to track a transaction like this?
I'm able to store some vars and pass them to the callback function to later use.
just as a sidenote here, in your case, there is no need to use 'utm_nooverride=1', since usually it wont take more than 30 minutes to checkout on the paying service site, the visit will be maintained when the visitor returns to your site.
About your question, unfortunately there is no way to achieve this kind of transaction, because the transaction is a visit-related tracking, and when the user comes back tomorrow to pay, it will be a new visit.
Also, as probably the user doesn´t really have to go back to your site to finish his purchase, I don´t really see the possibility.
Augusto Roselli
Web Analytics - dp6