OTPIQ Flutter SDK

The unofficial Flutter SDK for OTPIQ — an enterprise-grade SMS and messaging API for sending verification codes, custom messages, and managing sender IDs. Supports intelligent fallback routing across SMS, WhatsApp, and Telegram.

Preview

Here is a quick look at using the SDK in a Flutter application:

1. Initializing & Requesting in Flutter

Easily integrate the SDK into your widget's initialization:

Flutter Integration Example

2. Network Payload & Response

Structured JSON responses returned from the OTPIQ API:

Network Response Preview

3. Application Demo

Check project names and real-time credit balances dynamically:

Application Balance Demo

4. Received WhatsApp Message

WhatsApp template messages containing verification codes sent directly via OTPIQ:

Received WhatsApp Message

Features

  • Multi-Provider Support: Send messages via SMS, WhatsApp, or Telegram.
  • Smart Fallback Routes: Automatic provider switching for maximum delivery success (e.g. Try WhatsApp → Telegram → SMS).
  • Verification Codes: Automated OTP delivery with customizable codes.
  • Custom Messages: Send personalized messages with custom sender IDs.
  • Real-time Tracking: Monitor message delivery status across channels.
  • Credit Check: Retrieve remaining credits and project details.

Getting Started

Installation

Add otpiq_flutter to your pubspec.yaml dependencies:

dependencies:
  otpiq_flutter: ^0.0.1

Or run this command in your Flutter project directory:

flutter pub add otpiq_flutter

🔒 Security Best Practices

Warning

Never hardcode your OTPIQ API key in your Flutter application source code. Doing so allows anyone who decompiles your APK or IPA to extract the key and misuse your project credits.

For maximum security, always perform OTPIQ operations on the server side:

  • Use a backend framework like Serverpod, Dart Frog, or any other server-side environment.
  • Store your OTPIQ API key in server-side environment variables or configuration files.
  • Expose a secure endpoint (e.g., /verify-phone) from your server to your Flutter app, keeping the API key completely hidden from client binaries.

If Client-Side Integration is Required

If you must communicate directly with the OTPIQ API from your Flutter app, secure the key using these industry-standard methods:

  1. Environment Injecting: Inject the API key at build time using --dart-define or --dart-define-from-file to avoid hardcoding it in source files or committing it to version control (Git).
  2. Secure Storage: Retrieve the key from a remote configuration server or secure vault at runtime, and store it on the device using flutter_secure_storage (uses Keystore for Android and Keychain for iOS).
  3. Obfuscate Release Builds: Always obfuscate your production builds to make reverse engineering strings and code structure much more difficult:
    flutter build apk --obfuscate --split-debug-info=/<directory>
    

Usage

1. Initialize the SDK

Instantiate the Otpiq class with your project API key:

import 'package:otpiq_flutter/otpiq_flutter.dart';

final otpiq = Otpiq(apiKey: 'your_project_api_key_here');

// Configure the global WhatsApp credentials once after initialization (optional)
otpiq.setWhatsAppConfig(
  const OtpiqWhatsAppConfig(
    whatsappAccountId: 'your_whatsapp_account_id',
    whatsappPhoneId: 'your_whatsapp_phone_number_id',
  ),
);

2. Get Project Info

Retrieve information about the authenticated project, including remaining credits:

try {
  final projectInfo = await otpiq.getProjectInfo();
  print('Project Name: ${projectInfo.projectName}');
  print('Remaining Credit: ${projectInfo.credit} IQD');
} on ApiException catch (e) {
  print('Error: ${e.message} (Status: ${e.statusCode})');
}

3. Send SMS / Verification Codes

Send a Verification Code (OTP)

final verificationRequest = SmsVerificationRequest(
  phoneNumber: '964750123456',
  verificationCode: '123456',
  senderId: 'OTPIQ', // Optional custom sender ID
  provider: OtpiqProvider.whatsappSms, // Optional fallback provider enum
);

try {
  final response = await otpiq.sendSms(verificationRequest);
  print('SMS Sent! ID: ${response.smsId}');
} on ApiException catch (e) {
  print('Failed to send: ${e.message}');
}

Send a Custom Message

final customRequest = SmsCustomMessageRequest(
  phoneNumber: '964750123456',
  customMessage: 'Your order #12345 has been confirmed. Thank you!',
  senderId: 'OTPIQ',
);

final response = await otpiq.sendSms(customRequest);

Send a WhatsApp Template Message

// Note: Omit local WhatsApp credentials since they are configured globally on otpiq:
final whatsappRequest = SmsWhatsAppTemplateRequest(
  phoneNumber: '964750123456',
  templateName: 'verification_template',
);

final response = await otpiq.sendSms(whatsappRequest);

4. Track Message Delivery

Retrieve details and attempts sequence for a specific message using its smsId:

try {
  final track = await otpiq.trackSms('sms-1234567890abcdef123456');
  print('Status: ${track.status}');
  print('Is Final State: ${track.isFinalStatus}');
  print('Last Channel: ${track.lastChannel}');
  
  for (var attempt in track.channelFlow) {
    print('Channel ${attempt.channel}: Succeeded? ${attempt.success}');
  }
} on ApiException catch (e) {
  print('Error: ${e.message}');
}

Error Handling

All external API calls wrap errors and throw a custom ApiException class:

try {
  await otpiq.getProjectInfo();
} on ApiException catch (e) {
  print('Message: ${e.message}');
  print('Status Code: ${e.statusCode}');
  print('Response Data: ${e.data}');
}

License

This package is licensed under the MIT License. See LICENSE for details.

Libraries

otpiq_flutter