შიგთავსზე გადასვლა

ფლეშ ზარი

Flash Call არის ტელეფონის დადასტურების მეთოდი, რომელიც იყენებს გამოტოვებულ ზარს SMS-ის ნაცვლად ტელეფონის ნომრების დასადასტურებლად. ის უფრო სწრაფი, უსაფრთხო და ეკონომიურია.

მიმოხილვა

Flash ზარის დადასტურება მუშაობს:

  1. მომხმარებლის მოთხოვნის შემოწმება
  2. სისტემა იწყებს ზარს მომხმარებლის ტელეფონზე
  3. ზარი ავტომატურად წყდება 1-2 ზარის შემდეგ
  4. მომხმარებლის აპლიკაცია იჭერს აბონენტის ID-ს
  5. Caller ID დამოწმებულია მოსალოდნელი ნიმუშის მიხედვით
  6. მომხმარებელი დამოწმებულია

სარგებელი

ეფექტური

  • SMS-ზე 10-ჯერ იაფია
  • შეტყობინებების მიწოდების საფასური არ არის
  • შემცირებული ხარჯები მაღალი მოცულობის გადამოწმებისთვის

უფრო სწრაფად

  • მყისიერი გადამოწმება (1-3 წამი)
  • არ ელოდება SMS მიწოდებას
  • უკეთესი მომხმარებლის გამოცდილება

უფრო უსაფრთხო

  • უფრო რთული გადასაჭრელი ვიდრე SMS
  • შეტყობინებებში OTP არ ჩანს
  • მდგრადია SIM სვოპ შეტევების მიმართ

გლობალური მიღწევა

  • მუშაობს SMS შეზღუდვების მქონე ქვეყნებში
  • SMS ფილტრაციის პრობლემა არ არის
  • უნივერსალური ტელეფონის თავსებადობა

ძირითადი ფლეშ ზარი

მოთხოვნა

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

პარამეტრები

პარამეტრი ტიპი საჭირო აღწერა
დან სიმებიანი დიახ თქვენი გამგზავნის იდენტიფიკატორი
მდე სიმებიანი დიახ მიმღების ტელეფონის ნომერი (E.164)
ტიპი სიმებიანი დიახ დააყენეთ "flashcall"
callerId სიმებიანი დიახ ტელეფონის ნომერი, რომელიც დაურეკავს მომხმარებელს
ttl მთელი რიცხვი არა სიცოცხლის ხანგრძლივობა წამებში (ნაგულისხმევი: 60)

როგორ მუშაობს

1. მომხმარებელი შეიყვანს ტელეფონის ნომერს

მომხმარებელი აწვდის თავის ტელეფონის ნომერს თქვენს აპლიკაციაში:

Phone: +380XXXXXXXXX

2. მოითხოვეთ 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. API პასუხი

API აბრუნებს მოსალოდნელ აბონენტის ID შაბლონს:

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

4. ზარის დაწყება

სისტემა იწყებს ზარს მომხმარებლის ტელეფონზე და წყვეტს 1-2 დარეკვის შემდეგ.

5. გადაიღეთ აბონენტის ID

მომხმარებლის აპი იღებს შემომავალი ზარის აბონენტის ID-ს:

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

6. დაადასტურეთ ნიმუში

შეადარეთ დაფიქსირებული აბონენტის ID მოსალოდნელ შაბლონთან:

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

განხორციელების მაგალითები

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

ვებ (სერვერის მხარე)

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

პასუხის ფორმატი

წარმატებული პასუხი

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

რეაგირების ველები

ველი ტიპი აღწერა
messageId სიმებიანი უნიკალური დამადასტურებელი ID
სტატუსს სიმებიანი სტატუსი: მიღებული, უარყოფილი
callerId სიმებიანი სრული აბონენტის ID ნომერი
ნიმუში სიმებიანი შესატყვისი ნიმუში (ციფრები + ვარსკვლავი)
მდე სიმებიანი მიმღების ტელეფონის ნომერი
ttl მთელი რიცხვი მოქმედების ვადა წამებში

შაბლონის შესატყვისი

API აბრუნებს ნიმუშს ვარსკვლავებით, რომლებიც ფარავს რამდენიმე ციფრს:

Full number: +380123456789
Pattern:     ***456789

თქვენი აპლიკაცია უნდა:

  1. გადაიღეთ შემომავალი აბონენტის ID
  2. ამოიღეთ ციფრები აბონენტის ID-დან
  3. ემთხვევა შაბლონს (ვარსკვლავები = ნებისმიერი ციფრი)
  4. შეამოწმეთ მატჩი TTL პერიოდში

