Skip to content

🔔 Webhook-Operationen

Endpunkt

POST /api/return/webhook/complete-cardstorage/{type}/{id}

Beschreibung

Webhook-Endpunkt, der aufgerufen wird, wenn der Kartenspeicherungsvorgang abgeschlossen ist. Dieser Endpunkt wird automatisch vom System nach Abschluss der 3D-Secure-Verifizierung oder des Kartenregistrierungsprozesses aufgerufen und benachrichtigt, dass die Karteninformationen erfolgreich gespeichert wurden.

Pfadparameter

ParameterTypErforderlichBeschreibung
typestringWebhook-Typ (z.B. "recurring", "paymentOrder")
iduuidOperations-UUID
http
Content-Type: application/json
X-Webhook-Signature: {hash}

Anfrage: CompleteCardStorageWebhookRequest

json
{
  "ownerId": "OWN-123456",
  "cardId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "tenantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "hash": "a1b2c3d4e5f6...",
  "hashFields": "ownerId,cardId,tenantId,timestamp",
  "timestamp": 1708084800000
}

Parameter

ParameterTypErforderlichBeschreibung
ownerIdstringKarteninhaber-ID
cardIduuidGespeicherte Karten-UUID
tenantIduuidMandanten-UUID
hashstringSicherheits-Hash (HMAC-SHA256)
hashFieldsstringIn Hash-Berechnung verwendete Felder
timestampintegerUnix-Zeitstempel (Millisekunden)

Antwort

Erfolgreiche Anfrage (200 OK)

json
{
  "success": true,
  "message": "Kartenspeicherung erfolgreich abgeschlossen"
}

Hash-Verifizierung

Um die Webhook-Sicherheit zu gewährleisten, muss der Hash-Wert eingehender Anfragen verifiziert werden.

Hash-Berechnungsalgorithmus

javascript
// JavaScript-Beispiel
const crypto = require('crypto');

function calculateHash(data, secret) {
  const fields = data.hashFields.split(',');
  const values = fields.map(field => data[field]).join('|');
  
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(values);
  return hmac.digest('hex');
}

// Verifizierung
const receivedHash = request.body.hash;
const calculatedHash = calculateHash(request.body, YOUR_WEBHOOK_SECRET);

if (receivedHash === calculatedHash) {
  // Hash ist gültig, Verarbeitung fortsetzen
} else {
  // Hash ist ungültig, Anfrage ablehnen
}

C#-Beispiel

csharp
using System.Security.Cryptography;
using System.Text;

public string CalculateHash(CompleteCardStorageWebhookRequest data, string secret)
{
    var fields = data.HashFields.Split(',');
    var values = string.Join("|", fields.Select(f => 
        typeof(CompleteCardStorageWebhookRequest)
            .GetProperty(f)
            .GetValue(data)
            .ToString()
    ));
    
    using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
    {
        var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(values));
        return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
    }
}

// Verifizierung
var receivedHash = request.Hash;
var calculatedHash = CalculateHash(request, YOUR_WEBHOOK_SECRET);

if (receivedHash == calculatedHash)
{
    // Hash ist gültig
}

Webhook-Endpunkt Einrichtung

Um Webhooks vom System zu erhalten, müssen Sie Ihren eigenen Endpunkt konfigurieren.

Beispiel Webhook-Handler (Node.js/Express)

javascript
const express = require('express');
const app = express();

app.post('/webhooks/card-storage/:type/:id', express.json(), (req, res) => {
  const { type, id } = req.params;
  const webhookData = req.body;
  
  // Hash-Verifizierung
  const calculatedHash = calculateHash(webhookData, process.env.WEBHOOK_SECRET);
  
  if (webhookData.hash !== calculatedHash) {
    return res.status(401).json({ error: 'Ungültiger Hash' });
  }
  
  // Zeitstempelprüfung (Anfragen älter als 5 Minuten ablehnen)
  const now = Date.now();
  const difference = now - webhookData.timestamp;
  
  if (difference > 5 * 60 * 1000) {
    return res.status(401).json({ error: 'Anfrage abgelaufen' });
  }
  
  // In Datenbank speichern
  console.log(`Kartenspeicherung abgeschlossen für ${type}:${id}`);
  console.log(`Inhaber: ${webhookData.ownerId}, Karte: ${webhookData.cardId}`);
  
  // Erfolgreiche Antwort
  res.json({ success: true });
});

