private string ProcessCaptureRequest(Order order, HttpRequest request, IDictionary <string, string> settings) { var apiKey = settings[settings["mode"] + "_secret_key"]; ConfigureStripe(apiKey); try { var capture = settings.ContainsKey("capture") && settings["capture"].Trim().ToLower() == "true"; var intentService = new PaymentIntentService(); var intentOptions = new PaymentIntentCreateOptions { Amount = DollarsToCents(order.TotalPrice.Value.WithVat), Currency = CurrencyService.Instance.Get(order.StoreId, order.CurrencyId).IsoCode, Description = $"{order.CartNumber} - {order.PaymentInformation.Email}", Metadata = new Dictionary <string, string> { { "orderId", order.Id.ToString() }, { "cartNumber", order.CartNumber } }, CaptureMethod = capture ? "automatic" : "manual" }; if (settings.ContainsKey("send_stripe_receipt") && settings["send_stripe_receipt"] == "true") { intentOptions.ReceiptEmail = order.PaymentInformation.Email; } var intent = intentService.Create(intentOptions); order.Properties.AddOrUpdate(new CustomProperty("stripePaymentIntentId", intent.Id) { ServerSideOnly = true }); order.TransactionInformation.PaymentState = PaymentState.Initialized; order.Save(); return(JsonConvert.SerializeObject(new { payment_intent_client_secret = intent.ClientSecret })); } catch (Exception ex) { LoggingService.Instance.Error <Stripe>("Stripe(" + order.CartNumber + ") - ProcessCaptureRequest", ex); return(JsonConvert.SerializeObject(new { error = ex.Message })); } }
protected void FinalizeOrUpdateOrder(Order order, Invoice invoice) { var amount = CentsToDollars(invoice.AmountDue); var paymentState = invoice.Paid ? PaymentState.Captured : PaymentState.Authorized; if (!order.IsFinalized) { order.Finalize(amount, invoice.Id, paymentState); } else if (order.TransactionInformation.PaymentState != paymentState) { var currency = CurrencyService.Instance.Get(order.StoreId, order.CurrencyId); order.TransactionInformation.AmountAuthorized = new Amount(amount, currency); order.TransactionInformation.TransactionId = invoice.Id; order.TransactionInformation.PaymentState = paymentState; order.Save(); } }
protected void FinalizeOrUpdateOrder(Order order, PaymentIntent paymentIntent) { var amount = CentsToDollars(paymentIntent.Amount.Value); var transactionId = GetTransactionId(paymentIntent); var paymentState = GetPaymentState(paymentIntent); if (!order.IsFinalized && (paymentState == PaymentState.Authorized || paymentState == PaymentState.Captured)) { order.Finalize(amount, transactionId, paymentState); } else { var currency = CurrencyService.Instance.Get(order.StoreId, order.CurrencyId); order.TransactionInformation.AmountAuthorized = new Amount(amount, currency); order.TransactionInformation.TransactionId = transactionId; order.TransactionInformation.PaymentState = paymentState; order.Save(); } }
public override string ProcessRequest(Order order, HttpRequest request, IDictionary <string, string> settings) { var response = ""; try { order.MustNotBeNull("order"); request.MustNotBeNull("request"); settings.MustNotBeNull("settings"); // If in test mode, write out the form data to a text file if (settings.ContainsKey("mode") && settings["mode"] == "test") { LogRequest <Stripe>(request, logPostData: true); } // Stripe supports webhooks var stripeEvent = GetStripeEvent(request); if (stripeEvent.Type.StartsWith("charge.")) { var charge = Mapper <Charge> .MapFromJson(stripeEvent.Data.Object.ToString()); var paymentState = GetPaymentState(charge); if (order.TransactionInformation.PaymentState != paymentState) { order.TransactionInformation.TransactionId = charge.Id; order.TransactionInformation.PaymentState = paymentState; order.Save(); } } } catch (Exception exp) { LoggingService.Instance.Error <Stripe>("Stripe(" + order.CartNumber + ") - ProcessRequest", exp); } return(response); }
private string ProcessCaptureRequest(Order order, HttpRequest request, IDictionary <string, string> settings) { var apiKey = settings[settings["mode"] + "_secret_key"]; ConfigureStripe(apiKey); try { var capture = settings.ContainsKey("capture") && settings["capture"].Trim().ToLower() == "true"; PaymentIntent intent; var intentService = new PaymentIntentService(); var paymentIntentId = request.Form["stripePaymentIntentId"]; // If we don't have a stripe payment intent passed in then we create a payment // and try to create / capture it if (string.IsNullOrWhiteSpace(paymentIntentId)) { var intentOptions = new PaymentIntentCreateOptions { PaymentMethod = request.Form["stripePaymentMethodId"], Amount = DollarsToCents(order.TotalPrice.Value.WithVat), Currency = CurrencyService.Instance.Get(order.StoreId, order.CurrencyId).IsoCode, Description = $"{order.CartNumber} - {order.PaymentInformation.Email}", Metadata = new Dictionary <string, string> { { "orderId", order.Id.ToString() }, { "cartNumber", order.CartNumber } }, ConfirmationMethod = "manual", Confirm = true, CaptureMethod = capture ? "automatic" : "manual" }; if (settings.ContainsKey("send_stripe_receipt") && settings["send_stripe_receipt"] == "true") { intentOptions.ReceiptEmail = order.PaymentInformation.Email; } intent = intentService.Create(intentOptions); order.Properties.AddOrUpdate(new CustomProperty("stripePaymentIntentId", intent.Id) { ServerSideOnly = true }); order.TransactionInformation.PaymentState = PaymentState.Initialized; if (intent.Status != "succeeded") { order.Save(); } } // If we have a stripe payment intent then it means it wasn't confirmed first time around // so just try and confirm it again else { intent = intentService.Confirm(request.Form["stripePaymentIntentId"], new PaymentIntentConfirmOptions { PaymentMethod = request.Form["stripePaymentMethodId"] }); } if (intent.Status == "succeeded") { FinalizeOrUpdateOrder(order, intent); return(JsonConvert.SerializeObject(new { success = true })); } else if (intent.Status == "requires_action" && intent.NextAction.Type == "use_stripe_sdk") { return(JsonConvert.SerializeObject(new { requires_card_action = true, payment_intent_client_secret = intent.ClientSecret })); } return(JsonConvert.SerializeObject(new { error = "Invalid payment intent status" })); } catch (Exception ex) { LoggingService.Instance.Error <Stripe>("Stripe(" + order.CartNumber + ") - ProcessCaptureRequest", ex); return(JsonConvert.SerializeObject(new { error = ex.Message })); } }
public override string ProcessRequest(Order order, HttpRequest request, IDictionary <string, string> settings) { var response = ""; try { order.MustNotBeNull("order"); request.MustNotBeNull("request"); settings.MustNotBeNull("settings"); // If in test mode, write out the form data to a text file if (settings.ContainsKey("mode") && settings["mode"] == "test") { LogRequest <StripeSubscription>(request, logPostData: true); } // Stripe supports webhooks var stripeEvent = GetStripeEvent(request); // With subscriptions, Stripe creates an invoice for each payment // so to ensure subscription is live, we'll listen for successful invoice payment if (stripeEvent.Type.StartsWith("invoice.")) { var invoice = Mapper <Invoice> .MapFromJson(stripeEvent.Data.Object.ToString()); if (order.Properties["stripeCustomerId"] == invoice.CustomerId && order.Properties["stripeSubscriptionId"] == invoice.SubscriptionId) { var eventArgs = new StripeSubscriptionEventArgs { Order = order, Subscription = invoice.Subscription, Invoice = invoice }; switch (stripeEvent.Type) { case "invoice.payment_succeeded": if (order.TransactionInformation.PaymentState == PaymentState.Initialized || order.TransactionInformation.PaymentState == PaymentState.Authorized) { order.TransactionInformation.TransactionId = invoice.ChargeId; order.TransactionInformation.PaymentState = PaymentState.Captured; order.Save(); eventArgs.Type = StripeSubscriptionEventType.SubscriptionStarted; } else { eventArgs.Type = StripeSubscriptionEventType.SubscriptionRenewed; } break; case "invoice.payment_failed": if (!string.IsNullOrWhiteSpace(order.TransactionInformation.TransactionId) && invoice.Status == "past_due") { eventArgs.Type = StripeSubscriptionEventType.SubscriptionPastDue; } break; case "invoice.upcoming": eventArgs.Type = StripeSubscriptionEventType.SubscriptionRenewing; break; } OnStripeSubscriptionEvent(eventArgs); } } else if (stripeEvent.Type.StartsWith("customer.subscription.")) { var subscription = Mapper <Subscription> .MapFromJson(stripeEvent.Data.Object.ToString()); if (order.Properties["stripeCustomerId"] == subscription.CustomerId && order.Properties["stripeSubscriptionId"] == subscription.Id) { var eventArgs = new StripeSubscriptionEventArgs { Order = order, Subscription = subscription }; switch (stripeEvent.Type) { case "customer.subscription.trial_will_end": eventArgs.Type = StripeSubscriptionEventType.SubscriptionTrialEnding; break; case "customer.subscription.created": eventArgs.Type = StripeSubscriptionEventType.SubscriptionCreated; break; case "customer.subscription.updated": eventArgs.Type = StripeSubscriptionEventType.SubscriptionUpdated; break; case "customer.subscription.deleted": eventArgs.Type = StripeSubscriptionEventType.SubscriptionDeleted; break; } OnStripeSubscriptionEvent(eventArgs); } } } catch (Exception exp) { LoggingService.Instance.Error <StripeSubscription>("StripeSubscription(" + order.CartNumber + ") - ProcessRequest", exp); } return(response); }
public override CallbackInfo ProcessCallback(Order order, HttpRequest request, IDictionary <string, string> settings) { CallbackInfo callbackInfo = null; try { order.MustNotBeNull("order"); request.MustNotBeNull("request"); settings.MustNotBeNull("settings"); settings.MustContainKey("mode", "settings"); settings.MustContainKey("billing_mode", "settings"); settings.MustContainKey(settings["mode"] + "_secret_key", "settings"); // If in test mode, write out the form data to a text file if (settings.ContainsKey("mode") && settings["mode"] == "test") { LogRequest <StripeSubscription>(request, logPostData: true); } var billingMode = settings["billing_mode"]; ValidateBillingModeSetting(billingMode); var apiKey = settings[settings["mode"] + "_secret_key"]; // Create the stripe customer var customerService = new CustomerService(apiKey); var customer = customerService.Create(new CustomerCreateOptions { Email = order.PaymentInformation.Email, SourceToken = billingMode == "charge" ? request.Form["stripeToken"] : null, Metadata = new Dictionary <string, string> { { "customerId", order.CustomerId } } }); // Subscribe customer to plan(s) var subscriptionService = new SubscriptionService(apiKey); var subscriptionOptions = new SubscriptionCreateOptions { CustomerId = customer.Id, Billing = billingMode == "charge" ? Billing.ChargeAutomatically : Billing.SendInvoice, Items = order.OrderLines.Select(x => new SubscriptionItemOption { PlanId = !string.IsNullOrWhiteSpace(x.Properties["planId"]) ? x.Properties["planId"] : x.Sku, Quantity = (long)x.Quantity }).ToList(), TaxPercent = order.VatRate.Value, Metadata = new Dictionary <string, string> { { "orderId", order.Id.ToString() }, { "cartNumber", order.CartNumber } } }; foreach (var prop in order.Properties) { subscriptionOptions.Metadata.Add(prop.Alias, prop.Value); } var subscription = subscriptionService.Create(subscriptionOptions); // Stash the stripe info in the order order.Properties.AddOrUpdate("stripeCustomerId", customer.Id); order.Properties.AddOrUpdate("stripeSubscriptionId", subscription.Id); order.Save(); // Authorize the payment. We'll capture it on a successful webhook callback callbackInfo = new CallbackInfo(CentsToDollars(subscription.Plan.Amount.Value), subscription.Id, PaymentState.Authorized); } catch (StripeException e) { ReturnToPaymentFormWithException(order, request, e); } catch (Exception exp) { LoggingService.Instance.Error <StripeSubscription>("StripeSubscription(" + order.CartNumber + ") - ProcessCallback", exp); } return(callbackInfo); }
private string ProcessCaptureRequest(Order order, HttpRequest request, IDictionary <string, string> settings) { var apiKey = settings[settings["mode"] + "_secret_key"]; var billingMode = settings["billing_mode"]; ConfigureStripe(apiKey); ValidateBillingModeSetting(billingMode); var customerService = new CustomerService(); var subscriptionService = new SubscriptionService(); var invoiceService = new InvoiceService(); // Create the stripe customer var customer = customerService.Create(new CustomerCreateOptions { PaymentMethodId = billingMode == "charge" ? request.Form["stripePaymentMethodId"] : null, Email = order.PaymentInformation.Email, Metadata = new Dictionary <string, string> { { "customerId", order.CustomerId } } }); // Create subscription for customer (will auto attempt payment) var subscriptionOptions = new SubscriptionCreateOptions { CustomerId = customer.Id, Items = order.OrderLines.Select(x => new SubscriptionItemOption { PlanId = !string.IsNullOrWhiteSpace(x.Properties["planId"]) ? x.Properties["planId"] : x.Sku, Quantity = (long)x.Quantity }).ToList(), TaxPercent = order.VatRate.Value * 100, Metadata = new Dictionary <string, string> { { "orderId", order.Id.ToString() }, { "cartNumber", order.CartNumber } }, Expand = new[] { "latest_invoice.payment_intent" }.ToList() }; if (billingMode == "charge") { subscriptionOptions.CollectionMethod = "charge_automatically"; subscriptionOptions.DefaultPaymentMethodId = request.Form["stripePaymentMethodId"]; } else { subscriptionOptions.CollectionMethod = "send_invoice"; subscriptionOptions.DaysUntilDue = settings.ContainsKey("invoice_days_until_due") ? int.Parse("0" + settings["invoice_days_until_due"]) : 30; } foreach (var prop in order.Properties) { subscriptionOptions.Metadata.Add(prop.Alias, prop.Value); } var subscription = subscriptionService.Create(subscriptionOptions); var invoice = subscription.LatestInvoice; // Stash the stripe info in the order order.Properties.AddOrUpdate(new CustomProperty("stripeCustomerId", customer.Id) { ServerSideOnly = true }); order.Properties.AddOrUpdate(new CustomProperty("stripeSubscriptionId", subscription.Id) { ServerSideOnly = true }); order.Save(); if (subscription.Status == "active" || subscription.Status == "trialing") { return(JsonConvert.SerializeObject(new { success = true })); } else if (invoice.PaymentIntent.Status == "requires_action") { return(JsonConvert.SerializeObject(new { requires_action = true, payment_intent_client_secret = invoice.PaymentIntent.ClientSecret })); } return(JsonConvert.SerializeObject(new { error = "Invalid payment intent status" })); }
public override string ProcessRequest(Order order, HttpRequest request, IDictionary <string, string> settings) { string response = ""; try { order.MustNotBeNull("order"); settings.MustNotBeNull("settings"); settings.MustContainKey("sharedSecret", "settings"); string communicationType = request["communicationType"]; KlarnaOrder klarnaOrder = null; IConnector connector = Connector.Create(settings["sharedSecret"]); if (communicationType == "checkout") { settings.MustContainKey("merchant.id", "settings"); settings.MustContainKey("merchant.terms_uri", "settings"); settings.MustContainKey("locale", "settings"); //Cart information List <Dictionary <string, object> > cartItems = new List <Dictionary <string, object> > { new Dictionary <string, object> { { "reference", settings.ContainsKey("totalSku") ? settings["totalSku"] : "0001" }, { "name", settings.ContainsKey("totalName") ? settings["totalName"] : "Total" }, { "quantity", 1 }, { "unit_price", (int)(order.TotalPrice.Value.WithVat * 100M) }, { "tax_rate", 0 } } }; Dictionary <string, object> data = new Dictionary <string, object> { { "cart", new Dictionary <string, object> { { "items", cartItems } } } }; string klarnaLocation = order.Properties["klarnaLocation"]; string merchantTermsUri = settings["merchant.terms_uri"]; if (!merchantTermsUri.StartsWith("http")) { Uri baseUrl = new UriBuilder(HttpContext.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, HttpContext.Current.Request.Url.Port).Uri; merchantTermsUri = new Uri(baseUrl, merchantTermsUri).AbsoluteUri; } //Merchant information data["merchant"] = new Dictionary <string, object> { { "id", settings["merchant.id"] }, { "terms_uri", merchantTermsUri }, { "checkout_uri", request.UrlReferrer.ToString() }, { "confirmation_uri", order.Properties["teaCommerceContinueUrl"] }, { "push_uri", order.Properties["teaCommerceCallbackUrl"] } }; data["merchant_reference"] = new Dictionary <string, object>() { { "orderid1", order.CartNumber } }; //Combined data Currency currency = CurrencyService.Instance.Get(order.StoreId, order.CurrencyId); //If the currency is not a valid iso4217 currency then throw an error if (!Iso4217CurrencyCodes.ContainsKey(currency.IsoCode)) { throw new Exception("You must specify an ISO 4217 currency code for the " + currency.Name + " currency"); } data["purchase_country"] = CountryService.Instance.Get(order.StoreId, order.PaymentInformation.CountryId).RegionCode; data["purchase_currency"] = currency.IsoCode; data["locale"] = settings["locale"]; //Check if the order has a Klarna location URI property - then we try and update the order if (!string.IsNullOrEmpty(klarnaLocation)) { try { klarnaOrder = new KlarnaOrder(connector, new Uri(klarnaLocation)) { ContentType = KlarnaApiRequestContentType }; klarnaOrder.Fetch(); klarnaOrder.Update(data); } catch (Exception) { //Klarna cart session has expired and we make sure to remove the Klarna location URI property klarnaOrder = null; } } //If no Klarna order was found to update or the session expired - then create new Klarna order if (klarnaOrder == null) { klarnaOrder = new KlarnaOrder(connector) { BaseUri = settings.ContainsKey("testMode") && settings["testMode"] == "1" ? new Uri("https://checkout.testdrive.klarna.com/checkout/orders") : new Uri("https://checkout.klarna.com/checkout/orders"), ContentType = KlarnaApiRequestContentType }; //Create new order klarnaOrder.Create(data); klarnaOrder.Fetch(); order.Properties.AddOrUpdate(new CustomProperty("klarnaLocation", klarnaOrder.Location.ToString()) { ServerSideOnly = true }); order.Save(); } } else if (communicationType == "confirmation") { //get confirmation response string klarnaLocation = order.Properties["klarnaLocation"]; if (!string.IsNullOrEmpty(klarnaLocation)) { //Fetch and show confirmation page if status is not checkout_incomplete klarnaOrder = new KlarnaOrder(connector, new Uri(klarnaLocation)) { ContentType = KlarnaApiRequestContentType }; klarnaOrder.Fetch(); if ((string)klarnaOrder.GetValue("status") == "checkout_incomplete") { throw new Exception("Confirmation page reached without a Klarna order that is finished"); } } } //Get the JavaScript snippet from the Klarna order if (klarnaOrder != null) { JObject guiElement = klarnaOrder.GetValue("gui") as JObject; if (guiElement != null) { response = guiElement["snippet"].ToString(); } } } catch (Exception exp) { LoggingService.Instance.Error <Klarna>("Klarna(" + order.CartNumber + ") - ProcessRequest", exp); } return(response); }
protected virtual void SaveOrderPropertiesFromKlarnaCallback(Order order, KlarnaOrder klarnaOrder) { //Some order properties in Tea Commerce comes with a special alias, //defining a mapping of klarna propteries to these aliases. Store store = StoreService.Instance.Get(order.StoreId); Dictionary <string, string> magicOrderPropertyAliases = new Dictionary <string, string> { { "billing_address.given_name", Constants.OrderPropertyAliases.FirstNamePropertyAlias }, { "billing_address.family_name", Constants.OrderPropertyAliases.LastNamePropertyAlias }, { "billing_address.email", Constants.OrderPropertyAliases.EmailPropertyAlias }, }; //The klarna properties we wish to save on the order. List <string> klarnaPropertyAliases = new List <string> { "billing_address.given_name", "billing_address.family_name", "billing_address.care_of", "billing_address.street_address", "billing_address.postal_code", "billing_address.city", "billing_address.email", "billing_address.phone", "shipping_address.given_name", "shipping_address.family_name", "shipping_address.care_of", "shipping_address.street_address", "shipping_address.postal_code", "shipping_address.city", "shipping_address.email", "shipping_address.phone", }; Dictionary <string, object> klarnaProperties = klarnaOrder.Marshal(); foreach (string klarnaPropertyAlias in klarnaPropertyAliases) { //if a property mapping exists then use the magic alias, otherwise use the property name itself. string tcOrderPropertyAlias = magicOrderPropertyAliases.ContainsKey(klarnaPropertyAlias) ? magicOrderPropertyAliases[klarnaPropertyAlias] : klarnaPropertyAlias; string klarnaPropertyValue = ""; /* Some klarna properties are of the form parent.child * in which case the lookup in klarnaProperties * needs to be (in pseudocode) * klarnaProperties[parent].getValue(child) . * In the case that there is no '.' we assume that * klarnaProperties[klarnaPropertyAlias].ToString() * contains what we need. */ string[] klarnaPropertyParts = klarnaPropertyAlias.Split('.'); if (klarnaPropertyParts.Length == 1 && klarnaProperties.ContainsKey(klarnaPropertyAlias)) { klarnaPropertyValue = klarnaProperties[klarnaPropertyAlias].ToString(); } else if (klarnaPropertyParts.Length == 2 && klarnaProperties.ContainsKey(klarnaPropertyParts[0])) { JObject parent = klarnaProperties[klarnaPropertyParts[0]] as JObject; if (parent != null) { JToken value = parent.GetValue(klarnaPropertyParts[1]); klarnaPropertyValue = value != null?value.ToString() : ""; } } if (!string.IsNullOrEmpty(klarnaPropertyValue)) { order.Properties.AddOrUpdate(tcOrderPropertyAlias, klarnaPropertyValue); } } // order was passed as reference and updated. Saving it now. order.Save(); }
protected virtual void SaveOrderPropertiesFromKlarnaCallback( Order order, KlarnaOrder klarnaOrder ) { //Some order properties in Tea Commerce comes with a special alias, //defining a mapping of klarna propteries to these aliases. Store store = StoreService.Instance.Get( order.StoreId ); Dictionary<string, string> magicOrderPropertyAliases = new Dictionary<string, string>{ { "billing_address.given_name", Constants.OrderPropertyAliases.FirstNamePropertyAlias }, { "billing_address.family_name", Constants.OrderPropertyAliases.LastNamePropertyAlias }, { "billing_address.email", Constants.OrderPropertyAliases.EmailPropertyAlias }, }; //The klarna properties we wish to save on the order. List<string> klarnaPropertyAliases = new List<string>{ "billing_address.given_name", "billing_address.family_name", "billing_address.care_of", "billing_address.street_address", "billing_address.postal_code", "billing_address.city", "billing_address.email", "billing_address.phone", "shipping_address.given_name", "shipping_address.family_name", "shipping_address.care_of", "shipping_address.street_address", "shipping_address.postal_code", "shipping_address.city", "shipping_address.email", "shipping_address.phone" , }; Dictionary<string, object> klarnaProperties = klarnaOrder.Marshal(); foreach ( string klarnaPropertyAlias in klarnaPropertyAliases ) { //if a property mapping exists then use the magic alias, otherwise use the property name itself. string tcOrderPropertyAlias = magicOrderPropertyAliases.ContainsKey( klarnaPropertyAlias ) ? magicOrderPropertyAliases[ klarnaPropertyAlias ] : klarnaPropertyAlias; string klarnaPropertyValue = ""; /* Some klarna properties are of the form parent.child * in which case the lookup in klarnaProperties * needs to be (in pseudocode) * klarnaProperties[parent].getValue(child) . * In the case that there is no '.' we assume that * klarnaProperties[klarnaPropertyAlias].ToString() * contains what we need. */ string[] klarnaPropertyParts = klarnaPropertyAlias.Split( '.' ); if ( klarnaPropertyParts.Length == 1 && klarnaProperties.ContainsKey( klarnaPropertyAlias ) ) { klarnaPropertyValue = klarnaProperties[ klarnaPropertyAlias ].ToString(); } else if ( klarnaPropertyParts.Length == 2 && klarnaProperties.ContainsKey( klarnaPropertyParts[ 0 ] ) ) { JObject parent = klarnaProperties[ klarnaPropertyParts[ 0 ] ] as JObject; if ( parent != null ) { JToken value = parent.GetValue( klarnaPropertyParts[ 1 ] ); klarnaPropertyValue = value != null ? value.ToString() : ""; } } if ( !string.IsNullOrEmpty( klarnaPropertyValue ) ) { order.Properties.AddOrUpdate( tcOrderPropertyAlias, klarnaPropertyValue ); } } // order was passed as reference and updated. Saving it now. order.Save(); }
public override string ProcessRequest( Order order, HttpRequest request, IDictionary<string, string> settings ) { string response = ""; try { order.MustNotBeNull( "order" ); settings.MustNotBeNull( "settings" ); settings.MustContainKey( "sharedSecret", "settings" ); string communicationType = request[ "communicationType" ]; KlarnaOrder klarnaOrder = null; IConnector connector = Connector.Create( settings[ "sharedSecret" ] ); if ( communicationType == "checkout" ) { settings.MustContainKey( "merchant.id", "settings" ); settings.MustContainKey( "merchant.terms_uri", "settings" ); settings.MustContainKey( "locale", "settings" ); //Cart information List<Dictionary<string, object>> cartItems = new List<Dictionary<string, object>> { new Dictionary<string, object> { {"reference", settings.ContainsKey( "totalSku" ) ? settings[ "totalSku" ] : "0001"}, {"name", settings.ContainsKey( "totalName" ) ? settings[ "totalName" ] : "Total"}, {"quantity", 1}, {"unit_price", (int) ( order.TotalPrice.Value.WithVat*100M )}, {"tax_rate", 0} } }; Dictionary<string, object> data = new Dictionary<string, object> { { "cart", new Dictionary<string, object> { { "items", cartItems } } } }; string klarnaLocation = order.Properties[ "klarnaLocation" ]; string merchantTermsUri = settings[ "merchant.terms_uri" ]; if ( !merchantTermsUri.StartsWith( "http" ) ) { Uri baseUrl = new UriBuilder( HttpContext.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, HttpContext.Current.Request.Url.Port ).Uri; merchantTermsUri = new Uri( baseUrl, merchantTermsUri ).AbsoluteUri; } //Merchant information data[ "merchant" ] = new Dictionary<string, object> { {"id", settings[ "merchant.id" ]}, {"terms_uri", merchantTermsUri}, {"checkout_uri", request.UrlReferrer.ToString()}, {"confirmation_uri", order.Properties[ "teaCommerceContinueUrl" ]}, {"push_uri", order.Properties[ "teaCommerceCallbackUrl" ]} }; data[ "merchant_reference" ] = new Dictionary<string, object>() { {"orderid1", order.CartNumber} }; //Combined data Currency currency = CurrencyService.Instance.Get( order.StoreId, order.CurrencyId ); //If the currency is not a valid iso4217 currency then throw an error if ( !Iso4217CurrencyCodes.ContainsKey( currency.IsoCode ) ) { throw new Exception( "You must specify an ISO 4217 currency code for the " + currency.Name + " currency" ); } data[ "purchase_country" ] = CountryService.Instance.Get( order.StoreId, order.PaymentInformation.CountryId ).RegionCode; data[ "purchase_currency" ] = currency.IsoCode; data[ "locale" ] = settings[ "locale" ]; //Check if the order has a Klarna location URI property - then we try and update the order if ( !string.IsNullOrEmpty( klarnaLocation ) ) { try { klarnaOrder = new KlarnaOrder( connector, new Uri( klarnaLocation ) ) { ContentType = KlarnaApiRequestContentType }; klarnaOrder.Fetch(); klarnaOrder.Update( data ); } catch ( Exception ) { //Klarna cart session has expired and we make sure to remove the Klarna location URI property klarnaOrder = null; } } //If no Klarna order was found to update or the session expired - then create new Klarna order if ( klarnaOrder == null ) { klarnaOrder = new KlarnaOrder( connector ) { BaseUri = settings.ContainsKey( "testMode" ) && settings[ "testMode" ] == "1" ? new Uri( "https://checkout.testdrive.klarna.com/checkout/orders" ) : new Uri( "https://checkout.klarna.com/checkout/orders" ), ContentType = KlarnaApiRequestContentType }; //Create new order klarnaOrder.Create( data ); klarnaOrder.Fetch(); order.Properties.AddOrUpdate( new CustomProperty( "klarnaLocation", klarnaOrder.Location.ToString() ) { ServerSideOnly = true } ); order.Save(); } } else if ( communicationType == "confirmation" ) { //get confirmation response string klarnaLocation = order.Properties[ "klarnaLocation" ]; if ( !string.IsNullOrEmpty( klarnaLocation ) ) { //Fetch and show confirmation page if status is not checkout_incomplete klarnaOrder = new KlarnaOrder( connector, new Uri( klarnaLocation ) ) { ContentType = KlarnaApiRequestContentType }; klarnaOrder.Fetch(); if ( (string)klarnaOrder.GetValue( "status" ) == "checkout_incomplete" ) { throw new Exception( "Confirmation page reached without a Klarna order that is finished" ); } } } //Get the JavaScript snippet from the Klarna order if ( klarnaOrder != null ) { JObject guiElement = klarnaOrder.GetValue( "gui" ) as JObject; if ( guiElement != null ) { response = guiElement[ "snippet" ].ToString(); } } } catch ( Exception exp ) { LoggingService.Instance.Error<Klarna>( "Klarna(" + order.CartNumber + ") - ProcessRequest", exp ); } return response; }