Example #1
0
        public async Task <IActionResult> PayButtonHandle(string storeId, [FromForm] PayButtonViewModel model)
        {
            var store = StoreData;

            // TODO: extract validation to model
            if (model.Price <= 0)
            {
                ModelState.AddModelError("Price", "Price must be greater than 0");
            }

            if (!ModelState.IsValid)
            {
                return(View());
            }

            var invoice = await _InvoiceController.CreateInvoiceCore(new NBitpayClient.Invoice()
            {
                Price             = model.Price,
                Currency          = model.Currency,
                ItemDesc          = model.CheckoutDesc,
                OrderId           = model.OrderId,
                BuyerEmail        = model.NotifyEmail,
                NotificationURL   = model.ServerIpn,
                RedirectURL       = model.BrowserRedirect,
                FullNotifications = true
            }, store, HttpContext.Request.GetAbsoluteRoot());

            return(Redirect(invoice.Data.Url));
        }
        public async Task <DataWrapper <InvoiceResponse> > CreateInvoice([FromBody] Invoice invoice)
        {
            var bitToken = await CheckTokenPermissionAsync(Facade.Merchant, invoice.Token);

            var store = await FindStore(bitToken);

            return(await _InvoiceController.CreateInvoiceCore(invoice, store, HttpContext.Request.GetAbsoluteRoot()));
        }
Example #3
0
 public async Task <DataWrapper <InvoiceResponse> > CreateInvoice([FromBody] BitpayCreateInvoiceRequest invoice, CancellationToken cancellationToken)
 {
     if (invoice == null)
     {
         throw new BitpayHttpException(400, "Invalid invoice");
     }
     return(await _InvoiceController.CreateInvoiceCore(invoice, HttpContext.GetStoreData(), HttpContext.Request.GetAbsoluteRoot(), cancellationToken : cancellationToken));
 }
        public async Task <IActionResult> PayButtonHandle([FromForm] PayButtonViewModel model, CancellationToken cancellationToken)
        {
            var store = await _StoreRepository.FindStore(model.StoreId);

            if (store == null)
            {
                ModelState.AddModelError("Store", "Invalid store");
            }
            else
            {
                var storeBlob = store.GetStoreBlob();
                if (!storeBlob.AnyoneCanInvoice)
                {
                    ModelState.AddModelError("Store", "Store has not enabled Pay Button");
                }
            }

            if (model == null || model.Price <= 0)
            {
                ModelState.AddModelError("Price", "Price must be greater than 0");
            }

            if (!ModelState.IsValid)
            {
                return(View());
            }

            var invoice = await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
            {
                Price             = model.Price,
                Currency          = model.Currency,
                ItemDesc          = model.CheckoutDesc,
                OrderId           = model.OrderId,
                NotificationEmail = model.NotifyEmail,
                NotificationURL   = model.ServerIpn,
                RedirectURL       = model.BrowserRedirect,
                FullNotifications = true
            }, store, HttpContext.Request.GetAbsoluteRoot(), cancellationToken : cancellationToken);

            if (string.IsNullOrEmpty(model.CheckoutQueryString))
            {
                return(Redirect(invoice.Data.Url));
            }

            var additionalParamValues = HttpUtility.ParseQueryString(model.CheckoutQueryString);
            var uriBuilder            = new UriBuilder(invoice.Data.Url);
            var paramValues           = HttpUtility.ParseQueryString(uriBuilder.Query);

            paramValues.Add(additionalParamValues);
            uriBuilder.Query = paramValues.ToString();
            return(Redirect(uriBuilder.Uri.AbsoluteUri));
        }
