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