I-skip tungo sa nilalaman

Flash na Tawag

Ang Flash Call ay isang paraan ng pag-verify sa telepono na gumagamit ng hindi nasagot na tawag sa halip na SMS upang i-verify ang mga numero ng telepono. Ito ay mas mabilis, mas secure, at cost-effective.

Pangkalahatang-ideya

Gumagana ang pag-verify ng Flash Call sa pamamagitan ng:

  1. Humihiling ng pagpapatunay ang user
  2. Nagsisimula ang system ng isang tawag sa telepono ng user
  3. Awtomatikong tinatapos ang tawag pagkatapos ng 1-2 ring
  4. Kinukuha ng app ng user ang caller ID
  5. Ang Caller ID ay na-verify laban sa inaasahang pattern
  6. Ang user ay napatotohanan

Mga Benepisyo

Cost-Effective

  • Hanggang 10x na mas mura kaysa sa SMS
  • Walang bayad sa paghahatid ng mensahe
  • Mga pinababang gastos para sa mataas na dami ng pag-verify

Mas mabilis

  • Instant na pag-verify (1-3 segundo)
  • Walang paghihintay para sa paghahatid ng SMS
  • Mas mahusay na karanasan ng user

Mas Secure

  • Mas mahirap harangin kaysa sa SMS
  • Walang nakikitang OTP sa mga notification
  • Lumalaban sa mga pag-atake ng SIM swap

Pandaigdigang Abot

  • Gumagana sa mga bansang may mga paghihigpit sa SMS
  • Walang mga isyu sa pag-filter ng SMS
  • Universal phone compatibility

Pangunahing Flash Call

Kahilingan

{
  "from": "YourApp",
  "to": "+380XXXXXXXXX",
  "type": "flashcall",
  "messageData": {
    "callerId": "+380123456789"
  }
}

Mga Parameter

Parameter Uri Kinakailangan Paglalarawan
mula sa string Oo Ang iyong tagatukoy ng nagpadala
sa string Oo Numero ng telepono ng tatanggap (E.164)
uri string Oo Itakda sa "flashcall"
callerId string Oo Numero ng telepono na tatawag sa user
ttl integer Hindi Time-to-live sa mga segundo (default: 60)

Paano Ito Gumagana

1. Naglagay ang User ng Numero ng Telepono

Ibinibigay ng user ang kanilang numero ng telepono sa iyong app:

Phone: +380XXXXXXXXX

2. Humiling ng Flash na Tawag

Ang iyong server ay humihiling ng pag-verify ng flash call:

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. Tugon ng API

Ibinabalik ng API ang inaasahang pattern ng caller ID:

{
  "messagelistId": 123456,
  "messages": [
    {
      "messageId": "abc123def456",
      "status": "accepted",
      "callerId": "+380123456789",
      "pattern": "***456789",
      "to": "+380XXXXXXXXX"
    }
  ]
}

4. Simulan ang Tawag

Nagsisimula ang system ng isang tawag sa telepono ng user at nagtatapos pagkatapos ng 1-2 ring.

5. Kunin ang Caller ID

Kinukuha ng app ng user ang caller ID ng papasok na tawag:

// Android example
val cursor = contentResolver.query(
    CallLog.Calls.CONTENT_URI,
    arrayOf(CallLog.Calls.NUMBER),
    null, null,
    CallLog.Calls.DATE + " DESC"
)

6. I-verify ang Pattern

Ihambing ang nakuhang caller ID sa inaasahang pattern:

// 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);
}

Mga Halimbawa ng Pagpapatupad

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 (Server-Side)

// 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' });
  }
});

Format ng Tugon

Tagumpay na Tugon

{
  "messagelistId": 123456,
  "messages": [
    {
      "messageId": "abc123def456",
      "status": "accepted",
      "callerId": "+380123456789",
      "pattern": "***456789",
      "to": "+380XXXXXXXXX",
      "ttl": 60
    }
  ]
}

Mga Patlang ng Tugon

Patlang Uri Paglalarawan
messageId string Natatanging verification ID
status string Katayuan: tinanggap, tinanggihan
callerId string Buong numero ng caller ID
pattern string Pattern upang tumugma (mga digit + asterisk)
sa string Numero ng telepono ng tatanggap
ttl integer Panahon ng bisa sa mga segundo

Pagtutugma ng Pattern