Example #5
0
        public async Task <IActionResult> PayButtonHandle([FromForm] PayButtonViewModel model)
        {
            var store = await _StoreRepository.FindStore(model.StoreId);

            if (store == null)
            {
                ModelState.AddModelError("Store", "Invalid store");
            }
            else
            {
                var storeBlob = store.GetStoreBlob();
                if (!storeBlob.AnyoneCanInvoice)
                {
                    ModelState.AddModelError("Store", "Store has not enabled Pay Button");
                }
            }

            if (model == null || model.Price <= 0)
            {
                ModelState.AddModelError("Price", "Price must be greater than 0");
            }

            if (!ModelState.IsValid)
            {
                return(View());
            }

            var invoice = await _InvoiceController.CreateInvoiceCore(new NBitpayClient.Invoice()
            {
                Price             = model.Price,
                Currency          = model.Currency,
                ItemDesc          = model.CheckoutDesc,
                OrderId           = model.OrderId,
                NotificationEmail = model.NotifyEmail,
                NotificationURL   = model.ServerIpn,
                RedirectURL       = model.BrowserRedirect,
                FullNotifications = true
            }, store, HttpContext.Request.GetAbsoluteRoot());

            return(Redirect(invoice.Data.Url));
        }
        public async Task <IActionResult> PayButtonHandle([FromForm] PayButtonViewModel model, CancellationToken cancellationToken)
        {
            var store = await _StoreRepository.FindStore(model.StoreId);

            if (store == null)
            {
                ModelState.AddModelError("Store", "Invalid store");
            }
            else
            {
                var storeBlob = store.GetStoreBlob();
                if (!storeBlob.AnyoneCanInvoice)
                {
                    ModelState.AddModelError("Store", "La tienda no ha habilitado el botón de pago");
                }
            }

            if (model == null || model.Price <= 0)
            {
                ModelState.AddModelError("Price", "El precio debe ser mayor que 0");
            }

            if (!ModelState.IsValid)
            {
                return(View());
            }

            var invoice = await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
            {
                Price             = model.Price,
                Currency          = model.Currency,
                ItemDesc          = model.CheckoutDesc,
                OrderId           = model.OrderId,
                NotificationEmail = model.NotifyEmail,
                NotificationURL   = model.ServerIpn,
                RedirectURL       = model.BrowserRedirect,
                FullNotifications = true
            }, store, HttpContext.Request.GetAbsoluteRoot(), cancellationToken : cancellationToken);

            return(Redirect(invoice.Data.Url));
        }
