public async Task <IActionResult> ClaimPullPayment(string pullPaymentId, ViewPullPaymentModel vm) { using var ctx = _dbContextFactory.CreateContext(); var pp = await ctx.PullPayments.FindAsync(pullPaymentId); if (pp is null) { ModelState.AddModelError(nameof(pullPaymentId), "This pull payment does not exists"); } var ppBlob = pp.GetBlob(); var network = _networkProvider.GetNetwork <BTCPayNetwork>(ppBlob.SupportedPaymentMethods.Single().CryptoCode); IClaimDestination destination = null; if (network != null && (!ClaimDestination.TryParse(vm.Destination, network, out destination) || destination is null)) { ModelState.AddModelError(nameof(vm.Destination), $"Invalid destination"); } if (!ModelState.IsValid) { return(await ViewPullPayment(pullPaymentId)); } var result = await _pullPaymentHostedService.Claim(new ClaimRequest() { Destination = destination, PullPaymentId = pullPaymentId, Value = vm.ClaimedAmount, PaymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike) }); if (result.Result != ClaimRequest.ClaimResult.Ok) { if (result.Result == ClaimRequest.ClaimResult.AmountTooLow) { ModelState.AddModelError(nameof(vm.ClaimedAmount), ClaimRequest.GetErrorMessage(result.Result)); } else { ModelState.AddModelError(string.Empty, ClaimRequest.GetErrorMessage(result.Result)); } return(await ViewPullPayment(pullPaymentId)); } else { TempData.SetStatusMessageModel(new StatusMessageModel() { Message = $"You posted a claim of {_currencyNameTable.DisplayFormatCurrency(vm.ClaimedAmount, ppBlob.Currency)} to {vm.Destination}, this will get fullfilled later.", Severity = StatusMessageModel.StatusSeverity.Success }); } return(RedirectToAction(nameof(ViewPullPayment), new { pullPaymentId = pullPaymentId })); }
public async Task <IActionResult> CreatePayout(string pullPaymentId, CreatePayoutRequest request) { if (request is null) { return(NotFound()); } var network = request?.PaymentMethod is string paymentMethod? this._networkProvider.GetNetwork <BTCPayNetwork>(paymentMethod) : null; if (network is null) { ModelState.AddModelError(nameof(request.PaymentMethod), "Invalid payment method"); return(this.CreateValidationError(ModelState)); } using var ctx = _dbContextFactory.CreateContext(); var pp = await ctx.PullPayments.FindAsync(pullPaymentId); if (pp is null) { return(NotFound()); } var ppBlob = pp.GetBlob(); if (request.Destination is null || !ClaimDestination.TryParse(request.Destination, network, out var destination)) { ModelState.AddModelError(nameof(request.Destination), "The destination must be an address or a BIP21 URI"); return(this.CreateValidationError(ModelState)); } if (request.Amount is decimal v && (v < ppBlob.MinimumClaim || v == 0.0m)) { ModelState.AddModelError(nameof(request.Amount), $"Amount too small (should be at least {ppBlob.MinimumClaim})"); return(this.CreateValidationError(ModelState)); } var cd = _currencyNameTable.GetCurrencyData(pp.GetBlob().Currency, false); var result = await _pullPaymentService.Claim(new ClaimRequest() { Destination = destination, PullPaymentId = pullPaymentId, Value = request.Amount, PaymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike) }); switch (result.Result) { case ClaimRequest.ClaimResult.Ok: break; case ClaimRequest.ClaimResult.Duplicate: return(this.CreateAPIError("duplicate-destination", ClaimRequest.GetErrorMessage(result.Result))); case ClaimRequest.ClaimResult.Expired: return(this.CreateAPIError("expired", ClaimRequest.GetErrorMessage(result.Result))); case ClaimRequest.ClaimResult.NotStarted: return(this.CreateAPIError("not-started", ClaimRequest.GetErrorMessage(result.Result))); case ClaimRequest.ClaimResult.Archived: return(this.CreateAPIError("archived", ClaimRequest.GetErrorMessage(result.Result))); case ClaimRequest.ClaimResult.Overdraft: return(this.CreateAPIError("overdraft", ClaimRequest.GetErrorMessage(result.Result))); case ClaimRequest.ClaimResult.AmountTooLow: return(this.CreateAPIError("amount-too-low", ClaimRequest.GetErrorMessage(result.Result))); case ClaimRequest.ClaimResult.PaymentMethodNotSupported: return(this.CreateAPIError("payment-method-not-supported", ClaimRequest.GetErrorMessage(result.Result))); default: throw new NotSupportedException("Unsupported ClaimResult"); } return(Ok(ToModel(result.PayoutData, cd))); }