WappSync
A

WappSync Phone Verify - Documentazione API

Verifica telefonica in cui il Suo utente invia un codice a noi tramite WhatsApp - nessun OTP da digitare, un tocco, completamente verificato.

Come Funziona

1

Lei richiede un codice

Il Suo backend chiama la nostra API con il numero di telefono dell'utente. Restituiamo un codice univoco e il numero WhatsApp a cui inviarlo.

2

L'utente lo invia tramite WhatsApp

Il Suo utente tocca un link WhatsApp - il codice è precompilato. Nessun digitare, nessun copia e incolla. Basta premere invia.

3

Verificato istantaneamente

Riceviamo il messaggio, vediamo da quale numero WhatsApp è stato inviato e la Sua interrogazione restituisce auth=1 con il telefono certificato. Fatto!

Ottenga le Sue credenziali

Registrati su wappsync.com/mybusiness per ricevere:

CredenzialeDescrizione
businessidIl Suo ID aziendale numerico
businesskeyLa Sua chiave segreta - non condividerla mai, non inserirla mai nel codice lato client
Importante: Tutte le chiamate API devono provenire dal Suo backend. La businesskey viene usata per la firma HMAC e non deve mai comparire nel JavaScript del browser, nel codice sorgente HTML o nel codice dell'app mobile.

Due modalità di verifica

Phone Verify funziona in due modalità, scelte per singola richiesta. In entrambe, il Suo utente invia il codice a noi tramite WhatsApp - l'unica differenza è quale numero di telefono viene certificato.

confirm_phone (default)verify_sender
Lei inviaun numero di telefono Nnulla (nessun numero)
Cosa viene certificatoche il chiamante controlla N specificamentequalunque numero rispedisca effettivamente il codice
Uso tipicoaccesso / recupero su un numero in archivio, protezione contro il cambio di SIMnuova registrazione - «dammi un telefono reale e dimostrato per questo cliente»
Consegna del codiceInviato via WhatsApp a N e mostrato nella Sua interfaccia (delivery: pushed_to_phone)solo tramite Lei (delivery: relay_by_business) - consegna Lei il codice al Suo cliente
Risultato dell'interrogazionesender_matches_intended Le indica se il mittente è NphoneEnc è il numero certificato; sender_matches_intended è omesso
Sicurezza: confirm_phone dimostra il controllo di un numero dichiarato specifico; verify_sender dimostra il controllo di un numero e indica quale. Se il Suo flusso richiede che «il numero su questo account appartenga davvero all'utente», resti su confirm_phone con on_mismatch: reject.

Telefono corretto (on_mismatch): un caso comune è il cliente che dichiara A ma invia il codice da B (errore di digitazione / dual-SIM). In confirm_phone, reject (predefinito) lo tratta come un tentativo fallito; accept_sender certifica invece il mittente effettivo B (sender_matches_intended: false, phoneEnc = B), e il Suo backend decide se accettare il numero corretto B o richiedere un nuovo OTP per A.

Richieda un OTP inverso

Chiami questo dal Suo backend quando deve verificare un utente:

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

Corpo della richiesta (JSON)

CampoTipoDescrizione
businessidintIl Suo ID aziendale
businessrefstringUn riferimento univoco che genera per questa richiesta di autenticazione (ad es. bin2hex(random_bytes(4)))
phonestringIl numero di telefono dell'utente in formato internazionale (+40755123456). Obbligatorio in modalità confirm_phone; ometta o lasci vuoto per verify_sender.
modestringFacoltativo - confirm_phone (predefinito quando viene fornito un telefono) oppure verify_sender (predefinito quando il telefono è omesso)
on_mismatchstringFacoltativo (solo confirm_phone) - reject (predefinito) oppure accept_sender (certifica il mittente effettivo se il codice arriva da un numero diverso)
tsintTimestamp Unix corrente
hmacstringFirma HMAC-SHA256

Firma HMAC

Firmi questa stringa con la Sua businesskey:

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

Nella modalità verify_sender non c'è telefono, quindi la stringa firmata è {businessid}|{businessref}||{ts} (slot centrale vuoto).

Esempio:

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

Risposta

CampoTipoDescrizione
statusstring"ok" or "error"
reverseotp_displaystringIl codice che invia il Suo utente, ad es. "2FA-828161"
waphonestringIl numero WhatsApp A CUI il Suo utente invia il codice
logincodestringCodice interno da usare durante l'interrogazione
in_tsintTimestamp per la richiesta di interrogazione
out_tsintTimestamp della risposta
otp_valid_minutesintPer quanto tempo il codice è valido (predefinito 10)
modestringLa modalità attiva: confirm_phone o verify_sender
deliverystringpushed_to_phone (confirm_phone: il codice viene inviato via WhatsApp anche al telefono dichiarato) oppure relay_by_business (verify_sender: deve consegnare Lei il codice al Suo cliente)
hmacstringHMAC della risposta - verifichi con la Sua businesskey

