PrimeAPI Quickstart: Uygulamanıza e-İmza Ekleyin
PrimeAPI

PrimeAPI Quickstart: Uygulamanıza e-İmza Ekleyin

PrimeAPI ile web uygulamanıza e-imza özelliği ekleyin. PAdES, CAdES, XAdES ve mobil imza desteği. Bu yazıda .NET örneğiyle PAdES entegrasyonunu adım adım gösteriyoruz.

Nazmi E.

Nazmi E.

ONAYLARIM Destek Ekibi

Bir web uygulaması geliştiriyorsunuz ve müşteriniz "belgeler elektronik imzayla imzalansın" dedi. İmza standartlarını öğrenmek, sertifika yönetimini çözmek, farklı işletim sistemlerinde imza bileşenlerini çalıştırmak... Kulağa haftalar sürecek bir iş gibi geliyor, değil mi?

PrimeAPI tam olarak bu sorunu çözmek için tasarlandı. REST API çağrıları ve Onaylarım altyapısıyla mevcut web uygulamanıza e-imza özelliği kazandırabilirsiniz — hangi dili veya framework'ü kullanıyor olursanız olun.

PrimeAPI Ne Destekliyor?

PrimeAPI, ETSI standartlarına uyumlu üç temel imza formatını ve mobil imzayı tek bir API çatısı altında sunar:

  • PAdES — PDF dosyalarına e-imza. Görsel imza desteği, uzun vadeli doğrulama (LTV). Seviyeler: B-B, B-T, B-LT, B-LTA.
  • CAdES — Her türlü dosyaya e-imza. Detached signature desteği ile orijinal dosyaya dokunmadan imzalama. Seviyeler: BES, EPES, T, C, XL, A.
  • XAdES — XML dosyalarına e-imza. Enveloped, Enveloping ve Detached modları. e-Yazışma, e-Fatura gibi XML tabanlı senaryolar için. Seviyeler: BES, EPES, T, C, XL, A.
  • Mobil İmza — Turkcell, Vodafone ve Türk Telekom üzerinden SMS tabanlı onay ile imza. CAdES, PAdES ve XAdES formatlarının tümünde çalışır.

Tüm formatlarda P1-P4 profil desteği, SHA-256/384/512 hash algoritması seçimi ve imza doğrulama/yükseltme (upgrade) servisleri mevcuttur.

Bu yazıda en yaygın senaryo olan PAdES (PDF imzalama) entegrasyonunu adım adım göstereceğiz. CAdES ve XAdES entegrasyonları da aynı 3 adımlı akışı takip eder; yalnızca endpoint adresleri ve bazı parametreler farklılık gösterir.

Mimari

PrimeAPI, REST API tabanlı bir servistir. Backend tarafında herhangi bir dil veya framework kullanabilirsiniz — .NET, Java, Node.js, Python, Go, PHP... HTTP istekleri atabilen her ortam uygundur. Bu yazıdaki örnekleri .NET 6 ile göstereceğiz.

Entegrasyon üç katmandan oluşur:

[Tarayıcı]  ←→  [Backend Proxy]  ←→  [Onaylarım CoreAPI]
     ↕
[e-İmza Aracı (localhost:8099)]

Tarayıcı (Frontend): Kullanıcı arayüzü. e-İmza Aracı ile doğrudan iletişim kurar.

Backend Proxy (Sizin sunucunuz): API anahtarını güvenli şekilde tutar, Onaylarım CoreAPI'ye istekleri proxy'ler. API anahtarı asla tarayıcıya gönderilmez.

Onaylarım CoreAPI: Hash oluşturma, imza birleştirme ve dosya saklama işlemlerini yürütür.

e-İmza Aracı: Kullanıcının bilgisayarında çalışan hafif bir uygulama. Akıllı kart veya USB token ile yerel imzalama yapar. Java bağımlılığı yoktur; Windows, macOS ve Linux desteklenir.

Ön Gereksinimler

  • PrimeAPI API Anahtarı — Seneka'dan temin edin.
  • Backend uygulaması — Herhangi bir dil/framework. Bu yazıda .NET 6 kullanıyoruz.
  • e-İmza Aracı — Kullanıcının bilgisayarında kurulu olmalı.

1. Backend Proxy'yi Kurun (.NET Örneği)

Minimal bir .NET 6 Web API projesi oluşturun. appsettings.json'a Onaylarım API bilgilerini ekleyin:

{
  "OnaylarimApi": {
    "BaseUrl": "https://apitest.onaylarim.com",
    "ApiKey": "sizin-api-anahtariniz"
  }
}

Test ortamı için apitest.onaylarim.com, production için Seneka'nın size ileteceği URL'yi kullanın.

Options sınıfı:

public class OnaylarimApiOptions
{
    public string BaseUrl { get; set; }
    public string ApiKey { get; set; }
}

Program.cs'te yapılandırma:

builder.Services.Configure<OnaylarimApiOptions>(
    builder.Configuration.GetSection("OnaylarimApi"));

builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
        policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});

NuGet bağımlılıkları: Flurl.Http (HTTP client) ve BirImza.Types (request/response tipleri).

2. Controller Endpoint'lerini Yazın

Tek bir OnaylarimController ile tüm PAdES işlemlerini proxy'leyeceksiniz. Controller constructor'ı:

[ApiController]
[Route("[controller]")]
public partial class OnaylarimController : ControllerBase
{
    private readonly string _baseUrl;
    private readonly string _apiKey;

    public OnaylarimController(IOptions<OnaylarimApiOptions> options)
    {
        _baseUrl = options.Value.BaseUrl;
        _apiKey = options.Value.ApiKey;
    }
}

Dosya Yükleme Endpoint'i

[HttpPost("UploadFile")]
public async Task<IActionResult> UploadFile(IFormFile file)
{
    var response = await $"{_baseUrl}/CoreApiFile/UploadFile"
        .WithHeader("X-API-KEY", _apiKey)
        .PostMultipartAsync(mp =>
            mp.AddFile("file", file.OpenReadStream(), file.FileName))
        .ReceiveJson<OnaylarimApiResponse>();

    return Ok(response);
}

Yanıt, sonraki adımlarda kullanacağınız operationId'yi içerir.

CreateState (Hash Oluşturma)

[HttpPost("CreateStateOnOnaylarimApiForPadesV4")]
public async Task<IActionResult> CreateStateOnOnaylarimApiForPadesV4(
    [FromBody] SignStepOnePadesCoreV4 request)
{
    var response = await $"{_baseUrl}/V4/CoreApiPades/SignStepOnePadesCore"
        .WithHeader("X-API-KEY", _apiKey)
        .PostJsonAsync(request)
        .ReceiveJson<OnaylarimApiResponse>();

    return Ok(response);
}

FinishSign (İmzayı Tamamla)

[HttpPost("FinishSignForPadesV4")]
public async Task<IActionResult> FinishSignForPadesV4(
    [FromBody] SignStepThreePadesCoreV4 request)
{
    var response = await $"{_baseUrl}/V4/CoreApiPades/SignStepThreePadesCore"
        .WithHeader("X-API-KEY", _apiKey)
        .PostJsonAsync(request)
        .ReceiveJson<OnaylarimApiResponse>();

    return Ok(response);
}

3. Request/Response Tipleri

PAdES imzalama için kullanacağınız DTO'lar:

public class SignStepOnePadesCoreV4
{
    public string Certificate { get; set; }     // Base64 sertifika
    public string OperationId { get; set; }      // Dosya yüklemeden gelen ID
    public int SignatureLevel { get; set; }       // 1=BB, 2=BT, 3=BLT, 4=BLTA
    public int Profile { get; set; }              // 0=None, 1=P1, 2=P2, 3=P3, 4=P4
    public int HashAlgorithm { get; set; }        // 0=SHA256, 1=SHA384, 2=SHA512
    public SignatureWidgetInfo SignatureWidgetInfo { get; set; }
}

public class SignStepThreePadesCoreV4
{
    public string SignedData { get; set; }
    public string KeyId { get; set; }
    public string KeySecret { get; set; }
    public string OperationId { get; set; }
}

public class SignatureWidgetInfo
{
    public int Page { get; set; }
    public float X { get; set; }
    public float Y { get; set; }
    public float Width { get; set; }
    public float Height { get; set; }
    public string Text { get; set; }
    public int FontSize { get; set; }
}

public class OnaylarimApiResponse
{
    public bool IsSuccess { get; set; }
    public string OperationId { get; set; }
    public string State { get; set; }
    public string KeyID { get; set; }
    public string KeySecret { get; set; }
    public string Error { get; set; }
}

SignatureLevel enum değerleri: BB(1) temel imza, BT(2) zaman damgalı, BLT(3) uzun vadeli, BLTA(4) arşiv zaman damgalı. Çoğu senaryo için BLTA önerilir.

4. Frontend Entegrasyonu

Frontend tarafında üç iş yapmanız gerekiyor: e-İmza Aracı'na bağlanmak, backend proxy'ye dosya yüklemek ve imzalama akışını yönetmek.

e-İmza Aracı'na Bağlanma

e-İmza Aracı sırasıyla şu adreslerde aranır:

const signerUrls = [
  'https://localsigner.onaylarim.com:8099',
  'http://localsigner.onaylarim.com:8099',
  'http://localhost:8099'
];

async function connectToSigner() {
  for (const url of signerUrls) {
    try {
      await axios.get(`${url}/ping`, { timeout: 500 });
      const resetResponse = await axios.get(`${url}/reset`);
      // resetResponse.data → sertifika listesi
      return { url, certificates: resetResponse.data };
    } catch {
      continue;
    }
  }
  throw new Error('e-İmza Aracı bulunamadı. Lütfen uygulamayı başlatın.');
}