Example #7
0
        private async Task <IActionResult> CreateInvoiceForPaymentRequest(string id,
                                                                          bool redirectToInvoice,
                                                                          ViewPaymentRequestViewModel result,
                                                                          decimal?amount = null)
        {
            var pr = await _PaymentRequestRepository.FindPaymentRequest(id, null);

            var blob  = pr.GetBlob();
            var store = pr.StoreData;

            store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id));
            try
            {
                var redirectUrl = Request.GetDisplayUrl().TrimEnd("/pay", StringComparison.InvariantCulture)
                                  .Replace("hub?id=", string.Empty, StringComparison.InvariantCultureIgnoreCase);
                var newInvoiceId = (await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
                {
                    OrderId = $"{PaymentRequestRepository.GetOrderIdForPaymentRequest(id)}",
                    Currency = blob.Currency,
                    Price = amount.GetValueOrDefault(result.AmountDue),
                    FullNotifications = true,
                    BuyerEmail = result.Email,
                    RedirectURL = redirectUrl,
                }, store, HttpContext.Request.GetAbsoluteRoot(), new List <string>()
                {
                    PaymentRequestRepository.GetInternalTag(id)
                })).Data.Id;

                if (redirectToInvoice)
                {
                    return(RedirectToAction("Checkout", "Invoice", new { Id = newInvoiceId }));
                }

                return(Ok(newInvoiceId));
            }
            catch (BitpayHttpException e)
            {
                return(BadRequest(e.Message));
            }
        }
        public async Task <IActionResult> ContributeToCrowdfund(string appId, ContributeToCrowdfund request, CancellationToken cancellationToken)
        {
            var app = await _AppService.GetApp(appId, AppType.Crowdfund, true);

            if (app == null)
            {
                return(NotFound());
            }
            var settings = app.GetSettings <CrowdfundSettings>();


            var isAdmin = await _AppService.GetAppDataIfOwner(GetUserId(), appId, AppType.Crowdfund) != null;

            if (!settings.Enabled && !isAdmin)
            {
                return(NotFound("Crowdfund is not currently active"));
            }

            var info = (ViewCrowdfundViewModel)await _AppService.GetAppInfo(appId);

            info.HubPath = AppHub.GetHubPath(this.Request);
            if (!isAdmin &&
                ((settings.StartDate.HasValue && DateTime.Now < settings.StartDate) ||
                 (settings.EndDate.HasValue && DateTime.Now > settings.EndDate) ||
                 (settings.EnforceTargetAmount &&
                  (info.Info.PendingProgressPercentage.GetValueOrDefault(0) +
                   info.Info.ProgressPercentage.GetValueOrDefault(0)) >= 100)))
            {
                return(NotFound("Crowdfund is not currently active"));
            }

            var store = await _AppService.GetStore(app);

            var title = settings.Title;
            var price = request.Amount;

            ViewPointOfSaleViewModel.Item choice = null;
            if (!string.IsNullOrEmpty(request.ChoiceKey))
            {
                var choices = _AppService.Parse(settings.PerksTemplate, settings.TargetCurrency);
                choice = choices.FirstOrDefault(c => c.Id == request.ChoiceKey);
                if (choice == null)
                {
                    return(NotFound("Incorrect option provided"));
                }
                title = choice.Title;
                price = choice.Price.Value;
                if (request.Amount > price)
                {
                    price = request.Amount;
                }
            }

            if (!isAdmin && (settings.EnforceTargetAmount && info.TargetAmount.HasValue && price >
                             (info.TargetAmount - (info.Info.CurrentAmount + info.Info.CurrentPendingAmount))))
            {
                return(NotFound("Contribution Amount is more than is currently allowed."));
            }

            store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id));
            try
            {
                var invoice = await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
                {
                    OrderId               = AppService.GetCrowdfundOrderId(appId),
                    Currency              = settings.TargetCurrency,
                    ItemCode              = request.ChoiceKey ?? string.Empty,
                    ItemDesc              = title,
                    BuyerEmail            = request.Email,
                    Price                 = price,
                    NotificationURL       = settings.NotificationUrl,
                    NotificationEmail     = settings.NotificationEmail,
                    FullNotifications     = true,
                    ExtendedNotifications = true,
                    RedirectURL           = request.RedirectUrl ??
                                            new Uri(new Uri(new Uri(HttpContext.Request.GetAbsoluteRoot()), _BtcPayServerOptions.RootPath), $"apps/{appId}/crowdfund").ToString()
                }, store, HttpContext.Request.GetAbsoluteRoot(),
                                                                         new List <string> {
                    AppService.GetAppInternalTag(appId)
                },
                                                                         cancellationToken : cancellationToken);

                if (request.RedirectToCheckout)
                {
                    return(RedirectToAction(nameof(InvoiceController.Checkout), "Invoice",
                                            new { invoiceId = invoice.Data.Id }));
                }
                else
                {
                    return(Ok(invoice.Data.Id));
                }
            }
            catch (BitpayHttpException e)
            {
                return(BadRequest(e.Message));
            }
        }
        public async Task <IActionResult> PayPaymentRequest(string id, bool redirectToInvoice = true,
                                                            decimal?amount = null, CancellationToken cancellationToken = default)
        {
            if (amount.HasValue && amount.Value <= 0)
            {
                return(BadRequest("Please provide an amount greater than 0"));
            }
            var result = await _PaymentRequestService.GetPaymentRequest(id, GetUserId());

            if (result == null)
            {
                return(NotFound());
            }
            result.HubPath = PaymentRequestHub.GetHubPath(this.Request);
            if (result.AmountDue <= 0)
            {
                if (redirectToInvoice)
                {
                    return(RedirectToAction("ViewPaymentRequest", new { Id = id }));
                }

                return(BadRequest("Payment Request has already been settled."));
            }

            if (result.ExpiryDate.HasValue && DateTime.Now >= result.ExpiryDate)
            {
                if (redirectToInvoice)
                {
                    return(RedirectToAction("ViewPaymentRequest", new { Id = id }));
                }

                return(BadRequest("Payment Request has expired"));
            }

            var statusesAllowedToDisplay = new List <InvoiceStatus>()
            {
                InvoiceStatus.New
            };
            var validInvoice = result.Invoices.FirstOrDefault(invoice =>
                                                              Enum.TryParse <InvoiceStatus>(invoice.Status, true, out var status) &&
                                                              statusesAllowedToDisplay.Contains(status));

            if (validInvoice != null)
            {
                if (redirectToInvoice)
                {
                    return(RedirectToAction("Checkout", "Invoice", new { Id = validInvoice.Id }));
                }

                return(Ok(validInvoice.Id));
            }

            if (result.AllowCustomPaymentAmounts && amount != null)
            {
                amount = Math.Min(result.AmountDue, amount.Value);
            }
            else
            {
                amount = result.AmountDue;
            }


            var pr = await _PaymentRequestRepository.FindPaymentRequest(id, null);

            var blob  = pr.GetBlob();
            var store = pr.StoreData;

            try
            {
                var redirectUrl = Request.GetDisplayUrl().TrimEnd("/pay", StringComparison.InvariantCulture)
                                  .Replace("hub?id=", string.Empty, StringComparison.InvariantCultureIgnoreCase);
                var newInvoiceId = (await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
                {
                    OrderId = $"{PaymentRequestRepository.GetOrderIdForPaymentRequest(id)}",
                    Currency = blob.Currency,
                    Price = amount.Value,
                    FullNotifications = true,
                    BuyerEmail = result.Email,
                    RedirectURL = redirectUrl,
                }, store, HttpContext.Request.GetAbsoluteRoot(),
                                                                               new List <string>()
                {
                    PaymentRequestRepository.GetInternalTag(id)
                },
                                                                               cancellationToken: cancellationToken))
                                   .Data.Id;

                if (redirectToInvoice)
                {
                    return(RedirectToAction("Checkout", "Invoice", new { Id = newInvoiceId }));
                }

                return(Ok(newInvoiceId));
            }
            catch (BitpayHttpException e)
            {
                return(BadRequest(e.Message));
            }
        }
