authme_ekyc_sdk 1.0.0 authme_ekyc_sdk: ^1.0.0 copied to clipboard
A Flutter package of ekyc of authme.
import 'dart:developer';
import 'package:authme_ekyc_sdk/ekyc_feature.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:authme_ekyc_sdk/ekyc_sdk_plugin_bridge.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter AuthMe eKYC SDK Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const AuthMeHomePage(),
);
}
}
class AuthMeHomePage extends StatefulWidget {
const AuthMeHomePage({super.key});
@override
State<AuthMeHomePage> createState() => _AuthMeHomePageState();
}
class _AuthMeHomePageState extends State<AuthMeHomePage> {
String? _token;
bool _isLoading = false;
final AuthmeSdk _authMeSdk = AuthmeSdk();
late StreamSubscription _resultSubscription;
String _name = ""; // 這裡是要顯示的名字
var timestamp = DateTime.now().millisecondsSinceEpoch;
bool _needConfirm = true;
bool _isResultPageDisplayable = true;
bool _isResultEditable = true;
@override
void initState() {
super.initState();
_resultSubscription = _authMeSdk.resultStream.listen(
(result) {
if (result.containsKey('result')) {
final resultMap = result['result'];
if (resultMap is Map) {
// 取得主要資料層
final data = resultMap['data'];
// 取得圖片層
final images = resultMap['images'];
log("data: $data");
if (data is Map) {
// 只修改主要資料層
Map<String, String> modifications = Map.from(data);
// 修改需要更新的部分
modifications['address'] = 'new address';
// 確認結果時只傳送主要資料層的修改
_authMeSdk.confirmScanResult(modifications).then((_) {
log('Scan result confirmed');
}).catchError((error) {
log('Failed to confirm scan result: $error');
});
// 如果需要處理圖片,可以另外處理
if (images != null && images is Map<String, dynamic>) {
final frontImage = images['frontImage'];
final backImage = images['backImage'];
// 處理圖片...
}
}
}
} else if (result.containsKey('error')) {
// 處理錯誤
log("錯誤: ${result['error']}");
}
},
onError: (error) {
print("Stream error: $error");
},
);
_fetchToken();
initSDK();
}
Future<void> _fetchToken() async {
setState(() {
_isLoading = true;
});
try {
final response = await http.post(
Uri.parse('https://stage.auth.authme.com/connect/token'),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: {
'client_id': 'd7e8cf57499b4c348fbfb4b3e92d0182',
'client_secret': 'oy9rDBCv5trf6BJe',
'grant_type': 'client_credentials',
'scope': 'AuthmeServices customer_id:FlutterTest$timestamp event_name:default',
},
);
print(response);
if (response.statusCode == 200) {
final Map<String, dynamic> jsonResponse = json.decode(response.body);
setState(() {
_token = jsonResponse['access_token'];
_isLoading = false;
});
_authMeSdk.refreshToken(_token!);
} else {
throw Exception('Failed to load token');
}
} catch (e) {
setState(() {
_isLoading = false;
});
print('Error fetching token: $e');
}
}
void initSDK() {
var serverURL = "https://stage.api.authme.com";
var activateToken =
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJmZWF0dXJlcyI6bnVsbCwiZXhwIjoxNzY4MTg0MzM5LCJpc3MiOiJhdXRobWUuY29tIiwibmJmIjotNjIxMzU1OTY4MDB9.WsWXA-mlwe92reX8G5daqWLp19mE0CrmTSLRX8KKxIaeOyX1ijTvMnmgKHJTtJImgDtF7zY_SHnq8AI20cbxH0enGEMU8oVqso5zE4Qba74wqwOwvW1AOfpxX_iaYtJ7MgkZcv7aUhoak6YRo5lvPx1nyRd58J58-LJl5LaBysyGqbrPsNLeEQvHwi18Vs8YykPU1iQvlPbtRm254JIgPnqfZIK83t4AA-g_hZj-iGmUVdRrVNxXx8B96f03GgZIKqx00BYm-jZZBvhJMVuWzNrF7yMcwkPe4QZmDdiX4GfyQd_CAukVXB0nktcIMJ6JIgTMlGwxGdNNSzR8EG8qlw";
var activateCertificate =
"-----BEGIN CERTIFICATE-----\nMIIESzCCAzOgAwIBAgIUAJxh4eDXLq7oCYUCOyNQlbKj7FUwDQYJKoZIhvcNAQEL\nBQAwNzELMAkGA1UEBhMCVFcxDzANBgNVBAoTBkF1dGhtZTEXMBUGA1UEAwwOKi4o\nYXV0aG1lKS5jb20wHhcNMjQwNzEyMDIxODU5WhcNMjYwMTEwMTQxODU4WjAdMRsw\nGQYDVQQDExJhdXRobWUtd2ViZGVtby5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQDn4CuTMjCq8n67HLI4hkLY/fqyzBUmNxueeoZO3ll2UOpv9ZkO\n8bRz3bdQ/BQum0Glrim+wix41NelDz6R+l5oCJ+Wv7CgNqTY0dLJsjYVSzarXp18\nS/R6vCHFIQfia6i1FeyXJF9roAdFHCXlDLzfkUs2/nz+LU4xx6B9gzlArjeoCRAq\nxzehSVQc3CeAQe/aqiLHVdwVqD3LyDZySBs1kc1XS3Idp2vqMcMA21h7m44qnbJG\nhZWiQJnh+TdZC9nUCJ75709J36385k3yX3XMoU2kEm7aU0VOJ+EyJLvTrFt9EZgR\nXjKsYtRsZT3dCsn9vQH3YaMHFS/K+GPAtvTTAgMBAAGjggFnMIIBYzAMBgNVHRMB\nAf8EAjAAMB0GA1UdDgQWBBRbzVPru0OJvKuWCSsaRiK5JFG7pzAfBgNVHSMEGDAW\ngBTFUiqtAgJgJ1OBZ4E3sSQh2Z48HzCBjQYIKwYBBQUHAQEEgYAwfjB8BggrBgEF\nBQcwAoZwaHR0cDovL3ByaXZhdGVjYS1jb250ZW50LTYyY2NhNzhiLTAwMDAtMjEw\nNS1hN2YxLWQ0ZjU0N2Y4M2U3NC5zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Q3YzY2\nNjA2NDVjMDUzOTUxNWUyL2NhLmNydDCBggYDVR0fBHsweTB3oHWgc4ZxaHR0cDov\nL3ByaXZhdGVjYS1jb250ZW50LTYyY2NhNzhiLTAwMDAtMjEwNS1hN2YxLWQ0ZjU0\nN2Y4M2U3NC5zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Q3YzY2NjA2NDVjMDUzOTUx\nNWUyL2NybC5jcmwwDQYJKoZIhvcNAQELBQADggEBABemPM70DFKYJFXkEfBXcM29\n8Y97s8kct3UDPmdCR/n2BMGrhIJZ9/ieIYdcNvQED/GX+Iq9CMiju+0KyJoOKF5e\ndxBVWqKiuaBBQmhWDxQmjdK+/npIoN2CKX6LSdyzm1VPeDgnEKrAmzhTVc3DlP89\ngNoCp+ouxAA622pc1DFkbZzDQMa7TYcYs3bJWDOC9xSNiLXFOemMoh5iImwByacL\n5mK2ppvOsjnFPn9DfY9mM4rLKyLFZRFU4wY9IwDX52PK4z8DVz6D18bcINVZQbmU\nRNFAq4hK9vbwzdozc+XQzYqAQk8ObTDcqHo+JtAgo3Znk9TJyTXvsc0f2SjfzhQ=\n-----END CERTIFICATE-----\n\n";
_authMeSdk.initialize(
serverURL,
activateToken,
activateCertificate,
);
}
void _startAuthme() async {
_fetchToken();
if (_token != null) {
await _authMeSdk.startFeature(
_token!,
AuthmeFeature.TWID,
needConfirm: _needConfirm,
isResultPageDisplayable: _isResultPageDisplayable,
isResultEditable: _isResultEditable,
);
} else {
print('Token 不可用');
}
}
void _startAuthmeLiveness() async {
_fetchToken();
if (_token != null) {
await _authMeSdk.startFeature(
_token!,
AuthmeFeature.Liveness,
needConfirm: _needConfirm,
isResultPageDisplayable: _isResultPageDisplayable,
isResultEditable: _isResultEditable,
);
} else {
print('Token 不可用');
}
}
void _startAuthmePassport() async {
_fetchToken();
if (_token != null) {
await _authMeSdk.startFeature(
_token!,
AuthmeFeature.Passport,
needConfirm: _needConfirm,
isResultPageDisplayable: _isResultPageDisplayable,
isResultEditable: _isResultEditable,
);
} else {
print('Token 不可用');
}
}
void _startAuthmePassportNFC() async {
_fetchToken();
if (_token != null) {
await _authMeSdk.startFeature(
_token!,
AuthmeFeature.NFCPassport,
needConfirm: _needConfirm,
isResultPageDisplayable: _isResultPageDisplayable,
isResultEditable: _isResultEditable,
);
} else {
print('Token 不可用');
}
}
Widget _buildButtonColumn(String title, List<Map<String, Function>> buttons) {
return Expanded(
child: Column(
children: [
Text(title, style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 20),
...buttons.map((button) => Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: ElevatedButton(
onPressed: _token != null ? () => button.values.first() : null,
child: Text(button.keys.first),
),
)).toList(),
],
),
);
}
Widget _buildSettingsPanel() {
return Card(
margin: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text('設置', style: Theme.of(context).textTheme.titleLarge),
const SizedBox(height: 16),
SwitchListTile(
title: const Text('需要確認'),
value: _needConfirm,
onChanged: (bool value) {
setState(() {
_needConfirm = value;
});
},
),
SwitchListTile(
title: const Text('顯示結果頁面'),
value: _isResultPageDisplayable,
onChanged: (bool value) {
setState(() {
_isResultPageDisplayable = value;
});
},
),
SwitchListTile(
title: const Text('允許編輯結果'),
value: _isResultEditable,
onChanged: (bool value) {
setState(() {
_isResultEditable = value;
});
},
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text("Flutter AuthMe eKYC SDK Example"),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
_buildSettingsPanel(),
const SizedBox(height: 20),
Row(
children: [
_buildButtonColumn('Sample', [
{'Start AuthMe': () => _startAuthme()},
{'Start AuthMe Liveness': () => _startAuthmeLiveness()},
{'Start Authme Passport': () => _startAuthmePassport()},
{'Start Authme Passport NFC': () => _startAuthmePassportNFC()},
]),
if (_name.isNotEmpty)
Expanded(
child: Text(
"Name: $_name",
style: TextStyle(fontSize: 24),
),
),
],
),
],
),
),
);
}
@override
void dispose() {
_resultSubscription.cancel();
_authMeSdk.dispose();
super.dispose();
}
}