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);
                }

                if (request.QueryString["action"] == "capture")
                {
                    return(ProcessCaptureRequest(order, request, settings));
                }
                else
                {
                    // No action defined so assume it's a webhook request
                    return(ProcessWebhookRequest(order, request, settings));
                }
            }
            catch (Exception exp)
            {
                LoggingService.Instance.Error <Stripe>("Stripe(" + order.CartNumber + ") - ProcessRequest", exp);
            }

            return(response);
        }
示例#2
0
        public override PaymentHtmlForm GenerateHtmlForm(Order order, string teaCommerceContinueUrl, string teaCommerceCancelUrl, string teaCommerceCallBackUrl, string teaCommerceCommunicationUrl, IDictionary <string, string> settings)
        {
            order.MustNotBeNull("order");
            settings.MustNotBeNull("settings");
            settings.MustContainKey("paymentFormUrl", "settings");

            PaymentHtmlForm htmlForm = new PaymentHtmlForm {
                Action = settings["paymentFormUrl"]
            };

            order.Properties.AddOrUpdate(new CustomProperty("teaCommerceCommunicationUrl", teaCommerceCommunicationUrl)
            {
                ServerSideOnly = true
            });
            order.Properties.AddOrUpdate(new CustomProperty("teaCommerceContinueUrl", teaCommerceContinueUrl)
            {
                ServerSideOnly = true
            });
            order.Properties.AddOrUpdate(new CustomProperty("teaCommerceCallbackUrl", teaCommerceCallBackUrl)
            {
                ServerSideOnly = true
            });

            return(htmlForm);
        }
示例#3
0
        public override ApiInfo CapturePayment(Order order, IDictionary <string, string> settings)
        {
            try
            {
                order.MustNotBeNull("order");
                settings.MustNotBeNull("settings");
                settings.MustContainKey("mode", "settings");
                settings.MustContainKey(settings["mode"] + "_secret_key", "settings");

                var apiKey = settings[settings["mode"] + "_secret_key"];

                var chargeService = new ChargeService(apiKey);

                var captureOptions = new ChargeCaptureOptions()
                {
                    Amount = DollarsToCents(order.TransactionInformation.AmountAuthorized.Value)
                };

                var charge = chargeService.Capture(order.TransactionInformation.TransactionId, captureOptions);

                return(new ApiInfo(charge.Id, GetPaymentState(charge)));
            }
            catch (Exception exp)
            {
                LoggingService.Instance.Error <Stripe>("Stripe(" + order.OrderNumber + ") - GetStatus", exp);
            }

            return(null);
        }
