← Back to Portfolio

Integrating YGG Gift Cards & Webhook Notifications in ASP.NET Core Web API

Author: Dasan G | Date: June 01, 2025 | Category: Integrations & Webhooks

1. 🎯 Introduction

Modern e-commerce and reward platforms require seamless digital gift card issuance and fulfillment. YGG (YouGotGift / YGG API) enables programmatic gift card ordering, voucher code generation, and real-time status updates via HTTP webhooks.

In this article, we’ll build a complete production integration in C# containing:

2. 💳 YGG Gift Card Service Implementation

Create a dedicated service YggGiftCardService.cs to interact with YGG API endpoints:

using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

public interface IYggGiftCardService
{
    Task<YggOrderResponseDto> CreateGiftCardOrderAsync(YggOrderRequestDto request);
}

public class YggGiftCardService : IYggGiftCardService
{
    private readonly HttpClient _httpClient;
    private readonly IConfiguration _config;

    public YggGiftCardService(HttpClient httpClient, IConfiguration config)
    {
        _httpClient = httpClient;
        _config = config;
        
        var apiKey = _config["YggApi:ApiKey"];
        _httpClient.BaseAddress = new Uri(_config["YggApi:BaseUrl"] ?? "https://api.yougotgift.com/v1/");
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
    }

    public async Task<YggOrderResponseDto> CreateGiftCardOrderAsync(YggOrderRequestDto request)
    {
        var jsonContent = new StringContent(
            JsonSerializer.Serialize(request),
            Encoding.UTF8,
            "application/json");

        var response = await _httpClient.PostAsync("giftcards/order", jsonContent);
        response.EnsureSuccessStatusCode();

        var responseBody = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<YggOrderResponseDto>(responseBody, new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        })!;
    }
}

3. ⚓ Secure YGG Webhook Controller & HMAC Signature Validation

Webhooks deliver real-time events when gift card vouchers are issued, redeemed, or refunded. To prevent unauthorized spoofing, incoming webhook requests must verify the X-YGG-Signature header using HMAC SHA256 hashing:

using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using System.Text;

[ApiController]
[Route("api/webhooks/ygg")]
public class YggWebhookController : ControllerBase
{
    private readonly ILogger<YggWebhookController> _logger;
    private readonly string _webhookSecret;

    public YggWebhookController(IConfiguration config, ILogger<YggWebhookController> logger)
    {
        _logger = logger;
        _webhookSecret = config["YggApi:WebhookSecret"] ?? throw new ArgumentNullException("Secret missing");
    }

    [HttpPost("event-callback")]
    public async Task<IActionResult> HandleWebhookCallback()
    {
        // 1. Read Raw Request Body
        using var reader = new StreamReader(Request.Body);
        var rawJsonBody = await reader.ReadToEndAsync();

        // 2. Validate HMAC SHA256 Signature
        if (!Request.Headers.TryGetValue("X-YGG-Signature", out var receivedSignature))
        {
            _logger.LogWarning("YGG Webhook rejected: Missing X-YGG-Signature header.");
            return Unauthorized("Missing signature header.");
        }

        var computedSignature = ComputeHmacSha256(rawJsonBody, _webhookSecret);
        if (!string.Equals(receivedSignature, computedSignature, StringComparison.OrdinalIgnoreCase))
        {
            _logger.LogWarning("YGG Webhook rejected: Invalid HMAC signature.");
            return Unauthorized("Invalid signature.");
        }

        // 3. Parse Webhook Event Payload
        var webhookEvent = System.Text.Json.JsonSerializer.Deserialize<YggWebhookPayload>(rawJsonBody);
        
        _logger.LogInformation("YGG Webhook Verified | OrderId: {OrderId} | Event: {EventType} | Status: {Status}",
            webhookEvent?.OrderId, webhookEvent?.EventType, webhookEvent?.VoucherStatus);

        // 4. Process Event & Update Database State
        switch (webhookEvent?.EventType)
        {
            case "VOUCHER_ISSUED":
                // Update database order as fulfilled with voucher code
                break;
            case "VOUCHER_REDEEMED":
                // Mark voucher state as redeemed
                break;
            default:
                _logger.LogInformation("Ignored unhandled YGG event type: {EventType}", webhookEvent?.EventType);
                break;
        }

        return Ok(new { status = "success", message = "Webhook processed successfully" });
    }

    private static string ComputeHmacSha256(string data, string secret)
    {
        using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
        var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
        return Convert.ToHexString(hashBytes).ToLowerInvariant();
    }
}

4. ⚙️ Webhook Payload Data Transfer Objects (DTOs)

public class YggWebhookPayload
{
    public string OrderId { get; set; } = string.Empty;
    public string EventType { get; set; } = string.Empty;
    public string VoucherCode { get; set; } = string.Empty;
    public string VoucherStatus { get; set; } = string.Empty;
    public decimal Amount { get; set; }
    public string Currency { get; set; } = "INR";
    public DateTime EventTimestamp { get; set; }
}

5. 🏁 Conclusion

Integrating YGG digital gift cards with HMAC SHA256 authenticated webhooks provides a robust, real-time voucher fulfillment engine in ASP.NET Core Web API. By combining background HTTP clients with secure signature verification, enterprise platforms guarantee both delivery speed and transaction security.

← Back to Portfolio