flutter_hyperswitch 1.1.4 flutter_hyperswitch: ^1.1.4 copied to clipboard
Flutter Hyperswitch: Simplifying payment integration for Flutter apps with seamless API interactions and customizable UI.
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart' hide Card;
import 'package:flutter/material.dart' as material;
import 'package:flutter_hyperswitch/flutter_hyperswitch.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final String _endpoint =
Platform.isAndroid ? "http://10.0.2.2:5252" : "http://localhost:5252";
final _hyper = FlutterHyperswitch();
Session? _sessionId;
SavedSession? _savedSessionId;
String _statusText = '';
String _defaultPaymentMethodText = '';
String _confirmStatusText = '';
bool _isInitialized = false;
bool _showChangeButton = false;
int _confirmState = 0;
@override
void initState() {
super.initState();
_initPlatformState();
}
Future<void> _initPlatformState() async {
final response =
await http.get(Uri.parse("$_endpoint/create-payment-intent"));
if (response.statusCode == 200) {
final responseBody = jsonDecode(response.body) as Map<String, dynamic>;
_hyper.init(HyperConfig(publishableKey: responseBody['publishableKey']));
try {
_sessionId = await _hyper.initPaymentSession(PaymentMethodParams(
clientSecret: responseBody['clientSecret'],
configuration: Configuration(
appearance: Appearance(
font: Font(family: "montserrat_regular"),
shapes: Shapes(
shadow: Shadow(color: "#00000050", intensity: 5)),
primaryButton: PrimaryButton(
shapes: Shapes(
shadow:
Shadow(color: "#000000", intensity: 2)))))));
} catch (ex) {
print((ex as HyperswitchException).message);
}
setState(() {
_isInitialized = _sessionId != null;
_statusText =
_isInitialized ? _statusText : "initPaymentSession failed";
});
} else {
setState(() {
_statusText = "API Call Failed";
});
}
}
Future<void> _initializeHeadless() async {
if (_sessionId == null) {
setState(() {
_defaultPaymentMethodText = "SessionId is empty";
_statusText = "";
});
return;
}
try {
_savedSessionId =
await _hyper.getCustomerSavedPaymentMethods(_sessionId!);
final paymentMethod = await _hyper
.getCustomerDefaultSavedPaymentMethodData(_savedSessionId!);
if (paymentMethod is PaymentMethod) {
if (paymentMethod is Card) {
final card = paymentMethod;
_setDefaultPaymentMethodText(
"${card.nickName} ${card.cardNumber} ${card.expiryDate}", true);
_showChangeButton = true;
} else if (paymentMethod is Wallet) {
final wallet = paymentMethod;
_setDefaultPaymentMethodText(wallet.walletType, true);
}
} else if (paymentMethod is PaymentMethodError) {
_setDefaultPaymentMethodText(paymentMethod.message, false);
} else {
_setDefaultPaymentMethodText(
"getCustomerDefaultSavedPaymentMethodData failed", false);
}
} catch (error) {
_handleError(error, 1);
}
}
Future<void> _confirmPayment() async {
setState(() {
_confirmState = 1;
});
try {
if (_savedSessionId != null) {
final confirmWithCustomerDefaultPaymentMethodResponse = await _hyper
.confirmWithCustomerDefaultPaymentMethod(_savedSessionId!);
final message = confirmWithCustomerDefaultPaymentMethodResponse.message;
if (message != null) {
_setConfirmStatusText(
"${confirmWithCustomerDefaultPaymentMethodResponse.status.name}\n${message.name}");
} else {
_setConfirmStatusText(
"${confirmWithCustomerDefaultPaymentMethodResponse.status.name}\n${confirmWithCustomerDefaultPaymentMethodResponse.error.message}");
}
} else {
_setConfirmStatusText("SavedSession is empty");
}
} catch (error) {
_handleError(error, 2);
} finally {
setState(() {
_showChangeButton = false;
_defaultPaymentMethodText = '';
_confirmState = 0;
_initPlatformState();
});
}
}
Future<void> _presentPaymentSheet(bool isHeadless) async {
if (_sessionId == null) {
_setStatusText("SessionId is empty");
return;
}
try {
final presentPaymentSheetResponse =
await _hyper.presentPaymentSheet(_sessionId!);
if (isHeadless) {
_setConfirmStatusText(_buildMessage(
presentPaymentSheetResponse.status.name,
presentPaymentSheetResponse.message,
presentPaymentSheetResponse.error.message));
} else {
_setStatusText(_buildMessage(
presentPaymentSheetResponse.status.name,
presentPaymentSheetResponse.message,
presentPaymentSheetResponse.error.message));
}
if (presentPaymentSheetResponse.status != Status.cancelled) {
setState(() {
_showChangeButton = false;
_defaultPaymentMethodText = '';
_confirmState = 0;
_initPlatformState();
});
}
} catch (error) {
_handleError(error, 0);
}
}
String _buildMessage(String status, Result? message, String error) {
if (message != null) {
return "$status\n${message.name}";
} else {
return "$status\n$error";
}
}
void _handleError(dynamic error, int flow) {
final errorMessage =
error is HyperswitchException ? error.message : error.toString();
if (flow == 0) {
_setStatusText(errorMessage);
} else if (flow == 1) {
_setDefaultPaymentMethodText(errorMessage, false);
} else if (flow == 2) {
_setConfirmStatusText(errorMessage);
}
}
void _setStatusText(String text) {
setState(() {
_statusText = text;
});
}
void _setDefaultPaymentMethodText(String text, bool show) {
setState(() {
_defaultPaymentMethodText = text;
_confirmStatusText = '';
if (show) {
_confirmState = 2;
}
});
}
void _setConfirmStatusText(String text) {
setState(() {
_confirmStatusText = text;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(fontFamily: 'montserrat'),
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Column(
children: [
_buildHeadlessSdkExample(),
_buildPaymentSheetExample(),
],
),
),
);
}
Widget _buildHeadlessSdkExample() {
return Expanded(
child: material.Card(
elevation: 4,
margin: const EdgeInsets.all(18),
child: Padding(
padding: const EdgeInsets.all(36),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Center(
child: Text("Headless SDK Example",
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w500))),
Center(
child: ElevatedButton(
onPressed:
_isInitialized ? _initializeHeadless : null,
child: Text(_isInitialized
? "Initialize Headless"
: "Loading ..."))),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(child: Text(_defaultPaymentMethodText)),
if (_showChangeButton)
TextButton(
onPressed: () {
_presentPaymentSheet(true);
},
child: const Text("Change"))
]),
if (_confirmState > 0)
Center(
child: ElevatedButton(
onPressed:
_confirmState == 2 ? _confirmPayment : null,
child: Text(_confirmState == 1
? "Processing ..."
: "Confirm Payment"))),
if (_confirmStatusText.isNotEmpty)
Center(child: Text(_confirmStatusText))
]))));
}
Widget _buildPaymentSheetExample() {
return Expanded(
child: material.Card(
elevation: 4,
margin: const EdgeInsets.only(left: 18, right: 18, bottom: 18),
child: Padding(
padding: const EdgeInsets.all(36),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Center(
child: Text("Payment Sheet Example",
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w500))),
Center(
child: ElevatedButton(
onPressed: _isInitialized
? () {
_presentPaymentSheet(false);
}
: null,
child: Text(_isInitialized
? "Open Payment Sheet"
: "Loading ..."))),
Center(child: Text(_statusText))
]))));
}
}