Dokümantasyon

Çevrimdışı onay

Kullanıcının telefonu internetsiz olsa bile onay verebilir: sayfanızda bir QR gösterirsiniz, telefon bunu çevrimdışı okur, markanızı ve işlem detaylarını gösterir, Face ID ister ve 7 karakterlik bir kod üretir. Kullanıcı kodu sayfanıza yazar, Touchque doğrular. QR’ın içeriği yalnızca kullanıcının telefonu için şifrelenir; başka bir QR okuyucu veya JWT çözücü yalnızca şifreli veri görür. Kod tek bir işleme bağlıdır ve bir kez geçerlidir.

POST/offline/challenge
EndpointGövdeSonuç
POST /offline/challengeexternalUsername, type, details?, clientIp?, userAgent?, ttlSeconds?QR metni (qr), hazır QR görseli (qrDataUrl), challengeId, süre, totpAvailable
POST /offline/verifychallengeId, code{ approved: true, externalUsername, type } — yanlış kodda 401 + attemptsLeft
POST /offline/totp/verifyexternalUsername, code, type?, clientIp?Zaman tabanlı kod (düşük güvence). Kritik işlemlerde 403
Panel → Developers → App user policy → Offline sekmesinde “Offline sign (QR + code)” anahtarını açın (varsayılan kapalı). Kritik işlemler için ayrıca “Allow offline sign for critical actions” gerekir ve işlem detayı (details) zorunludur. Zaman tabanlı kod aynı sekmede ayrı bir anahtardır, “Offline time-based code (lower assurance)”, ve çevrimdışı onayın açık olmasını ister.
Sınırlar: Kod, telefonun çevrimiçi risk kontrolü olmadan üretilir; sahte bir sayfa gerçek bir QR’ı olduğu gibi gösterebilir (telefon markayı, konumu ve cihazı gösterir). Bu bir MAC tabanlı doğrulamadır: kodu yalnızca Touchque doğrulayabilir. 5 yanlış denemede challenge kilitlenir, kullanıcı başına saatlik başarısız deneme sınırı vardır.
Çevrimdışı zaman tabanlı kod (isteğe bağlı)

Politikada “Offline time-based code” açıksa uygulama, kamera/QR olmadan 30 sn’de bir değişen 7 karakterlik kod gösterir. İşlem detayı taşımaz ve süresi içinde iletilebilir; bu yüzden düşük güvencelidir ve kritik işlemler için asla kabul edilmez. Her kod bir kez kullanılabilir.

Challenge ve doğrulama
const { Touchque } = require('@touchque/node');
const tq = new Touchque({ apiKey: 'tq_abc123', apiSecret: 'YOUR_API_SECRET' });

// 1) Kullanıcı çevrimdışı doğrulamayı seçtiğinde bir meydan okuma oluştur
const challenge = await tq.offline.challenge({
  externalUsername: 'user@yourcompany.com',
  type: 'WITHDRAW',                       // Dashboard'daki işlem tipi
  details: { Amount: '5.000 TRY', To: 'TR12 0006 …' },
  clientIp: req.ip,
  userAgent: req.get('user-agent'),
});

// Sayfada göster:
// <img src={challenge.qrDataUrl} />   (veya challenge.qr metnini kendi QR çiziciniz ile çizin)

// 2) Kullanıcı telefondaki 7 karakterlik kodu yazınca doğrula
const result = await tq.offline.verify({ challengeId: challenge.challengeId, code: 'K7M-2QXP' });
if (result.approved) { /* işlemi tamamla */ }
else { /* result.reason, result.attemptsLeft */ }
Cevap 200
{
  "challengeId": "c0ffee…",
  "qr": "TQ2.k1.pKq3…",
  "qrDataUrl": "data:image/png;base64,…",
  "expiresAt": "2026-09-26T12:02:00.000Z",
  "expiresInSeconds": 120,
  "totpAvailable": false
}
Zaman tabanlı kod
// Düşük güvence: QR/işlem detayı yok. Kritik işlemler için reddedilir.
const result = await tq.offline.verifyTotp({
  externalUsername: 'user@yourcompany.com',
  code: 'K7M-2QXP',
  type: 'LOGIN',
  clientIp: req.ip,
});
// result = { approved: true } | { approved: false, reason: 'invalid_code' | 'offline_totp_disabled' | … }