flutter_snapmint_sdk 0.0.5
flutter_snapmint_sdk: ^0.0.5 copied to clipboard
Snapmint Flutter SDK for Web, Android, iOS, Linux, macOS and Windows
example/lib/main.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_snapmint_sdk/flutter_snapmint_sdk.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final GlobalKey<ScaffoldMessengerState> _messengerKey = GlobalKey<ScaffoldMessengerState>();
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
final TextEditingController _checkoutUrlController = TextEditingController(
text:
'https://pay.sandbox.snapmint.com?id=56231&token=xFsRDgNrsG_PK9MtCmbx&merchantId=1456&logo=null&title=null',
);
bool _uiShown = false; // prevent double UI
String _lastStatusText = '';
@override
void initState() {
super.initState();
//initPlatformState();
}
Future<void> openSnapMintModule() async {
_uiShown = false;
final checkoutUrl = _checkoutUrlController.text.trim();
if (checkoutUrl.isEmpty) {
_showResponseDialog({
'status': 'failure',
'statusCode': 400,
'responseMsg': 'Please enter a valid checkout URL',
});
return;
}
try {
debugPrint('[Example] Calling RNSnapmintCheckout with URL: ' + checkoutUrl);
final result = await RNSnapmintCheckout.openSnapmintMerchant(
checkoutUrl,
options: PaymentOptions(
onSuccess: (r) {
debugPrint('[Example] onSuccess: ' + (r.responseMsg ?? r.message ?? 'no message'));
_showSuccessUI({
'status': r.status,
'statusCode': r.statusCode,
'responseMsg': r.responseMsg ?? r.message,
'paymentId': r.paymentId,
});
},
onError: (e) {
debugPrint('[Example] onError: ' + (e.responseMsg ?? e.message ?? 'no message'));
_showErrorUI({
'status': e.status,
'statusCode': e.statusCode,
'responseMsg': e.responseMsg ?? e.message,
});
},
),
);
debugPrint('[Example] Promise resolved with: ' + (result.responseMsg ?? result.message ?? 'no message'));
// Do not show fallback dialog to avoid duplicate UI
} catch (e) {
debugPrint('[Example] Promise rejected with: ' + e.toString());
_showErrorUI({
'status': 'failure',
'statusCode': 500,
'responseMsg': e.toString(),
});
}
}
void _showSuccessUI(Map<String, dynamic> data) {
if (_uiShown || !mounted) return;
_uiShown = true;
setState(() {
_lastStatusText = 'Success: ' + (data['responseMsg']?.toString() ?? '');
});
// Toast/snackbar
_messengerKey.currentState?.showSnackBar(SnackBar(
content: Text('Success: ' + (data['responseMsg']?.toString() ?? '')),
));
// Dialog
WidgetsBinding.instance.addPostFrameCallback((_) => _showResponseDialog(data));
}
void _showErrorUI(Map<String, dynamic> data) {
if (_uiShown || !mounted) return;
_uiShown = true;
setState(() {
_lastStatusText = 'Error: ' + (data['responseMsg']?.toString() ?? '');
});
_messengerKey.currentState?.showSnackBar(SnackBar(
content: Text('Error: ' + (data['responseMsg']?.toString() ?? '')),
));
WidgetsBinding.instance.addPostFrameCallback((_) => _showResponseDialog(data));
}
@override
void dispose() {
_checkoutUrlController.dispose();
super.dispose();
}
void _showResponseDialog(Map<String, dynamic> responseData) {
final dialogContext = _navigatorKey.currentContext ?? context;
final dynamic statusCode = responseData["statusCode"];
final String? status = responseData["status"]?.toString();
final bool isSuccess =
status == 'success' || statusCode == 200 || statusCode == '200' || statusCode == 'SUCCESS';
showDialog(
context: dialogContext,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
isSuccess ? "Success Response" : "Error Response",
style: TextStyle(
color: isSuccess ? Colors.green : Colors.red,
fontWeight: FontWeight.bold,
),
),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Status: ${responseData["status"] ?? "N/A"}",
style: const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(
"Status Code: ${responseData["statusCode"] ?? "N/A"}",
style: const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
if (responseData["responseMsg"] != null) ...[
Text(
"Response Message:",
style: const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
Text(responseData["responseMsg"]),
const SizedBox(height: 8),
],
if (responseData["error"] != null) ...[
Text(
"Error:",
style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.red),
),
const SizedBox(height: 4),
Text(responseData["error"]),
const SizedBox(height: 8),
],
if (responseData["message"] != null) ...[
Text(
"Message:",
style: const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
Text(responseData["message"]),
const SizedBox(height: 8),
],
const Text(
"Full Response Data:",
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(4),
),
child: Text(
const JsonEncoder.withIndent(' ').convert(responseData),
style: const TextStyle(fontSize: 12, fontFamily: 'monospace'),
),
),
],
),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text("Close"),
),
],
);
},
);
}
// Removed platform version demo code
@override
Widget build(BuildContext context) {
return MaterialApp(
scaffoldMessengerKey: _messengerKey,
navigatorKey: _navigatorKey,
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 20),
Container(
margin: const EdgeInsets.only(left: 20, right: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_lastStatusText.isNotEmpty) ...[
Text(
_lastStatusText,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
),
const SizedBox(height: 8),
],
// Checkout URL input (similar to RN test app dynamic URL)
TextField(
controller: _checkoutUrlController,
decoration: const InputDecoration(
labelText: 'Checkout URL',
hintText: 'https://pay.sandbox.snapmint.com/...',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.url,
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () {
openSnapMintModule();
},
child: const Text(
"Open SDK",
style: TextStyle(
fontSize: 14,
color: Colors.blue,
fontFamily: 'Roboto',
fontWeight: FontWeight.w400,
),
)),
const SizedBox(
height: 10,
),
const Text(
'WebView EMI Button Test (Debug Mode)',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
const RNSnapmintButton(
amount: '20000',
merchantPath: '4858/snap_titan.json',
// fontFamily: FontFamilyConfig(fontFamily: 'Roboto', fontMultiplier: 16),
// buttonWidth: 300,
),
const SizedBox(height: 15),
const SizedBox(
height: 5,
),
// Gold widget removed
const Text(
'Debug: Check console/logs for API and WebView debugging info',
style: TextStyle(fontSize: 12, color: Colors.grey),
textAlign: TextAlign.center,
),
],
),
),
],
),
),
),
),
);
}
}