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));
 }
Beispiel #2
0
        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 is decimal v ? v <= 0 : false))
            {
                ModelState.AddModelError("Price", "Price must be greater than 0");
            }

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

            DataWrapper <InvoiceResponse> invoice = null;

            try
            {
                invoice = await _InvoiceController.CreateInvoiceCore(new BitpayCreateInvoiceRequest()
                {
                    Price                = model.Price,
                    Currency             = model.Currency,
                    ItemDesc             = model.CheckoutDesc,
                    OrderId              = model.OrderId,
                    NotificationEmail    = model.NotifyEmail,
                    NotificationURL      = model.ServerIpn,
                    RedirectURL          = model.BrowserRedirect,
                    FullNotifications    = true,
                    DefaultPaymentMethod = model.DefaultPaymentMethod
                }, store, HttpContext.Request.GetAbsoluteRoot(), cancellationToken : cancellationToken);
            }
            catch (BitpayHttpException e)
            {
                ModelState.AddModelError("Store", e.Message);
                if (model.JsonResponse)
                {
                    return(BadRequest(ModelState));
                }

                return(View());
            }

            if (model.JsonResponse)
            {
                return(Json(new
                {
                    InvoiceId = invoice.Data.Id,
                    InvoiceUrl = invoice.Data.Url
                }));
            }

            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));
        }
Beispiel #3
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,
                                                          RequiresRefundEmail requiresRefundEmail = RequiresRefundEmail.InheritFromStore,
                                                          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;
            decimal?price = null;
            Dictionary <string, InvoiceSupportedTransactionCurrency> paymentMethods = null;

            ViewPointOfSaleViewModel.Item choice = null;
            if (!string.IsNullOrEmpty(choiceKey))
            {
                var choices = _AppService.GetPOSItems(settings.Template, settings.Currency);
                choice = choices.FirstOrDefault(c => c.Id == choiceKey);
                if (choice == null)
                {
                    return(NotFound());
                }
                title = choice.Title;
                if (choice.Price.Type == ViewPointOfSaleViewModel.Item.ItemPrice.ItemPriceType.Topup)
                {
                    price = null;
                }
                else
                {
                    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.GetPOSItems(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 BitpayCreateInvoiceRequest()
                {
                    ItemCode        = choice?.Id,
                    ItemDesc        = title,
                    Currency        = settings.Currency,
                    Price           = price,
                    BuyerEmail      = email,
                    OrderId         = orderId ?? AppService.GetPosOrderId(appId),
                    NotificationURL =
                        string.IsNullOrEmpty(notificationUrl) ? settings.NotificationUrl : notificationUrl,
                    RedirectURL = !string.IsNullOrEmpty(redirectUrl) ? redirectUrl
                                : !string.IsNullOrEmpty(settings.RedirectUrl) ? settings.RedirectUrl
                                : Request.GetDisplayUrl(),
                    FullNotifications     = true,
                    ExtendedNotifications = true,
                    PosData = string.IsNullOrEmpty(posData) ? null : posData,
                    RedirectAutomatically          = settings.RedirectAutomatically,
                    SupportedTransactionCurrencies = paymentMethods,
                    RequiresRefundEmail            = requiresRefundEmail == RequiresRefundEmail.InheritFromStore
                        ? store.GetStoreBlob().RequiresRefundEmail
                        : requiresRefundEmail == RequiresRefundEmail.On,
                }, store, HttpContext.Request.GetAbsoluteRoot(),
                                                                         new List <string>() { AppService.GetAppInternalTag(appId) },
                                                                         cancellationToken);

                return(RedirectToAction(nameof(UIInvoiceController.Checkout), "UIInvoice", 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 }));
            }
        }