Beispiel Webhook-Handler (C# / ASP.NET Core)

csharp
[ApiController]
[Route("webhooks")]
public class WebhookController : ControllerBase
{
    private readonly string _webhookSecret;
    
    public WebhookController(IConfiguration configuration)
    {
        _webhookSecret = configuration["WebhookSecret"];
    }
    
    [HttpPost("card-storage/{type}/{id}")]
    public IActionResult CompleteCardStorage(
        string type, 
        Guid id, 
        [FromBody] CompleteCardStorageWebhookRequest request)
    {
        // Hash-Verifizierung
        var calculatedHash = CalculateHash(request, _webhookSecret);
        
        if (request.Hash != calculatedHash)
        {
            return Unauthorized(new { error = "Ungültiger Hash" });
        }
        
        // Zeitstempelprüfung
        var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
        var difference = now - request.Timestamp;
        
        if (difference > 5 * 60 * 1000) // 5 Minuten
        {
            return Unauthorized(new { error = "Anfrage abgelaufen" });
        }
        
        // Operation speichern
        _logger.LogInformation(
            "Kartenspeicherung abgeschlossen für {Type}:{Id}, Inhaber: {OwnerId}, Karte: {CardId}",
            type, id, request.OwnerId, request.CardId
        );
        
        return Ok(new { success = true });
    }
}

Webhook-URL-Konfiguration

Sie können Ihre Webhook-URL über das Klogs-Verwaltungspanel konfigurieren:

  1. Melden Sie sich beim Klogs-Dashboard an
  2. Gehen Sie zu Einstellungen > Webhook-Konfiguration
  3. Geben Sie Ihren Endpunkt im Feld Kartenspeicherungs-Webhook-URL ein
  4. Notieren Sie den Webhook-Secret-Schlüssel
  5. Verifizieren Sie durch Senden eines Test-Webhooks

Webhook-URL-Format

https://ihredomain.com/webhooks/card-storage/{type}/{id}

Sicherheitsempfehlungen

  • ✅ Führen Sie immer eine Hash-Verifizierung durch
  • ✅ Verhindern Sie Replay-Angriffe durch Zeitstempelprüfung
  • ✅ Verwenden Sie HTTPS
  • ✅ Speichern Sie Webhook-Secret sicher (Umgebungsvariablen)
  • ✅ Implementieren Sie Ratenbegrenzung
  • ✅ Erwägen Sie die Verwendung einer IP-Whitelist
  • ❌ Verarbeiten Sie nicht ohne Hash-Verifizierung
  • ❌ Kodieren Sie Webhook-Secret nicht fest im Code

Fehlersituationen

SituationBeschreibungLösung
401 UnauthorizedHash-Verifizierung fehlgeschlagenPrüfen Sie den Secret-Schlüssel
401 UnauthorizedZeitstempel abgelaufenPrüfen Sie die Serverzeit
404 Not FoundWebhook-Endpunkt nicht gefundenPrüfen Sie die URL-Konfiguration
500 Server ErrorWebhook-VerarbeitungsfehlerPrüfen Sie die Logs

Wiederholungsmechanismus

Wenn der Webhook fehlschlägt (einen anderen HTTP-Code als 2xx zurückgibt), wiederholt das System automatisch:

    1. Wiederholung: Sofort
    1. Wiederholung: Nach 5 Minuten
    1. Wiederholung: Nach 15 Minuten
    1. Wiederholung: Nach 1 Stunde
    1. Wiederholung: Nach 6 Stunden

⚠️ Hinweis: Nach 5 Versuchen wird der Webhook als fehlgeschlagen markiert und erfordert manuelle Intervention.

Webhook-Protokollierung

Es wird empfohlen, Webhook-Anfragen zu protokollieren:

javascript
// Protokollierungsbeispiel
console.log({
  timestamp: new Date().toISOString(),
  type: type,
  id: id,
  ownerId: webhookData.ownerId,
  cardId: webhookData.cardId,
  success: true
});

Testen

Sie können einen Test-Webhook vom Klogs-Dashboard senden, um Ihren Webhook zu testen:

bash
# Manueller Test mit cURL
curl -X POST https://ihredomain.com/webhooks/card-storage/recurring/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
  -H "Content-Type: application/json" \
  -d '{
    "ownerId": "OWN-TEST",
    "cardId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "tenantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "hash": "test-hash-value",
    "hashFields": "ownerId,cardId,tenantId,timestamp",
    "timestamp": 1708084800000
  }'

Verwandte Endpunkte