Compare commits

...

3 Commits

Author SHA1 Message Date
23fb20ecfe Add email to modell 2020-09-11 08:02:04 +02:00
7771904210 use refund email directly 2020-09-11 07:45:52 +02:00
01da9c25bc GreenField: Invoices: Add Refund Email endpoint
This reverts commit 709b06baa330fc670b2e4358dc69ecdb7b6aa4e5.
2020-09-11 07:38:37 +02:00
6 changed files with 146 additions and 0 deletions

View File

@ -47,6 +47,17 @@ namespace BTCPayServer.Client
return await HandleResponse<InvoiceData>(response);
}
public virtual async Task<InvoiceData> AddCustomerEmailToInvoice(string storeId, string invoiceId,
AddCustomerEmailRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var response = await _httpClient.SendAsync(
CreateHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/email", bodyPayload: request,
method: HttpMethod.Post), token);
return await HandleResponse<InvoiceData>(response);
}
public virtual async Task<InvoiceData> MarkInvoiceStatus(string storeId, string invoiceId,
MarkInvoiceStatusRequest request, CancellationToken token = default)
{

View File

@ -12,6 +12,7 @@ namespace BTCPayServer.Client.Models
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
public decimal Amount { get; set; }
public string Currency { get; set; }
public string CustomerEmail { get; set; }
public JObject Metadata { get; set; }
public CheckoutOptions Checkout { get; set; } = new CheckoutOptions();

View File

@ -845,6 +845,17 @@ namespace BTCPayServer.Tests
Assert.Equal(newInvoice.Metadata, invoice.Metadata);
//update
await AssertHttpError(403, async () =>
{
await viewOnly.AddCustomerEmailToInvoice(user.StoreId, invoice.Id, new AddCustomerEmailRequest()
{
Email = "j@g.com"
});
});
await client.AddCustomerEmailToInvoice(user.StoreId, invoice.Id, new AddCustomerEmailRequest()
{
Email = "j@g.com"
});
invoice = await viewOnly.GetInvoice(user.StoreId, newInvoice.Id);
await AssertValidationError(new[] { nameof(MarkInvoiceStatusRequest.Status) }, async () =>

View File

@ -108,6 +108,11 @@ namespace BTCPayServer.Controllers.GreenField
ModelState.AddModelError(nameof(request.Amount), "The amount should be 0 or more.");
}
if (!string.IsNullOrEmpty(request.CustomerEmail) && !EmailValidator.IsEmail(request.CustomerEmail))
{
request.AddModelError(invoiceRequest => invoiceRequest.CustomerEmail, "Invalid email address", this);
}
if (string.IsNullOrEmpty(request.Currency))
{
ModelState.AddModelError(nameof(request.Currency), "Currency is required");
@ -183,6 +188,43 @@ namespace BTCPayServer.Controllers.GreenField
return await GetInvoice(storeId, invoiceId);
}
[Authorize(Policy = Policies.CanCreateInvoice,
AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
[HttpPost("~/api/v1/stores/{storeId}/invoices/{invoiceId}/email")]
public async Task<IActionResult> AddCustomerEmail(string storeId, string invoiceId,
AddCustomerEmailRequest request)
{
var store = HttpContext.GetStoreData();
if (store == null)
{
return NotFound();
}
var invoice = await _invoiceRepository.GetInvoice(invoiceId, true);
if (invoice.StoreId != store.Id)
{
return NotFound();
}
if (!EmailValidator.IsEmail(request.Email))
{
request.AddModelError(invoiceRequest => invoiceRequest.Email, "Invalid email address",
this);
}
else if (!string.IsNullOrEmpty(invoice.RefundMail))
{
request.AddModelError(invoiceRequest => invoiceRequest.Email, "Email address already set",
this);
}
if (!ModelState.IsValid)
return this.CreateValidationError(ModelState);
await _invoiceRepository.UpdateInvoice(invoice.Id, new UpdateCustomerModel() { Email = request.Email });
return await GetInvoice(storeId, invoiceId);
}
[Authorize(Policy = Policies.CanModifyStoreSettings,
AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
[HttpPost("~/api/v1/stores/{storeId}/invoices/{invoiceId}/unarchive")]
@ -219,6 +261,7 @@ namespace BTCPayServer.Controllers.GreenField
return new InvoiceData()
{
ExpirationTime = entity.ExpirationTime,
CustomerEmail = entity.RefundMail,
MonitoringExpiration = entity.MonitoringExpiration,
CreatedTime = entity.InvoiceTime,
Amount = entity.Price,

View File

@ -166,6 +166,7 @@ namespace BTCPayServer.Controllers
entity.Currency = invoice.Currency;
entity.Price = invoice.Amount;
entity.SpeedPolicy = invoice.Checkout.SpeedPolicy ?? store.SpeedPolicy;
entity.RefundMail = invoice.CustomerEmail;
IPaymentFilter excludeFilter = null;
if (invoice.Checkout.PaymentMethods != null)
{

View File

@ -216,6 +216,79 @@
]
}
},
"/api/v1/stores/{storeId}/invoices/{invoiceId}/email": {
"post": {
"tags": [
"Invoices"
],
"summary": "Add customer email to invoice",
"parameters": [
{
"name": "storeId",
"in": "path",
"required": true,
"description": "The store to query",
"schema": {
"type": "string"
}
},
{
"name": "invoiceId",
"in": "path",
"required": true,
"description": "The invoice to update",
"schema": {
"type": "string"
}
}
],
"description": "Adds the customer's email to the invoice if it has not been set already.",
"operationId": "Invoices_AddCustomerEmail",
"responses": {
"200": {
"description": "The updated invoice",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvoiceData"
}
}
}
},
"400": {
"description": "A list of errors that occurred when updating the invoice",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ValidationProblemDetails"
}
}
}
},
"403": {
"description": "If you are authenticated but forbidden to update the invoice"
}
},
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AddCustomerEmailRequest"
}
}
}
},
"security": [
{
"API Key": [
"btcpay.store.cancreateinvoice"
],
"Basic": []
}
]
}
},
"/api/v1/stores/{storeId}/invoices/{invoiceId}/status": {
"post": {
"tags": [
@ -493,6 +566,12 @@
"nullable": true,
"description": "The currency the invoice will use"
},
"customerEmail": {
"type": "string",
"format": "email",
"nullable": true,
"description": "The email of the customer"
},
"metadata": {
"type": "string",
"nullable": true,