/reset çağrısı hem aracı sıfırlar hem de bağlı akıllı karttaki sertifikaları döner.

İmzalama Akışı

const BACKEND_URL = 'https://localhost:7294'; // veya production URL

async function signPdf(file, certificate, signerUrl, pin) {
  // Adım 0: Dosya yükle
  const formData = new FormData();
  formData.append('file', file);
  
  const uploadResponse = await axios.post(
    `${BACKEND_URL}/Onaylarim/UploadFile`, formData);
  const operationId = uploadResponse.data.operationId;

  // Adım 1: CreateState — hash oluştur
  const createStateResponse = await axios.post(
    `${BACKEND_URL}/Onaylarim/CreateStateOnOnaylarimApiForPadesV4`, {
      certificate: certificate,  // Base64 sertifika verisi
      operationId: operationId,
      signatureLevel: 4,         // BLTA
      profile: 1,                // P1
      hashAlgorithm: 0           // SHA256
    });
  
  const { state, keyID, keySecret } = createStateResponse.data;

  // Adım 2: Yerel imzalama — e-İmza Aracı ile
  const signResponse = await axios.post(`${signerUrl}/signStepTwo`, {
    keyId: keyID,
    keySecret: keySecret,
    state: state,
    slot: 0,
    pin: pin,
    certificateIndex: 0
  });
  
  const signedData = signResponse.data.signedData;

  // Adım 3: FinishSign — imzayı tamamla
  const finishResponse = await axios.post(
    `${BACKEND_URL}/Onaylarim/FinishSignForPadesV4`, {
      signedData: signedData,
      keyId: keyID,
      keySecret: keySecret,
      operationId: createStateResponse.data.operationId
    });

  return finishResponse.data; // { isSuccess, operationId }
}

Görsel İmza

PDF'e görsel imza kutusu eklemek için CreateState adımında signatureWidgetInfo gönderin:

{
  certificate: certificate,
  operationId: operationId,
  signatureLevel: 4,
  profile: 1,
  hashAlgorithm: 0,
  signatureWidgetInfo: {
    page: 1,
    x: 50,
    y: 700,
    width: 200,
    height: 80,
    text: "İmzalayan: Mehmet Yılmaz\nTarih: 12.04.2026",
    fontSize: 10
  }
}

Diğer İmza Türleri

Bu yazıda PAdES'i gösterdik ama CAdES ve XAdES entegrasyonları da aynı 3 adımlı akışı izler. Değişen sadece endpoint adresleri ve bazı ek parametrelerdir:

PAdESCAdESXAdES
KullanımPDF dosyalarıHer türlü dosyaXML dosyaları
StepOne Endpoint/V4/CoreApiPades/SignStepOnePadesCore/V4/CoreApiCades/SignStepOneCadesCore/V4/CoreApiXades/SignStepOneXadesCore
StepThree Endpoint/V4/CoreApiPades/SignStepThreePadesCore/V4/CoreApiCades/SignStepThreeCadesCore/V4/CoreApiXades/SignStepThreeXadesCore
Ek ParametrelersignatureWidgetInfo (görsel imza)detached, serialOrParallelsignatureMode (Enveloped/Enveloping/Detached)

Mobil imza için de ayrı endpoint'ler mevcuttur. Detaylar için API dokümantasyonuna bakabilirsiniz.

Hata Yönetimi

Her API yanıtında isSuccess ve error alanlarını kontrol edin:

if (!response.data.isSuccess) {
  console.error('İşlem başarısız:', response.data.error);
}

Sık karşılaşılan durumlar: e-İmza Aracı'nın çalışmıyor olması (ping timeout), yanlış PIN girişi (signStepTwo hatası), süresi dolmuş sertifika.

Özet

PrimeAPI, CAdES, PAdES, XAdES ve mobil imzayı tek bir REST API çatısı altında sunar. Tüm formatlarda aynı 3 adımlı akış geçerlidir:

  1. Dosya yükleoperationId al
  2. CreateState → Sertifika + operationId gönder, state/keyId/keySecret al
  3. signStepTwo → e-İmza Aracı'nda yerel imzala → signedData al
  4. FinishSignsignedData gönder, imzalı dosyayı tamamla

Backend proxy'niz API anahtarını güvenli tutar, tarayıcı sadece e-İmza Aracı ile konuşur. REST API tabanlı olduğu için dilden ve platformdan bağımsız çalışır.


PrimeAPI V4'ün profil desteği, imza seviyeleri ve diğer yenilikleri hakkında daha fazla bilgi için BirImza PrimeAPI V4 yazımıza göz atabilirsiniz.

Detaylı API dokümantasyonu için primeapidocs.onaylarim.com adresini ziyaret edin.

API anahtarı almak ve entegrasyon desteği için bizimle iletişime geçin.

İlgili Yazılar

Tüm yazıları gör