Chamada Flash
Flash Call é um método de verificação de telefone que usa uma chamada perdida em vez de SMS para verificar números de telefone. É mais rápido, mais seguro e econômico.
Visão geral
A verificação de Flash Call funciona por:
- O usuário solicita verificação
- O sistema inicia uma chamada para o telefone do usuário
- A chamada é encerrada automaticamente após 1-2 toques
- O aplicativo do usuário captura o identificador de chamadas
- O identificador de chamadas é verificado em relação ao padrão esperado
- O usuário está autenticado
Benefícios
Econômico
- Até 10x mais barato que SMS
- Sem taxas de entrega de mensagens
- Custos reduzidos para verificação de alto volume
Mais rápido
- Verificação instantânea (1-3 segundos)
- Sem espera pela entrega de SMS
- Melhor experiência do usuário
Mais seguro
- Mais difícil de interceptar do que SMS
- Nenhum OTP visível nas notificações
- Resistente a ataques de troca de SIM
Alcance global
- Funciona em países com restrições de SMS
- Sem problemas com filtragem de SMS
- Compatibilidade universal com telefone
Chamada Flash Básica
Solicitação
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
}
}
Parâmetros
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
de |
corda | Sim | Seu identificador de remetente |
para |
corda | Sim | Número de telefone do destinatário (E.164) |
tipo |
corda | Sim | Defina como "flashcall" |
callerId |
corda | Sim | Número de telefone que ligará para o usuário |
ttl |
inteiro | Não | Tempo de vida em segundos (padrão: 60) |
Como funciona
1. O usuário insere o número de telefone
O usuário fornece seu número de telefone no seu aplicativo:
2. Solicitar chamada flash
Seu servidor solicita verificação de chamada flash:
curl -X POST https://restapi.smsbat.com/bat/messagelist \
-H "X-Authorization-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"messages": [{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
},
"ttl": 60
}]
}'
3. Resposta da API
A API retorna o padrão de identificação de chamada esperado:
CODE_BLOCO_3
4. Iniciar chamada
O sistema inicia uma chamada para o telefone do usuário e termina após 1 ou 2 toques.
5. Capturar ID do chamador
O aplicativo do usuário captura o identificador de chamadas da chamada recebida:
// Android example
val cursor = contentResolver.query(
CallLog.Calls.CONTENT_URI,
arrayOf(CallLog.Calls.NUMBER),
null, null,
CallLog.Calls.DATE + " DESC"
)
6. Verifique o padrão
Compare o identificador de chamadas capturado com o padrão esperado:
CODE_BLOCO_5
Exemplos de implementação
Android
class FlashCallVerification {
fun requestFlashCall(phoneNumber: String) {
// 1. Request flash call from API
val response = api.requestFlashCall(phoneNumber)
val pattern = response.pattern
// 2. Wait for incoming call
val callReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == TelephonyManager.ACTION_PHONE_STATE_CHANGED) {
val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
if (state == TelephonyManager.EXTRA_STATE_RINGING) {
val callerId = intent.getStringExtra(
TelephonyManager.EXTRA_INCOMING_NUMBER
)
// 3. Verify caller ID against pattern
if (verifyPattern(callerId, pattern)) {
onVerificationSuccess()
}
}
}
}
}
// Register receiver
context.registerReceiver(
callReceiver,
IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED)
)
}
private fun verifyPattern(callerId: String?, pattern: String): Boolean {
if (callerId == null) return false
val regex = pattern.replace("*", "\\d").toRegex()
return regex.matches(callerId)
}
}
iOS
class FlashCallVerification {
func requestFlashCall(phoneNumber: String) {
// 1. Request flash call from API
api.requestFlashCall(phoneNumber) { response in
let pattern = response.pattern
// 2. Use CallKit to detect incoming call
let provider = CXProvider(configuration: providerConfiguration)
provider.setDelegate(self, queue: nil)
// Store pattern for verification
self.expectedPattern = pattern
}
}
// CallKit delegate
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
// Capture caller ID
let callerId = action.callUUID.uuidString
// Verify against pattern
if verifyPattern(callerId: callerId, pattern: expectedPattern) {
onVerificationSuccess()
}
action.fulfill()
}
private func verifyPattern(callerId: String, pattern: String) -> Bool {
let regex = try! NSRegularExpression(
pattern: pattern.replacingOccurrences(of: "*", with: "\\d")
)
let range = NSRange(location: 0, length: callerId.count)
return regex.firstMatch(in: callerId, range: range) != nil
}
}
Web (lado do servidor)
// Node.js example
const express = require('express');
const app = express();
app.post('/request-verification', async (req, res) => {
const { phoneNumber } = req.body;
// 1. Request flash call
const response = await fetch('https://restapi.smsbat.com/bat/messagelist', {
method: 'POST',
headers: {
'X-Authorization-Key': process.env.SMSBAT_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
messages: [{
from: 'YourApp',
to: phoneNumber,
type: 'flashcall',
messageData: {
callerId: process.env.FLASH_CALL_NUMBER
},
ttl: 60
}]
})
});
const data = await response.json();
const { messageId, pattern } = data.messages[0];
// 2. Store pattern for verification
await redis.setex(`flashcall:${messageId}`, 60, pattern);
// 3. Return pattern to client
res.json({ messageId, pattern });
});
app.post('/verify-flashcall', async (req, res) => {
const { messageId, callerId } = req.body;
// 1. Get expected pattern
const pattern = await redis.get(`flashcall:${messageId}`);
if (!pattern) {
return res.status(400).json({ error: 'Verification expired' });
}
// 2. Verify caller ID
const regex = new RegExp(pattern.replace(/\*/g, '\\d'));
const isValid = regex.test(callerId);
if (isValid) {
// Mark phone as verified
await markPhoneVerified(callerId);
res.json({ verified: true });
} else {
res.status(400).json({ error: 'Invalid caller ID' });
}
});
Formato de resposta
Resposta de sucesso
CODE_BLOCO_9
Campos de resposta
| Campo | Tipo | Descrição |
|---|---|---|
mensagemId |
corda | ID de verificação exclusivo |
estado |
corda | Status: aceito, rejeitado |
callerId |
corda | Número completo de identificação de chamadas |
padrão |
corda | Padrão a combinar (dígitos + asteriscos) |
para |
corda | Número de telefone do destinatário |
ttl |
inteiro | Período de validade em segundos |
Correspondência de padrões
A API retorna um padrão com asteriscos mascarando alguns dígitos:
Seu aplicativo deve:
- Capture o identificador de chamadas recebidas
- Extraia dígitos do identificador de chamadas
- Combine com o padrão (asteriscos = qualquer dígito)
- Verifique a correspondência dentro do período TTL
Alternativa para SMS
Se a Flash Call falhar, volte automaticamente para SMS:
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
},
"fallback": {
"type": "sms",
"text": "Your verification code is: 123456"
},
"ttl": 60
}
Casos de uso
Registro de conta
Verifique os números de telefone durante a inscrição sem custos de SMS.
Verificação de login
Autenticação de dois fatores usando chamada flash.
Atualização do número de telefone
Verifique o novo número de telefone quando o usuário atualizar o perfil.
Confirmação de transação
Confirme transações de alto valor com chamada flash.
Melhores práticas
TTL
- ✅ Defina TTL para 60-90 segundos
- ✅ Permitir que o usuário tente novamente após a expiração
- ❌ Não use TTL por mais de 120 segundos
Experiência do usuário
- Mostrar mensagem "Aguardando chamada..."
- Exibir temporizador de contagem regressiva (60 segundos)
- Fornece a opção "Usar SMS em vez disso"
- Detectar e verificar automaticamente o identificador de chamadas
Tratamento de erros
- Lidar com permissões de telefone ausentes
- Tempo limite após TTL expirar
- Fornece opção de retorno de SMS
- Mostrar mensagens de erro claras
Permissões
Solicite permissões de telefone antes da chamada flash:
Android:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
iOS:
Teste
- Teste em diferentes dispositivos
- Teste com diferentes operadoras
- Testar cenários de negação de permissão
- Testar cenários de tempo limite da rede
Limitações
Suporte à plataforma
- Funciona em todos os dispositivos móveis
- Requer capacidade de chamada telefônica
- Precisa de permissão READ_PHONE_STATE
- Pode não funcionar em tablets sem telefone
Rede
- Requer conexão telefônica ativa
- Pode falhar em más condições de rede
- Restrições da operadora podem ser aplicadas
- As tarifas internacionais podem variar
Privacidade
- Os usuários podem bloquear números desconhecidos
- Alguns dispositivos possuem bloqueio de chamadas
- Requer permissões explícitas
- Considere as preocupações com a privacidade do usuário
Solução de problemas
Chamada não recebida
- Verifique se o telefone tem sinal
- Verifique o formato do número (E.164)
- Verifique as restrições da operadora
- Experimente o substituto de SMS
Padrão não correspondente
- Certifique-se de capturar o identificador de chamadas correto
- Tira caracteres não numéricos
- Verifique o formato do padrão
- Verifique dentro do período TTL
Permissão negada
- Solicite permissões corretamente
- Explique por que as permissões são necessárias
- Fornecer alternativa (SMS)
- Manuseie graciosamente
Próximas etapas
- Viber OTP - Entrega alternativa de OTP
- Mensagens SMS - SMS substituto
- Verificar status - Rastrear o status da chamada flash