mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-20 10:40:29 +01:00
87 lines
3.9 KiB
C#
87 lines
3.9 KiB
C#
using BTCPayServer.Filters;
|
|
using Microsoft.Extensions.Logging;
|
|
using BTCPayServer.Logging;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using NBitcoin;
|
|
using NBitcoin.Payment;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using BTCPayServer.Services.Invoices;
|
|
|
|
namespace BTCPayServer.Controllers
|
|
{
|
|
public partial class InvoiceController
|
|
{
|
|
[HttpGet]
|
|
[Route("i/{invoiceId}/{cryptoCode?}")]
|
|
[AcceptMediaTypeConstraint("application/bitcoin-paymentrequest")]
|
|
public async Task<IActionResult> GetInvoiceRequest(string invoiceId, string cryptoCode = null)
|
|
{
|
|
if (cryptoCode == null)
|
|
cryptoCode = "BTC";
|
|
var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId);
|
|
var network = _NetworkProvider.GetNetwork(cryptoCode);
|
|
var cryptoId = new CryptoDataId(cryptoCode, Payments.PaymentTypes.BTCLike);
|
|
if (invoice == null || invoice.IsExpired() || network == null || !invoice.Support(cryptoId))
|
|
return NotFound();
|
|
|
|
var dto = invoice.EntityToDTO(_NetworkProvider);
|
|
var cryptoData = dto.CryptoInfo.First(c => c.GetCryptoDataId() == cryptoId);
|
|
PaymentRequest request = new PaymentRequest
|
|
{
|
|
DetailsVersion = 1
|
|
};
|
|
request.Details.Expires = invoice.ExpirationTime;
|
|
request.Details.Memo = invoice.ProductInformation.ItemDesc;
|
|
request.Details.Network = network.NBitcoinNetwork;
|
|
request.Details.Outputs.Add(new PaymentOutput() { Amount = cryptoData.Due, Script = BitcoinAddress.Create(cryptoData.Address, network.NBitcoinNetwork).ScriptPubKey });
|
|
request.Details.MerchantData = Encoding.UTF8.GetBytes(invoice.Id);
|
|
request.Details.Time = DateTimeOffset.UtcNow;
|
|
request.Details.PaymentUrl = new Uri(invoice.ServerUrl.WithTrailingSlash() + ($"i/{invoice.Id}"), UriKind.Absolute);
|
|
|
|
var store = await _StoreRepository.FindStore(invoice.StoreId);
|
|
if (store == null)
|
|
throw new BitpayHttpException(401, "Unknown store");
|
|
|
|
if (store.StoreCertificate != null)
|
|
{
|
|
try
|
|
{
|
|
request.Sign(store.StoreCertificate, PKIType.X509SHA256);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logs.PayServer.LogWarning(ex, "Error while signing payment request");
|
|
}
|
|
}
|
|
|
|
return new PaymentRequestActionResult(request);
|
|
}
|
|
|
|
[HttpPost]
|
|
[Route("i/{invoiceId}", Order = 99)]
|
|
[Route("i/{invoiceId}/{cryptoCode}", Order = 99)]
|
|
[MediaTypeConstraint("application/bitcoin-payment")]
|
|
public async Task<IActionResult> PostPayment(string invoiceId, string cryptoCode = null)
|
|
{
|
|
var invoice = await _InvoiceRepository.GetInvoice(null, invoiceId);
|
|
if (cryptoCode == null)
|
|
cryptoCode = "BTC";
|
|
var network = _NetworkProvider.GetNetwork(cryptoCode);
|
|
if (network == null || invoice == null || invoice.IsExpired() || !invoice.Support(new Services.Invoices.CryptoDataId(cryptoCode, Payments.PaymentTypes.BTCLike)))
|
|
return NotFound();
|
|
|
|
var wallet = _WalletProvider.GetWallet(network);
|
|
if (wallet == null)
|
|
return NotFound();
|
|
var payment = PaymentMessage.Load(Request.Body);
|
|
var unused = wallet.BroadcastTransactionsAsync(payment.Transactions);
|
|
await _InvoiceRepository.AddRefundsAsync(invoiceId, payment.RefundTo.Select(p => new TxOut(p.Amount, p.Script)).ToArray(), network.NBitcoinNetwork);
|
|
return new PaymentAckActionResult(payment.CreateACK(invoiceId + " is currently processing, thanks for your purchase..."));
|
|
}
|
|
}
|
|
}
|