🔔 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
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| type | string | ✅ | Webhook-Typ (z.B. "recurring", "paymentOrder") |
| id | uuid | ✅ | Operations-UUID |
Header
Content-Type: application/json
X-Webhook-Signature: {hash}Anfrage: CompleteCardStorageWebhookRequest
{
"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
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| ownerId | string | ❌ | Karteninhaber-ID |
| cardId | uuid | ✅ | Gespeicherte Karten-UUID |
| tenantId | uuid | ✅ | Mandanten-UUID |
| hash | string | ❌ | Sicherheits-Hash (HMAC-SHA256) |
| hashFields | string | ❌ | In Hash-Berechnung verwendete Felder |
| timestamp | integer | ✅ | Unix-Zeitstempel (Millisekunden) |
Antwort
Erfolgreiche Anfrage (200 OK)
{
"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-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
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)
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)
[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:
- Melden Sie sich beim Klogs-Dashboard an
- Gehen Sie zu Einstellungen > Webhook-Konfiguration
- Geben Sie Ihren Endpunkt im Feld Kartenspeicherungs-Webhook-URL ein
- Notieren Sie den Webhook-Secret-Schlüssel
- 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
| Situation | Beschreibung | Lösung |
|---|---|---|
| 401 Unauthorized | Hash-Verifizierung fehlgeschlagen | Prüfen Sie den Secret-Schlüssel |
| 401 Unauthorized | Zeitstempel abgelaufen | Prüfen Sie die Serverzeit |
| 404 Not Found | Webhook-Endpunkt nicht gefunden | Prüfen Sie die URL-Konfiguration |
| 500 Server Error | Webhook-Verarbeitungsfehler | Prüfen Sie die Logs |
Wiederholungsmechanismus
Wenn der Webhook fehlschlägt (einen anderen HTTP-Code als 2xx zurückgibt), wiederholt das System automatisch:
- Wiederholung: Sofort
- Wiederholung: Nach 5 Minuten
- Wiederholung: Nach 15 Minuten
- Wiederholung: Nach 1 Stunde
- 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:
// 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:
# 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
}'
