Compare commits
3 Commits
efwh3
...
invoices/e
Author | SHA1 | Date | |
---|---|---|---|
23fb20ecfe | |||
7771904210 | |||
01da9c25bc |
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 () =>
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user