Example #10
0
        public async Task <IActionResult> ViewPointOfSale(string appId,
                                                          PosViewType viewType,
                                                          [ModelBinder(typeof(InvariantDecimalModelBinder))] decimal amount,
                                                          string email,
                                                          string orderId,
                                                          string notificationUrl,
                                                          string redirectUrl,
                                                          string choiceKey,
                                                          string posData = null, CancellationToken cancellationToken = default)
        {
            var app = await _AppService.GetApp(appId, AppType.PointOfSale);

            if (string.IsNullOrEmpty(choiceKey) && amount <= 0)
            {
                return(RedirectToAction(nameof(ViewPointOfSale), new { appId = appId }));
            }
            if (app == null)
            {
                return(NotFound());
            }
            var settings = app.GetSettings <PointOfSaleSettings>();

            settings.DefaultView = settings.EnableShoppingCart ? PosViewType.Cart : settings.DefaultView;
            if (string.IsNullOrEmpty(choiceKey) && !settings.ShowCustomAmount && settings.DefaultView != PosViewType.Cart)
            {
                return(RedirectToAction(nameof(ViewPointOfSale), new { appId = appId, viewType = viewType }));
            }
            string title = null;
            var    price = 0.0m;
            Dictionary <string, InvoiceSupportedTransactionCurrency> paymentMethods = null;

            ViewPointOfSaleViewModel.Item choice = null;
            if (!string.IsNullOrEmpty(choiceKey))
            {
                var choices = _AppService.Parse(settings.Template, settings.Currency);
                choice = choices.FirstOrDefault(c => c.Id == choiceKey);
                if (choice == null)
                {
                    return(NotFound());
                }
                title = choice.Title;
                price = choice.Price.Value;
                if (amount > price)
                {
                    price = amount;
                }

                if (choice.Inventory.HasValue)
                {
                    if (choice.Inventory <= 0)
                    {
                        return(RedirectToAction(nameof(ViewPointOfSale), new { appId = appId }));
                    }
                }

                if (choice?.PaymentMethods?.Any() is true)
                {
                    paymentMethods = choice?.PaymentMethods.ToDictionary(s => s,
                                                                         s => new InvoiceSupportedTransactionCurrency()
                    {
                        Enabled = true
                    });
                }
            }
            else
            {
                if (!settings.ShowCustomAmount && settings.DefaultView != PosViewType.Cart)
                {
                    return(NotFound());
                }
                price = amount;
                title = settings.Title;

                //if cart IS enabled and we detect posdata that matches the cart system's, check inventory for the items
                if (!string.IsNullOrEmpty(posData) &&
                    settings.DefaultView == PosViewType.Cart &&
                    AppService.TryParsePosCartItems(posData, out var cartItems))
                {
                    var choices = _AppService.Parse(settings.Template, settings.Currency);
                    foreach (var cartItem in cartItems)
                    {
                        var itemChoice = choices.FirstOrDefault(c => c.Id == cartItem.Key);
                        if (itemChoice == null)
                        {
                            return(NotFound());
                        }

                        if (itemChoice.Inventory.HasValue)
                        {
                            switch (itemChoice.Inventory)
                            {
                            case int i when i <= 0:
                                return(RedirectToAction(nameof(ViewPointOfSale), new { appId }));

                            case int inventory when inventory < cartItem.Value:
                                return(RedirectToAction(nameof(ViewPointOfSale), new { appId }));
                            }
                        }
                    }
                }
            }
            var store = await _AppService.GetStore(app);

            try
            {
                var invoice = await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
                {
                    ItemCode        = choice?.Id,
                    ItemDesc        = title,
                    Currency        = settings.Currency,
                    Price           = price,
                    BuyerEmail      = email,
                    OrderId         = orderId,
                    NotificationURL =
                        string.IsNullOrEmpty(notificationUrl) ? settings.NotificationUrl : notificationUrl,
                    RedirectURL           = redirectUrl ?? Request.GetDisplayUrl(),
                    FullNotifications     = true,
                    ExtendedNotifications = true,
                    PosData = string.IsNullOrEmpty(posData) ? null : posData,
                    RedirectAutomatically          = settings.RedirectAutomatically,
                    SupportedTransactionCurrencies = paymentMethods,
                }, store, HttpContext.Request.GetAbsoluteRoot(),
                                                                         new List <string>() { AppService.GetAppInternalTag(appId) },
                                                                         cancellationToken);

                return(RedirectToAction(nameof(InvoiceController.Checkout), "Invoice", new { invoiceId = invoice.Data.Id }));
            }
            catch (BitpayHttpException e)
            {
                TempData.SetStatusMessageModel(new StatusMessageModel()
                {
                    Html         = e.Message.Replace("\n", "<br />", StringComparison.OrdinalIgnoreCase),
                    Severity     = StatusMessageModel.StatusSeverity.Error,
                    AllowDismiss = true
                });
                return(RedirectToAction(nameof(ViewPointOfSale), new { appId = appId }));
            }
        }
        public async Task <IActionResult> ViewPointOfSale(string appId,
                                                          [ModelBinder(typeof(InvariantDecimalModelBinder))] decimal amount,
                                                          string email,
                                                          string orderId,
                                                          string notificationUrl,
                                                          string redirectUrl,
                                                          string choiceKey,
                                                          string posData = null, CancellationToken cancellationToken = default)
        {
            var app = await _AppService.GetApp(appId, AppType.PointOfSale);

            if (string.IsNullOrEmpty(choiceKey) && amount <= 0)
            {
                return(RedirectToAction(nameof(ViewPointOfSale), new { appId = appId }));
            }
            if (app == null)
            {
                return(NotFound());
            }
            var settings = app.GetSettings <PointOfSaleSettings>();

            if (string.IsNullOrEmpty(choiceKey) && !settings.ShowCustomAmount && !settings.EnableShoppingCart)
            {
                return(RedirectToAction(nameof(ViewPointOfSale), new { appId = appId }));
            }
            string title = null;
            var    price = 0.0m;

            ViewPointOfSaleViewModel.Item choice = null;
            if (!string.IsNullOrEmpty(choiceKey))
            {
                var choices = _AppService.Parse(settings.Template, settings.Currency);
                choice = choices.FirstOrDefault(c => c.Id == choiceKey);
                if (choice == null)
                {
                    return(NotFound());
                }
                title = choice.Title;
                price = choice.Price.Value;
                if (amount > price)
                {
                    price = amount;
                }
            }
            else
            {
                if (!settings.ShowCustomAmount && !settings.EnableShoppingCart)
                {
                    return(NotFound());
                }
                price = amount;
                title = settings.Title;
            }
            var store = await _AppService.GetStore(app);

            store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id));
            var invoice = await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
            {
                ItemCode        = choice?.Id,
                ItemDesc        = title,
                Currency        = settings.Currency,
                Price           = price,
                BuyerEmail      = email,
                OrderId         = orderId,
                NotificationURL =
                    string.IsNullOrEmpty(notificationUrl) ? settings.NotificationUrl : notificationUrl,
                NotificationEmail     = settings.NotificationEmail,
                RedirectURL           = redirectUrl ?? Request.GetDisplayUrl(),
                FullNotifications     = true,
                ExtendedNotifications = true,
                PosData = string.IsNullOrEmpty(posData) ? null : posData,
                RedirectAutomatically = settings.RedirectAutomatically,
            }, store, HttpContext.Request.GetAbsoluteRoot(),
                                                                     new List <string>() { AppService.GetAppInternalTag(appId) },
                                                                     cancellationToken);

            return(RedirectToAction(nameof(InvoiceController.Checkout), "Invoice", new { invoiceId = invoice.Data.Id }));
        }
