### Install StandardWebhooks via CLI Source: https://github.com/codefactors/standardwebhooks/blob/main/README.md Command to add the StandardWebhooks NuGet package to a .NET project. ```bash dotnet add package StandardWebhooks --version 1.0.33 ``` -------------------------------- ### Initialize StandardWebhook Class Source: https://context7.com/codefactors/standardwebhooks/llms.txt Demonstrates various ways to instantiate the StandardWebhook class, including using signing keys with or without prefixes, byte arrays, or custom Svix configurations. ```csharp using StandardWebhooks; // Basic initialization with signing key (with whsec_ prefix) var webhook = new StandardWebhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"); // Initialize without prefix (base64-encoded key directly) var webhookNoPrefix = new StandardWebhook("MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"); // Initialize with byte array key byte[] keyBytes = Convert.FromBase64String("MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"); var webhookFromBytes = new StandardWebhook(keyBytes); // Initialize with Svix-compatible headers var webhookSvix = new StandardWebhook( "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw", WebhookConfigurationOptions.Svix ); ``` -------------------------------- ### Implementing Multi-Signature Support Source: https://context7.com/codefactors/standardwebhooks/llms.txt Shows how to verify webhooks when multiple signatures are provided in the header. This is essential for seamless key rotation where multiple signing keys may be valid simultaneously. ```csharp using Microsoft.AspNetCore.Http; using StandardWebhooks; var webhook = new StandardWebhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"); var payload = "{\"event\":\"test\"}"; var msgId = "msg_multi_sig_001"; var timestamp = DateTimeOffset.UtcNow; var validSignature = webhook.Sign(msgId, timestamp, payload); var multipleSignatures = string.Join(" ", new[] { "v1,invalid_old_signature_AAAAAAAAAAAAAAAAAAAAA=", "v2,future_version_signature_BBBBBBBBBBBBBBBBB=", validSignature, "v1,another_invalid_signature_CCCCCCCCCCCCCCCCC=" }); var headers = new HeaderDictionary { { "webhook-id", msgId }, { "webhook-timestamp", timestamp.ToUnixTimeSeconds().ToString() }, { "webhook-signature", multipleSignatures } }; webhook.Verify(payload, headers); Console.WriteLine("Multi-signature verification passed!"); ``` -------------------------------- ### Configure Webhook Header Options Source: https://context7.com/codefactors/standardwebhooks/llms.txt Shows how to use predefined header configurations like StandardWebhooks or Svix, and how to define custom header keys for message ID, signature, and timestamp. ```csharp using StandardWebhooks; var standardOptions = WebhookConfigurationOptions.StandardWebhooks; var webhookStandard = new StandardWebhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw", standardOptions); var svixOptions = WebhookConfigurationOptions.Svix; var webhookSvix = new StandardWebhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw", svixOptions); var customOptions = new WebhookConfigurationOptions { IdHeaderKey = "X-Webhook-Id", SignatureHeaderKey = "X-Webhook-Signature", TimestampHeaderKey = "X-Webhook-Timestamp" }; var webhookCustom = new StandardWebhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw", customOptions); ``` -------------------------------- ### Register and Inject IStandardWebhookFactory in ASP.NET Core Source: https://context7.com/codefactors/standardwebhooks/llms.txt Demonstrates how to register the IStandardWebhookFactory in the dependency injection container and inject it into a controller. It covers basic registration, configuration-based keys, and usage for sending and verifying webhooks. ```csharp using Microsoft.Extensions.DependencyInjection; using StandardWebhooks; var builder = WebApplication.CreateBuilder(args); services.AddSingleton(sp => new StandardWebhookFactory("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw")); services.AddSingleton(sp => new StandardWebhookFactory( "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw", WebhookConfigurationOptions.Svix )); services.AddSingleton(sp => { var config = sp.GetRequiredService(); var signingKey = config["Webhooks:SigningKey"]!; return new StandardWebhookFactory(signingKey); }); [ApiController] [Route("api/[controller]")] public class WebhooksController : ControllerBase { private readonly IStandardWebhookFactory _webhookFactory; public WebhooksController(IStandardWebhookFactory webhookFactory) => _webhookFactory = webhookFactory; [HttpPost("send")] public async Task SendWebhook([FromBody] WebhookRequest request) { var webhook = _webhookFactory.CreateWebhook(); var content = webhook.MakeHttpContent(request.Payload, $"msg_{Guid.NewGuid():N}", DateTimeOffset.UtcNow); return Ok(); } } ``` -------------------------------- ### Generate HttpContent for Webhooks Source: https://github.com/codefactors/standardwebhooks/blob/main/README.md Demonstrates how to create a signed HttpContent object for a webhook payload using a signing key and message metadata. ```csharp var myEntity = new MyEntity { Id = 1, Name = "Test Entity", Description = "This is a test entity" }; var webhook = new StandardWebhook(WEBHOOK_SIGNING_KEY); var sendingTime = DateTimeOffset.UtcNow; var webhookContent = webhook.MakeHttpContent(myEntity, DEFAULT_MSG_ID, sendingTime); ``` -------------------------------- ### Create WebhookContent Directly in C# Source: https://context7.com/codefactors/standardwebhooks/llms.txt Demonstrates how to directly create a `WebhookContent` instance, which is a specialized `ByteArrayContent`. This class is useful for advanced scenarios where manual control over the serialized JSON payload and signature calculation is needed. It automatically sets the `Content-Type` header. ```csharp using System.Text.Json; using StandardWebhooks; public class NotificationPayload { public string Title { get; set; } = default!; public string Message { get; set; } = default!; public DateTime SentAt { get; set; } } // Create webhook content directly var payload = new NotificationPayload { Title = "New Order", Message = "Order #12345 has been placed", SentAt = DateTime.UtcNow }; var jsonOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = false }; // Create WebhookContent instance var webhookContent = WebhookContent.Create(payload, jsonOptions); // Get the serialized content as string (useful for signing) string jsonPayload = webhookContent.ToString(); // Output: {"title":"New Order","message":"Order #12345 has been placed","sentAt":"2024-01-15T10:30:00Z"} // Content-Type header is automatically set // webhookContent.Headers.ContentType: application/json; charset=utf-8 ``` -------------------------------- ### Configure Webhook Factory for Dependency Injection Source: https://github.com/codefactors/standardwebhooks/blob/main/README.md Configures the IStandardWebhookFactory in an ASP.NET Core service container to enable dependency injection of webhook instances. ```csharp // In Program.cs, or wherever services are configured. services.AddSingleton(sp => new StandardWebhookFactory(WEBHOOK_SIGNING_KEY)); // In method, add IStandardWebhookFactory as an injected parameter and then: var webhook = webhookFactory.CreateWebhook(); ``` -------------------------------- ### Generate Webhook Signature Source: https://context7.com/codefactors/standardwebhooks/llms.txt Shows how to sign a payload using the Sign method, which produces a v1 signature string suitable for HTTP headers. ```csharp using StandardWebhooks; var signingKey = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"; var webhook = new StandardWebhook(signingKey); var msgId = "msg_p5jXN8AQM9LWM0D4loKWxJek"; var timestamp = DateTimeOffset.UtcNow; var payload = "{\"event\":\"order.created\",\"data\":{\"orderId\":12345,\"amount\":99.99}}"; // Generate signature string signature = webhook.Sign(msgId, timestamp, payload); Console.WriteLine($"Generated signature: {signature}"); ``` -------------------------------- ### Verify Webhook Signature Source: https://github.com/codefactors/standardwebhooks/blob/main/README.md Shows how to verify the authenticity of an incoming webhook request. It throws a WebhookVerificationException if the signature is invalid. ```csharp // Assumes messageBody contains string representation of message content // and request is an HttpRequest with the Standard Webhooks headers set var webhook = new StandardWebhook(WEBHOOK_SIGNING_KEY); // Throws WebhookVerificationException if verification fails webhook.Verify(messageBody, request.Headers); ``` -------------------------------- ### Create Signed HttpContent with StandardWebhooks in C# Source: https://context7.com/codefactors/standardwebhooks/llms.txt Generates an `HttpContent` object with JSON-serialized payload and automatically includes Standard Webhooks headers like `webhook-id`, `webhook-timestamp`, and `webhook-signature`. This method is recommended for sending webhooks via `HttpClient`. It accepts custom `JsonSerializerOptions` for flexible JSON serialization. ```csharp using System.Text.Json; using System.Text.Json.Serialization; using StandardWebhooks; // Define your webhook payload model public class OrderEvent { public string EventType { get; set; } = default!; public int OrderId { get; set; } public decimal Amount { get; set; } public string CustomerEmail { get; set; } = default!; } // Create the webhook instance var webhook = new StandardWebhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"); // Create payload var orderEvent = new OrderEvent { EventType = "order.created", OrderId = 12345, Amount = 99.99m, CustomerEmail = "customer@example.com" }; var msgId = $"msg_{Guid.NewGuid():N}"; var timestamp = DateTimeOffset.UtcNow; // Create HttpContent with automatic signing HttpContent content = webhook.MakeHttpContent(orderEvent, msgId, timestamp); // Content now has these headers set automatically: // - webhook-id: msg_ // - webhook-timestamp: // - webhook-signature: v1, // - Content-Type: application/json; charset=utf-8 // Send the webhook using var httpClient = new HttpClient(); var response = await httpClient.PostAsync("https://example.com/webhook-endpoint", content); // With custom JSON serialization options var jsonOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, WriteIndented = false }; HttpContent customContent = webhook.MakeHttpContent(orderEvent, msgId, timestamp, jsonOptions); // Payload: {"eventType":"order.created","orderId":12345,"amount":99.99,"customerEmail":"customer@example.com"} ``` -------------------------------- ### Handling WebhookVerificationException in .NET Source: https://context7.com/codefactors/standardwebhooks/llms.txt Demonstrates how to catch and handle WebhookVerificationException when verifying incoming webhook requests. It covers scenarios such as missing headers, invalid signature formats, expired timestamps, and signature mismatches. ```csharp using Microsoft.AspNetCore.Http; using StandardWebhooks; using StandardWebhooks.Diagnostics; var webhook = new StandardWebhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"); // Example 1: Missing required headers var emptyHeaders = new HeaderDictionary(); try { webhook.Verify("{}", emptyHeaders); } catch (WebhookVerificationException ex) { Console.WriteLine(ex.Message); } // Example 2: Invalid signature format var badFormatHeaders = new HeaderDictionary { { "webhook-id", "msg_001" }, { "webhook-timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString() }, { "webhook-signature", "invalid-format-no-comma" } }; try { webhook.Verify("{}", badFormatHeaders); } catch (WebhookVerificationException ex) { Console.WriteLine(ex.Message); } // Example 3: Timestamp too old (> 5 minutes) var oldTimestamp = DateTimeOffset.UtcNow.AddMinutes(-10).ToUnixTimeSeconds(); var oldHeaders = new HeaderDictionary { { "webhook-id", "msg_001" }, { "webhook-timestamp", oldTimestamp.ToString() }, { "webhook-signature", "v1,some_signature" } }; try { webhook.Verify("{}", oldHeaders); } catch (WebhookVerificationException ex) { Console.WriteLine(ex.Message); } // Example 4: Signature mismatch var mismatchHeaders = new HeaderDictionary { { "webhook-id", "msg_001" }, { "webhook-timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString() }, { "webhook-signature", "v1,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" } }; try { webhook.Verify("{\"data\":\"test\"}", mismatchHeaders); } catch (WebhookVerificationException ex) { Console.WriteLine(ex.Message); } ``` -------------------------------- ### POST /api/webhooks/receive Source: https://context7.com/codefactors/standardwebhooks/llms.txt Receives and verifies an incoming webhook request using the configured signing key and headers. ```APIDOC ## POST /api/webhooks/receive ### Description Receives a raw webhook payload and verifies its authenticity using the signature provided in the request headers. ### Method POST ### Endpoint /api/webhooks/receive ### Parameters #### Request Headers - **webhook-id** (string) - Required - The unique message ID. - **webhook-signature** (string) - Required - The HMAC signature. - **webhook-timestamp** (string) - Required - The timestamp of the message. ### Request Example { "data": "..." } ### Response #### Success Response (200) - **Status** (string) - Returns 200 OK if the signature is valid. #### Error Response (401) - **Status** (string) - Returns 401 Unauthorized if the signature verification fails. ``` -------------------------------- ### Create Signed HttpContent for AOT with JsonSerializerContext in C# Source: https://context7.com/codefactors/standardwebhooks/llms.txt Creates an `HttpContent` object for Standard Webhooks using a `JsonSerializerContext` for Native AOT compatibility. This overload ensures trimmer-safe JSON serialization by leveraging source-generated serialization contexts, essential for Ahead-of-Time compilation. ```csharp using System.Text.Json; using System.Text.Json.Serialization; using StandardWebhooks; // Define source-generated serialization context for AOT compatibility [JsonSerializable(typeof(WebhookPayload))] public partial class WebhookJsonContext : JsonSerializerContext { } public class WebhookPayload { public string Type { get; set; } = default!; public Dictionary? Data { get; set; } } // Create webhook with AOT-compatible serialization var webhook = new StandardWebhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"); var payload = new WebhookPayload { Type = "user.updated", Data = new Dictionary { { "userId", 42 }, { "email", "updated@example.com" } } }; var msgId = "msg_aot_example_001"; var timestamp = DateTimeOffset.UtcNow; // Use source-generated context for AOT compatibility HttpContent aotContent = webhook.MakeHttpContent( payload, msgId, timestamp, WebhookJsonContext.Default ); // Send with HttpClient using var httpClient = new HttpClient(); await httpClient.PostAsync("https://example.com/webhook", aotContent); ``` -------------------------------- ### Verify Webhook Signature Source: https://context7.com/codefactors/standardwebhooks/llms.txt Demonstrates verifying incoming webhook requests within an ASP.NET Core controller or manually using the Verify method. It handles exceptions for invalid signatures or expired timestamps. ```csharp using Microsoft.AspNetCore.Http; using StandardWebhooks; using StandardWebhooks.Diagnostics; [HttpPost("webhook")] public async Task ReceiveWebhook([FromServices] IStandardWebhookFactory webhookFactory) { using var reader = new StreamReader(Request.Body); string payload = await reader.ReadToEndAsync(); var webhook = webhookFactory.CreateWebhook(); try { webhook.Verify(payload, Request.Headers); return Ok(); } catch (WebhookVerificationException ex) { return Unauthorized(); } } // Manual header verification example var headers = new HeaderDictionary { { "webhook-id", "msg_p5jXN8AQM9LWM0D4loKWxJek" }, { "webhook-timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString() }, { "webhook-signature", "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=" } }; var verifyWebhook = new StandardWebhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"); verifyWebhook.Verify("{\"test\": 2432232314}", headers); ``` -------------------------------- ### POST /api/webhooks/send Source: https://context7.com/codefactors/standardwebhooks/llms.txt Sends a signed webhook payload to a target URL using the injected IStandardWebhookFactory. ```APIDOC ## POST /api/webhooks/send ### Description Sends a signed webhook payload to a specified target URL. The factory generates the necessary headers based on the configured signing key. ### Method POST ### Endpoint /api/webhooks/send ### Request Body - **Payload** (object) - Required - The data to be sent in the webhook body. - **TargetUrl** (string) - Required - The destination URL for the webhook. ### Request Example { "Payload": { "event": "user.created", "id": 123 }, "TargetUrl": "https://webhook.site/example" } ### Response #### Success Response (200) - **Status** (string) - Returns 200 OK if the webhook was successfully delivered. #### Error Response (4xx/5xx) - **Status** (integer) - Returns the status code received from the target URL. ``` -------------------------------- ### Webhook HttpContent Generation Source: https://github.com/codefactors/standardwebhooks/blob/main/README.md Creates a signed HttpContent object for outgoing webhooks, including necessary headers for the Standard Webhooks specification. ```APIDOC ## POST /generate-webhook ### Description Generates an HttpContent object containing the signed payload, ready to be sent via HttpClient. It automatically calculates the signature based on the payload and signing key. ### Method POST ### Endpoint /generate-webhook ### Parameters #### Request Body - **payload** (object) - Required - The data entity to be sent in the webhook. - **msgId** (string) - Required - A unique identifier for the message. ### Request Example { "payload": {"id": 1, "name": "Test Entity"}, "msgId": "msg_12345" } ### Response #### Success Response (200) - **HttpContent** (object) - The prepared content with 'webhook-signature' and other required headers attached. ``` -------------------------------- ### Webhook Signature Verification Source: https://github.com/codefactors/standardwebhooks/blob/main/README.md Verifies the authenticity of an incoming webhook request by validating its signature against the provided signing key and request headers. ```APIDOC ## POST /verify-webhook ### Description Verifies the signature of an incoming webhook request using the Standard Webhooks specification. If the signature is invalid or missing, it throws a WebhookVerificationException. ### Method POST ### Endpoint /verify-webhook ### Parameters #### Request Body - **messageBody** (string) - Required - The raw string representation of the webhook payload. #### Headers - **webhook-signature** (string) - Required - The signature header provided by the sender. ### Request Example { "messageBody": "{\"id\": 1, \"event\": \"user.created\"}" } ### Response #### Success Response (200) - **status** (string) - Returns success if the signature matches. #### Error Response (400) - **error** (string) - WebhookVerificationException: Thrown when signature validation fails. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.