დაბრუნება SMS-ზე

თუ Flash Call ვერ მოხერხდა, ავტომატურად დაუბრუნდით SMS-ს:

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

გამოყენების შემთხვევები

ანგარიშის რეგისტრაცია

დაადასტურეთ ტელეფონის ნომრები რეგისტრაციისას SMS-ის ხარჯების გარეშე.

შესვლის შემოწმება

ორი ფაქტორიანი ავთენტიფიკაცია ფლეშ ზარის გამოყენებით.

ტელეფონის ნომრის განახლება

დაადასტურეთ ახალი ტელეფონის ნომერი, როდესაც მომხმარებელი განაახლებს პროფილს.

ტრანზაქციის დადასტურება

დაადასტურეთ მაღალი ღირებულების ტრანზაქციები ფლეშ ზარით.

საუკეთესო პრაქტიკა

TTL

  • ✅ დააყენეთ TTL 60-90 წამზე
  • ✅ ნება მიეცით მომხმარებელს ხელახლა სცადოს ვადის გასვლის შემდეგ
  • ❌ არ გამოიყენოთ TTL 120 წამზე მეტი ხნის განმავლობაში

მომხმარებლის გამოცდილება

  • აჩვენეთ შეტყობინება "ველოდები ზარს...".
  • უკუმთვლელი ტაიმერის ჩვენება (60 წამი)
  • მიუთითეთ ვარიანტი "სანაცვლოდ SMS-ის გამოყენება"
  • ავტომატური ამოცნობა და გადამოწმება აბონენტის ID

შეცდომის დამუშავება

  • გაუმკლავდეთ დაკარგული ტელეფონის ნებართვებს
  • ტაიმაუტი TTL-ის ამოწურვის შემდეგ
  • მიაწოდეთ SMS სარეზერვო ვარიანტი
  • მკაფიო შეცდომის შეტყობინებების ჩვენება

ნებართვები

მოითხოვეთ ტელეფონის ნებართვები ფლეშ ზარამდე:

ანდროიდი:

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

ტესტირება

  • ტესტირება სხვადასხვა მოწყობილობებზე
  • ტესტი სხვადასხვა მატარებლებთან
  • ტესტის ნებართვის უარყოფის სცენარები
  • შეამოწმეთ ქსელის დროის ამოწურვის სცენარები

შეზღუდვები

პლატფორმის მხარდაჭერა

  • მუშაობს ყველა მობილურ მოწყობილობაზე
  • მოითხოვს სატელეფონო ზარის შესაძლებლობას
  • საჭიროებს READ_PHONE_STATE ნებართვას
  • შეიძლება არ იმუშაოს ტაბლეტებზე ტელეფონის გარეშე

ქსელი

  • საჭიროებს აქტიურ სატელეფონო კავშირს
  • შეიძლება ჩავარდეს ქსელის ცუდ პირობებში
  • შეიძლება მოქმედებდეს ოპერატორის შეზღუდვები
  • საერთაშორისო ტარიფები შეიძლება განსხვავდებოდეს

კონფიდენციალურობა

  • მომხმარებლებს შეუძლიათ დაბლოკონ უცნობი ნომრები
  • ზოგიერთ მოწყობილობას აქვს ზარის დაბლოკვა
  • მოითხოვს მკაფიო ნებართვებს
  • განიხილეთ მომხმარებლის კონფიდენციალურობის საკითხები

პრობლემების მოგვარება

ზარი არ მიიღება

  • შეამოწმეთ ტელეფონს აქვს სიგნალი
  • გადაამოწმეთ ნომრის ფორმატი (E.164)
  • შეამოწმეთ ოპერატორის შეზღუდვები
  • სცადეთ SMS სარეზერვო

შაბლონი არ ემთხვევა

  • დარწმუნდით, რომ მიიღეთ სწორი აბონენტის ID
  • ამოიღეთ არაციფრული სიმბოლოები
  • შეამოწმეთ შაბლონის ფორმატი
  • გადაამოწმეთ TTL პერიოდში

ნებართვა უარყოფილია

  • მოითხოვეთ ნებართვები სწორად
  • ახსენით, რატომ არის საჭირო ნებართვები
  • მიაწოდეთ ალტერნატივა (SMS)
  • მოხდენილად მოაგვარე

შემდეგი ნაბიჯები