Ang API ay nagbabalik ng isang pattern na may mga asterisk na nagtatakip ng ilang digit:

Full number: +380123456789
Pattern:     ***456789

Ang iyong app ay dapat na:

  1. Kunin ang papasok na caller ID
  2. I-extract ang mga digit mula sa caller ID
  3. Itugma laban sa pattern (mga asterisk = anumang digit)
  4. I-verify ang tugma sa loob ng panahon ng TTL

Fallback sa SMS

Kung nabigo ang Flash Call, awtomatikong bumabalik sa SMS:

{
  "from": "YourApp",
  "to": "+380XXXXXXXXX",
  "type": "flashcall",
  "messageData": {
    "callerId": "+380123456789"
  },
  "fallback": {
    "type": "sms",
    "text": "Your verification code is: 123456"
  },
  "ttl": 60
}

Mga Kaso ng Paggamit

Pagpaparehistro ng Account

I-verify ang mga numero ng telepono sa panahon ng pag-signup nang walang gastos sa SMS.

Pag-verify sa Pag-login

Dalawang-factor na pagpapatotoo gamit ang flash call.

Update sa Numero ng Telepono

I-verify ang bagong numero ng telepono kapag nag-update ng profile ang user.

Kumpirmasyon ng Transaksyon

Kumpirmahin ang mga transaksyong may mataas na halaga gamit ang flash call.

Pinakamahuhusay na Kasanayan

TTL

  • ✅ Itakda ang TTL sa 60-90 segundo
  • ✅ Payagan ang user na subukang muli pagkatapos mag-expire
  • ❌ Huwag gumamit ng TTL nang higit sa 120 segundo

Karanasan ng Gumagamit

  • Ipakita ang mensaheng "Naghihintay ng tawag..."
  • Display countdown timer (60 segundo)
  • Magbigay ng opsyon na "Gumamit ng SMS sa halip"
  • Auto-detect at i-verify ang caller ID

Error sa Paghawak

  • Pangasiwaan ang mga nawawalang pahintulot sa telepono
  • Timeout pagkatapos mag-expire ang TTL
  • Magbigay ng pagpipiliang fallback ng SMS
  • Ipakita ang malinaw na mga mensahe ng error

Mga Pahintulot

Humiling ng mga pahintulot sa telepono bago ang flash call:

Android:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />

iOS:

<key>NSPhoneCallUsageDescription</key>
<string>We need phone access to verify your number</string>

Pagsubok

  • Pagsubok sa iba't ibang mga device
  • Subukan sa iba't ibang mga carrier
  • Subukan ang mga senaryo ng pagtanggi sa pahintulot
  • Subukan ang network timeout na mga sitwasyon

Mga Limitasyon

Suporta sa Platform

  • Gumagana sa lahat ng mga mobile device
  • Nangangailangan ng kakayahan sa pagtawag sa telepono
  • Kailangan ng READ_PHONE_STATE na pahintulot
  • Maaaring hindi gumana sa mga tablet na walang telepono

Network

  • Nangangailangan ng aktibong koneksyon sa telepono
  • Maaaring mabigo sa mahihirap na kundisyon ng network
  • Maaaring malapat ang mga paghihigpit sa carrier
  • Maaaring mag-iba ang mga internasyonal na rate

Privacy

  • Maaaring harangan ng mga user ang mga hindi kilalang numero
  • Ang ilang mga aparato ay may pag-block ng tawag
  • Nangangailangan ng tahasang mga pahintulot
  • Isaalang-alang ang mga alalahanin sa privacy ng user

Pag-troubleshoot

Hindi Natanggap ang Tawag

  • Suriin ang telepono ay may signal
  • I-verify ang format ng numero (E.164)
  • Suriin ang mga paghihigpit ng carrier
  • Subukan ang SMS fallback

Hindi Nagtutugma ang Pattern

  • Tiyakin ang pagkuha ng tamang caller ID
  • I-strip ang mga non-digit na character
  • Suriin ang format ng pattern
  • I-verify sa loob ng panahon ng TTL

Tinanggihan ang Pahintulot

  • Humiling ng mga pahintulot nang maayos
  • Ipaliwanag kung bakit kailangan ng mga pahintulot
  • Magbigay ng alternatibo (SMS)
  • Pangasiwaan nang maayos

Mga Susunod na Hakbang