Developer forum

Forum » Integration » Order Capture (through Scheduled Tasks)

Order Capture (through Scheduled Tasks)

Søren Jakobsen
Reply

Hi Community,

is it possible through a Scheduled Task to do order capture? or do we need to custom code it?

DW version 9.10.13.

Best regards Søren


Replies

 
Nicolai Pedersen
Reply

Hi Søren

There is no specific scheduled task for it as it is now. But I have justed asked if someone knows if this is possible. Captures are possible using i.e. URLs from external systems, but not sure it can just capture all...

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Soren and Nicolai,

 

We have implemented something similar for the US market. The key thing is to take a specific order state (configured on the Scheduled task), for example, an order is fulfilled in the ERP and the state changes to "Ready for Capture", then the scheduled task picks up on all orders that are in that order state, captures the amount and then changes the state to "Completed" or "Ready for invoice" (some other state that the ERP will then know what to do next, if anything).

 

Our version still accounts for a few other things because it's supports a log of legacy stuff so it does too much. I can share the code if needed, and I'm attaching a screendump of the parameters but essentially:

  • A - We determine how we want to get orders
    • By an order custom field (legacy)
    • By Order State/Status
    • DoCapturePayment (specific order custom field that our integration team uses)
  • B - We batch import orders and invoices and do payment on invoices. You would not need this
  • C - Lessons learned settings. Don't capture any order that may have been completed very very soon and only get a batch or orders at the time
  • D - What do to after Complete is done

 

Behind the scenes we also skip failed captures, only consider orders where the payment method allows for capture and the amount is not captured and some other basic validations.

 

Our goal with user order states is that we have order notifications that can be triggered easilly, so it's flexible if/when we need them.

 

Hope this helps,

Nuno Aguiar

2021-10-07_10-46-56.jpg
 
Søren Jakobsen
Reply

Thanks Nuno,

I really appriciated your reply. Could you share the code?

beste regards Søren

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Soren,

 

Sure, check the attachement. Let me know if you have any questions.

 

Best Regards,

Nuno Aguiar

 
Søren Jakobsen
Reply

Hi Nuno,

Thanks. I'm not able to download the .cs file. Can you either zip it or send it to my email sbj@easyflow.dk?

 
Nicolai Pedersen
Reply

And some of our own code:

using Dynamicweb.Ecommerce;
using Dynamicweb.Ecommerce.Orders
using Dynamicweb.Ecommerce.Orders.Gateways;

var order = Order.GetOrderById(orderid);
var result = new PaymentOperationResultModel();

            if (order != null)
            {
                var manager = OrderManager.GetFor(order);
                try
                {
                    var captureResult = amount == 0 ? manager.Capture() : manager.PartialCapture(Converter.ToInt64(amount * 100), false);

                    result.Status = captureResult.State.ToString();
                    result.Message = captureResult.Message;
                }
                catch (Exception e)
                {
                    result.Status = "Failed";
                    result.Message = $"Unhandled internal exception: {e.Message}";
                }
            }
            else
            {
                result.Status = "Failed";
                result.Message = "Order not found for specified order id.";
            }
            return result;


public class PaymentOperationResultModel
    {
        /// <summary>
        /// The status of operation
        /// </summary>
        public string Status;
        /// <summary>
        /// The extended message about result or error description.
        /// </summary>
        public string Message;

    }
 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Soren,

 

Attached as a zip. That way others can benefit as well if needed.

 

Happy coding.

Nuno Aguiar

 
Søren Jakobsen
Reply

Thanks Nuno, much appreciated.

I have started the implementation of the code and have a couple of questions:

line 7: "Ecommerce.LiveIntegration.XmlRendering" do I need that reference?

line 385: "UrlHandler.Instance.SetEnvironmentFromOrder(order);" is SetEnvironmentFromOrder a custom method?

line 390: "LiveIntegrationSubmitType.CaptureTask" is that a custom enum?

line 546: "options.Add(state.Id, Helpers.GetStateLabel(state));" is GetStateLabel a custom method?

If the above is custom coded could you provide the code?

Thanks, Søren

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Soren,

 