Verifica l'HMAC della risposta against {businessid}|{businessref}|{logincode}|{reverseotp_display}|{waphone}|{out_ts}.

Cosa mostrare al Suo utente

Mostri il codice e il numero di telefono. Usi un link whatsapp://send così l'utente può inviarlo con un solo tocco:

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

Interroga la verifica

Interroga ogni 2-3 secondi finché l'utente non è verificato:

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

Corpo della richiesta (JSON)

CampoTipoDescrizione
businessidintIl Suo ID aziendale
businessrefstringLo stesso riferimento della chiamata precedente
logincodestringIl logincode dalla risposta di getReverseOTP
in_tsintIl ts originale dalla richiesta getReverseOTP
hmacstringHMAC-SHA256 di {businessid}|{businessref}|{logincode}|{in_ts}

Risposta

CampoTipoSignificato
used0⏳ Ancora in attesa - interroghi di nuovo
used1✅ Appena verificato - la prima interrogazione che lo vede lo consuma
used2🔒 Già consumato da un'interrogazione precedente
auth1L'utente è verificato - effettui l'accesso!
phoneEncstringTelefono certificato cifrato AES-256-CBC (solo quando auth=1) - il mittente quando è stato ricevuto un codice (identico al Suo numero dichiarato con confirm_phone rigoroso)
triesintVengono contati i tentativi falliti (codice errato o telefono errato)
expiredbooltrue quando ci sono troppi tentativi falliti (tentativi ≥ 4) - richieda un nuovo OTP
modestringLa modalità di questa richiesta: confirm_phone o verify_sender
sender_matches_intendedboolconfirm_phone soltanto, una volta ricevuto un codice - true = il mittente è il numero che ha chiesto di verificare; false = è stato certificato un mittente corretto. Omesso in verify_sender.
out_tsintTimestamp della risposta
hmacstringHMAC - verifichi con {businessid}|{businessref}|{logincode}|{used}|{phoneEnc}|{out_ts}

Quando auth === 1, è stato ricevuto un codice valido. Decifri phoneEnc per ottenere il telefono certificato (controlli sender_matches_intended in modalità confirm_phone), poi effettui l'accesso dell'utente.

Decifra il numero di telefono

Quando auth=1, phoneEnc contiene il telefono certificato (il mittente che si è dimostrato) cifrato con AES-256-CBC usando la Sua 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

Esempio frontend

L'unica interfaccia di cui ha bisogno - la mostri dopo che il Suo backend ha chiamato getReverseOTP:

<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>

Esempio PHP completo

Pronto per il copia e incolla. Sostituisca YOUR_BUSINESS_ID e 'your-secret-key' con i valori di 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: invii phone => '' (e facoltativamente mode => 'verify_sender') - non viene inviato nulla su WhatsApp, quindi deve trasmettere Lei il reverseotp_display al Suo cliente. Con auth=1, phoneEnc si decifra nel numero certificato del mittente; non c'è alcun sender_matches_intended da controllare.

accept_sender: per confirm_phone, aggiunga 'on_mismatch' => 'accept_sender'. Se auth=1 e sender_matches_intended è false, il numero certificato differisce da quello richiesto - lo accetti come numero corretto oppure richieda un nuovo OTP per il numero di cui ha effettivamente bisogno.

Gestione degli errori

L'API restituisce "status": "error" con un message leggibile:

HTTPmessageQuando
400Missing required parametersHa dimenticato un campo obbligatorio
400A phone is required in confirm_phone modeconfirm_phone richiesto senza un telefono
400Invalid mode / Invalid on_mismatchValore enum sconosciuto
400The phone number is invalid or not a mobile number.Formato del telefono non valido
403Unknown or invalid business IDbusinessid errato
403Invalid HMACLa firma non corrisponde - controlli la stringa da firmare
409This request was already used.businessref+in_ts duplicato

Sicurezza

🔐 HMAC-signedOgni richiesta e risposta viene verificata con la Sua businesskey
📱 Corrispondenza del telefono in base alla modalitàconfirm_phone verifica che il mittente corrisponda al numero richiesto; verify_sender / accept_sender certificano solo il mittente effettivo - mai un numero che non ha inviato nulla
🎯 Codici live univociDue codici in sospeso non condividono lo stesso valore, quindi un codice in arrivo viene associato in modo deterministico a una sola richiesta
🔂 Single-useI codici passano da 0→1→2, mai riutilizzabili
⏱ Time-limitedI codici scadono dopo 10 minuti, massimo 4 tentativi di consegna
🔒 Nessun segreto lato clientLa Sua businesskey resta sul Suo server; mai nel codice del browser
🛡 Cifrato AES-256I numeri di telefono nelle risposte sono cifrati con la Sua businesskey

Provalo dal vivo

🎮 Flusso di accesso demo - una demo funzionante che mostra l'esperienza utente completa.

🧪 Strumento di test API - richiede il Suo businessid e la Sua businesskey da wappsync.com/mybusiness.