itc_card_scanner 0.0.2
itc_card_scanner: ^0.0.2 copied to clipboard
A Flutter plugin for scanning credit cards using device camera with OCR. Extracts card number, expiry date, cardholder name, and card type.
ITC Card Scanner #
A Flutter plugin for scanning credit cards using device camera with OCR capabilities. Automatically extracts card number, expiry date, cardholder name, and card type.
Features #
✅ Card Number Detection - Automatically scans and validates card numbers
✅ Expiry Date Extraction - Detects MM/YY format dates
✅ Cardholder Name Recognition - Extracts name from card
✅ Card Type Identification - Detects Visa, MasterCard, Amex, etc.
✅ Real-time Preview - Shows detected information overlay
✅ Cross Platform - Works on both Android and iOS
Supported Card Types #
- Visa
- MasterCard
- American Express
- Discover
- JCB
- Diners Club
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
itc_card_scanner: ^0.0.1
Then run:
flutter pub get
Platform Setup #
Android Setup #
1. Minimum SDK Version
Ensure your android/app/build.gradle has minimum SDK 24:
android {
defaultConfig {
minSdkVersion 24 // Required for camera and ML Kit
targetSdkVersion 34
}
}
2. Permissions (Automatically Added)
The plugin automatically adds these permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera.any" />
<uses-feature android:name="android.hardware.camera.autofocus" />
3. ProGuard Rules (If Using)
If you're using ProGuard, add these rules to android/app/proguard-rules.pro:
# Keep ML Kit classes
-keep class com.google.mlkit.** { *; }
-keep class com.google.android.gms.** { *; }
# Keep camera classes
-keep class androidx.camera.** { *; }
iOS Setup #
1. Minimum iOS Version
Ensure your ios/Runner.xcodeproj targets iOS 13.0+:
Open ios/Podfile and set:
platform :ios, '13.0'
2. Camera Permission (Required)
Add camera permission to ios/Runner/Info.plist:
<dict>
<!-- Add these keys -->
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan credit cards</string>
<!-- Optional: If your app needs microphone -->
<key>NSMicrophoneUsageDescription</key>
<string>This app may need microphone access for camera functionality</string>
</dict>
3. Update iOS Deployment Target
In ios/Flutter/AppFramework.xcconfig, ensure:
IPHONEOS_DEPLOYMENT_TARGET = 13.0
Usage #
Basic Usage #
import 'package:itc_card_scanner/itc_card_scanner.dart';
final _scanner = ItcCardScanner();
// Scan a card
final result = await _scanner.scanCard();
if (result != null && result['success'] == true) {
String cardNumber = result['cardNumber'];
String expiryDate = result['expiryDate'];
String cardholderName = result['cardholderName'];
String cardType = result['cardType'];
print('Card: $cardNumber');
print('Expiry: $expiryDate');
print('Name: $cardholderName');
print('Type: $cardType');
} else {
print('Scan cancelled or failed');
}
With Data Model #
import 'package:itc_card_scanner/itc_card_scanner.dart';
final result = await ItcCardScanner().scanCard();
if (result != null) {
final cardDetails = ScannedCardDetails.fromMap(result);
if (cardDetails.success) {
print('Scanned: ${cardDetails.cardNumber}');
print('Expires: ${cardDetails.expiryDate}');
print('Holder: ${cardDetails.cardholderName}');
print('Type: ${cardDetails.cardType}');
}
}
Error Handling #
try {
final result = await ItcCardScanner().scanCard();
if (result != null && result['success'] == true) {
// Handle successful scan
handleScannedCard(result);
} else {
// Handle cancelled scan
print('User cancelled the scan');
}
} catch (e) {
// Handle errors
print('Error scanning card: $e');
}
Complete Example #
import 'package:flutter/material.dart';
import 'package:itc_card_scanner/itc_card_scanner.dart';
class CardScanPage extends StatefulWidget {
@override
_CardScanPageState createState() => _CardScanPageState();
}
class _CardScanPageState extends State<CardScanPage> {
final _scanner = ItcCardScanner();
String _result = 'Tap scan to start';
bool _isLoading = false;
void _scanCard() async {
setState(() {
_isLoading = true;
});
try {
final result = await _scanner.scanCard();
if (result != null && result['success'] == true) {
setState(() {
_result = '''
Card Number: ${result['cardNumber']}
Expiry Date: ${result['expiryDate']}
Cardholder: ${result['cardholderName']}
Card Type: ${result['cardType']}
''';
});
} else {
setState(() {
_result = 'Scan cancelled by user';
});
}
} catch (e) {
setState(() {
_result = 'Error: $e';
});
} finally {
setState(() {
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Card Scanner Demo'),
backgroundColor: Colors.blue,
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ElevatedButton(
onPressed: _isLoading ? null : _scanCard,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
padding: EdgeInsets.all(16),
),
child: _isLoading
? CircularProgressIndicator(color: Colors.white)
: Text(
'SCAN CARD',
style: TextStyle(fontSize: 18, color: Colors.white),
),
),
SizedBox(height: 20),
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
child: Text(
_result,
style: TextStyle(fontSize: 14),
),
),
],
),
),
);
}
}
API Reference #
Methods #
scanCard()
Launches the card scanner and returns scanned card details.
Returns: Future<Map<String, dynamic>?>
Response Format:
{
'cardNumber': '1234 5678 9012 3456',
'expiryDate': '12/25',
'cardholderName': 'JOHN DOE',
'cardType': 'Visa',
'success': true
}
Possible Values:
- cardNumber: Formatted card number with spaces
- expiryDate: MM/YY format
- cardholderName: Uppercase name or empty string
- cardType: 'Visa', 'MasterCard', 'American Express', 'Discover', 'JCB', 'Diners Club', 'Unknown'
- success: Boolean indicating if scan was successful
getPlatformVersion()
Returns the current platform version.
Returns: Future<String?>
Data Models #
ScannedCardDetails
class ScannedCardDetails {
final String cardNumber;
final String expiryDate;
final String cardholderName;
final String cardType;
final bool success;
factory ScannedCardDetails.fromMap(Map<String, dynamic> map);
}
Troubleshooting #
Common Issues #
Android Issues
-
Camera Permission Denied
- Ensure user grants camera permission when prompted
- Check if device has camera hardware
-
Build Errors
- Verify
minSdkVersionis 24 or higher - Clean and rebuild:
flutter clean && flutter pub get
- Verify
-
ML Kit Issues
- Ensure device has Google Play Services
- Check internet connection for first-time ML Kit download
iOS Issues
-
Camera Permission Denied
- Verify
NSCameraUsageDescriptionis in Info.plist - Check iOS Settings → Privacy → Camera
- Verify
-
Build Errors
- Ensure iOS deployment target is 13.0+
- Run
cd ios && pod install
-
Simulator Issues
- Physical device recommended for camera functionality
- Simulator may have limited camera features
Performance Tips #
- Good Lighting: Ensure adequate lighting for better OCR accuracy
- Steady Hand: Hold device steady while scanning
- Card Position: Position card within the overlay frame
- Clean Card: Ensure card surface is clean and readable
Requirements #
- Flutter: >= 3.0.0
- Dart: >= 3.0.0
- Android: API level 24+ (Android 7.0+)
- iOS: 13.0+
- Camera: Device must have camera hardware
- Permissions: Camera access required
Privacy & Security #
- 🔒 Local Processing: All card data is processed locally on the device
- 🚫 No Network: No card information is transmitted to external servers
- 💾 No Storage: Card data is not stored on the device
- 🛡️ Secure: OCR processing happens in device memory only
Contributing #
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Support #
For issues and feature requests, please visit our GitHub repository.