Flitsoproep
Flash Call is een telefoonverificatiemethode waarbij een gemiste oproep in plaats van een sms wordt gebruikt om telefoonnummers te verifiëren. Het is sneller, veiliger en kosteneffectiever.
Overzicht
Flash Call-verificatie werkt door:
- Gebruiker vraagt om verificatie
- Het systeem start een oproep naar de telefoon van de gebruiker
- Het gesprek wordt automatisch beëindigd na 1-2 belsignalen
- De app van de gebruiker legt de beller-ID vast
- Beller-ID wordt geverifieerd aan de hand van het verwachte patroon
- Gebruiker is geverifieerd
Voordelen
Kosteneffectief
- Tot 10x goedkoper dan sms
- Geen bezorgkosten voor berichten
- Lagere kosten voor verificatie van grote volumes
Sneller
- Onmiddellijke verificatie (1-3 seconden)
- Niet wachten op sms-bezorging
- Betere gebruikerservaring
Veiliger
- Moeilijker te onderscheppen dan sms
- Geen OTP zichtbaar in meldingen
- Bestand tegen SIM-swap-aanvallen
Wereldwijd bereik
- Werkt in landen met sms-beperkingen
- Geen problemen met sms-filtering
- Universele telefooncompatibiliteit
Basisflitsoproep
Verzoek
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
}
}
Parameters
| Parameter | Typ | Vereist | Beschrijving |
|---|---|---|---|
van |
tekenreeks | Ja | Uw afzender-ID |
naar |
tekenreeks | Ja | Telefoonnummer ontvanger (E.164) |
type |
tekenreeks | Ja | Instellen op "flashcall" |
bellerId |
tekenreeks | Ja | Telefoonnummer dat gebruiker zal bellen |
ttl |
geheel getal | Nee | Time-to-live in seconden (standaard: 60) |
Hoe het werkt
1. Gebruiker voert telefoonnummer in
De gebruiker geeft zijn telefoonnummer op in uw app:
2. Vraag een flitsoproep aan
Uw server vraagt om flash-oproepverificatie:
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. API-reactie
API retourneert het verwachte beller-ID-patroon:
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX"
}
]
}
4. Start een oproep
Het systeem start een oproep naar de telefoon van de gebruiker en beëindigt deze na 1-2 belsignalen.
5. Leg beller-ID vast
De app van de gebruiker legt de beller-ID van de inkomende oproep vast:
// Android example
val cursor = contentResolver.query(
CallLog.Calls.CONTENT_URI,
arrayOf(CallLog.Calls.NUMBER),
null, null,
CallLog.Calls.DATE + " DESC"
)
6. Controleer patroon
Vergelijk de vastgelegde beller-ID met het verwachte patroon:
// JavaScript example
function verifyFlashCall(callerId, pattern) {
// Remove non-digits
const callerDigits = callerId.replace(/\D/g, '');
const patternDigits = pattern.replace(/\*/g, '.');
// Check if matches pattern
const regex = new RegExp(patternDigits);
return regex.test(callerDigits);
}
Implementatievoorbeelden
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 (serverzijde)
// 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' });
}
});
Antwoordformaat
Succesreactie
{
"messagelistId": 123456,
"messages": [
{
"messageId": "abc123def456",
"status": "accepted",
"callerId": "+380123456789",
"pattern": "***456789",
"to": "+380XXXXXXXXX",
"ttl": 60
}
]
}
Reactievelden
| Veld | Typ | Beschrijving |
|---|---|---|
berichtId |
tekenreeks | Unieke verificatie-ID |
status |
tekenreeks | Status: geaccepteerd, afgewezen |
bellerId |
tekenreeks | Volledig beller-ID-nummer |
patroon |
tekenreeks | Passend patroon (cijfers + sterretjes) |
naar |
tekenreeks | Telefoonnummer ontvanger |
ttl |
geheel getal | Geldigheidsduur in seconden |
Patroonaanpassing
De API retourneert een patroon met sterretjes die enkele cijfers maskeren:
Uw app moet:
- Leg inkomende beller-ID vast
- Cijfers uit nummerherkenning extraheren
- Match met patroon (sterretjes = elk cijfer)
- Controleer de match binnen de TTL-periode
Terugval op sms
Als Flash Call mislukt, val dan automatisch terug naar SMS:
{
"from": "YourApp",
"to": "+380XXXXXXXXX",
"type": "flashcall",
"messageData": {
"callerId": "+380123456789"
},
"fallback": {
"type": "sms",
"text": "Your verification code is: 123456"
},
"ttl": 60
}
Gebruiksscenario's
Accountregistratie
Verifieer telefoonnummers tijdens het aanmelden zonder sms-kosten.
Inlogverificatie
Tweefactorauthenticatie met behulp van Flash Call.
Telefoonnummer bijwerken
Controleer nieuw telefoonnummer wanneer gebruiker profiel bijwerkt.
Transactiebevestiging
Bevestig transacties met een hoge waarde met een flash-oproep.
Beste praktijken
TTL
- ✅ Stel TTL in op 60-90 seconden
- ✅ Laat de gebruiker het opnieuw proberen na het verlopen
- ❌Gebruik TTL niet langer dan 120 seconden
Gebruikerservaring
- Toon het bericht "Wacht op oproep...".
- Afteltimer weergeven (60 seconden)
- Bied de optie "Gebruik in plaats daarvan SMS"
- Automatische detectie en verificatie van nummerherkenning
Foutafhandeling
- Behandel ontbrekende telefoonrechten
- Time-out nadat TTL is verlopen
- Bied een SMS-fallback-optie
- Toon duidelijke foutmeldingen
Machtigingen
Telefoonrechten aanvragen vóór flash-oproep:
Android:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
iOS:
Testen
- Test op verschillende apparaten
- Test met verschillende vervoerders
- Test scenario's voor het weigeren van toestemming
- Test netwerktime-outscenario's
Beperkingen
Platformondersteuning
- Werkt op alle mobiele apparaten
- Vereist telefoongesprekken
- Heeft READ_PHONE_STATE toestemming nodig
- Werkt mogelijk niet op tablets zonder telefoon
Netwerk
- Vereist een actieve telefoonverbinding
- Kan mislukken bij slechte netwerkomstandigheden
- Er kunnen beperkingen van toepassing zijn op vervoerders
- Internationale tarieven kunnen variëren
Privacy
- Gebruikers kunnen onbekende nummers blokkeren
- Sommige apparaten hebben oproepblokkering
- Vereist expliciete toestemming
- Houd rekening met zorgen over de privacy van gebruikers
Problemen oplossen
Oproep niet ontvangen
- Controleer of de telefoon signaal heeft
- Getalformaat verifiëren (E.164)
- Controleer de beperkingen van de vervoerder
- Probeer SMS-fallback
Patroon komt niet overeen
- Zorg ervoor dat de juiste nummerherkenning wordt vastgelegd
- Strip niet-cijferige tekens
- Controleer het patroonformaat
- Verifieer binnen TTL-periode
Toestemming geweigerd
- Vraag rechten correct aan
- Leg uit waarom machtigingen nodig zijn
- Bied alternatief (SMS)
- Ga er sierlijk mee om
Volgende stappen
- Viber OTP - Alternatieve OTP-levering
- SMS-berichten - SMS-reserve
- Status controleren - Volg de status van de flashoproep