With the new VAT rules in EU we are trying to set VAT depending on what country user selects in Klarna.
Given the docs from Klarna:
Note: If you also provide a country in the billing address object, this will override the sent in purchase_country of the session.
- Allow the consumer to change the shipping country by enabling all your shipping countries on the checkout order.
- Use the address_update callback to keep shipping methods and prices updated.
- It is mandatory to use the country_change callback with this setup. When you receive a callback you need to consider to…
3a Update the language, we recommend to match the billing address country if we support it.
3b Update the currency to a local one if you are configured for it to get a core-country experience. Or update it to a non-local one to offer card. - Set the purchase_country to a best guess of the consumers country.
Done
-
I have added all my countries to shipping and billing properties when
UpdateDataSentToKlarna
is run. -
I have updated the call in
address_update
to check thecheckoutOrderData?.BillingCheckoutAddress?.Country
from Klarna and then update the purchase country (in 4).
Issue here is how can I update the VAT for the order?
Since this is an update from Klarna servers there is no_cartAccessor
.
I tried using ILitiumKcoOrder by fetching the order there and then set orderCarrier.CountryId to the new country and then run CalculateOrderTotals but the VAT is incorrect.
I also tried to manully set VAT but that does not seem to work. -
This never seems to trigger (checked the logs in klarna but nothing, only
address_update
// KlarnaPaymentConfig.cs
[HttpPost]
public ActionResult AddressUpdate(string accountId, string transactionNumber, [FromJsonBody] CheckoutOrder checkoutOrderData)
{
_logger.LogDebug("Address update started accountId {accountId} transactionNumber {transactionNumber}.", accountId, transactionNumber);
var klarnaCheckout = CreateKlarnaCheckoutApi(accountId);
var checkoutOrder = klarnaCheckout.FetchKcoOrder(transactionNumber) as LitiumKcoOrder;;
var result = _paymentConfigv3.AddressUpdate(checkoutOrder, ref checkoutOrderData);
if (result.Updated)
klarnaCheckout.UpdateKcoOrderOnDisc(result.CheckoutOrder.OrderCarrier);
_logger.LogDebug("Completed.");
//if the correct Json result is not written to Klarna, the checkout snippet will show and error!.
return Content(_jsonSerializer.Serialize(checkoutOrderData));
}
// KlarnaPaymentConfigV3.cs
public (bool Updated, ILitiumKcoOrder CheckoutOrder) AddressUpdate(ILitiumKcoOrder checkoutOrder, ref CheckoutOrder checkoutOrderData)
{
// If the campaigns depend on address location, re-calculate the cart, after updating delivery addresses.
// if you recalculate order totals, the checkoutOrderData must contain the correct order rows and order total values.
var checkoutCountry = checkoutOrderData?.BillingCheckoutAddress?.Country;
if (string.IsNullOrWhiteSpace(checkoutCountry))
return (false, null);
var orderCarrier = checkoutOrder.OrderCarrier;
if (orderCarrier == null)
return (false, null);
var country = _countryService.Get(checkoutCountry);
orderCarrier.CountryID = country.SystemId;
orderCarrier.OverallVatPercentage = 0;
orderCarrier.OrderRows.ForEach(x =>
{
x.TotalVATAmount = 0;
x.VATPercentage = 0;
});
_moduleECommerce.Orders.CalculateOrderTotals(orderCarrier, SecurityToken.CurrentSecurityToken);
_moduleECommerce.Orders.CalculatePaymentInfoAmounts(orderCarrier, SecurityToken.CurrentSecurityToken);
checkoutOrderData.PurchaseCountry = checkoutCountry;
checkoutOrderData.OrderAmount = Convert.ToInt32(checkoutOrder.OrderCarrier.GrandTotal * 100);
checkoutOrderData.OrderTaxAmount = Convert.ToInt32(checkoutOrder.OrderCarrier.TotalVAT * 100);
foreach (var orderLine in checkoutOrderData.OrderLines)
{
orderLine.TaxRate = 0;
orderLine.TotalTaxAmount = 0;
}
return (true, checkoutOrder);
}
private ExecutePaymentArgs CreatePaymentArgs(OrderCarrier order, string private ExecutePaymentArgs CreatePaymentArgs(OrderCarrier order, string paymentAccountId)
{
var tlsUsage = _routeRequestLookupInfoAccessor.RouteRequestLookupInfo.IsSecureConnection;
if (!tlsUsage)
{
this.Log().Trace("Klarna Checkout Validation is disabled. To enable the validate you need to use https on the checkout page.");
}
// Get the fallback delivery methods that will be send to KSS
var ids = _requestModelAccessor.RequestModel.ChannelModel?.Channel?.CountryLinks?.FirstOrDefault(x => x.CountrySystemId == order.CountryID)?.DeliveryMethodSystemIds ?? Enumerable.Empty<Guid>();
var allDeliveryMethods = _moduleECommerce.DeliveryMethods.GetAll();
var kssDeliveryMethod = allDeliveryMethods.FirstOrDefault(x => ConstantsAndKeys.KSSDeliveryMethodName.Equals(x.Name, StringComparison.OrdinalIgnoreCase));
var kssDeliveryMethodId = kssDeliveryMethod != null && ids.Contains(kssDeliveryMethod.ID) ? kssDeliveryMethod.ID : Guid.Empty;
var currentDeliveryMethods = kssDeliveryMethodId == Guid.Empty ?
ids.Select(x => allDeliveryMethods.First(y => y.ID == x)) :
(ids.Count() == 1 ? allDeliveryMethods.Where(x => x.ID == kssDeliveryMethodId) : ids.Where(z => z != kssDeliveryMethodId).Select(x => allDeliveryMethods.First(y => y.ID == x)));
var deliveryMethodIds = currentDeliveryMethods.Select(z => z.ID).ToList();
var checkoutFlowInfo = _cartAccessor.Cart.CheckoutFlowInfo;
checkoutFlowInfo.ExecutePaymentMode = ExecutePaymentMode.Reserve;
checkoutFlowInfo.RequireConsumerConfirm = false;
var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
var checkoutPage = _requestModelAccessor.RequestModel.WebsiteModel.Fields.GetValue<PointerPageItem>(AcceleratorWebsiteFieldNameConstants.CheckoutPage);
var checkoutPageUrl = GetAbsolutePageUrl(checkoutPage);
var checkoutPageEntity = checkoutPage.EntitySystemId.MapTo<PageModel>();
var termsAndConditionPage = checkoutPageEntity.GetValue<PointerPageItem>(CheckoutPageFieldNameConstants.TermsAndConditionsPage);
var termsAndConditionPageUrl = GetAbsolutePageUrl(termsAndConditionPage);
var proxy = ConfigurationManager.AppSettings["Proxy"] as string ?? string.Empty;
var channelUri = new Uri(_urlService.GetUrl(_requestModelAccessor.RequestModel.ChannelModel.Channel, new ChannelUrlArgs() { AbsoluteUrl = true }));
var confirmationUrl = new Uri(channelUri, urlHelper.Action("Confirmation", "KlarnaPayment", null, Uri.UriSchemeHttps));
var validateUrl = new Uri(channelUri, urlHelper.Action("Validate", "KlarnaPayment", null, Uri.UriSchemeHttps)).ReplaceHost(proxy);
var pushUrl = new Uri(channelUri, urlHelper.Action("PushNotification", "KlarnaPayment", null, Uri.UriSchemeHttps)).ReplaceHost(proxy);
var updateAddressUrl = new Uri(channelUri, urlHelper.Action("AddressUpdate", "KlarnaPayment", null, Uri.UriSchemeHttps)).ReplaceHost(proxy);
var shippingOptionUpdateUrl = new Uri(channelUri, urlHelper.Action("ShippingOptionUpdate", "KlarnaPayment", null, Uri.UriSchemeHttps)).ReplaceHost(proxy);
var countryChangeUrl = new Uri(channelUri, urlHelper.Action("CountryChange", "KlarnaPayment", null, Uri.UriSchemeHttps)).ReplaceHost(proxy);
checkoutFlowInfo.SetValue(ConstantsAndKeys.TermsUrlKey, termsAndConditionPageUrl);
checkoutFlowInfo.SetValue(ConstantsAndKeys.CheckoutUrlKey, checkoutPageUrl);
checkoutFlowInfo.SetValue(ConstantsAndKeys.ConfirmationUrlKey, confirmationUrl.AbsoluteUri);
checkoutFlowInfo.SetValue(ConstantsAndKeys.PushUrlKey, pushUrl.AbsoluteUri);
checkoutFlowInfo.SetValue(ConstantsAndKeys.ShippingOptionUpdateUrlKey, shippingOptionUpdateUrl.AbsoluteUri);
checkoutFlowInfo.SetValue(ConstantsAndKeys.ValidationUrlKey, validateUrl.AbsoluteUri);
checkoutFlowInfo.SetValue(ConstantsAndKeys.DeliveryMethodIds, deliveryMethodIds);
checkoutFlowInfo.SetValue(ConstantsAndKeys.CountryChangeUrlKey, countryChangeUrl.AbsoluteUri);
checkoutFlowInfo.SetValue(ConstantsAndKeys.AddressUpdateUrlKey, updateAddressUrl.AbsoluteUri);
return new KlarnaPaymentArgsCreator().CreatePaymentArgs(checkoutFlowInfo);
}
CreateOrder
Does not seam to add countryChanged callback, could be why it does not call anything.
"merchant_urls": {
"terms": "https://casall.localtest.me/en-eu/",
"checkout": "https://casall.localtest.me/en-eu/checkout?accountId=KCOV3_EU&transactionNumber={checkout.order.id}",
"confirmation": "https://casall.localtest.me/site.axd/KlarnaPayment/Confirmation?accountId=KCOV3_EU&transactionNumber={checkout.order.id}",
"push": "https://945f543732a7.ngrok.io/site.axd/KlarnaPayment/PushNotification?accountId=KCOV3_EU&transactionNumber={checkout.order.id}",
"validation": "https://945f543732a7.ngrok.io/site.axd/KlarnaPayment/Validate?accountId=KCOV3_EU&transactionNumber={checkout.order.id}",
"shipping_option_update": "https://945f543732a7.ngrok.io/site.axd/KlarnaPayment/ShippingOptionUpdate?accountId=KCOV3_EU&transactionNumber={checkout.order.id}",
"address_update": "https://945f543732a7.ngrok.io/site.axd/KlarnaPayment/AddressUpdate?accountId=KCOV3_EU&transactionNumber={checkout.order.id}",
"notification": "https://casall.localtest.me/PaymentProviderResult.axd/StaticCallback/KlarnaV3?accountId=KCOV3_EU&transactionNumber={checkout.order.id}"
},
Address update
{
"purchase_country": "be",
"purchase_currency": "EUR",
"locale": "en-GB",
"billing_address": {
"given_name": "Artur",
"family_name": "O",
"email": "mail@gmail.com",
"street_address": "Kerklosstraat 161",
"postal_code": "9700",
"city": "Bevere",
"phone": "+32 491 77 20 61",
"country": "be"
},
"shipping_address": {
"given_name": "Artur",
"family_name": "Olech",
"email": "mail@gmail.com",
"street_address": "Kerklosstraat 161",
"postal_code": "9700",
"city": "Bevere",
"phone": "+32 491 77 20 61",
"country": "be"
},
"order_amount": 6892,
"order_tax_amount": 0,
"order_lines": [
{
"type": "physical",
"reference": "21124901038",
"name": "Scuba Zip Bikini Top - Black",
"quantity": 1,
"quantity_unit": "nos",
"unit_price": 7990,
"tax_rate": 0,
"total_amount": 7990,
"total_discount_amount": 0,
"total_tax_amount": 0,
"shipping_attributes": {
"weight": 110
}
},
{
"type": "shipping_fee",
"reference": "0",
"name": "KSS",
"quantity": 1,
"quantity_unit": "nos",
"unit_price": 500,
"tax_rate": 0,
"total_amount": 500,
"total_discount_amount": 0,
"total_tax_amount": 0
}
],
"customer": {},
"selected_shipping_option": {
"id": "a805b491-5db1-4b3a-9221-4b30026489ac",
"name": "UPS Standard (Non Docs)",
"price": 500,
"tax_amount": 0,
"tax_rate": 0,
"preselected": false,
"shipping_method": "Home",
"delivery_details": {
"carrier": "ups",
"class": "standard"
}
},
"recurring": false
}
Litium version: 7.6.1