This is a pretty old code, so I had to look up a few things:

 

  • line 7: Yes, because it's where we're storing the enum  LiveIntegrationSubmitType. https://www.screencast.com/t/4gUshbZM0RNL
    This is used in line 390
    (this enum should live elsewhere)
     
  • line 385: I don't know if it's custom to be honest. We branched off from LiveIntegrationV2 (provided by DK) almost as soon as it was released some 4 years ago and have been adding a lot of our features on top of it.
    This one in particular I don't believe it is. I see some logic because of multiple endpoints being configured
    I'm attaching the code for the UrlHandler.cs file where that lives
     
  • line 390: I believe it is. Enum shown above
     
  • line 546: Yes. Here's what it does
    public static string GetStateLabel(OrderState state)
    {
        var orderFlow = OrderFlow.GetAllFlows().FirstOrDefault(of => of.ID.Equals(state.OrderFlowId));
    
        if (orderFlow == null)
        {
            return state.Name;
        }
    
        return string.Concat(state.Name, " (", orderFlow.Name, ")");
    
    

 

Let me know if you need additional help.

 

Best Regards,

Nuno Aguiar

 
Anders Ebdrup
Anders Ebdrup
Reply

Dear Nuno & Nicolai,

 

I am also working on a solution with capturing in 9.13.6, but cannot get any of the suggestions to work.

We are stuck with this stacktrace:

System.ArgumentException: Value does not fall within the expected range.
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   at System.Web.Hosting.IIS7WorkerRequest.GetServerVariableInternal(String name)
   at System.Web.HttpRequestWrapper.get_UserHostAddress()
   at Dynamicweb.Ecommerce.Cart.CheckoutHandler.LogErrorWithName(Order order, Exception ex, String name, String message, Object[] args)
   at Dynamicweb.Ecommerce.CheckoutHandlers.QuickPayPaymentWindow.QuickPayPaymentWindow.Capture(Order order, Int64 amount, Boolean final)
   at Dynamicweb.Ecommerce.Orders.OrderService.Capture(Order order, Int64 amount, Boolean final)
   at NAVIntegration.ScheduledTasks.CaptureOrders.Run() in D:\Repos\NAVIntegration\ScheduledTasks\CaptureOrders.cs:line 37

 

Any ideas on this one?

 

Best regards,

Anders

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Anders,

 

Not really. Looks like you're trying to capture payments with QuickPay and I never worked with it. But it seems the error message is related to some error related to the response from QuickPay.

 

Have you tried to capture payments from the backend? And could it be related to a specific order/transaction?

 

Maybe changing your scheduled task to do 1 order at a time, and if it fails, you try to capture that order normally. Assuming you are using the API, the error would be the same, thus proving the problem is with the checkout handler (credentials or some bug). If you can do it from the backend, then it might be your code.

 

Best Regards,

Nuno Aguiar

 
Anders Ebdrup
Anders Ebdrup
Reply

Dear Nuno,

 

I can capture through the webapi and the administration, but not through the api in a scheduled task. Do you know if the code needs a user?

 

Best regards, Anders

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

HI Anders,

 

Odd. With the checkout handlers we have experience on, there is no need for users. We simply get a CaptureResult enum, which generated by Dynamicweb as a result of a capture.

 

And looking at the source code of QuickPayPaymentWindow, there isn't anything special about it. It's just implementing the normal capture methods (no user required). Somebody from Dynamicweb would have to help you more. Maybe if you post your scheduled task code I could help more.

 

BR,

Nuno Aguiar

 
Anders Ebdrup
Anders Ebdrup
Reply

Dear Nuno,

 

I have now tracked it down and the problem is caused by this one: "Context.Current.Request.UserHostAddress" throwing the exception in "LogErrorWithName" and "LogEventWithName". So the capture is actually working but throws an exception because of the logging part.

I hope that this can be fixed?

 

Best regrads, Anders

 

 

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Anders,

 

Hopefully. I guess someone from Dynamicweb would have to respond to this. I know you addressed Nicolai as well, but he hasn't responded yet. Maybe someone else will in the meanwhile.

 

Nuno Aguiar

 
Anders Ebdrup
Anders Ebdrup
Reply

Dear Nuno,

 

Yes, and I can see that the issue is introduced in this commit: https://dev.azure.com/dynamicwebsoftware/_git/Dynamicweb/commit/e2b57879870e03cc98aa5f5c95eed28fc89d1377?refName=refs%2Fheads%2Fmain&_a=compare&path=%2Fsrc%2F77%20-%20Ecommerce%2FDynamicweb.Ecommerce%2FCart%2FCheckoutHandler.cs. So you are right, that we need someone from DW to fix the issue.

 

Best regards, Anders

 
Oleg Rodionov Dynamicweb Employee
Oleg Rodionov
Reply

Hi all,

I've created new task 8858 against the issue reporder by Anders above. Thanks.

BR, Oleg QA 

 
Kristian Kirkholt Dynamicweb Employee
Kristian Kirkholt
Reply

Hi All

Checkout Bug #8858 has been fixed in Dynamicweb version 9.13.13 and 9.14.1 
Get this version from the download section https://doc.dynamicweb.dk/downloads/dynamicweb-9

Sorry for any inconvenience this may have caused

Kind Regards
Care Support 
Kristian Kirkholt 

 

You must be logged in to post in the forum