WappSync
A

WappSync Phone Verify - API-Dokumentation

Telefonverifizierung, bei der Ihr Nutzer einen Code sendet an uns über WhatsApp - kein OTP eintippen, ein Tippen, vollständig verifiziert.

Wie es funktioniert

1

Sie fordern einen Code an

Ihr Backend ruft unsere API mit der Telefonnummer des Nutzers auf. Wir geben einen eindeutigen Code und die WhatsApp-Nummer zurück, an die er gesendet werden soll.

2

Nutzer sendet ihn über WhatsApp

Ihr Nutzer tippt auf einen WhatsApp-Link - der Code ist vorausgefüllt. Kein Eintippen, kein Kopieren und Einfügen. Er drückt nur auf Senden.

3

Sofort verifiziert

Wir erhalten die Nachricht, sehen, von welcher WhatsApp-Nummer sie gesendet wurde, und Ihre Abfrage gibt auth=1 mit der zertifizierten Telefonnummer zurück. Fertig!

Ihre Anmeldedaten erhalten

Registrieren Sie sich unter wappsync.com/mybusiness um zu erhalten:

AnmeldedatenBeschreibung
businessidIhre numerische Business-ID
businesskeyIhr geheimer Schlüssel - niemals weitergeben, niemals in clientseitigen Code einfügen
Wichtig: Alle API-Aufrufe müssen von Ihrem Backend ausgehen. Der businesskey wird für die HMAC-Signierung verwendet und darf niemals in Browser-JavaScript, HTML-Quelltext oder Mobile-App-Code erscheinen.

Zwei Verifizierungsmodi

Phone Verify läuft in zwei Modi, die pro Anfrage gewählt werden. In beiden sendet Ihr Nutzer den Code an uns über WhatsApp - der einzige Unterschied ist welche Telefonnummer zertifiziert wird.

confirm_phone (default)verify_sender
Sie sendeneine Telefonnummer Nnichts (keine Nummer)
Was zertifiziert wirddass der Anrufer gezielt N kontrolliertwelche Nummer den Code tatsächlich zurücksendet
Typische VerwendungLogin / Wiederherstellung über eine hinterlegte Nummer, Schutz gegen SIM-TauschNeuregistrierung - „gib mir eine echte, nachgewiesene Nummer für diesen Kunden“
Code-ZustellungPer WhatsApp an N gesendet und in Ihrer Oberfläche angezeigt (delivery: pushed_to_phone)nur über Sie (delivery: relay_by_business) - Sie übergeben den Code Ihrem Kunden
Abfrageergebnissender_matches_intended teilt Ihnen mit, ob der Absender N istphoneEnc ist die zertifizierte Nummer; sender_matches_intended wird weggelassen
Sicherheit: confirm_phone beweist die Kontrolle über eine bestimmte angegebene Nummer; verify_sender beweist die Kontrolle über irgendeine Nummer und meldet, welche. Wenn Ihr Ablauf erfordert, dass „die Nummer auf diesem Konto wirklich dem Nutzer gehört“, bleiben Sie bei confirm_phone mit on_mismatch: reject.

Korrigierte Telefonnummer (on_mismatch): ein häufiger Fall ist, dass der Kunde A angibt, den Code aber von B sendet (Tippfehler / Dual-SIM). In confirm_phone wird dies durch reject (Standard) als fehlgeschlagener Versuch behandelt; accept_sender zertifiziert stattdessen den tatsächlichen Absender B (sender_matches_intended: false, phoneEnc = B), und Ihr Backend entscheidet, ob es die korrigierte Nummer B akzeptiert oder ein neues OTP für A anfordert.

Ein Reverse-OTP anfordern

Rufen Sie dies von Ihrem Backend auf, wenn Sie einen Nutzer verifizieren müssen:

POSThttps://wappsync.com/phone-verify/api/getReverseOTP

Anfrage-Body (JSON)

