banking_dcb_sdk_flutter 1.0.7
banking_dcb_sdk_flutter: ^1.0.7 copied to clipboard
Partner UI Integration Library for Flutter
example/lib/main.dart
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:app_links/app_links.dart';
import 'package:banking_dcb_sdk_flutter/banking_dcb_sdk_flutter.dart';
import 'package:banking_dcb_sdk_flutter_example/DeepLinkTest.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import 'DeepLinkTest2.dart';
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await dotenv.load(fileName: "lib/.env");
HttpOverrides.global = MyHttpOverrides();
await BankingDcbSdkFlutter.init(
dotenv.env['BASE_URL']!,
whitelistedDomains: [
"razorpay.com",
"m2pfintech.com",
"https://capture.kyc.idfy.com"
],
deviceBindingEnabled: false,
);
runApp(MyApp());
}
final GlobalKey<NavigatorState> navKey = GlobalKey<NavigatorState>();
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _appLinks = AppLinks();
StreamSubscription<Uri>? _sub;
Uri? _pendingUri; // for when navigator isn't ready yet
@override
void initState() {
super.initState();
_setupDeepLinks();
}
Future<void> _setupDeepLinks() async {
// Cold start
final initial = await _appLinks.getInitialLink();
if (initial != null) {
_handleDeepLink(initial);
}
// While running / in background
_sub = _appLinks.uriLinkStream.listen(
(uri) => _handleDeepLink(uri),
onError: (e) => debugPrint("DeepLink error: $e"),
);
}
void _handleDeepLink(Uri uri) {
debugPrint("DeepLink received: $uri");
if (uri.scheme == "dcbexample" && uri.host == "deeplink_test") {
_pendingUri = uri;
WidgetsBinding.instance.addPostFrameCallback((_) {
final nav = navKey.currentState;
if (nav == null) {
debugPrint("Navigator not ready yet, keeping pendingUri");
return;
}
// Clear pending uri
final toOpen = _pendingUri;
_pendingUri = null;
if (toOpen != null) {
debugPrint("Navigating to DeepLinkTest for $toOpen");
nav.push(
MaterialPageRoute(builder: (_) => DeepLinkTest()),
);
}
});
}
}
@override
void dispose() {
_sub?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navKey,
debugShowCheckedModeBanner: false,
home: FirstPage(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Welcome'),
),
body: Column(children: [
Center(
child: ElevatedButton(
child: Text('Go to Home'),
onPressed: () {
// If you don't want to come back to this screen on back press:
Navigator.push(
context,
MaterialPageRoute(builder: (_) => MyHome()),
);
},
),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => DeepLinkTest(),
));
},
child: Text('Deeplink Test'))
]),
);
}
}
class MyHome extends StatefulWidget {
@override
_MyHomeState createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> {
final _formKey = GlobalKey<FormState>();
final _nameController = TextEditingController();
final _emailController = TextEditingController();
final _phoneController = TextEditingController();
final _prospectIDController = TextEditingController();
final _partnerUserIdController = TextEditingController();
String name = '';
String email = '';
String phone = '';
// final String? clientId = dotenv.env['KID'];
String baseUrl = '';
String token = '';
@override
void initState() {
baseUrl = dotenv.env['BASE_URL']!;
super.initState();
// _setupDeepLinks();
_checkSession((WebViewCallback action) {
switch (action.type) {
case WebViewCallbackType.redirect:
print("Redirected with status: ${action.status}");
break;
case WebViewCallbackType.logout:
print("User logged out");
break;
}
});
}
Future<void> _checkSession(WebViewCallbackFunction callback) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? name = prefs.getString('name');
String? email = prefs.getString('email');
String? phone = prefs.getString('phone');
setState(() {
_nameController.text = name ?? '';
_emailController.text = email ?? '';
_phoneController.text = phone ?? '';
});
}
Future<void> createToken(
//SBM
String module,
String photo,
WebViewCallbackFunction callback,
{String? nameInput,
String? emailInput,
String? phoneInput}) async {
setState(() {
name = nameInput?.isNotEmpty == true ? nameInput! : _nameController.text;
email =
emailInput?.isNotEmpty == true ? emailInput! : _emailController.text;
phone =
phoneInput?.isNotEmpty == true ? phoneInput! : _phoneController.text;
});
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('name', name);
await prefs.setString('email', email);
await prefs.setString('phone', phone);
final String clientId = dotenv.env['KID']!;
print("clientId $clientId");
final Map<String, Object> headers = {
'kid': clientId,
'typ': 'JWT',
'alg': 'HS256',
};
final Map<String, String> attributes = {
'name': name.trim(),
'photo': photo,
"partner_user_id": _partnerUserIdController.text.trim() ?? "1234"
};
const Duration expirationDuration = Duration(milliseconds: 300000);
final clientSecret = dotenv.env['CLIENT_SECRET'];
print("clientSecret $clientSecret");
final jwt = JWT(
{
'attributes': attributes,
// 'module': '/banking/dcb/credit_card/CRE',
// "redirect_url": "https://credilio.in",
"prospect_id": _prospectIDController.text.trim(),
"device_binded": true,
},
header: headers,
);
token = await jwt.sign(
SecretKey(clientSecret!),
expiresIn: expirationDuration,
);
print("Token generated FROM client side is: $token for module $module");
final sdkLoginResponse = await BankingDcbSdkFlutter.instance
.sdkLogin(context, token: token, partner: 'dcb');
print("sdkLoginResponse $sdkLoginResponse");
//do some activity
final publicApiResponse = await BankingDcbSdkFlutter.instance.publicCallAPI(
'',
'POST',
body: {'token': token},
);
print("Public API response: ${publicApiResponse}");
//do some activity
await BankingDcbSdkFlutter.instance.open(context, module, token, callback);
}
@override
void dispose() {
_nameController.dispose();
_emailController.dispose();
_phoneController.dispose();
_prospectIDController.dispose();
_partnerUserIdController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Spacer(),
SizedBox(
height: 48,
child: TextButton(
style: TextButton.styleFrom(
foregroundColor: Colors.black,
),
onPressed: () {
if (_formKey.currentState!.validate()) {
createToken(dotenv.env['SPENSE_MODULE']!, '',
(WebViewCallback action) {
switch (action.type) {
case WebViewCallbackType.redirect:
print(
"Redirected with status: ${action.status}");
break;
case WebViewCallbackType.logout:
print("User logged out");
break;
}
});
}
},
child: const Text(
'Dashboard',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
),
],
),
SizedBox(height: MediaQuery.of(context).size.height * 0.02),
const Text(
'User Details',
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
SizedBox(height: MediaQuery.of(context).size.height * 0.02),
TextFormField(
controller: _prospectIDController,
decoration: const InputDecoration(
fillColor: Colors.grey,
labelText: 'Prospect ID',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your prospect ID';
}
return null;
},
),
SizedBox(
height: 48,
child: TextButton(
style: TextButton.styleFrom(
foregroundColor: Colors.black,
),
onPressed: () {
if (_formKey.currentState!.validate()) {
createToken('${dotenv.env['MODULE']!}/pay_bill', '',
(WebViewCallback action) {
switch (action.type) {
case WebViewCallbackType.redirect:
print("Redirected with status: ${action.status}");
break;
case WebViewCallbackType.logout:
print("User logged out");
break;
}
});
}
},
child: const Text(
'Pay Bill',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
),
SizedBox(
height: 48,
child: TextButton(
style: TextButton.styleFrom(
foregroundColor: Colors.black,
),
onPressed: () {
createToken(
'/banking/dcb/credit_card/ZET/card_limits', '',
(WebViewCallback action) {
switch (action.type) {
case WebViewCallbackType.redirect:
print("Redirected with status: ${action.status}");
break;
case WebViewCallbackType.logout:
print("User logged out");
break;
}
});
},
child: const Text(
'Manage Card',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
),
],
),
),
),
),
);
}
}