indian_pay 0.0.3
indian_pay: ^0.0.3 copied to clipboard
A Flutter plugin that enables seamless integration of Indian payment gateways including Payin, Payout, and transaction status APIs with clean UI components.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'res/const_button.dart';
import 'res/const_color.dart';
import 'res/const_text.dart';
import 'screens/payin_screen.dart';
import 'screens/paying_status_screen.dart';
import 'screens/payout_screen.dart';
import 'screens/payout_status_screen.dart';
import 'utils/routes/routes.dart';
import 'utils/routes/routes_name.dart';
import 'view_model/payin_status_view_model.dart';
import 'view_model/payout_status_view_model.dart';
import 'view_model/payout_view_model.dart';
import 'view_model/pyin_view_model.dart';
double height = 0.0;
double width = 0.0;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
height = constraints.maxHeight;
width = constraints.maxWidth;
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => PayinViewModel()),
ChangeNotifierProvider(create: (_) => PayoutViewModel()),
ChangeNotifierProvider(create: (_) => PayinStatusViewModel()),
ChangeNotifierProvider(create: (_) => MerchantPayoutHistoryViewModel()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: PaymentGatewayUI(),
),
);
},
);
}
}
class PayinDemoScreen extends StatelessWidget {
const PayinDemoScreen({super.key});
@override
Widget build(BuildContext context) {
final payinVM = Provider.of<PayinViewModel>(context);
return Scaffold(
appBar: AppBar(
title: const Text("IndianPay SDK Demo"),
backgroundColor: Colors.blue,
),
body: Stack(
children: [
Center(
child: ElevatedButton(
onPressed: () {
payinVM.payinApi(
"ORDER123",
"100",
"Demo User",
"demo@example.com",
"9999999999",
"SDK Test",
context,
);
},
child: const Text("Pay Now"),
),
),
if (payinVM.isLoading)
const Center(child: CircularProgressIndicator()),
],
),
);
}
}
class PaymentGatewayUI extends StatefulWidget {
@override
State<PaymentGatewayUI> createState() => _PaymentGatewayUIState();
}
class _PaymentGatewayUIState extends State<PaymentGatewayUI> {
int selectedIndex = -1; // -1 means nothing selected
final List<Map<String, String>> items = [
{'image':"example/assets/payment.png", 'name': 'Paying'},
{'image': "example/assets/payment-method_14686594.png", 'name': 'Payout'},
{'image': "example/assets/smartphone_1951593.png", 'name': 'Paying Status'},
{'image': "example/assets/payment-method_14686594.png", 'name': 'Payout Status'},
];
@override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
return Scaffold(backgroundColor: AppColor.kBackgroundColor,
appBar: AppBar(
backgroundColor: AppColor.kLightBlueColor,
title: headingBold(text: "Indian Pay", color: AppColor.kBackgroundColor),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 12),
tittleBold(text: "Welcome"),
SizedBox(height: 12),
ListView.builder(
itemCount: items.length,
shrinkWrap: true,
itemBuilder: (context, index) {
final isSelected = selectedIndex == index;
return GestureDetector(
onTap: () {
setState(() {
selectedIndex = index;
});
},
child: Container(
margin: EdgeInsets.symmetric(vertical: 4),
padding: EdgeInsets.all(8),
width: width,
height: 80,
decoration: BoxDecoration(
color: isSelected ? AppColor.r2 .withOpacity(0.2) : Colors.white,
border: Border.all(
color: isSelected ? AppColor.r3 : AppColor.kSecondaryColor,
width: isSelected ? 1.5 : 0.2,
),
borderRadius: BorderRadius.circular(10),
),
child: Row(
children: [
SizedBox(
height: 40,
width: 40,
child: Image.asset("assets/bill.png"),
),
SizedBox(width: 8),
tittleMedium(text: items[index]['name']!),
Spacer(),
Icon(Icons.arrow_forward_ios_sharp, color: AppColor.kSecondaryColor),
],
),
),
);
},
),
],
),
),
bottomSheet: Container(
color: Colors.white, // ensure there's no BoxDecoration with borderRadius
padding: EdgeInsets.symmetric(horizontal: 20,vertical: 5),
width: width,
height: 55,
child: AppBtn(height: 30,
width: width * 0.88,
title: "Continue",
color: AppColor.kLightBlueColor,
onTap: () {
if (selectedIndex == -1) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Please select an option first'),
));
} else {
switch (selectedIndex) {
case 0:
Navigator.push(context, MaterialPageRoute(builder: (_) => PayinScreen()));
break;
case 1:
Navigator.push(context, MaterialPageRoute(builder: (_) => PayoutScreen()));
break;
case 2:
Navigator.push(context, MaterialPageRoute(builder: (_) => PayinStatusScreen()));
break;
case 3:
Navigator.push(context, MaterialPageRoute(builder: (_) => PayoutStatusScreen()));
break;
}
}
},
),
),
);
}
}