FeldTypBeschreibung
businessidintIhre Business-ID
businessrefstringEine eindeutige Referenz, die Sie für diese Authentifizierungsanfrage erzeugen (z. B. bin2hex(random_bytes(4)))
phonestringDie Telefonnummer des Nutzers im internationalen Format (+40755123456). Erforderlich im Modus confirm_phone; bei verify_sender weglassen oder leer lassen.
modestringOptional - confirm_phone (Standard, wenn ein Telefon angegeben wird) oder verify_sender (Standard, wenn das Telefon weggelassen wird)
on_mismatchstringOptional (nur confirm_phone) - reject (Standard) oder accept_sender (zertifiziert den tatsächlichen Absender, wenn der Code von einer anderen Nummer kommt)
tsintAktueller Unix-Zeitstempel
hmacstringHMAC-SHA256-Signatur

HMAC-Signierung

Signieren Sie diese Zeichenfolge mit Ihrem businesskey:

{businessid}|{businessref}|{phone}|{ts}

Im Modus verify_sender gibt es kein Telefon, daher lautet die signierte Zeichenfolge {businessid}|{businessref}||{ts} (leeres mittleres Feld).

Beispiel:

$hmac = hash_hmac('sha256', "{$businessid}|{$businessref}|{$phone}|{$ts}", $businesskey);

Antwort

FeldTypBeschreibung
statusstring"ok" or "error"
reverseotp_displaystringDer Code, den Ihr Nutzer sendet, z. B. "2FA-828161"
waphonestringDie WhatsApp-Nummer, AN die Ihr Nutzer den Code sendet
logincodestringInterner Code zur Verwendung beim Abfragen
in_tsintZeitstempel für die Abfrageanfrage
out_tsintZeitstempel der Antwort
otp_valid_minutesintWie lange der Code gültig ist (Standard 10)
modestringDer aktive Modus: confirm_phone oder verify_sender
deliverystringpushed_to_phone (confirm_phone: der Code wird zusätzlich per WhatsApp an das angegebene Telefon gesendet) oder relay_by_business (verify_sender: Sie müssen den Code selbst an Ihren Kunden weitergeben)
hmacstringHMAC der Antwort - verifizieren mit Ihrem businesskey

HMAC der Antwort verifizieren against {businessid}|{businessref}|{logincode}|{reverseotp_display}|{waphone}|{out_ts}.

Was Sie Ihrem Nutzer anzeigen sollten

Zeigen Sie den Code und die Telefonnummer an. Verwenden Sie einen whatsapp://send-Link, damit der Nutzer ihn mit einem Tippen senden kann:

<a href="whatsapp://send?phone=40725296320&text=2FA-828161">
  💬 Send Code via WhatsApp
</a>

Verifizierung abfragen

Abfragen alle 2-3 Sekunden bis der Nutzer verifiziert ist:

POSThttps://wappsync.com/phone-verify/api/getReverseOTPStatus

Anfrage-Body (JSON)

FeldTypBeschreibung
businessidintIhre Business-ID
businessrefstringDieselbe Referenz wie beim vorherigen Aufruf
logincodestringDer logincode aus der getReverseOTP-Antwort
in_tsintDer ursprüngliche ts aus der getReverseOTP-Anfrage
hmacstringHMAC-SHA256 von {businessid}|{businessref}|{logincode}|{in_ts}

Antwort

FeldTypBedeutung
used0⏳ Noch am Warten - fragen Sie erneut ab
used1✅ Gerade verifiziert - die erste Abfrage, die dies sieht, verbraucht ihn
used2🔒 Bereits von einer früheren Abfrage verbraucht
auth1Nutzer ist verifiziert - melden Sie ihn an!
phoneEncstringZertifizierte Telefonnummer, AES-256-CBC-verschlüsselt (nur bei auth=1) - der Absender, wenn ein Code empfangen wurde (identisch mit Ihrer angegebenen Nummer bei striktem confirm_phone)
triesintFehlgeschlagene Versuche werden gezählt (falscher Code oder falsches Telefon)
expiredbooltrue bei zu vielen fehlgeschlagenen Versuchen (Versuche ≥ 4) - fordern Sie ein neues OTP an
modestringDer Modus dieser Anfrage: confirm_phone oder verify_sender
sender_matches_intendedboolconfirm_phone nur, sobald ein Code empfangen wurde - true = der Absender ist die Nummer, die Sie verifizieren wollten; false = ein korrigierter Absender wurde zertifiziert. Wird bei verify_sender weggelassen.
out_tsintZeitstempel der Antwort
hmacstringHMAC - verifizieren mit {businessid}|{businessref}|{logincode}|{used}|{phoneEnc}|{out_ts}

