We are using Nets Easy with custom code (not Vendr checkout). If the buyer closes the connection before they enter the confirmation page, but after they made the payment, the order will not be completed.
We have made a function that picks up the order, get the information that lacks from Nets to fill in the missing data in the order and set it to new and authorized.
We are using the same classes and functions as we do when we are creating the orders in the first place.
The problem is that when we pick up these half created orders we can not do anything with them. The order hav been initialized with the InitializeTransaction, so they have orderId and orderlines.
What I want to do is adding all the information from Nets (buyer and transaction) and set the order to new and autherized.
I am considering making a new copy of them and start from new, but is there a easy fix where we do not get duplicates of the order?
In regards to your issue though, it sounds like you need to integrate a webhook to trigger order finalization rather than using the redirect to the continue URL as the trigger as this is exactly what webhooks were introduced for in order to ensure orders are finalized in the background regardless as to what the user does on the front end.
Take a look at Bjarne's repo as that should be fully configured to handle webhooks as order finalization.
It depends to what extent you need to edit an order. You should be able to populate transaction info and properties which I think it all you need.
I'd need to know more about what exactly you are trying to do in code, and what exact errors you are hitting.
Matt
PS I've been speaking with Bjarne a lot during his development and I can well believe webhooks weren't present before. Bjarne has been pushing them to get what we believe to be minimum requirements for this type of stuff so I'm sure Bjarne may have had a hand in getting this stuff sorted with them.
sorry about the late reply.
As you wrote, all I need to do is populate properties and update transaction. For some reason it does not save the changes. I get the order, I can add properties to it, the order looks fine, we save the order and when we get the order from db trough orderservice the changes are gone. No errors during save, but off course error when we tries to finalize and the order does not contain the correct information.
It's like the order is held by transaction control, but then we should have some sort of error during debug.
I also look at the order in db and cant see anything wrong.
I add a bit of the code that is working trough checkout, but that is not saving when I pick up the order.
using (var uow = _unitOfWorkProvider.Create())
{
StringBuilder strBuild = new StringBuilder();
var order = _orderService.GetOrder(orderId)
.AsWritable(uow);
if (string.IsNullOrEmpty(details.Payment.Consumer.PrivatePerson.FirstName) && string.IsNullOrEmpty(details.Payment.Consumer.Company.ContactDetails.FirstName))
strBuild.Append("FirstName missing from Nets /n");
order.SetProperty(Constants.Properties.Customer.FirstNamePropertyAlias, details.Payment.Consumer.PrivatePerson.FirstName ?? details.Payment.Consumer.Company.ContactDetails.FirstName);
order.SetProperty("shippingFirstName", details.Payment.Consumer.PrivatePerson.FirstName ?? details.Payment.Consumer.Company.ContactDetails.FirstName);
order.SetProperty("billingFirstName", details.Payment.Consumer.PrivatePerson.FirstName ?? details.Payment.Consumer.Company.ContactDetails.FirstName);
if (string.IsNullOrEmpty(details.Payment.Consumer.PrivatePerson.LastName) && string.IsNullOrEmpty(details.Payment.Consumer.Company.ContactDetails.LastName))
strBuild.Append("LastName missing from Nets /n");
order.SetProperty(Constants.Properties.Customer.LastNamePropertyAlias, details.Payment.Consumer.PrivatePerson.LastName ?? details.Payment.Consumer.Company.ContactDetails.LastName);
order.SetProperty("shippingLastName", details.Payment.Consumer.PrivatePerson.LastName ?? details.Payment.Consumer.Company.ContactDetails.LastName);
order.SetProperty("billingLastName", details.Payment.Consumer.PrivatePerson.LastName ?? details.Payment.Consumer.Company.ContactDetails.LastName);
if (string.IsNullOrEmpty(details.Payment.Consumer.PrivatePerson.Email) && string.IsNullOrEmpty(details.Payment.Consumer.Company.ContactDetails.Email))
strBuild.Append("Email missing from Nets /n");
order.SetProperty(Constants.Properties.Customer.EmailPropertyAlias, details.Payment.Consumer.PrivatePerson.Email ?? details.Payment.Consumer.Company.ContactDetails.Email);
order.SetProperty("email", details.Payment.Consumer.PrivatePerson.Email);
if (string.IsNullOrEmpty(details.Payment.Consumer.PrivatePerson.PhoneNumber.Number) && string.IsNullOrEmpty(details.Payment.Consumer.Company.ContactDetails.PhoneNumber.Number))
strBuild.Append("Phone missing from Nets /n");
order.SetProperty("shippingTelephone", details.Payment.Consumer.PrivatePerson.PhoneNumber.Number ?? details.Payment.Consumer.Company.ContactDetails.PhoneNumber.Number);
order.SetProperty("billingTelephone", details.Payment.Consumer.PrivatePerson.PhoneNumber.Number ?? details.Payment.Consumer.Company.ContactDetails.PhoneNumber.Number);
order.SetProperty("prefix", details.Payment.Consumer.PrivatePerson.PhoneNumber.Prefix ?? details.Payment.Consumer.Company.ContactDetails.PhoneNumber.Prefix);
if (string.IsNullOrEmpty(details.Payment.Consumer.ShippingAddress.AddressLine1))
strBuild.Append("AddressLine1 missing from Nets /n");
order.SetProperty("shippingAddressLine1", details.Payment.Consumer.ShippingAddress.AddressLine1);
order.SetProperty("billingAddressLine1", details.Payment.Consumer.ShippingAddress.AddressLine1);
order.SetProperty("shippingAddressLine2", details.Payment.Consumer.ShippingAddress.AddressLine2);
order.SetProperty("billingAddressLine2", details.Payment.Consumer.ShippingAddress.AddressLine2);
if (string.IsNullOrEmpty(details.Payment.Consumer.ShippingAddress.PostalCode))
strBuild.Append("PostalCode missing from Nets /n");
order.SetProperty("shippingZipCode", details.Payment.Consumer.ShippingAddress.PostalCode);
order.SetProperty("billingZipCode", details.Payment.Consumer.ShippingAddress.PostalCode);
if (string.IsNullOrEmpty(details.Payment.Consumer.ShippingAddress.City))
strBuild.Append("City missing from Nets /n");
order.SetProperty("shippingCity", details.Payment.Consumer.ShippingAddress.City);
order.SetProperty("billingCity", details.Payment.Consumer.ShippingAddress.City);
if (string.IsNullOrEmpty(details.Payment.Consumer.ShippingAddress.Country))
strBuild.Append("Country missing from Nets /n");
order.SetProperty("shippingCountry", details.Payment.Consumer.ShippingAddress.Country);
order.SetProperty("shippingSameAsBilling", "1");
if (user != null)
{
order.SetProperty("accountNumber", user.MemberPersonalia.AccountNumber.ToString());
order.SetProperty("userEmail", user.MemberPersonalia.EmailAddress?.ToString());
order.AssignToCustomer(user.MemberPersonalia.AccountNumber.ToString());
}
//Paymentsdetails
order.SetProperty("paymentType", details.Payment.PaymentDetails.PaymentType);
order.SetProperty("paymentMethod", details.Payment.PaymentDetails.PaymentMethod);
order.SetProperty("maskedPan", details.Payment.PaymentDetails.CardDetails.MaskedPan);
order.SetProperty("expiryDate", details.Payment.PaymentDetails.CardDetails.ExpiryDate);
//Invoicedetails
order.SetProperty("invoiceDueDate", details.Payment.PaymentDetails.InvoiceDetails?.DueDate ?? "");
order.SetProperty("invoiceNumber", details.Payment.PaymentDetails.InvoiceDetails?.InvoiceNumber ?? "");
order.SetProperty("invoiceOcr", details.Payment.PaymentDetails.InvoiceDetails?.Ocr ?? "");
order.SetProperty("invoicePdfLink", details.Payment.PaymentDetails.InvoiceDetails?.PdfLink ?? "");
//Companydetails
order.SetProperty("merchantReference", details.Payment.Consumer.Company?.MerchantReference ?? "");
order.SetProperty("companyName", details.Payment.Consumer.Company?.Name ?? "");
order.SetProperty("registrationNumber", details.Payment.Consumer.Company?.RegistrationNumber ?? "");
if (string.IsNullOrEmpty(strBuild.ToString()))
order.SetOrderStatus(new Guid(NEW_STATUS_ID));
else
order.SetOrderStatus(new Guid(ERROR_STATUS_ID));
_orderService.SaveOrder(order);
uow.Complete();
Ok, and is that the only code that runs at that time which modifies that order? Also, when you say you checked the database, does the database contain the properties + values, but it's just not returning them when you request the order?
Thats the only code that add properties, we also finalize the order and set the order to new and authorized.
All the changes i do to the order are not stored in db. I have tried to update status and stuff just to see if I could do anything, but nothing is saved.
When I run the updatorder (the code), the order contains 21 properties, but when I do a request to db I only get one and that is the one I add when creating the order - paymentId from Nets
Ok, well, depending on when these things occur and whether any can run at the same time, you may have a situation where you are fetching the order, then have 2 things making changes to it and so the final update to the order is potentially overwriting the previous order with the order state it has from a previous snapshot.
Effectively you can think of calling AsWritable as taking a snapshot of the order and allowing edits, and then the order isn't written back to the store services cache until is wrapping uow is complete.
You may need to check the order of these things to make sure there isn't anything being run at the same time.
Alternatively, you may need to make sure you don't have any errors and that you are always calling uow.Complete() on all open units of work, including in event handlers etc, as any incomplete uow will revert all changes. Quite often if it silently doesn't update, it's often an incomplete uow that's the problem.
Cant edit order
We are using Nets Easy with custom code (not Vendr checkout). If the buyer closes the connection before they enter the confirmation page, but after they made the payment, the order will not be completed.
We have made a function that picks up the order, get the information that lacks from Nets to fill in the missing data in the order and set it to new and authorized.
We are using the same classes and functions as we do when we are creating the orders in the first place.
The problem is that when we pick up these half created orders we can not do anything with them. The order hav been initialized with the InitializeTransaction, so they have orderId and orderlines. What I want to do is adding all the information from Nets (buyer and transaction) and set the order to new and autherized.
I am considering making a new copy of them and start from new, but is there a easy fix where we do not get duplicates of the order?
Hi Dag,
You might want to take a look at this branch from Bjarne https://github.com/bjarnef/vendr-payment-provider-dibs/tree/feature/dibs-easy who is pretty close to having a working Nets Easy payment provider. Maybe you can offer to help test this one over writing a custom one?
In regards to your issue though, it sounds like you need to integrate a webhook to trigger order finalization rather than using the redirect to the continue URL as the trigger as this is exactly what webhooks were introduced for in order to ensure orders are finalized in the background regardless as to what the user does on the front end.
Take a look at Bjarne's repo as that should be fully configured to handle webhooks as order finalization.
Hope this helps
Matt
Thanks for your fast reply Matt!
You are correct in that we should have used the webhooks, but at the time we created it the webhooks did not function... (true story)
I will most likely rewrite the payment solution, but until then I need to pick up those orders.
Is the best way to create new orders and copy from the half-finnished?
It depends to what extent you need to edit an order. You should be able to populate transaction info and properties which I think it all you need.
I'd need to know more about what exactly you are trying to do in code, and what exact errors you are hitting.
Matt
PS I've been speaking with Bjarne a lot during his development and I can well believe webhooks weren't present before. Bjarne has been pushing them to get what we believe to be minimum requirements for this type of stuff so I'm sure Bjarne may have had a hand in getting this stuff sorted with them.
Thanks again Matt,
sorry about the late reply. As you wrote, all I need to do is populate properties and update transaction. For some reason it does not save the changes. I get the order, I can add properties to it, the order looks fine, we save the order and when we get the order from db trough orderservice the changes are gone. No errors during save, but off course error when we tries to finalize and the order does not contain the correct information.
It's like the order is held by transaction control, but then we should have some sort of error during debug.
I also look at the order in db and cant see anything wrong.
I add a bit of the code that is working trough checkout, but that is not saving when I pick up the order.
BTW the details in the code is from NETS
What version of Vendr / Umbraco are you using?
Umbraco version 8.11.1 Vendr v1.4.2
Thanks
Ok, and is that the only code that runs at that time which modifies that order? Also, when you say you checked the database, does the database contain the properties + values, but it's just not returning them when you request the order?
Thats the only code that add properties, we also finalize the order and set the order to new and authorized.
All the changes i do to the order are not stored in db. I have tried to update status and stuff just to see if I could do anything, but nothing is saved.
When I run the updatorder (the code), the order contains 21 properties, but when I do a request to db I only get one and that is the one I add when creating the order - paymentId from Nets
When you say
What is this code? and how is that code run in relation to these properties being set?
We have three steps where we adjust the order:
first we initialize the order:
Then we update the order and set the status to new, the code I posted earlier
Last we Finalize:
When the customer leaves before the redirect, only the initialize part is completed.
Ok, well, depending on when these things occur and whether any can run at the same time, you may have a situation where you are fetching the order, then have 2 things making changes to it and so the final update to the order is potentially overwriting the previous order with the order state it has from a previous snapshot.
Effectively you can think of calling
AsWritable
as taking a snapshot of the order and allowing edits, and then the order isn't written back to the store services cache until is wrappinguow
is complete.You may need to check the order of these things to make sure there isn't anything being run at the same time.
Alternatively, you may need to make sure you don't have any errors and that you are always calling
uow.Complete()
on all open units of work, including in event handlers etc, as any incomplete uow will revert all changes. Quite often if it silently doesn't update, it's often an incomplete uow that's the problem.Matt
is working on a reply...