From 155bf53551cf878816faa9decec8c805295b129a Mon Sep 17 00:00:00 2001 From: "raul@facturapi.io" Date: Thu, 17 Oct 2024 17:39:17 -0600 Subject: [PATCH] chore(webhooks): add webhooks methods with signatureValidation method --- Constants/WebhookEvents.cs | 12 ++++ Models/Webhook.cs | 21 +++++++ Models/WebhookValidateSignature.cs | 20 ++++++ Router/WebhookRouter.cs | 40 ++++++++++++ Wrappers/WebhookWrapper.cs | 98 ++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+) create mode 100644 Constants/WebhookEvents.cs create mode 100644 Models/Webhook.cs create mode 100644 Models/WebhookValidateSignature.cs create mode 100644 Router/WebhookRouter.cs create mode 100644 Wrappers/WebhookWrapper.cs diff --git a/Constants/WebhookEvents.cs b/Constants/WebhookEvents.cs new file mode 100644 index 0000000..54a59b6 --- /dev/null +++ b/Constants/WebhookEvents.cs @@ -0,0 +1,12 @@ +namespace Facturapi +{ + public static class WebhooksEvents + { + public const string INVOICE_CREATED = "invoice.global_invoice_created"; + public const string STATUS_UPDATED = "invoice.status_updated"; + public const string CANCELLATION_STATUS_UPDATED = "invoice.cancellation_status_updated"; + public const string SELF_INVOICE_COMPLETE = "receipt.self_invoice_complete"; + public const string RECEIPT_STATUS_UPDATED = "receipt.status_updated"; + public const string RECEIPT_CANCELLATION_STATUS_UPDATED = "receipt.cancellation_status_updated"; + } +} diff --git a/Models/Webhook.cs b/Models/Webhook.cs new file mode 100644 index 0000000..d5a8bb9 --- /dev/null +++ b/Models/Webhook.cs @@ -0,0 +1,21 @@ +using System; + +namespace Facturapi +{ + public class Webhook + + { + public string Id { get; set; } + public DateTime CreatedAt { get; set; } + + public string[] EnabledEvents { get; set; } + + public bool Livemode { get; set; } + + public Organization Organization { get; set; } + + public string Url { get; set; } + + public string Status { get; set; } + } +} \ No newline at end of file diff --git a/Models/WebhookValidateSignature.cs b/Models/WebhookValidateSignature.cs new file mode 100644 index 0000000..9dbd99e --- /dev/null +++ b/Models/WebhookValidateSignature.cs @@ -0,0 +1,20 @@ +using System; + +namespace Facturapi +{ + public class WebhookValidateSignature + + { + public string Id { get; set; } + public DateTime CreatedAt { get; set; } + + public bool Livemode { get; set; } + + public string Organization { get; set; } + + public string Type { get; set; } + + public object Data { get; set; } + + } +} \ No newline at end of file diff --git a/Router/WebhookRouter.cs b/Router/WebhookRouter.cs new file mode 100644 index 0000000..ffb73a3 --- /dev/null +++ b/Router/WebhookRouter.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +namespace Facturapi +{ + internal static partial class Router + { + public static string ListWebhooks(Dictionary query = null) + { + return UriWithQuery("webhooks", query); + } + + public static string RetrieveWebhook(string id) + { + return $"webhooks/{id}"; + } + + public static string CreateWebhook() + { + return "webhooks"; + } + + public static string UpdateWebhook(string id) + { + return RetrieveWebhook(id); + } + + public static string DeleteWebhook(string id) + { + return RetrieveWebhook(id); + } + + public static string ValidateSignature() + { + return "webhooks/validate-signature"; + } + + + } +} diff --git a/Wrappers/WebhookWrapper.cs b/Wrappers/WebhookWrapper.cs new file mode 100644 index 0000000..156efe5 --- /dev/null +++ b/Wrappers/WebhookWrapper.cs @@ -0,0 +1,98 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace Facturapi.Wrappers +{ + public class WebhookWrapper : BaseWrapper + { + public WebhookWrapper(string apiKey, string apiVersion = "v2") : base(apiKey, apiVersion) + { + } + + public async Task> ListAsync(Dictionary query = null) + { + var response = await client.GetAsync(Router.ListWebhooks(query)); + var resultString = await response.Content.ReadAsStringAsync(); + + if (!response.IsSuccessStatusCode) + { + var error = JsonConvert.DeserializeObject(resultString); + throw new FacturapiException(error["message"].ToString()); + } + + var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); + return searchResult; + } + + public async Task CreateAsync(Dictionary data) + { + var response = await client.PostAsync(Router.CreateWebhook(), new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")); + var resultString = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) + { + var error = JsonConvert.DeserializeObject(resultString); + throw new FacturapiException(error["message"].ToString()); + } + var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); + return webhook; + } + + public async Task RetrieveAsync(string id) + { + var response = await client.GetAsync(Router.RetrieveWebhook(id)); + var resultString = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) + { + var error = JsonConvert.DeserializeObject(resultString); + throw new FacturapiException(error["message"].ToString()); + } + var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); + return webhook; + } + + public async Task UpdateAsync(string id, Dictionary data) + { + var response = await client.PutAsync(Router.UpdateWebhook(id), new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")); + var resultString = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) + { + var error = JsonConvert.DeserializeObject(resultString); + throw new FacturapiException(error["message"].ToString()); + } + var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); + return webhook; + } + + public async Task DeleteAsync(string id) + { + var response = await client.DeleteAsync(Router.DeleteWebhook(id)); + var resultString = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) + { + var error = JsonConvert.DeserializeObject(resultString); + throw new FacturapiException(error["message"].ToString()); + } + var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); + return webhook; + } + + public async Task ValidateSignatureAsync(Dictionary data) + { + var response = await client.PostAsync(Router.ValidateSignature(),new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")); + var resultString = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) + { + var error = JsonConvert.DeserializeObject(resultString); + throw new FacturapiException(error["message"].ToString()); + } + var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); + return webhook; + } + + } +}