示例#4
0
        public override PaymentHtmlForm GenerateHtmlForm( Order order, string teaCommerceContinueUrl, string teaCommerceCancelUrl, string teaCommerceCallBackUrl, string teaCommerceCommunicationUrl, IDictionary<string, string> settings )
        {
            order.MustNotBeNull( "order" );
              settings.MustNotBeNull( "settings" );
              settings.MustContainKey( "paymentFormUrl", "settings" );

              PaymentHtmlForm htmlForm = new PaymentHtmlForm {
            Action = settings[ "paymentFormUrl" ]
              };

              order.Properties.AddOrUpdate( new CustomProperty( "teaCommerceCommunicationUrl", teaCommerceCommunicationUrl ) { ServerSideOnly = true } );
              order.Properties.AddOrUpdate( new CustomProperty( "teaCommerceContinueUrl", teaCommerceContinueUrl ) { ServerSideOnly = true } );
              order.Properties.AddOrUpdate( new CustomProperty( "teaCommerceCallbackUrl", teaCommerceCallBackUrl ) { ServerSideOnly = true } );

              return htmlForm;
        }
        public override ApiInfo RefundPayment(Order order, IDictionary <string, string> settings)
        {
            try
            {
                order.MustNotBeNull("order");
                settings.MustNotBeNull("settings");
                settings.MustContainKey("mode", "settings");
                settings.MustContainKey(settings["mode"] + "_secret_key", "settings");

                // We can only refund a captured charge, so make sure we have one
                // otherwise there is nothing we can do
                if (order.TransactionInformation.TransactionId == null)
                {
                    return(null);
                }

                var apiKey = settings[settings["mode"] + "_secret_key"];

                ConfigureStripe(apiKey);

                var refundService       = new RefundService();
                var refundCreateOptions = new RefundCreateOptions()
                {
                    Charge = order.TransactionInformation.TransactionId
                };

                var refund = refundService.Create(refundCreateOptions);
                var charge = refund.Charge;

                if (charge == null)
                {
                    var chargeService = new ChargeService();
                    charge = chargeService.Get(order.TransactionInformation.TransactionId);
                }

                return(new ApiInfo(charge.Id, GetPaymentState(charge)));
            }
            catch (Exception exp)
            {
                LoggingService.Instance.Error <Stripe>("Stripe(" + order.OrderNumber + ") - RefundPayment", exp);
            }

            return(null);
        }
        public override CallbackInfo ProcessCallback(Order order, HttpRequest request, IDictionary <string, string> settings)
        {
            try
            {
                order.MustNotBeNull("order");
                request.MustNotBeNull("request");
                settings.MustNotBeNull("settings");
                settings.MustContainKey("billing_mode", "settings");

                // Because we need more fine grained control over the callback process
                // we actually perform all the callback functionality from within the
                // ProcessRequest method instead. We only really use the callback
                // function for when the billing mode is invoice as this means
                // that the payment screen won't have been displayed and so the
                // stripe subscription won't have been setup yet and so we need to
                // do it now.
                var billingMode = settings["billing_mode"];

                ValidateBillingModeSetting(billingMode);

                if (billingMode == "invoice")
                {
                    ProcessCaptureRequest(order, request, settings);

                    var apiKey = settings[settings["mode"] + "_secret_key"];

                    ConfigureStripe(apiKey);

                    var subscriptionService = new SubscriptionService();
                    var subscription        = subscriptionService.Get(order.Properties["stripeSubscriptionId"]);
                    var invoice             = subscription.LatestInvoice ?? new InvoiceService().Get(subscription.LatestInvoiceId);

                    return(new CallbackInfo(CentsToDollars(invoice.AmountDue), invoice.Id, PaymentState.Authorized));
                }
            }
            catch (Exception exp)
            {
                LoggingService.Instance.Error <StripeSubscription>("StripeSubscription(" + order.CartNumber + ") - ProcessCallback", exp);
            }

            return(null);
        }
示例#7
0
        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("sharedSecret", "settings");

                IConnector  connector   = Connector.Create(settings["sharedSecret"]);
                KlarnaOrder klarnaOrder = new KlarnaOrder(connector, new Uri(order.Properties["klarnaLocation"]))
                {
                    ContentType = KlarnaApiRequestContentType
                };
                klarnaOrder.Fetch();

                if ((string)klarnaOrder.GetValue("status") == "checkout_complete")
                {
                    //We need to populate the order with the information entered into Klarna.
                    SaveOrderPropertiesFromKlarnaCallback(order, klarnaOrder);

                    decimal amount   = ((JObject)klarnaOrder.GetValue("cart"))["total_price_including_tax"].Value <decimal>() / 100M;
                    string  klarnaId = klarnaOrder.GetValue("id").ToString();

                    callbackInfo = new CallbackInfo(amount, klarnaId, PaymentState.Authorized);

                    klarnaOrder.Update(new Dictionary <string, object>()
                    {
                        { "status", "created" }
                    });
                }
                else
                {
                    throw new Exception("Trying to process a callback from Klarna with an order that isn't completed");
                }
            } catch (Exception exp) {
                LoggingService.Instance.Error <Klarna>("Klarna(" + order.CartNumber + ") - Process callback", exp);
            }

            return(callbackInfo);
        }
