diff --git a/DocumentService.API/Controllers/PdfSignatureController.cs b/DocumentService.API/Controllers/PdfSignatureController.cs
new file mode 100644
index 0000000..d9efb40
--- /dev/null
+++ b/DocumentService.API/Controllers/PdfSignatureController.cs
@@ -0,0 +1,72 @@
+using DocumentOperator.Application.Common.Dto;
+using DocumentOperator.Application.SignPdf;
+using DocumentService.Domain.Common.Exceptions;
+using MediatR;
+using Microsoft.AspNetCore.Mvc;
+
+namespace DocumentService.API.Controllers;
+
+///
+/// Controller for PDF digital signing (PKCS#11 / company certificate).
+///
+[ApiController]
+[Route("api/pdf/signature")]
+public class PdfSignatureController(IMediator mediator) : ControllerBase
+{
+ ///
+ /// Digitally signs a PDF using the configured PKCS#11 signing infrastructure.
+ ///
+ /// Base64-encoded PDF, optional signature image, and signing options
+ /// Cancellation token
+ /// Signed PDF
+ /// PDF signed successfully - returns signed PDF
+ /// Invalid input (Base64 format error, invalid appearance)
+ /// Internal server error during signing
+ [HttpPost("sign")]
+ [Consumes("application/json")]
+ [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)]
+ public async Task Sign([FromBody] SignPdfRequest request, CancellationToken cancellationToken)
+ {
+ byte[] signedPdf;
+ try
+ {
+ signedPdf = await mediator.Send(new SignPdfCommand
+ {
+ InputPdf = new MemoryStream(Convert.FromBase64String(request.Base64Pdf)),
+ Options = request.Options,
+ SignatureImage = string.IsNullOrWhiteSpace(request.Base64SignatureImage)
+ ? null
+ : new MemoryStream(Convert.FromBase64String(request.Base64SignatureImage))
+ }, cancellationToken);
+ }
+ catch (FormatException ex)
+ {
+ throw new BadRequestException("Invalid Base64 format: " + ex.Message);
+ }
+
+ return File(signedPdf, "application/pdf", "signed.pdf");
+ }
+}
+
+///
+/// Request DTO for PDF signing via JSON payload.
+///
+public sealed class SignPdfRequest
+{
+ ///
+ /// Base64-encoded PDF to sign.
+ ///
+ public required string Base64Pdf { get; init; }
+
+ ///
+ /// Optional Base64-encoded signature image (PNG/JPEG).
+ ///
+ public string? Base64SignatureImage { get; init; }
+
+ ///
+ /// Signing options (metadata + appearance).
+ ///
+ public required PdfSignOptionsDto Options { get; init; }
+}
diff --git a/DocumentService.API/DocumentService.API.csproj b/DocumentService.API/DocumentService.API.csproj
index 1540120..fdfc245 100644
--- a/DocumentService.API/DocumentService.API.csproj
+++ b/DocumentService.API/DocumentService.API.csproj
@@ -36,6 +36,8 @@
+
+
diff --git a/DocumentService.API/Program.cs b/DocumentService.API/Program.cs
index cbd09dd..8943e98 100644
--- a/DocumentService.API/Program.cs
+++ b/DocumentService.API/Program.cs
@@ -7,8 +7,10 @@ using DocumentService.Infrastructure.Configuration;
using DocumentService.Application;
using DocumentService.Application.Common.Configuration;
using DocumentService.Infrastructure;
+using DocumentService.Infrastructure.Crypt.DependencyInjection;
using DocumentService.API.Middleware;
using DocumentService.API.Configuration;
+using DocumentOperator.Application;
var builder = WebApplication.CreateBuilder(args);
@@ -50,6 +52,8 @@ try
// ========================================
builder.Services.AddApplication(builder.Configuration); // Application Layer (MediatR, FluentValidation, Behaviors)
builder.Services.AddInfrastructure(); // Infrastructure Layer (DevExpress, Services)
+ builder.Services.AddDocumentOperatorApplication(builder.Configuration); // PDF signing Application (MediatR)
+ builder.Services.AddCryptInfrastructure(builder.Configuration); // PKCS#11 PDF signing (DevExpress)
builder.Services.AddControllers(); // Controllers (Controller-based API)
builder.Services.AddEndpointsApiExplorer();