Example #12
0
 public async Task <DataWrapper <InvoiceResponse> > CreateInvoice([FromBody] Invoice invoice)
 {
     return(await _InvoiceController.CreateInvoiceCore(invoice, HttpContext.GetStoreData(), HttpContext.Request.GetAbsoluteRoot()));
 }
Example #13
0
        public async Task <IActionResult> ViewPointOfSale(string appId,
                                                          decimal amount,
                                                          string email,
                                                          string orderId,
                                                          string notificationUrl,
                                                          string redirectUrl,
                                                          string choiceKey)
        {
            var app = await _AppsHelper.GetApp(appId, AppType.PointOfSale);

            if (string.IsNullOrEmpty(choiceKey) && amount <= 0)
            {
                return(RedirectToAction(nameof(ViewPointOfSale), new { appId = appId }));
            }
            if (app == null)
            {
                return(NotFound());
            }
            var settings = app.GetSettings <PointOfSaleSettings>();

            if (string.IsNullOrEmpty(choiceKey) && !settings.ShowCustomAmount)
            {
                return(RedirectToAction(nameof(ViewPointOfSale), new { appId = appId }));
            }
            string title = null;
            var    price = 0.0m;

            if (!string.IsNullOrEmpty(choiceKey))
            {
                var choices = _AppsHelper.Parse(settings.Template, settings.Currency);
                var choice  = choices.FirstOrDefault(c => c.Id == choiceKey);
                if (choice == null)
                {
                    return(NotFound());
                }
                title = choice.Title;
                price = choice.Price.Value;
            }
            else
            {
                if (!settings.ShowCustomAmount)
                {
                    return(NotFound());
                }
                price = amount;
                title = settings.Title;
            }
            var store = await _AppsHelper.GetStore(app);

            store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id));
            var invoice = await _InvoiceController.CreateInvoiceCore(new NBitpayClient.Invoice()
            {
                ItemDesc          = title,
                Currency          = settings.Currency,
                Price             = price,
                BuyerEmail        = email,
                OrderId           = orderId,
                NotificationURL   = notificationUrl,
                RedirectURL       = redirectUrl,
                FullNotifications = true
            }, store, HttpContext.Request.GetAbsoluteRoot());

            return(Redirect(invoice.Data.Url));
        }
        public async Task <IActionResult> ContributeToCrowdfund(string appId, ContributeToCrowdfund request)
        {
            var app = await _AppsHelper.GetApp(appId, AppType.Crowdfund, true);

            if (app == null)
            {
                return(NotFound());
            }
            var settings = app.GetSettings <CrowdfundSettings>();


            var isAdmin = await _AppsHelper.GetAppDataIfOwner(GetUserId(), appId, AppType.Crowdfund) != null;

            if (!settings.Enabled)
            {
                if (!isAdmin)
                {
                    return(NotFound("Crowdfund is not currently active"));
                }
            }

            var info = await _CrowdfundHubStreamer.GetCrowdfundInfo(appId);

            if (!isAdmin &&

                ((settings.StartDate.HasValue && DateTime.Now < settings.StartDate) ||
                 (settings.EndDate.HasValue && DateTime.Now > settings.EndDate) ||
                 (settings.EnforceTargetAmount &&
                  (info.Info.PendingProgressPercentage.GetValueOrDefault(0) +
                   info.Info.ProgressPercentage.GetValueOrDefault(0)) >= 100)))
            {
                return(NotFound("Crowdfund is not currently active"));
            }

            var store = await _AppsHelper.GetStore(app);

            var title = settings.Title;
            var price = request.Amount;

            ViewPointOfSaleViewModel.Item choice = null;
            if (!string.IsNullOrEmpty(request.ChoiceKey))
            {
                var choices = _AppsHelper.Parse(settings.PerksTemplate, settings.TargetCurrency);
                choice = choices.FirstOrDefault(c => c.Id == request.ChoiceKey);
                if (choice == null)
                {
                    return(NotFound("Incorrect option provided"));
                }
                title = choice.Title;
                price = choice.Price.Value;
                if (request.Amount > price)
                {
                    price = request.Amount;
                }
            }

            if (!isAdmin && (settings.EnforceTargetAmount && info.TargetAmount.HasValue && price >
                             (info.TargetAmount - (info.Info.CurrentAmount + info.Info.CurrentPendingAmount))))
            {
                return(NotFound("Contribution Amount is more than is currently allowed."));
            }

            store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id));
            var invoice = await _InvoiceController.CreateInvoiceCore(new Invoice()
            {
                OrderId               = $"{CrowdfundHubStreamer.CrowdfundInvoiceOrderIdPrefix}{appId}",
                Currency              = settings.TargetCurrency,
                ItemCode              = request.ChoiceKey ?? string.Empty,
                ItemDesc              = title,
                BuyerEmail            = request.Email,
                Price                 = price,
                NotificationURL       = settings.NotificationUrl,
                FullNotifications     = true,
                ExtendedNotifications = true,
                RedirectURL           = request.RedirectUrl ?? Request.GetDisplayUrl(),
            }, store, HttpContext.Request.GetAbsoluteRoot());

            if (request.RedirectToCheckout)
            {
                return(RedirectToAction(nameof(InvoiceController.Checkout), "Invoice",
                                        new { invoiceId = invoice.Data.Id }));
            }
            else
            {
                return(Ok(invoice.Data.Id));
            }
        }