示例#8
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);
        }
        public override ApiInfo GetStatus(Order order, IDictionary <string, string> settings)
        {
            try
            {
                order.MustNotBeNull("order");
                settings.MustNotBeNull("settings");
                settings.MustContainKey("mode", "settings");
                settings.MustContainKey(settings["mode"] + "_secret_key", "settings");

                var apiKey = settings[settings["mode"] + "_secret_key"];

                ConfigureStripe(apiKey);

                // See if we have a payment intent ID to work from
                var paymentIntentId = order.Properties["stripePaymentIntentId"];
                if (!string.IsNullOrWhiteSpace(paymentIntentId))
                {
                    var paymentIntentService    = new PaymentIntentService();
                    var paymentIntentGetOptions = new PaymentIntentGetOptions();
                    var paymentIntent           = paymentIntentService.Get(paymentIntentId, paymentIntentGetOptions);
                    return(new ApiInfo(GetTransactionId(paymentIntent), GetPaymentState(paymentIntent)));
                }

                // No payment intent, so look for a charge ID
                if (!string.IsNullOrWhiteSpace(order.TransactionInformation.TransactionId))
                {
                    var chargeService = new ChargeService();
                    var charge        = chargeService.Get(order.TransactionInformation.TransactionId);
                    return(new ApiInfo(GetTransactionId(charge), GetPaymentState(charge)));
                }
            }
            catch (Exception exp)
            {
                LoggingService.Instance.Error <Stripe>("Stripe(" + order.OrderNumber + ") - GetStatus", exp);
            }

            return(null);
        }
        public override ApiInfo CancelPayment(Order order, IDictionary <string, string> settings)
        {
            try
            {
                order.MustNotBeNull("order");
                settings.MustNotBeNull("settings");
                settings.MustContainKey("mode", "settings");
                settings.MustContainKey(settings["mode"] + "_secret_key", "settings");

                // Try canceling the payment intent
                var stripePaymentIntentId = order.Properties["stripePaymentIntentId"];
                if (!string.IsNullOrWhiteSpace(stripePaymentIntentId))
                {
                    var apiKey = settings[settings["mode"] + "_secret_key"];

                    ConfigureStripe(apiKey);

                    var service = new PaymentIntentService();
                    var options = new PaymentIntentCancelOptions();
                    var intent  = service.Cancel(stripePaymentIntentId, options);

                    return(new ApiInfo(GetTransactionId(intent), GetPaymentState(intent)));
                }

                // If there is a transaction ID (a charge) then it's too late to cancel
                // so we just attempt to refund it
                if (order.TransactionInformation.TransactionId != null)
                {
                    return(RefundPayment(order, settings));
                }
            }
            catch (Exception exp)
            {
                LoggingService.Instance.Error <Stripe>("Stripe(" + order.OrderNumber + ") - RefundPayment", exp);
            }

            return(null);
        }
示例#11
0
        public override ApiInfo GetStatus(Order order, IDictionary <string, string> settings)
        {
            try
            {
                order.MustNotBeNull("order");
                settings.MustNotBeNull("settings");
                settings.MustContainKey("mode", "settings");
                settings.MustContainKey(settings["mode"] + "_secret_key", "settings");

                var apiKey = settings[settings["mode"] + "_secret_key"];

                var chargeService = new ChargeService(apiKey);
                var charge        = chargeService.Get(order.TransactionInformation.TransactionId);

                return(new ApiInfo(charge.Id, GetPaymentState(charge)));
            }
            catch (Exception exp)
            {
                LoggingService.Instance.Error <Stripe>("Stripe(" + order.OrderNumber + ") - GetStatus", exp);
            }

            return(null);
        }
        public override ApiInfo CapturePayment(Order order, IDictionary <string, string> settings)
        {
            try
            {
                order.MustNotBeNull("order");
                settings.MustNotBeNull("settings");
                settings.MustContainKey("mode", "settings");
                settings.MustContainKey(settings["mode"] + "_secret_key", "settings");

                // We can only capture a payment intent, so make sure we have one
                // otherwise there is nothing we can do
                var paymentIntentId = order.Properties["stripePaymentIntentId"];
                if (string.IsNullOrWhiteSpace(paymentIntentId))
                {
                    return(null);
                }

                var apiKey = settings[settings["mode"] + "_secret_key"];

                ConfigureStripe(apiKey);

                var paymentIntentService = new PaymentIntentService();
                var paymentIntentOptions = new PaymentIntentCaptureOptions
                {
                    AmountToCapture = DollarsToCents(order.TransactionInformation.AmountAuthorized.Value),
                };
                var paymentIntent = paymentIntentService.Capture(paymentIntentId, paymentIntentOptions);

                return(new ApiInfo(GetTransactionId(paymentIntent), GetPaymentState(paymentIntent)));
            }
            catch (Exception exp)
            {
                LoggingService.Instance.Error <Stripe>("Stripe(" + order.OrderNumber + ") - GetStatus", exp);
            }

            return(null);
        }
        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);
        }