Wenn auth === 1, wurde ein gültiger Code empfangen. Entschlüsseln Sie phoneEnc, um die zertifizierte Telefonnummer zu erhalten (prüfen Sie sender_matches_intended im Modus confirm_phone), und melden Sie den Nutzer dann an.

Telefonnummer entschlüsseln

Wenn auth=1, enthält phoneEnc die zertifizierte Telefonnummer (den Absender, der sich bewiesen hat), verschlüsselt mit AES-256-CBC unter Verwendung Ihres businesskey:

function decryptPhoneAES($encryptedData, $businesskey) {
    $method = 'AES-256-CBC';
    $key = hash('sha256', $businesskey, true);
    $enc = str_replace(['-', '_'], ['+', '/'], $encryptedData);
    $enc = str_pad($enc, strlen($enc) % 4 === 0
        ? strlen($enc) : strlen($enc) + 4 - strlen($enc) % 4,
        '=', STR_PAD_RIGHT);
    $decoded = base64_decode($enc);
    $iv = substr($decoded, 0, 16);
    $ciphertext = substr($decoded, 16);
    return openssl_decrypt($ciphertext, $method, $key, OPENSSL_RAW_DATA, $iv);
}

$phone = decryptPhoneAES($response['phoneEnc'], $businesskey);
// Store this phone - it's the user's verified identity

Frontend-Beispiel

Die einzige Oberfläche, die Sie brauchen - zeigen Sie sie an, nachdem Ihr Backend getReverseOTP aufgerufen hat:

<div style="text-align:center; max-width:400px; margin:auto;">
  <p>Send this exact code via WhatsApp from your phone:</p>

  <div style="font-size:28px; font-weight:bold; color:#25D366;
              letter-spacing:3px;">
    2FA-828161
  </div>

  <p>to <strong>+40 725 296 320</strong></p>

  <a href="whatsapp://send?phone=40725296320&text=2FA-828161"
     style="display:inline-block; padding:14px 30px; background:#25D366;
            color:white; font-size:18px; font-weight:bold; border-radius:8px;
            text-decoration:none; margin-top:12px;">
    💬 Send via WhatsApp
  </a>

  <p style="color:#888; font-size:13px; margin-top:12px;">
    ⏱ Code expires in 10 minutes - no typing required!
  </p>
</div>

Vollständiges PHP-Beispiel

Bereit zum Kopieren und Einfügen. Ersetzen Sie YOUR_BUSINESS_ID und 'your-secret-key' durch die Werte von wappsync.com/mybusiness.

<?php
$businessid  = YOUR_BUSINESS_ID;       // from wappsync.com/mybusiness
$businesskey = 'your-secret-key';       // from wappsync.com/mybusiness - keep server-side

// ── Step 1: Request reverse OTP ──
$businessref = bin2hex(random_bytes(4));
$phone       = $_POST['phone'];         // user's phone from your form
$ts          = time();

$hmac = hash_hmac('sha256',
    "{$businessid}|{$businessref}|{$phone}|{$ts}",
    $businesskey
);

$response = callAPI('https://wappsync.com/phone-verify/api/getReverseOTP', [
    'businessid'  => $businessid,
    'businessref' => $businessref,
    'phone'       => $phone,
    'ts'          => $ts,
    'hmac'        => $hmac,
]);

