Callback / webhook
Polling yerine callback kullanmanızı öneriyoruz. Dashboard'da Developers → Webhooks altında backend adresinizi Callback URL olarak girin. Kullanıcı onayladığında/reddettiğinde Touchque bu URL'ye POST gönderir.
Önerilen yöntem: Callback, polling'e göre daha verimli ve hızlıdır.
Callback payload (Touchque → siz)
| Alan | Tip | Açıklama |
|---|---|---|
requestId | UUID | Giriş isteğinin kimliği |
status | string | "SUCCESS" (onaylandı; durum sorgusunda CONFIRMED) / "REJECTED" |
externalUsername | string | Kullanıcı ID |
timestamp | ISO 8601 | İşlem zamanı |
signature | hex | HMAC-SHA256 imzası |
Callback'te
x-signature header'ını mutlaka doğrulayın! API secret'ınızla imzalanır; Developers → Webhooks altındaki Signing secret aynı değerdir.Callback işleyici
const express = require('express');
const { Touchque } = require('@touchque/node');
const app = express();
const tq = new Touchque({
apiKey: 'tq_abc123',
apiSecret: 'YOUR_API_SECRET'
});
// Webhook Callback - Touchque'dan gelen bildirim
app.post('/touchque/callback', express.text({ type: 'application/json' }), (req, res) => {
try {
const headerSig = req.headers['x-signature'];
// İmzayı doğrula ve içeriği parse et
const payload = tq.webhook.verify({
rawBody: req.body,
signature: headerSig
});
if (payload.status === 'SUCCESS') {
// ✅ Kullanıcı onayladı
console.log(`User ${payload.externalUsername} approved!`);
}
res.json({ received: true });
} catch (err) {
res.status(401).json({ error: 'Invalid signature' });
}
});
app.listen(3000);<?php
require_once 'vendor/autoload.php';
use Touchque\Touchque;
use Touchque\Config;
$tq = new Touchque(new Config('tq_abc123', 'YOUR_API_SECRET'));
$payload = file_get_contents('php://input');
$headerSig = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
try {
// SDK ile imzayı doğrula ve içeriği al
$data = $tq->webhook->verify($payload, $headerSig);
if ($data['status'] === 'SUCCESS') {
// ✅ Kullanıcı onayladı
// loginUser($data['externalUsername']);
}
http_response_code(200);
echo json_encode(['received' => true]);
} catch (\Exception $e) {
http_response_code(401);
echo json_encode(['error' => 'Invalid signature']);
}package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"github.com/Touchque/touchque-go/v5/touchque"
)
func main() {
tq, err := touchque.New(touchque.DefaultConfig("tq_abc123", "YOUR_API_SECRET"))
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/touchque/callback", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
headerSig := r.Header.Get("X-Signature")
// SDK ile imzayı doğrula ve içeriği al
payload, err := tq.Webhook.Verify(string(body), headerSig)
if err != nil {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}
if payload["status"] == "SUCCESS" {
// ✅ Kullanıcı onayladı
fmt.Printf("User %s approved!\n", payload["externalUsername"])
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]bool{"received": true})
})
log.Fatal(http.ListenAndServe(":3000", nil))
}from flask import Flask, request, jsonify
from touchque import Touchque, Config
app = Flask(__name__)
tq = Touchque(Config(api_key="tq_abc123", api_secret="YOUR_API_SECRET"))
@app.route("/touchque/callback", methods=["POST"])
def touchque_callback():
raw_body = request.get_data(as_text=True)
header_sig = request.headers.get("X-Signature", "")
try:
# SDK ile imzayı doğrula ve içeriği al
payload = tq.webhook.verify(raw_body, header_sig)
if payload["status"] == "SUCCESS":
# ✅ Kullanıcı onayladı
print(f"User {payload['externalUsername']} approved!")
return jsonify({"received": True}), 200
except Exception as e:
return jsonify({"error": "Invalid signature"}), 401
if __name__ == "__main__":
app.run(port=3000)// Program.cs (ASP.NET Core; builder.Services.AddTouchque() registers TouchqueClient)
app.MapPost("/touchque/callback", async (HttpRequest request, TouchqueClient tq) =>
{
using var reader = new StreamReader(request.Body);
var rawBody = await reader.ReadToEndAsync();
try
{
// SDK ile imzayı doğrula ve içeriği al
var payload = tq.Webhook.Verify(rawBody, request.Headers["X-Signature"]);
if ((string?)payload["status"] == "SUCCESS")
{
// ✅ Kullanıcı onayladı
}
return Results.Ok(new { received = true });
}
catch (TouchqueWebhookSignatureException)
{
return Results.Unauthorized();
}
});@PostMapping("/touchque/callback")
ResponseEntity<Map<String, Boolean>> callback(@RequestBody String rawBody, @RequestHeader("X-Signature") String signature) {
try {
// SDK ile imzayı doğrula ve içeriği al
ObjectNode payload = tq.webhook().verify(rawBody, signature);
if ("SUCCESS".equals(payload.path("status").asText())) {
// ✅ Kullanıcı onayladı
}
return ResponseEntity.ok(Map.of("received", true));
} catch (TouchqueWebhookSignatureException e) {
return ResponseEntity.status(401).build();
}
}class TouchqueCallbacksController < ApplicationController
skip_forgery_protection
def create
# SDK ile imzayı doğrula ve içeriği al
payload = Touchque.client.webhook.verify(request.raw_post, request.headers["X-Signature"])
if payload["status"] == "SUCCESS"
# ✅ Kullanıcı onayladı
end
render json: { received: true }
rescue Touchque::WebhookSignatureError
head :unauthorized
end
end# Callback sizin sunucunuza gelir.
# Test etmek için örnek payload:
curl -X POST http://localhost:3000/touchque/callback \
-H "Content-Type: application/json" \
-H "x-signature: HMAC_SIGNATURE_HERE" \
-d '{
"requestId": "uuid-123",
"status": "SUCCESS",
"externalUsername": "user@yourcompany.com",
"timestamp": "2026-02-18T00:00:00Z"
}'