I am struggling with some concepts which I cannot find the answer to in the docs:
Being a long-time user of TeaCommerce, there we had the concept of an order being Finalized, which meant the order was completely payed. The OrderFinalized event we used there, meant that the order was finished and post-processing can start (e-mails, etc.).
In Vendr, I am struggling a bit with this concept. Because, for instance, how do I handle the following concepts:
Scenario 1. User creates orders, starts payment process and cancels payment.
What is the recommended return value of the ProcessCallback for this kind of situation? If I send a:
The order is being Finalized, shown in the back-end, and the Vendr Finalized Event is being called. But why? It's not entirely clear which payment status triggers which events.
Scenario 2. User creates orders, starts payment process, complete payment and redirects to thank you page. Payment is fulfilled by the payment gateway in the background on a later time (and thus sending several different statuses in between).
In short my main questions are:
Which Payment statuses should I use and which events are triggered when?
Can I use the IsFinalized option to confirm an order is completely finalized, payed and ready for post-processing?
If you are familiar with TC then it shouldn't be too much of a leap to get to grips with Vendr's payment provider API as really all we've tried to do is to simplify it and merge some things that we felt weren't necessary, that said if it's not clear then we probably need to look at improving our docs a little and maybe a guide on porting from TC could be useful.
Ok, so the key difference really in Vendr vs TC is that we have just a single ProcessCallback method which is used for any communication to the payment provider, compared to TC which had a ProcessCallback method which was used to finalize and order and a ProcessRequest method which was used for arbitrary communication. The issue I saw in TC's implementation was that things weren't often that clear cut and there are a number of providers that mix these two things up, so in Vendr we just decided to make one method for all provider communication.
Because the callback method can be used for multiple purposes then, the important thing to know about the CallbackResult object is that all of it's properties are optional and you should only return values for a given property when necessary.
TransactionInfo - Should only be populated and returned when you want to finalize an order with the given payment status. If your transaction isn't finalized due to being canceled or the likes, then don't return transaction info. Returning transaction info is a terminal state and once populated the order is finalized and can't be changed.
MetaData - This allows you to pass meta data from the payment provider to be persisted in the order object as property values. We expose this collection to allow these properties to be persisted once, rather than the old TC way of resaving an order within the payment provider. In Vendr payment providers you should never need to resave the order. Any data that was passed in meta data will be available from the order.Properties collection.
HttpResponse - Is useful when you are using the callback method for for client side communication with the provider and also for things like webhook handlers where you may need to return a JSON response or a HTTP status code. By default this will just be a plain OK status, but if you do need to pass data or change the response status, you can populate this to do so.
So with this in mind, in answer to your questions
Scenario 1: In this case, you aren't finalizing your order so you would not set a transaction info. If you wanted to perform the redirect, you could do it with a HttpResponse but the better approach would be to use the cancelUrl that is passed in to the GenerateForm method as this will handle returning the order to a modifiable state.
Scenario 2: For this you would use the ProcessCallback method as a webhook handler and so you will likely need to return a HTTP status to the 3rd party to show that the request was successful. At the same time, you can pass info back in the TransactionInfo object as the order updates and Vendr will automatically finalize the order on the first request, and then update the transaction info on any additional requests to that method, so for example, your first request might finalize the order and set the payment status to authorized, but then a subsequent request may actually set the payment status to captured.
Regarding sending of emails, we send the order receipt email as part of the order finalizing event, however if there are things that are reliant on payment actually being cancelled you may want to instead listen for PaymentStatusChange event and watch for it changing to Captured and then perform your task. We do this ourselves on the actual Vendr store only generating and sending licenses when the payment becomes captured.
I hope this helps clarify things, and hopefully you can see how we've tried to merge and simplify what was a little cumbersome in TC.
Yea, in some places where things are likely to change at the same time we do bundle them into the same notification so this is probably one of those situations.
Thanks for raising this though as it shows we should probably try and make that clearer in some way 🤔
I think these 3 information blocks about the entities TransactionInfo, MetaData and HttpResponse would be a very good addition to the docs.
The part that was a bit unclear for me, was that I am able to send a CallBackResult without a TransactionInfo and that sending any TransactionInfo triggers a finalization of on order, independent of what the PaymentStatus for that TransactionInfo is in the CallBackResult.
Two final questions about this:
We currently utilizing the "FinalizeAtContinueUrl" property in our payment provider, but what is the exact consequence of settings this property to true?
Is it possible to send a CallBackResult without a TransactionInfo, but only metadata, to save some state of the payment process in the order? For instance when the payment is being checked, we receive a intermediate state from our payment provider. We don't want to finalize the order at that time, because the order is not payed yet, but we would like to save this status info in the order (cart).
In TC we would be able to see the carts in the back-end, and our client could track the state of the payment using that cart. When the payment is really finished and accepted, we finalized the order and the Order was created.
In Vendr however, in the back-office we cannot see the carts. This makes this process a little different. I am looking for a best practice to handle these kind of situations.
Cool, well I'll see what I can do about making that all clearer in the docs 👍
RE your additional questions
FinalizeAtContinueUrl is a setting which when set to true means that redirects to the continue URL (which is where you are normally sent after a successful payment at the payment gateway portal) will trigger the ProcessCallback method at the same time such that your finalization logic can be triggered at that point. This is generally used mostly by payment gateways that only support notifying the initiator via a redirect of successful payment, ie, redirecting to the continue page means payment was successful, however if payments are confirmed async via webhook, then you'd want to set this to false so that only an explicit call to the ProcessCallback request via the callbackUrl will trigger the finalization logic. So when this is false, redirecting to the continue url will just take you to the continue URL location only and won't attempt to finalize the order at that point.
Yes you can return just a meta data response in order to store data in the order and then finalize the order on another request. RE draft orders, we don't currently support this yet however it is in our 2021 plans having come 3rd in our roadmap survey we did at the beginning of the year https://vendr.net/blog/vendr-2021-roadmap-survey-the-results/ Unfortunately we don't have a fixed date for this, but this will give you an idea of it's priority. In the meantime, the best solution might be to create a dashboard for those orders, or inject a custom tree node into the stores tree with custom UI to process them (there is a good example of this in the Vendr Reviews community contributed add-on https://github.com/vendrcontrib/vendr-reviews).
Payment process
Hi,
I am struggling with some concepts which I cannot find the answer to in the docs:
Being a long-time user of TeaCommerce, there we had the concept of an order being Finalized, which meant the order was completely payed. The OrderFinalized event we used there, meant that the order was finished and post-processing can start (e-mails, etc.).
In Vendr, I am struggling a bit with this concept. Because, for instance, how do I handle the following concepts:
Scenario 1. User creates orders, starts payment process and cancels payment.
What is the recommended return value of the ProcessCallback for this kind of situation? If I send a:
The order is being Finalized, shown in the back-end, and the Vendr Finalized Event is being called. But why? It's not entirely clear which payment status triggers which events.
Scenario 2. User creates orders, starts payment process, complete payment and redirects to thank you page. Payment is fulfilled by the payment gateway in the background on a later time (and thus sending several different statuses in between).
In short my main questions are:
Hello Rody,
You need to call
order.InitializeTransaction()
which will assign the order an order number and put it in an initialized state.Then you can call the Finalize method to mark the transaction as complete once you’ve captured payment.
If you are wanting to bypass the checkout process and move an order to be finalized without taking payment then you need to call
Hey Rody,
If you are familiar with TC then it shouldn't be too much of a leap to get to grips with Vendr's payment provider API as really all we've tried to do is to simplify it and merge some things that we felt weren't necessary, that said if it's not clear then we probably need to look at improving our docs a little and maybe a guide on porting from TC could be useful.
Ok, so the key difference really in Vendr vs TC is that we have just a single
ProcessCallback
method which is used for any communication to the payment provider, compared to TC which had aProcessCallback
method which was used to finalize and order and aProcessRequest
method which was used for arbitrary communication. The issue I saw in TC's implementation was that things weren't often that clear cut and there are a number of providers that mix these two things up, so in Vendr we just decided to make one method for all provider communication.Because the callback method can be used for multiple purposes then, the important thing to know about the
CallbackResult
object is that all of it's properties are optional and you should only return values for a given property when necessary.order.Properties
collection.So with this in mind, in answer to your questions
Scenario 1: In this case, you aren't finalizing your order so you would not set a transaction info. If you wanted to perform the redirect, you could do it with a
HttpResponse
but the better approach would be to use thecancelUrl
that is passed in to theGenerateForm
method as this will handle returning the order to a modifiable state.Scenario 2: For this you would use the
ProcessCallback
method as a webhook handler and so you will likely need to return a HTTP status to the 3rd party to show that the request was successful. At the same time, you can pass info back in theTransactionInfo
object as the order updates and Vendr will automatically finalize the order on the first request, and then update the transaction info on any additional requests to that method, so for example, your first request might finalize the order and set the payment status to authorized, but then a subsequent request may actually set the payment status to captured.Regarding sending of emails, we send the order receipt email as part of the order finalizing event, however if there are things that are reliant on payment actually being cancelled you may want to instead listen for PaymentStatusChange event and watch for it changing to Captured and then perform your task. We do this ourselves on the actual Vendr store only generating and sending licenses when the payment becomes captured.
I hope this helps clarify things, and hopefully you can see how we've tried to merge and simplify what was a little cumbersome in TC.
Matt
Hi, I can't find notifications for PaymentStatus change on a Order. It seems that isn't under Vendr.Core.Events.Notification.
How I can register to the specified PaymentStatusChanged event?
Thank you for the help
Payment status changes fire the
OrderTransactionUpdated
so it's this you'll want to register forThank you, I wasn't thinking that is was related to TransactionInfo of PaymentProvider so I wasn't considering it.
Yea, in some places where things are likely to change at the same time we do bundle them into the same notification so this is probably one of those situations.
Thanks for raising this though as it shows we should probably try and make that clearer in some way 🤔
Hi Matt,
Thanks for the clear response.
I think these 3 information blocks about the entities TransactionInfo, MetaData and HttpResponse would be a very good addition to the docs. The part that was a bit unclear for me, was that I am able to send a CallBackResult without a TransactionInfo and that sending any TransactionInfo triggers a finalization of on order, independent of what the PaymentStatus for that TransactionInfo is in the CallBackResult.
Two final questions about this:
We currently utilizing the "FinalizeAtContinueUrl" property in our payment provider, but what is the exact consequence of settings this property to true?
Is it possible to send a CallBackResult without a TransactionInfo, but only metadata, to save some state of the payment process in the order? For instance when the payment is being checked, we receive a intermediate state from our payment provider. We don't want to finalize the order at that time, because the order is not payed yet, but we would like to save this status info in the order (cart). In TC we would be able to see the carts in the back-end, and our client could track the state of the payment using that cart. When the payment is really finished and accepted, we finalized the order and the Order was created. In Vendr however, in the back-office we cannot see the carts. This makes this process a little different. I am looking for a best practice to handle these kind of situations.
Hey Rody,
Cool, well I'll see what I can do about making that all clearer in the docs 👍
RE your additional questions
FinalizeAtContinueUrl
is a setting which when set to true means that redirects to the continue URL (which is where you are normally sent after a successful payment at the payment gateway portal) will trigger theProcessCallback
method at the same time such that your finalization logic can be triggered at that point. This is generally used mostly by payment gateways that only support notifying the initiator via a redirect of successful payment, ie, redirecting to the continue page means payment was successful, however if payments are confirmed async via webhook, then you'd want to set this to false so that only an explicit call to theProcessCallback
request via the callbackUrl will trigger the finalization logic. So when this is false, redirecting to the continue url will just take you to the continue URL location only and won't attempt to finalize the order at that point.Yes you can return just a meta data response in order to store data in the order and then finalize the order on another request. RE draft orders, we don't currently support this yet however it is in our 2021 plans having come 3rd in our roadmap survey we did at the beginning of the year https://vendr.net/blog/vendr-2021-roadmap-survey-the-results/ Unfortunately we don't have a fixed date for this, but this will give you an idea of it's priority. In the meantime, the best solution might be to create a dashboard for those orders, or inject a custom tree node into the stores tree with custom UI to process them (there is a good example of this in the Vendr Reviews community contributed add-on https://github.com/vendrcontrib/vendr-reviews).
Hope this helps
Matt
is working on a reply...