bharat_pay_kit 0.0.1
bharat_pay_kit: ^0.0.1 copied to clipboard
A unified Flutter payment gateway package for India. Supports Razorpay, Cashfree, PhonePe, Paytm, Google Pay, PayU, Stripe, CCAvenue, Instamojo, and UPI — all with a single consistent API, stunning 3D [...]
/// bharat_pay_kit example application.
///
/// Demonstrates BharatPayButton, BharatPayCardWidget, BharatPayGatewaySelector,
/// BharatPaySheet, and BharatPayStatusWidget.
library;
import 'package:bharat_pay_kit/bharat_pay_kit.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const BharatPayKitExampleApp());
}
/// Root widget of the demo application.
class BharatPayKitExampleApp extends StatelessWidget {
const BharatPayKitExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BharatPayKit Demo',
debugShowCheckedModeBanner: false,
theme: BharatPayTheme.lightTheme,
darkTheme: BharatPayTheme.darkTheme,
home: const _DemoHome(),
);
}
}
class _DemoHome extends StatefulWidget {
const _DemoHome();
@override
State<_DemoHome> createState() => _DemoHomeState();
}
class _DemoHomeState extends State<_DemoHome>
with SingleTickerProviderStateMixin {
late TabController _tabController;
PaymentGateway _selectedGateway = PaymentGateway.razorpay;
double _amount = 499.0;
final TextEditingController _amountCtrl =
TextEditingController(text: '499');
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
// Initialise with Razorpay using sandbox test key
BharatPayKit.init(
gateway: PaymentGateway.razorpay,
config: const GatewayConfig(
apiKey: 'rzp_test_1DP5mmOlF5G5ag',
environment: PayEnvironment.sandbox,
),
);
}
@override
void dispose() {
_tabController.dispose();
_amountCtrl.dispose();
BharatPayKit.dispose();
super.dispose();
}
PaymentRequest get _request => PaymentRequest(
amount: _amount,
orderId: 'order_${DateTime.now().millisecondsSinceEpoch}',
customerName: 'Aarav Sharma',
customerEmail: 'aarav@example.com',
customerPhone: '9876543210',
description: 'Premium Plan',
);
GatewayConfig _configFor(PaymentGateway gw) {
const testVpa = 'merchant@upi';
return GatewayConfig(
apiKey: gw == PaymentGateway.razorpay
? 'rzp_test_1DP5mmOlF5G5ag'
: testVpa,
environment: PayEnvironment.sandbox,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BharatPayKit Demo'),
bottom: TabBar(
controller: _tabController,
tabs: const [
Tab(icon: Icon(Icons.payment), text: 'Pay'),
Tab(icon: Icon(Icons.credit_card), text: 'Card'),
Tab(icon: Icon(Icons.check_circle), text: 'Status'),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
_PayTab(
selectedGateway: _selectedGateway,
amount: _amount,
amountCtrl: _amountCtrl,
request: _request,
configFor: _configFor,
onGatewaySelected: (gw) {
setState(() => _selectedGateway = gw);
BharatPayKit.switchGateway(
gateway: gw,
config: _configFor(gw),
);
},
onAmountChanged: (v) {
final parsed = double.tryParse(v);
if (parsed != null) setState(() => _amount = parsed);
},
),
// Card demo tab
const _CardTab(),
// Status demo tab
_StatusTab(amount: _amount, gateway: _selectedGateway),
],
),
);
}
}
// ─── Pay Tab ──────────────────────────────────────────────────────────────────
class _PayTab extends StatelessWidget {
final PaymentGateway selectedGateway;
final double amount;
final TextEditingController amountCtrl;
final PaymentRequest request;
final GatewayConfig Function(PaymentGateway) configFor;
final ValueChanged<PaymentGateway> onGatewaySelected;
final ValueChanged<String> onAmountChanged;
const _PayTab({
required this.selectedGateway,
required this.amount,
required this.amountCtrl,
required this.request,
required this.configFor,
required this.onGatewaySelected,
required this.onAmountChanged,
});
@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.symmetric(vertical: 24),
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Text(
'Select Gateway',
style: BharatPayTheme.headingStyle.copyWith(fontSize: 16),
),
),
const SizedBox(height: 12),
// Gateway selector
BharatPayGatewaySelector(
gateways: PaymentGateway.values,
initialSelected: selectedGateway,
onGatewaySelected: onGatewaySelected,
),
const SizedBox(height: 24),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Enter Amount', style: BharatPayTheme.headingStyle.copyWith(fontSize: 16)),
const SizedBox(height: 10),
// Amount input
TextField(
controller: amountCtrl,
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
prefixText: '₹ ',
hintText: '0.00',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
),
onChanged: onAmountChanged,
),
const SizedBox(height: 32),
// Pay button
BharatPayButton(
amount: amount,
label: 'Pay via ${selectedGateway.displayName}',
onPayPressed: () => BharatPayKit.pay(request, context: context),
onSuccess: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('✅ Payment successful!'),
backgroundColor: BharatPayColors.success,
),
);
},
onFailure: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('❌ Payment failed. Please retry.'),
backgroundColor: BharatPayColors.failure,
),
);
},
),
const SizedBox(height: 16),
// Show sheet button
SizedBox(
width: double.infinity,
height: 52,
child: OutlinedButton.icon(
icon: const Icon(Icons.list_alt_rounded),
label: const Text('Show All Gateways'),
style: OutlinedButton.styleFrom(
side: const BorderSide(color: BharatPayColors.primary),
foregroundColor: BharatPayColors.primary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
),
),
onPressed: () => BharatPaySheet.show(
context,
gateways: PaymentGateway.values,
request: request,
configBuilder: configFor,
onSuccess: (r) => ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('✅ ${r.gateway.displayName} success!'),
backgroundColor: BharatPayColors.success),
),
onFailure: (r) => ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('❌ ${r.errorMessage}'),
backgroundColor: BharatPayColors.failure),
),
),
),
),
],
),
),
],
);
}
}
// ─── Card Tab ─────────────────────────────────────────────────────────────────
class _CardTab extends StatelessWidget {
const _CardTab();
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const BharatPayCardWidget(
cardNumber: '4111111111111111',
cardHolderName: 'Aarav Sharma',
expiryDate: '12/27',
cvv: '123',
),
const SizedBox(height: 24),
Text(
'Tap the card to flip it!',
style: BharatPayTheme.bodyStyle,
),
const SizedBox(height: 32),
const BharatPayCardWidget(
cardNumber: '5200828282828210',
cardHolderName: 'Priya Patel',
expiryDate: '08/26',
cvv: '321',
),
],
),
),
);
}
}
// ─── Status Tab ───────────────────────────────────────────────────────────────
class _StatusTab extends StatelessWidget {
final double amount;
final PaymentGateway gateway;
const _StatusTab({required this.amount, required this.gateway});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Preview Status Screens', style: BharatPayTheme.headingStyle),
const SizedBox(height: 32),
SizedBox(
width: double.infinity,
height: 52,
child: ElevatedButton.icon(
icon: const Icon(Icons.check_circle_outline),
label: const Text('Show Success Screen'),
style: ElevatedButton.styleFrom(
backgroundColor: BharatPayColors.success,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14)),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => Scaffold(
body: BharatPayStatusWidget(
response: PaymentResponse.success(
gateway: gateway,
paymentId: 'pay_demo_${DateTime.now().millisecondsSinceEpoch}',
orderId: 'order_demo_001',
amount: amount,
currency: 'INR',
),
onContinue: () => Navigator.pop(context),
),
),
),
);
},
),
),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
height: 52,
child: ElevatedButton.icon(
icon: const Icon(Icons.error_outline),
label: const Text('Show Failure Screen'),
style: ElevatedButton.styleFrom(
backgroundColor: BharatPayColors.failure,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14)),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => Scaffold(
body: BharatPayStatusWidget(
response: PaymentResponse.failure(
gateway: gateway,
errorMessage: 'Payment declined by your bank.',
errorCode: 402,
),
onRetry: () => Navigator.pop(context),
),
),
),
);
},
),
),
],
),
);
}
}