Hi there,
I have a payment gateway that consists of two "callbacks":
1. The initial callback for the user using GetReturnValuesFromUrl
2. A call back service that is called minutes or hours later with an up-to-date status of the payment.
I am having some troubles finding out when to update which value, and when to use UpdateGateway result and so on. Here are the options that seem to be related to the order and its status:
order.Complete
order.Errors
order.Gateway.SetOrderComplete
order.GatewayPaymentStatus
order.GatewayResult
order.GatewayTransactionProblems
order.TransactionAmount
order.TransactionNumber
order.TransactionPayGatewayCode
order.TransactionStatus
order.TransactionType
order.TransactionValue
order.UpdateGatewayResult
Is there any guidance on when to set / call what? The API sample doesn't go into this. Additionally, I used Reflector to dig into the existing V1 gateways, and all seem to be doinf something else ;-)
Currently, I have this:
1. User call backpage (e.g. step 6)
order.TransactionType = transactionTypeFromRequest;
order.TransactionNumber = transactioNumberFromRequest;
order.Save();
order.GatewayResult = aBunchOfresultXml;
order.TransactionNumber = transactioNumberFromRequest;
order.UpdateGatewayResult(isComplete);
2. The call back page:
order.TransactionNumber = item.pspReference;
order.PaymentMethod = item.paymentMethod;
order.StateID = AppConfiguration.OrderStates.OrderStateBetaald; // "OS2" for Paid or OS3 for cancelled
order.GatewayResult = someXmlFromTheCallback;
order.TransactionStatus = ConvertAdyenCodeToDwCode(item.eventCode); // Something like "Paid" or "Rejected"
order.Complete = isPaid;
order.GatewayTransactionProblems.Clear(); // Need to do this to clear previous errors
order.GatewayPaymentStatus = ConvertAdyenCodeToDwCode(item.eventCode); // Something like "Paid" or "Rejected"
order.UpdateGatewayResult(true);
order.Save();
As you can see, there's some duplication between the two, and I am overwriting stuff like TransactionNumber and GatewayResult.
Can anyone make some sense of this and tell me / show me when to set and use what? Most of the API documentation for the properties seem to be automatically generated and contain the quite useless "Gets or sets the Property Name" comments... ;-)
Kind regards,
Imar
Developer forum
E-mail notifications
Payment Gateways (V1) and results
Posted on 10/11/2010 12:06:20
Replies
Jeppe Eriksson Agger
Posted on 12/11/2010 10:21:50
Hi Imar
I would recommend not setting some values until you have the final value to set. IE. TransactionNumber should be set on your second callback page. You can set it on the first callback if you want to avoid an extra line in the log file saying "Warning: No transaction ID is set on this order.", but that would be the extend of the usefulness of setting it here.
In fact unless the first callback contains any information you don't get from the second callback, I don't see any reason to save anything there (other that what the Cart saves automatically, that is ;)).
This will of course mean, that the order is not set Complete at this point. But if I understand you correctly, then the order isn't really complete until you receive the second callback anyway, right?
Please let me know if this was of any help to you--or if I completely misunderstood your question ;-)
- Jeppe
I would recommend not setting some values until you have the final value to set. IE. TransactionNumber should be set on your second callback page. You can set it on the first callback if you want to avoid an extra line in the log file saying "Warning: No transaction ID is set on this order.", but that would be the extend of the usefulness of setting it here.
In fact unless the first callback contains any information you don't get from the second callback, I don't see any reason to save anything there (other that what the Cart saves automatically, that is ;)).
This will of course mean, that the order is not set Complete at this point. But if I understand you correctly, then the order isn't really complete until you receive the second callback anyway, right?
Please let me know if this was of any help to you--or if I completely misunderstood your question ;-)
- Jeppe
Posted on 12/11/2010 11:40:40
Hi Jeppe,
Thanks for your reply. Yes, it's helpful and you understood my question ;-)
>> You can set it on the first callback if you want to avoid an extra line in the log file saying "Warning: No transaction ID is set on this order.",
Yes, but I can imagine it's also useful to have this in case the call backs fails, so you have at least a reference number to look into the payment gateway's site, no?
>> But if I understand you correctly, then the order isn't really complete until you receive the second callback anyway, right?
Yes, correct. However, if I am not mistaken, "Complete" in Dynamicweb simply means "visited step 6", right? So it would be set to Complete by Dynamicweb unless I change that in GetReturnValuesFromUrl, is that right?
Does my second set of property setters for the Callback page (see code in first post) look right and complete to you?
Thanks,
Imar
Thanks for your reply. Yes, it's helpful and you understood my question ;-)
>> You can set it on the first callback if you want to avoid an extra line in the log file saying "Warning: No transaction ID is set on this order.",
Yes, but I can imagine it's also useful to have this in case the call backs fails, so you have at least a reference number to look into the payment gateway's site, no?
>> But if I understand you correctly, then the order isn't really complete until you receive the second callback anyway, right?
Yes, correct. However, if I am not mistaken, "Complete" in Dynamicweb simply means "visited step 6", right? So it would be set to Complete by Dynamicweb unless I change that in GetReturnValuesFromUrl, is that right?
Does my second set of property setters for the Callback page (see code in first post) look right and complete to you?
Thanks,
Imar
Jeppe Eriksson Agger
Posted on 15/11/2010 12:06:10
A couple of good points there :-)
Fallback/redundancy is always nice when dealing with something as fragile as server to server callbacks. But whether it's necessary is really down to the administration part of the gateway. Most, if not all, of the gateways I've implemented have the orders registered by order id and not transaction id, but I guess it comes down to preference and how the gateways administration is constructed. No real harm done if you save the TransactionNumber on both callbacks--is what I'm trying to say, I think ;-)
For the standard order flow and gateways, you are correct. The order property "Complete" is used to indicate that Step 6 was visited. But since your flow is different and not really standard, you can use it to indicate, that the second callback has been received. But you can do this in a number of ways: Custom field, Complete property, Order state (which you do now, if I'm not mistaken), and probably other ways as well. The downside to using "Complete" differently than standard is that you'll end up with incomplete (red) orders in eCom if the second callback fails.
You mention that you use the GetReturnValuesFromUrl method. This indicates to me, that your gateway is not set up to be a Callback gateway, ie. a gateway, that handles much more itself. If you reflect through our Quickpay3 gateway you'll see, that it's much more independant and doesn't use GetReturnValuesFromUrl at all. The way to do that is to implement the IGatewayCallback interface. However this might be a talk for another day :-)
With regard to the last property setters, they look fine to me. The only extra thing we do in our code is adjust stock. This is done in the method SetOrderComplete in the GatewayProvider base class.
- Jeppe
Fallback/redundancy is always nice when dealing with something as fragile as server to server callbacks. But whether it's necessary is really down to the administration part of the gateway. Most, if not all, of the gateways I've implemented have the orders registered by order id and not transaction id, but I guess it comes down to preference and how the gateways administration is constructed. No real harm done if you save the TransactionNumber on both callbacks--is what I'm trying to say, I think ;-)
For the standard order flow and gateways, you are correct. The order property "Complete" is used to indicate that Step 6 was visited. But since your flow is different and not really standard, you can use it to indicate, that the second callback has been received. But you can do this in a number of ways: Custom field, Complete property, Order state (which you do now, if I'm not mistaken), and probably other ways as well. The downside to using "Complete" differently than standard is that you'll end up with incomplete (red) orders in eCom if the second callback fails.
You mention that you use the GetReturnValuesFromUrl method. This indicates to me, that your gateway is not set up to be a Callback gateway, ie. a gateway, that handles much more itself. If you reflect through our Quickpay3 gateway you'll see, that it's much more independant and doesn't use GetReturnValuesFromUrl at all. The way to do that is to implement the IGatewayCallback interface. However this might be a talk for another day :-)
With regard to the last property setters, they look fine to me. The only extra thing we do in our code is adjust stock. This is done in the method SetOrderComplete in the GatewayProvider base class.
- Jeppe
Posted on 15/11/2010 16:28:35
>> The way to do that is to implement the IGatewayCallback interface. However this might be a talk for another day :-)
Would love to hear or read more about that. I am basing my current code on the Dutch gateways we helped develop more than a year ago.
>> The only extra thing we do in our code is adjust stock. This is done in the method SetOrderComplete in the GatewayProvider base class.
So that means I need to do this myself? This isn't handled in Step 6 automatically? Good to know, or we'll have stock forever..... ;-)
Imar
Posted on 16/11/2010 14:00:17
Hi Jeppe,
Another thing I just ran into. I tried this:
order.Gateway.SetOrderComplete(order, item.pspReference, order.GatewayResult);
but the code crashes because the Gateway property is null. I am constructing the order like this:
Order order = new Order(orderid);
Is there something I need to do to populate the Gateway property?
Imar
Another thing I just ran into. I tried this:
order.Gateway.SetOrderComplete(order, item.pspReference, order.GatewayResult);
but the code crashes because the Gateway property is null. I am constructing the order like this:
Order order = new Order(orderid);
Is there something I need to do to populate the Gateway property?
Imar
Posted on 16/11/2010 14:34:15
Right, did some debugging and reflecting and found this in the Payment class's constructor:
if ((payment.ID == IDStr) && ((Context.LanguageID == "") || (payment.LanguageID == Context.LanguageID)))
In other words, the Payment doesn't get filled when the context languages differ which is likely to happen as I have three different languages.
Can I simply solve this by setting the following at the top of the Web Service that handles the callback and updates the order to synchronize the current language with the one from the order?
Dynamicweb.eCommerce.Common.Context.LanguageID = order.LanguageID;
Is there a need to reset this again later?
Thanks,
Imar
if ((payment.ID == IDStr) && ((Context.LanguageID == "") || (payment.LanguageID == Context.LanguageID)))
In other words, the Payment doesn't get filled when the context languages differ which is likely to happen as I have three different languages.
Can I simply solve this by setting the following at the top of the Web Service that handles the callback and updates the order to synchronize the current language with the one from the order?
Dynamicweb.eCommerce.Common.Context.LanguageID = order.LanguageID;
Is there a need to reset this again later?
Thanks,
Imar
Jeppe Eriksson Agger
Posted on 17/11/2010 10:15:42
Hi Imar
Sorry for the late answer, but I was away yesterday.
I'm sad to say this, but there's no documentation on the IGatewayCallback interface. The best I can do, at the moment, is send you a couple of implementations. Let me know, if you need this.
I would like to clarify a statement from earlier. For gateways, that don't implement the IGatewayCallback, stock is adjusted automatically in step 6 (CartCatch.LastStepInOrder). IGatewayCallback gateways need to handle this internally. The idea behind implementing the interface is to let the gateways handle the callback, fully. This has advantages and disadvantages. Biggest advantage, and the reason for it, is the possibility to control the callback. Biggest disadvantage is that you need to update stuff on the order yourself.
With regard to the web service and setting language, then I don't see an issue with this since it runs in its own session, and therefore doesn't influence anything else, and the Gateway property is lazy loaded. You also don't need to reset it again due to this.
- Jeppe
Sorry for the late answer, but I was away yesterday.
I'm sad to say this, but there's no documentation on the IGatewayCallback interface. The best I can do, at the moment, is send you a couple of implementations. Let me know, if you need this.
I would like to clarify a statement from earlier. For gateways, that don't implement the IGatewayCallback, stock is adjusted automatically in step 6 (CartCatch.LastStepInOrder). IGatewayCallback gateways need to handle this internally. The idea behind implementing the interface is to let the gateways handle the callback, fully. This has advantages and disadvantages. Biggest advantage, and the reason for it, is the possibility to control the callback. Biggest disadvantage is that you need to update stuff on the order yourself.
With regard to the web service and setting language, then I don't see an issue with this since it runs in its own session, and therefore doesn't influence anything else, and the Gateway property is lazy loaded. You also don't need to reset it again due to this.
- Jeppe
Posted on 17/11/2010 10:27:40
Hi Jeppe,
Yes, I would love to see some implemenations. Can you e-mail them to me (or attach them to this post if they are considered "public").
With regard to the stock: yep, figured out that it's done in LastStepInOrder: http://engage.dynamicweb-cms.com/default.aspx?ID=5&action=ShowThread&ThreadID=2289
Right now, I am setting a flag in OrderComplete. If the flag isn't there in the callback, I subtract the stock myself in the gateway callback.
I made some progress with setting the context language and updating the order, and it all seems to work fine so far.
Thanks,
Imar
Yes, I would love to see some implemenations. Can you e-mail them to me (or attach them to this post if they are considered "public").
With regard to the stock: yep, figured out that it's done in LastStepInOrder: http://engage.dynamicweb-cms.com/default.aspx?ID=5&action=ShowThread&ThreadID=2289
Right now, I am setting a flag in OrderComplete. If the flag isn't there in the callback, I subtract the stock myself in the gateway callback.
I made some progress with setting the context language and updating the order, and it all seems to work fine so far.
Thanks,
Imar
Jeppe Eriksson Agger
Posted on 17/11/2010 10:52:59
I've sent an email to you, however I'm not sure you got it. Are you still using the dynamicweb.nl-address? If not, you can send me an email at jea@dynamicweb.dk and I'll reply to that instead.
- Jeppe
- Jeppe
Posted on 17/11/2010 11:00:02
Yes, I received your message; thanks!
Imar
Imar
You must be logged in to post in the forum