예제 #1
0
        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();
            }
        }
예제 #4
0
        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" }));
        }
예제 #9
0
        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);
        }
예제 #10
0
        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();
        }
예제 #11
0
        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();
        }
예제 #12
0
        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;
        }