diff --git a/Klarna.Rest/Klarna.Rest.Core.Tests/Data/CheckoutOrderKss.json b/Klarna.Rest/Klarna.Rest.Core.Tests/Data/CheckoutOrderKss.json new file mode 100644 index 0000000..5d93e29 --- /dev/null +++ b/Klarna.Rest/Klarna.Rest.Core.Tests/Data/CheckoutOrderKss.json @@ -0,0 +1,138 @@ +{ + "order_id": "b16fd3f5-054e-6c70-90a8-b10748db28ad", + "status": "checkout_incomplete", + "purchase_country": "se", + "purchase_currency": "SEK", + "locale": "en-US", + "billing_address": { + "given_name": "Test", + "family_name": "User", + "email": "utku.sayin@litium.com", + "street_address": "Langelandsgatan 31", + "postal_code": "16443", + "city": "Kista", + "phone": "+46 70 973 42 32", + "country": "se" + }, + "customer": { + "gender": "male" + }, + "shipping_address": { + "given_name": "Test", + "family_name": "User", + "email": "utku.sayin@litium.com", + "street_address": "Langelandsgatan 31", + "postal_code": "16443", + "city": "Kista", + "phone": "+46 70 973 42 32", + "country": "se" + }, + "order_amount": 20400, + "order_tax_amount": 4080, + "order_lines": [ + { + "type": "physical", + "reference": "637163166670779736-02423006_M", + "name": "Square scarfe", + "quantity": 1, + "quantity_unit": "nos", + "unit_price": 19900, + "tax_rate": 2500, + "total_amount": 19900, + "total_discount_amount": 0, + "total_tax_amount": 3980 + }, + { + "type": "shipping_fee", + "reference": "0", + "name": "KSS", + "quantity": 1, + "quantity_unit": "nos", + "unit_price": 500, + "tax_rate": 2500, + "total_amount": 500, + "total_discount_amount": 0, + "total_tax_amount": 100 + } + ], + "merchant_urls": { + "terms": "http://Example.localtest.me/checkout/terms-and-condition", + "checkout": "http://Example.localtest.me/checkout?accountId=KCOV3_SE&transactionNumber={checkout.order.id}", + "confirmation": "https://example.com/site.axd/KlarnaPayment/Confirmation?accountId=KCOV3_SE&transactionNumber={checkout.order.id}", + "push": "https://example.com/site.axd/KlarnaPayment/PushNotification?accountId=KCOV3_SE&transactionNumber={checkout.order.id}", + "validation": "https://example.com/site.axd/KlarnaPayment/Validate?accountId=KCOV3_SE&transactionNumber={checkout.order.id}", + "shipping_option_update": "https://example.com/site.axd/KlarnaPayment/ShippingOptionUpdate?accountId=KCOV3_SE&transactionNumber={checkout.order.id}", + "address_update": "https://example.com/site.axd/KlarnaPayment/AddressUpdate?accountId=KCOV3_SE&transactionNumber={checkout.order.id}", + "notification": "http://Example.localtest.me/PaymentProviderResult.axd/StaticCallback/KlarnaV3?accountId=KCOV3_SE&transactionNumber={checkout.order.id}" + }, + "html_snippet": "
\n
\n \n

Oops.

\n

It looks like an important part of the checkout experience failed to load and we are unable to offer you a way to pay right now.

\n

Please refresh the page to try again. If this isn't the first time you've seen this message then there may be a more permanent error and you should contact customer service at Klarna.com.

\n
\n \n \n
", + "started_at": "2020-05-27T18:59:49Z", + "last_modified_at": "2020-05-27T18:59:54Z", + "options": { + "allow_separate_shipping_address": true, + "color_button": "#ff69b4", + "date_of_birth_mandatory": true, + "title_mandatory": false, + "national_identification_number_mandatory": false, + "require_validate_callback_success": false, + "show_subtotal_detail": false + }, + "external_payment_methods": [ + { + "name": "Cash on delivery", + "redirect_url": "https://example.com/site.axd/KlarnaPayment/ChangePaymentMethod?PaymentProvider=DirectPay&PaymentMethod=DirectPayment&RedirectUrl=%2Fcheckout.PlaceOrderDirect", + "fee": 0 + } + ], + "external_checkouts": [], + "shipping_options": [ + { + "id": "4c208f95-f693-45c4-ace8-3a15ecd5916b", + "name": "Express package", + "description": "", + "price": 3000, + "tax_amount": 600, + "tax_rate": 2500, + "preselected": false, + "shipping_method": "Own", + "delivery_details": {}, + "tms_reference": "PickupStore" + }, + { + "id": "9f29ec8f-c0a8-4f34-9377-be99c8e22d5a", + "name": "Standard package", + "description": "", + "price": 2000, + "tax_amount": 400, + "tax_rate": 2500, + "preselected": false, + "shipping_method": "Own", + "delivery_details": {}, + "tms_reference": "PickupStore" + } + ], + "recurring": false, + "selected_shipping_option": { + "id": "id-1000", + "name": "Pickup Box", + "price": 500, + "tax_amount": 0, + "tax_rate": 0, + "preselected": false, + "shipping_method": "BoxUnreg", + "delivery_details": { + "carrier": "instabox", + "class": "economy", + "pickup_location": { + "id": "loc-2", + "name": "Coop Loet", + "address": { + "street_address": "Storgatan 59", + "postal_code": "97232", + "city": "Luleå", + "country": "se" + } + } + } + } +} \ No newline at end of file diff --git a/Klarna.Rest/Klarna.Rest.Core.Tests/Klarna.Rest.Core.Tests.csproj b/Klarna.Rest/Klarna.Rest.Core.Tests/Klarna.Rest.Core.Tests.csproj index f1920d5..fcf5a70 100644 --- a/Klarna.Rest/Klarna.Rest.Core.Tests/Klarna.Rest.Core.Tests.csproj +++ b/Klarna.Rest/Klarna.Rest.Core.Tests/Klarna.Rest.Core.Tests.csproj @@ -46,6 +46,9 @@ Always + + Always + Always diff --git a/Klarna.Rest/Klarna.Rest.Core.Tests/Models/CheckoutOrderTest.cs b/Klarna.Rest/Klarna.Rest.Core.Tests/Models/CheckoutOrderTest.cs index ffe86f7..120f0d5 100644 --- a/Klarna.Rest/Klarna.Rest.Core.Tests/Models/CheckoutOrderTest.cs +++ b/Klarna.Rest/Klarna.Rest.Core.Tests/Models/CheckoutOrderTest.cs @@ -26,6 +26,27 @@ public void CanDeserialize() } } + public class CheckoutOrderKssTest + { + [Fact] + public void CanReadJson() + { + var json = File.ReadAllText(Path.Combine(System.Environment.CurrentDirectory, "Data", "CheckoutOrderKss.json")); + Assert.True(!string.IsNullOrEmpty(json)); + } + + [Fact] + public void CanDeserialize() + { + var json = File.ReadAllText(Path.Combine(System.Environment.CurrentDirectory, "Data", "CheckoutOrderKss.json")); + var checkoutOrder = JsonConvert.DeserializeObject(json); + Assert.Equal("b16fd3f5-054e-6c70-90a8-b10748db28ad", checkoutOrder.OrderId); + Assert.Equal("id-1000", checkoutOrder.SelectedShippingOption.Id); + Assert.Equal("loc-2", checkoutOrder.SelectedShippingOption.DeliveryDetails.PickupLocation.Id); + Assert.Equal("Storgatan 59", checkoutOrder.SelectedShippingOption.DeliveryDetails.PickupLocation.Address.StreetAddress); + } + } + public class CallbackAddressUpdateTest { [Fact] diff --git a/Klarna.Rest/Klarna.Rest.Core/Model/ShippingCarrierProduct.cs b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingCarrierProduct.cs new file mode 100644 index 0000000..2bac5ae --- /dev/null +++ b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingCarrierProduct.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace Klarna.Rest.Core.Model +{ + /// + /// Shipping carrier Product + /// + public class ShippingCarrierProduct + { + /// + /// Carrier product name + /// + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } + /// + /// Carrier product identifier + /// + [JsonProperty(PropertyName = "identifier")] + public string Identifier { get; set; } + } +} \ No newline at end of file diff --git a/Klarna.Rest/Klarna.Rest.Core/Model/ShippingDeliveryDetails.cs b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingDeliveryDetails.cs new file mode 100644 index 0000000..3e8871b --- /dev/null +++ b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingDeliveryDetails.cs @@ -0,0 +1,38 @@ +using Newtonsoft.Json; + +namespace Klarna.Rest.Core.Model +{ + /// + /// DeliveryDetails. + /// + public class ShippingDeliveryDetails + { + /// + /// Carrier product name. + /// + [JsonProperty(PropertyName = "carrier")] + public string Carrier { get; set; } + /// + /// Type of shipping class. + /// + [JsonProperty(PropertyName = "class")] + public string Class { get; set; } + /// + /// Upstream carrier product + /// + [JsonProperty(PropertyName = "product")] + public ShippingCarrierProduct Product { get; set; } + + /// + /// The selected location for this shipping + /// + [JsonProperty(PropertyName = "pickup_location")] + public ShippingPickupLocation PickupLocation { get; set; } + + /// + /// The selected timeslot for this shipping + /// + [JsonProperty(PropertyName = "timeslot")] + public ShippingTimeslot Timeslot { get; set; } + } +} \ No newline at end of file diff --git a/Klarna.Rest/Klarna.Rest.Core/Model/ShippingOption.cs b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingOption.cs index 6170924..dff5708 100644 --- a/Klarna.Rest/Klarna.Rest.Core/Model/ShippingOption.cs +++ b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingOption.cs @@ -60,5 +60,17 @@ public class ShippingOption [JsonConverter(typeof(StringEnumConverter))] [JsonProperty(PropertyName = "shipping_method")] public ShippingMethod ShippingMethod { get; set; } + + /// + /// The delivery details for this shipping option + /// + [JsonProperty(PropertyName = "delivery_details")] + public ShippingDeliveryDetails DeliveryDetails { get; set; } + + /// + /// TMS reference. Required to map completed orders to shipments reserved in TMS. + /// + [JsonProperty(PropertyName = "tms_reference")] + public string TmsReference { get; set; } } } \ No newline at end of file diff --git a/Klarna.Rest/Klarna.Rest.Core/Model/ShippingPickupLocation.cs b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingPickupLocation.cs new file mode 100644 index 0000000..0741d32 --- /dev/null +++ b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingPickupLocation.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; + +namespace Klarna.Rest.Core.Model +{ + /// + /// Pickup location + /// + public class ShippingPickupLocation + { + /// + /// Id. + /// + /// Required + [JsonProperty(PropertyName = "id")] + public string Id { get; set; } + /// + /// Name. + /// + /// Reqiured + [JsonProperty(PropertyName = "name")] + public string Name { get; set; } + + /// + /// Pickup location address + /// + [JsonProperty(PropertyName = "address")] + public CheckoutAddressInfo Address { get; set; } + } +} \ No newline at end of file diff --git a/Klarna.Rest/Klarna.Rest.Core/Model/ShippingTimeslot.cs b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingTimeslot.cs new file mode 100644 index 0000000..7841402 --- /dev/null +++ b/Klarna.Rest/Klarna.Rest.Core/Model/ShippingTimeslot.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; + +namespace Klarna.Rest.Core.Model +{ + /// + /// Timeslot + /// + public class ShippingTimeslot + { + /// + /// Id. + /// + /// Required + [JsonProperty(PropertyName = "id")] + public string Id { get; set; } + + /// + /// Start time. + /// + /// Required + [JsonProperty(PropertyName = "start")] + public string Start { get; set; } + + /// + /// End time. + /// + /// Required + [JsonProperty(PropertyName = "end")] + public string End { get; set; } + } +} \ No newline at end of file