public async Task <IActionResult> CreateInvoice(string storeId, CreateInvoiceRequest request) { var store = HttpContext.GetStoreData(); if (store == null) { return(NotFound()); } if (request.Amount < 0.0m) { ModelState.AddModelError(nameof(request.Amount), "The amount should be 0 or more."); } if (string.IsNullOrEmpty(request.Currency)) { ModelState.AddModelError(nameof(request.Currency), "Currency is required"); } if (request.Checkout.PaymentMethods?.Any() is true) { for (int i = 0; i < request.Checkout.PaymentMethods.Length; i++) { if (!PaymentMethodId.TryParse(request.Checkout.PaymentMethods[i], out _)) { request.AddModelError(invoiceRequest => invoiceRequest.Checkout.PaymentMethods[i], "Invalid payment method", this); } } } if (request.Checkout.Expiration != null && request.Checkout.Expiration < TimeSpan.FromSeconds(30.0)) { request.AddModelError(invoiceRequest => invoiceRequest.Checkout.Expiration, "Expiration time must be at least 30 seconds", this); } if (request.Checkout.PaymentTolerance != null && (request.Checkout.PaymentTolerance < 0 || request.Checkout.PaymentTolerance > 100)) { request.AddModelError(invoiceRequest => invoiceRequest.Checkout.PaymentTolerance, "PaymentTolerance can only be between 0 and 100 percent", this); } if (!ModelState.IsValid) { return(this.CreateValidationError(ModelState)); } try { var invoice = await _invoiceController.CreateInvoiceCoreRaw(request, store, Request.GetAbsoluteUri("")); return(Ok(ToModel(invoice))); } catch (BitpayHttpException e) { return(this.CreateAPIError(null, e.Message)); } }
public async Task <IActionResult> CreateInvoice(string storeId, CreateInvoiceRequest request) { var store = HttpContext.GetStoreData(); if (store == null) { return(StoreNotFound()); } if (request.Amount < 0.0m) { ModelState.AddModelError(nameof(request.Amount), "The amount should be 0 or more."); } if (string.IsNullOrEmpty(request.Currency)) { ModelState.AddModelError(nameof(request.Currency), "Currency is required"); } request.Checkout = request.Checkout ?? new CreateInvoiceRequest.CheckoutOptions(); if (request.Checkout.PaymentMethods?.Any() is true) { for (int i = 0; i < request.Checkout.PaymentMethods.Length; i++) { if (!PaymentMethodId.TryParse(request.Checkout.PaymentMethods[i], out _)) { request.AddModelError(invoiceRequest => invoiceRequest.Checkout.PaymentMethods[i], "Invalid payment method", this); } } } if (request.Checkout.Expiration != null && request.Checkout.Expiration < TimeSpan.FromSeconds(30.0)) { request.AddModelError(invoiceRequest => invoiceRequest.Checkout.Expiration, "Expiration time must be at least 30 seconds", this); } if (request.Checkout.PaymentTolerance != null && (request.Checkout.PaymentTolerance < 0 || request.Checkout.PaymentTolerance > 100)) { request.AddModelError(invoiceRequest => invoiceRequest.Checkout.PaymentTolerance, "PaymentTolerance can only be between 0 and 100 percent", this); } if (request.Checkout.DefaultLanguage != null) { var lang = LanguageService.FindLanguage(request.Checkout.DefaultLanguage); if (lang == null) { request.AddModelError(invoiceRequest => invoiceRequest.Checkout.DefaultLanguage, "The requested defaultLang does not exists, Browse the ~/misc/lang page of your BTCPay Server instance to see the list of supported languages.", this); } else { // Ensure this is good case request.Checkout.DefaultLanguage = lang.Code; } } if (!ModelState.IsValid) { return(this.CreateValidationError(ModelState)); } try { var invoice = await _invoiceController.CreateInvoiceCoreRaw(request, store, Request.GetAbsoluteUri("")); return(Ok(ToModel(invoice))); } catch (BitpayHttpException e) { return(this.CreateAPIError(null, e.Message)); } }
public async Task <IActionResult> ShopifyInvoiceEndpoint( string storeId, string orderId, decimal amount, bool checkOnly = false) { var invoiceOrderId = $"{ShopifyOrderMarkerHostedService.SHOPIFY_ORDER_ID_PREFIX}{orderId}"; var matchedExistingInvoices = await _invoiceRepository.GetInvoices(new InvoiceQuery() { OrderId = new[] { invoiceOrderId }, StoreId = new[] { storeId } }); matchedExistingInvoices = matchedExistingInvoices.Where(entity => entity.GetInternalTags(ShopifyOrderMarkerHostedService.SHOPIFY_ORDER_ID_PREFIX) .Any(s => s == orderId)) .ToArray(); var firstInvoiceStillPending = matchedExistingInvoices.FirstOrDefault(entity => entity.GetInvoiceState().Status == InvoiceStatusLegacy.New); if (firstInvoiceStillPending != null) { return(Ok(new { invoiceId = firstInvoiceStillPending.Id, status = firstInvoiceStillPending.Status.ToString().ToLowerInvariant() })); } var firstInvoiceSettled = matchedExistingInvoices.LastOrDefault(entity => new[] { InvoiceStatusLegacy.Paid, InvoiceStatusLegacy.Complete, InvoiceStatusLegacy.Confirmed } .Contains( entity.GetInvoiceState().Status)); var store = await _storeRepository.FindStore(storeId); var shopify = store?.GetStoreBlob()?.GetShopifySettings(); ShopifyApiClient client = null; ShopifyOrder order = null; if (shopify?.IntegratedAt.HasValue is true) { client = new ShopifyApiClient(_clientFactory, shopify.CreateShopifyApiCredentials()); order = await client.GetOrder(orderId); if (string.IsNullOrEmpty(order?.Id)) { return(NotFound()); } } if (firstInvoiceSettled != null) { //if BTCPay was shut down before the tx managed to get registered on shopify, this will fix it on the next UI load in shopify if (client != null && order?.FinancialStatus == "pending" && firstInvoiceSettled.Status != InvoiceStatusLegacy.Paid) { await new OrderTransactionRegisterLogic(client).Process(orderId, firstInvoiceSettled.Id, firstInvoiceSettled.Currency, firstInvoiceSettled.Price.ToString(CultureInfo.InvariantCulture), true); order = await client.GetOrder(orderId); } if (order?.FinancialStatus != "pending" && order?.FinancialStatus != "partially_paid") { return(Ok(new { invoiceId = firstInvoiceSettled.Id, status = firstInvoiceSettled.Status.ToString().ToLowerInvariant() })); } } if (checkOnly) { return(Ok()); } if (shopify?.IntegratedAt.HasValue is true) { if (string.IsNullOrEmpty(order?.Id) || !new[] { "pending", "partially_paid" }.Contains(order.FinancialStatus)) { return(NotFound()); } //we create the invoice at due amount provided from order page or full amount if due amount is bigger than order amount var invoice = await _invoiceController.CreateInvoiceCoreRaw( new CreateInvoiceRequest() { Amount = amount < order.TotalPrice ? amount : order.TotalPrice, Currency = order.Currency, Metadata = new JObject { ["orderId"] = invoiceOrderId } }, store, Request.GetAbsoluteUri(""), new List <string>() { invoiceOrderId }); return(Ok(new { invoiceId = invoice.Id, status = invoice.Status.ToString().ToLowerInvariant() })); } return(NotFound()); }