nttdatapay_flutter 1.0.0
nttdatapay_flutter: ^1.0.0 copied to clipboard
Flutter SDK for NTT DATA Payment Services India with WebView support
NTTDATAPAY Flutter #
Flutter plugin for integrating NTT DATA Payment Services India in Android and iOS applications.
Features #
- Secure token generation
- WebView based checkout
- UPI intent support (GPay, PhonePe, Paytm, Cred, etc.)
- Android & iOS support
- UAT & Production environments
Installation #
To integrate the nttdatapay_flutter in your Flutter project, add the following dependency to your pubspec.yaml file:
dependencies:
nttdatapay_flutter: ^1.0.0
Alternatively, run the following command:
flutter pub add nttdatapay_flutter
After adding the dependency, fetch the package by running:
flutter pub get
Usage #
To integrate the Nttdatapay payment functionality, follow the steps below:
Import package
import 'package:nttdatapay_flutter/nttdatapay_flutter.dart';
Example Usage
import 'package:flutter/material.dart';
import 'package:nttdatapay_flutter/nttdatapay_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool loading = false;
late String txnId;
/// User inputs
final String email = "test.usersas@xyz.in";
final String mobile = "8888888888";
final String amount = "1.00";
/// Merchant configuration (DO NOT hardcode in real apps)
final atomConfig = const AtomConfig(
merchId: "XXXXXX",
txnPassword: "XXX@123",
prodId: "XXX",
reqEncKey: "XXXXXXXXXXXXXXXXXXXXXXXXX",
reqSalt: "XXXXXXXXXXXXXXXXXXXXXXXXX",
resDecKey: "XXXXXXXXXXXXXXXXXXXXXXXXX",
resSalt: "XXXXXXXXXXXXXXXXXXXXXXXXX",
reqHashKey: "XXXXXXXXXX",
resHashKey: "XXXXXXXXXXXXX",
txnCurrency: "INR",
environment: AtomEnvironment.uat,
);
/// Generate token + open payment
Future<void> _payNow(BuildContext context) async {
final BuildContext ctx = context; // ✅ capture early
setState(() {
loading = true;
txnId = "INV${DateTime.now().millisecondsSinceEpoch}";
});
try {
/// Generate Atom Token
final atomTokenId = await AtomAuthService.generateToken(
config: atomConfig,
txnId: txnId,
amount: amount,
email: email,
mobile: mobile,
udf1: "udf1",
udf2: "udf2",
udf3: "udf3",
udf4: "udf4",
udf5: "udf5",
);
if (!ctx.mounted) return;
setState(() => loading = false);
/// Open WebView and WAIT for final result
final AtomPaymentResult? result =
await Navigator.push<AtomPaymentResult>(
ctx,
MaterialPageRoute(
builder: (_) => AtomPaymentWebView(
atomTokenId: atomTokenId,
merchId: atomConfig.merchId,
returnUrl: atomConfig.returnUrl,
config: atomConfig,
email: email,
mobile: mobile,
showAppBar: true,
appBarTitle: "Complete Payment",
),
),
);
if (!ctx.mounted) return;
/// HANDLE RESULT
if (result == null) {
_showSnack(ctx, "Payment window closed by user", Colors.orange);
return;
}
switch (result.status) {
case "OTS0000":
_showSnack(ctx, "Payment Successful", Colors.green);
break;
case "OTS0551":
case "PENDING":
_showSnack(
ctx,
result.description.isNotEmpty
? result.description
: "Payment Pending",
Colors.orange,
);
break;
case "OTS0600":
_showSnack(ctx, "Payment Failed", Colors.red);
break;
case "CANCELLED":
_showSnack(ctx, "Payment cancelled by user", Colors.orange);
break;
case "TIMEOUT":
_showSnack(
ctx,
"Session timed out. Please try again.",
Colors.orange,
);
break;
default:
_showSnack(
ctx,
"Payment Failed (Status: ${result.status})",
Colors.red,
);
}
} catch (e) {
if (!ctx.mounted) return;
setState(() => loading = false);
_showSnack(ctx, "Payment initiation failed: $e", Colors.red);
}
}
/// Snack helper (context-safe)
void _showSnack(BuildContext ctx, String msg, Color color) {
ScaffoldMessenger.of(ctx).showSnackBar(
SnackBar(content: Text(msg), backgroundColor: color),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("NTTDATAPAY Demo"), centerTitle: true),
body: Center(
child: loading
? const CircularProgressIndicator()
: ElevatedButton(
onPressed: () => _payNow(context),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 40,
vertical: 14,
),
),
child: const Text("Pay Now", style: TextStyle(fontSize: 16)),
),
),
);
}
}