Example #15
0
        public async Task <IActionResult> PayPaymentRequest(string id, bool redirectToInvoice = true,
                                                            decimal?amount = null, CancellationToken cancellationToken = default)
        {
            if (amount.HasValue && amount.Value <= 0)
            {
                return(BadRequest("Please provide an amount greater than 0"));
            }

            var result = await _PaymentRequestService.GetPaymentRequest(id, GetUserId());

            if (result == null)
            {
                return(NotFound());
            }

            if (result.Archived)
            {
                if (redirectToInvoice)
                {
                    return(RedirectToAction("ViewPaymentRequest", new { Id = id }));
                }

                return(BadRequest("Payment Request cannot be paid as it has been archived"));
            }

            result.HubPath = PaymentRequestHub.GetHubPath(this.Request);
            if (result.AmountDue <= 0)
            {
                if (redirectToInvoice)
                {
                    return(RedirectToAction("ViewPaymentRequest", new { Id = id }));
                }

                return(BadRequest("Payment Request has already been settled."));
            }

            if (result.ExpiryDate.HasValue && DateTime.Now >= result.ExpiryDate)
            {
                if (redirectToInvoice)
                {
                    return(RedirectToAction("ViewPaymentRequest", new { Id = id }));
                }

                return(BadRequest("Payment Request has expired"));
            }

            var stateAllowedToDisplay = new HashSet <InvoiceState>()
            {
                new InvoiceState(InvoiceStatusLegacy.New, InvoiceExceptionStatus.None),
                new InvoiceState(InvoiceStatusLegacy.New, InvoiceExceptionStatus.PaidPartial),
            };
            var currentInvoice = result
                                 .Invoices
                                 .FirstOrDefault(invoice => stateAllowedToDisplay.Contains(invoice.State));

            if (currentInvoice != null)
            {
                if (redirectToInvoice)
                {
                    return(RedirectToAction("Checkout", "Invoice", new { Id = currentInvoice.Id }));
                }

                return(Ok(currentInvoice.Id));
            }

            if (result.AllowCustomPaymentAmounts && amount != null)
            {
                amount = Math.Min(result.AmountDue, amount.Value);
            }
            else
            {
                amount = result.AmountDue;
            }


            var pr = await _PaymentRequestRepository.FindPaymentRequest(id, null, cancellationToken);

            var blob  = pr.GetBlob();
            var store = pr.StoreData;

            try
            {
                var redirectUrl  = _linkGenerator.PaymentRequestLink(id, Request.Scheme, Request.Host, Request.PathBase);
                var newInvoiceId = (await _InvoiceController.CreateInvoiceCore(new BitpayCreateInvoiceRequest()
                {
                    OrderId = $"{PaymentRequestRepository.GetOrderIdForPaymentRequest(id)}",
                    Currency = blob.Currency,
                    Price = amount.Value,
                    FullNotifications = true,
                    BuyerEmail = result.Email,
                    RedirectURL = redirectUrl,
                }, store, HttpContext.Request.GetAbsoluteRoot(),
                                                                               new List <string>()
                {
                    PaymentRequestRepository.GetInternalTag(id)
                },
                                                                               cancellationToken: cancellationToken))
                                   .Data.Id;

                if (redirectToInvoice)
                {
                    return(RedirectToAction("Checkout", "Invoice", new { Id = newInvoiceId }));
                }

                return(Ok(newInvoiceId));
            }
            catch (BitpayHttpException e)
            {
                return(BadRequest(e.Message));
            }
        }