$data = json_decode($response, true);
$code      = $data['reverseotp_display'];  // "2FA-828161"
$waphone   = $data['waphone'];             // "+40725296320"
$logincode = $data['logincode'];
$in_ts     = $data['in_ts'];

// ── Show the code to your user (render frontend example above) ──

// ── Step 2: Poll until verified ──
$maxAttempts = 40;  // ~2 minutes at 3s intervals
$attempt = 0;

do {
    sleep(3);
    $attempt++;

    $hmac = hash_hmac('sha256',
        "{$businessid}|{$businessref}|{$logincode}|{$in_ts}",
        $businesskey
    );

    $response = callAPI(
        'https://wappsync.com/phone-verify/api/getReverseOTPStatus',
        [
            'businessid'  => $businessid,
            'businessref' => $businessref,
            'logincode'   => $logincode,
            'in_ts'       => $in_ts,
            'hmac'        => $hmac,
        ]
    );

    $data = json_decode($response, true);

} while (($data['auth'] ?? 0) !== 1 && $attempt < $maxAttempts);

if (($data['auth'] ?? 0) === 1) {
    // ✅ Verified - log the user in!
    $phone = decryptPhoneAES($data['phoneEnc'], $businesskey);
    $_SESSION['user_phone'] = $phone;
    header('Location: /dashboard');
    exit;
} else {
    echo "Verification timed out. Please try again.";
}

// ── Helper ──
function callAPI($url, $payload) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
}

verify_sender: senden Sie phone => '' (und optional mode => 'verify_sender') - es wird nichts per WhatsApp gesendet, Sie müssen den reverseotp_display also selbst an Ihren Kunden weitergeben. Bei auth=1 entschlüsselt sich phoneEnc zur zertifizierten Absendernummer; es gibt kein sender_matches_intended zu prüfen.

accept_sender: fügen Sie für confirm_phone 'on_mismatch' => 'accept_sender' hinzu. Wenn auth=1 und sender_matches_intended false ist, weicht die zertifizierte Nummer von der angeforderten ab - akzeptieren Sie sie als korrigierte Nummer oder fordern Sie ein neues OTP für die tatsächlich benötigte Nummer an.

Fehlerbehandlung

Die API gibt "status": "error" mit einer lesbaren message zurück:

HTTPmessageWann
400Missing required parametersSie haben ein Pflichtfeld vergessen
400A phone is required in confirm_phone modeconfirm_phone ohne Telefon angefordert
400Invalid mode / Invalid on_mismatchUnbekannter Enum-Wert
400The phone number is invalid or not a mobile number.Ungültiges Telefonnummernformat
403Unknown or invalid business IDFalsche businessid
403Invalid HMACDie Signatur stimmt nicht überein - prüfen Sie Ihre Signaturzeichenfolge
409This request was already used.Doppelte businessref+in_ts

Sicherheit

🔐 HMAC-signedJede Anfrage und jede Antwort wird mit Ihrem businesskey verifiziert
📱 Modusabhängiger Telefonabgleichconfirm_phone prüft, ob der Absender mit der angeforderten Nummer übereinstimmt; verify_sender / accept_sender zertifizieren nur den tatsächlichen Absender - niemals eine Nummer, die nichts gesendet hat
🎯 Eindeutige Live-CodesZwei offene Codes haben nie denselben Wert, sodass ein eingehender Code eindeutig einer Anfrage zugeordnet wird
🔂 Single-useCodes durchlaufen 0→1→2, niemals wiederverwendbar
⏱ Time-limitedCodes laufen nach 10 Minuten ab, maximal 4 Zustellversuche
🔒 Keine Client-GeheimnisseIhr businesskey bleibt auf Ihrem Server; niemals im Browser-Code
🛡 AES-256-verschlüsseltTelefonnummern in Antworten werden mit Ihrem businesskey verschlüsselt

Live ausprobieren

🎮 Demo-Login-Ablauf - eine funktionierende Demo, die das komplette Nutzererlebnis zeigt.

🧪 API-Testwerkzeug - erfordert Ihre eigene businessid und businesskey von wappsync.com/mybusiness.