# .NET Webhook Receiver Guide

This section of Ottu Webhook Receivers Integration Guide focuses on `.NET` technologies, providing developers with practical examples and clear guidance for integrating Ottu webhook notifications into `.NET` applications. Our objective is to enable effective setup and management of webhook events.

## [**Database Setup**](#database-setup)

Necessary data models and entity configurations for managing and storing webhook notifications and associated data in a `.NET` application are detailed here. The primary goal is to ensure the efficient capture of data pertaining to webhook notifications and  the [Checkout API Responses](https://docs.ottu.com/developer/checkout-api).

## [**Models and Entity Configuration**](#models-and-entity-configuration)

We require two main models: Checkout and Webhook.&#x20;

* #### The Checkout model:&#x20;

  is designed to store details of the checkout process, including the [session ID](https://docs.ottu.com/checkout-api#session_id-string-mandatory) that uniquely identifies each payment transaction.
* #### The Webhook model:&#x20;

  It is structured to capture and store data from webhook notifications.

### [**Creating the Checkout Model**](#creating-the-checkout-model)

The [Checkout model](#the-checkout-model) represents the data structure for storing information received from the [Checkout API response](https://docs.ottu.com/checkout-api#response-parameters). Here’s how you can define this model and configure its entities in `.NET`:

#### Model Definition:

```csharp
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;

namespace YourNamespace.Models
{
    public class Checkout
    {
        [Key]
        [Required]
        [StringLength(100)]
        public string SessionId { get; set; }

        [Required]
        [StringLength(250)]
        public string Type { get; set; }

        [Required]
        [StringLength(250)]
        public string PaymentType { get; set; }

        [Required]
        [StringLength(20)]
        public string Amount { get; set; }

        [Required]
        [StringLength(10)]
        public string CurrencyCode { get; set; }

        [Required]
        [StringLength(250)]
        public string State { get; set; }

        [StringLength(250)]
        public string CustomerId { get; set; }

        [StringLength(250)]
        public string Token { get; set; }

        [Column(TypeName = "jsonb")]
        public JsonDocument Agreement { get; set; }

        [Column(TypeName = "jsonb")]
        public JsonDocument ExtraParams { get; set; }

        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
        public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
    }
}
```

### [Creating Webhook Model in `C#`](#creating-webhook-model-in-c)

```csharp
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
using System.Linq;

namespace YourNamespace.Models
{
    public class Webhook
    {
        [Key]
        public int Id { get; set; }

        [Required]
        [StringLength(250)]
        public string SessionId { get; set; }

        [ForeignKey("Checkout")]
        public string CheckoutSessionId { get; set; }

        public Checkout Checkout { get; set; }

        [Column(TypeName = "jsonb")]
        public JsonDocument Payload { get; set; }

        public DateTime Timestamp { get; set; } = DateTime.UtcNow;

        public static Webhook CreateFromWebhook(string sessionId, JsonDocument payload, ApplicationDbContext context)
        {
            var checkout = context.Checkouts.FirstOrDefault(c => c.SessionId == sessionId);
            var webhook = new Webhook
            {
                SessionId = sessionId,
                Payload = payload,
                CheckoutSessionId = sessionId,  // Ensuring the foreign key is properly assigned
                Checkout = checkout
            };

            context.Webhooks.Add(webhook);
            context.SaveChanges();

            // Potential business logic for updating checkout details can be implemented here
            return webhook;
        }
    }
}
```

## [Setting Up Webhook Controller in `.NET`](#setting-up-webhook-controller-in-.net)

A new `Controller` should be created in your `.NET` project. This can be accomplished manually or by utilizing scaffolding tools in `Visual Studio` or the `.NET CLI`.

Here’s an example of how the `WebhookController` could look:

```csharp
using Microsoft.AspNetCore.Mvc;
using System;
using System.Text.Json;
using YourNamespace.Models;
using System.Linq;
using Microsoft.Extensions.Logging;

namespace YourNamespace.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WebhookController : ControllerBase
    {
        private readonly ILogger<WebhookController> _logger;
        private readonly ApplicationDbContext _context;

        public WebhookController(ILogger<WebhookController> logger, ApplicationDbContext context)
        {
            _logger = logger;
            _context = context;
        }

        [HttpPost]
        public IActionResult ReceiveWebhook([FromBody] JsonElement payload)
        {
            _logger.LogInformation("Webhook received: {Payload}", payload.GetRawText());

            if (!VerifySignature(payload))
            {
                return StatusCode(401, new { detail = "Unable to verify signature" });
            }

            try
            {
                var processedData = ProcessData(payload);
                var savedWebhook = SaveData(processedData);
                return Ok(new { detail = "Success", webhookId = savedWebhook.Id });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to process webhook");
                return StatusCode(400, new { detail = "Failed to process webhook" });
            }
        }

        private bool VerifySignature(JsonElement payload)
        {
            // Assume `CheckSignature` is an actual implementation method
            // Example implementation might look for a computed hash of the payload and compare it against a signature in the header
            var signature = HttpContext.Request.Headers["Signature"].FirstOrDefault();
            // Placeholder for actual implementation:
            return CheckSignature(payload.GetRawText(), signature, _context.WebhookKey);
        }

        private Webhook ProcessData(JsonElement payload)
        {
            // Assuming that the payload structure is known and matches the dictionary key names
            var data = JsonSerializer.Deserialize<Dictionary<string, string>>(payload.GetRawText());
            var sessionId = data["session_id"];
            return Webhook.CreateFromWebhook(sessionId, payload, _context);
        }

        private Webhook SaveData(Webhook webhook)
        {
            _context.Webhooks.Add(webhook);
            _context.SaveChanges();
            return webhook;
        }
    }
}
```

#### **Key Points:**

1. **Signature Verification**:
   * It's crucial to verify the incoming webhook’s signature securely to ensure the data's integrity and authenticity. The signature verification logic should adhere to the method outlined in Ottu’s official documentation, available [here](https://docs.ottu.com/developer/webhooks/signing-mechanism).
2. **Data Processing**:
   * The controller deserializes the JSON payload and processes it according to predefined business rules. The `ProcessData` method is tailored to manage the specific structure of the webhook data.
3. **Data Storage**:
   * Once processed, the data is stored in the database using the `SaveData` method, typically through Entity Framework or another ORM.
4. **Logging**:
   * Logging is essential for debugging and tracking webhook activity. It is important to log both the reception of data and any errors that occur.

**Conclusion:**

The foundational code detailed above establishes a solid starting point for developing a webhook receiver within a `.NET` environment. To further enhance integration and ensure effective operation, consider adopting the above [Key Points](#key-points) with following best practices:

* **Response Status Codes**: It is essential to meticulously manage the response status codes returned to Ottu, ensuring clear communication regarding the success or failure of the webhook handling.
* **Understanding Endpoint Requirements:** Comprehensive knowledge of all endpoint requirements is essential for full compliance with Ottu's operational standards. Detailed information is available on our [Endpoint Requirements](https://docs.ottu.com/developer/webhooks/..#endpoint-requirements) page.

This guide is specifically designed to provide you with the necessary tools to set up a robust and streamlined webhook receiver. By following these industry best practices, you can manage webhook notifications with precision and security, ensuring that your integration is both effective and compliant.