示例#15
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;
        }
示例#16
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);
        }
示例#17
0
        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(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 <Stripe>(request, logPostData: true);
                }

                var apiKey  = settings[settings["mode"] + "_secret_key"];
                var capture = settings["capture"].TryParse <bool>() ?? false;

                // TODO: Create a flag to decide whether to create customers
                // or maybe we should create them if order.customerId is set?
                // var customerService = new CustomerService(apiKey);

                var chargeService = new ChargeService(apiKey);

                var chargeOptions = new ChargeCreateOptions {
                    Amount      = DollarsToCents(order.TotalPrice.Value.WithVat),
                    Currency    = CurrencyService.Instance.Get(order.StoreId, order.CurrencyId).IsoCode,
                    SourceId    = request.Form["stripeToken"],
                    Description = $"{order.CartNumber} - {order.PaymentInformation.Email}",
                    Capture     = capture,
                    Metadata    = new Dictionary <string, string>
                    {
                        { "orderId", order.Id.ToString() },
                        { "cartNumber", order.CartNumber }
                    }
                };

                if (settings.ContainsKey("send_stripe_receipt") && settings["send_stripe_receipt"] == "true")
                {
                    chargeOptions.ReceiptEmail = order.PaymentInformation.Email;
                }

                var charge = chargeService.Create(chargeOptions);

                // Check payment ammount
                if (charge.Amount != chargeOptions.Amount)
                {
                    throw new StripeException(HttpStatusCode.Unauthorized,
                                              new StripeError {
                        ChargeId = charge.Id,
                        Code     = "TEA_ERROR",
                        Message  = "Payment ammount differs from authorized payment ammount"
                    }, "Payment ammount differs from authorized payment ammount");
                }

                // Check paid status
                if (!charge.Paid)
                {
                    throw new StripeException(HttpStatusCode.Unauthorized,
                                              new StripeError {
                        ChargeId = charge.Id,
                        Code     = "TEA_ERROR",
                        Message  = "Payment failed"
                    }, "Payment failed");
                }

                callbackInfo = new CallbackInfo(CentsToDollars(charge.Amount), charge.Id, capture ? PaymentState.Captured : PaymentState.Authorized);
            }
            catch (StripeException e)
            {
                ReturnToPaymentFormWithException(order, request, e);
            }
            catch (Exception exp)
            {
                LoggingService.Instance.Error <Stripe>("Stripe(" + order.CartNumber + ") - ProcessCallback", exp);
            }

            return(callbackInfo);
        }
示例#18
0
        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( "sharedSecret", "settings" );

            IConnector connector = Connector.Create( settings[ "sharedSecret" ] );
            KlarnaOrder klarnaOrder = new KlarnaOrder( connector, new Uri( order.Properties[ "klarnaLocation" ] ) ) {
              ContentType = KlarnaApiRequestContentType
            };
            klarnaOrder.Fetch();

            if ( (string)klarnaOrder.GetValue( "status" ) == "checkout_complete" ) {

              //We need to populate the order with the information entered into Klarna.
              SaveOrderPropertiesFromKlarnaCallback( order, klarnaOrder );

              decimal amount = ( (JObject)klarnaOrder.GetValue( "cart" ) )[ "total_price_including_tax" ].Value<decimal>() / 100M;
              string klarnaId = klarnaOrder.GetValue( "id" ).ToString();

              callbackInfo = new CallbackInfo( amount, klarnaId, PaymentState.Authorized );

              klarnaOrder.Update( new Dictionary<string, object>() { { "status", "created" } } );
            } else {
              throw new Exception( "Trying to process a callback from Klarna with an order that isn't completed" );
            }
              } catch ( Exception exp ) {
            LoggingService.Instance.Error<Klarna>( "Klarna(" + order.CartNumber + ") - Process callback", exp );
              }

              return callbackInfo;
        }