Flutter支付处理插件flutter_nmi的使用
Flutter支付处理插件flutter_nmi的使用
本项目是一个Flutter插件包的起点,该插件包包含用于iOS和/或Android平台的特定实现代码。以下是关于如何使用flutter_nmi
插件处理支付的详细示例。
开始使用
首先,确保你已经在项目中添加了flutter_nmi
插件。在你的pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter_nmi: ^版本号
然后运行flutter pub get
来获取依赖。
示例代码
以下是使用flutter_nmi
插件进行支付处理的完整示例代码。
示例代码
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_beep/flutter_beep.dart';
import 'package:flutter_nmi/flutter_nmi.dart';
class NMIDevice {
static const kGeniusMini = "Genius Mini";
static const kBBPOS = "BBPOS";
static const kMiura = "Miura";
static const kOther = "Other";
}
class Action {
static const kTransaction = "Transaction";
static const kTMSUpdate = "TMSUpdate";
static const kPinPadStatus = "PinPadStatus";
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late FlutterNmi nmi;
String transactionStatus = "点击下方按钮进行支付";
bool isLoading = false;
bool isTMSUpdate = false;
bool isPinPadStatus = false;
bool mShowWarningDialog = false;
BuildContext? mBuilderContext;
Timer? timer;
TextEditingController amountController = TextEditingController();
TextEditingController transactionIdController = TextEditingController();
[@override](/user/override)
void initState() {
super.initState();
}
initialize() async {
setState(() {
isLoading = true;
});
var params = {
"action": Action.kTransaction,
"api_key": "VZueqyW43Ya8WgMD4Yx4G8qn6mED3yCq",
"sandbox": "1",
"signature_required": "1",
"no_signature_below_amount": "3",
"amount": "10",
"surcharge": "0",
"tip": "2",
"device_type": NMIDevice.kBBPOS,
"currency": "USD",
"transactionId": ""
};
//服务费
nmi = FlutterNmi.instance(
onPinPadInitializationCompleted: onPinPadInitializationCompleted,
onPinPadInitializationFailed: onPinPadInitializationFailed,
onPinPadConnectionStarted: onPinPadConnectionStarted,
onPinPadConnected: onPinPadConnected,
onPinPadDisConnected: onPinPadDisConnected,
onPinPadConnectionFailed: onPinPadConnectionFailed,
onPinPadConfigurationUpdate: onPinPadConfigurationUpdate,
onPinPadTMSUpdateCompleted: onPinPadTMSUpdateCompleted,
onPinPadTMSUpdateFailed: onPinPadTMSUpdateFailed,
onTransactionStatusUpdate: onTransactionStatusUpdate,
onTransactionFailed: onTransactionFailed,
onTransactionCompleted: onTransactionCompleted,
onPinPadStatusUpdated: onPinPadStatusUpdated,
onTransactionTerminated: onTransactionTerminated,
);
mShowWarningDialog = true;
nmi.initialize(params);
}
requestTMSUpdate() {
setState(() {
isLoading = true;
});
isTMSUpdate = true;
var params = {
"action": Action.kTMSUpdate,
"api_key": "VZueqyW43Ya8WgMD4Yx4G8qn6mED3yCq",
"sandbox": "1",
"device_type": NMIDevice.kBBPOS,
};
nmi = FlutterNmi.instance(
onPinPadInitializationCompleted: onPinPadInitializationCompleted,
onPinPadInitializationFailed: onPinPadInitializationFailed,
onPinPadConnectionStarted: onPinPadConnectionStarted,
onPinPadConnected: onPinPadConnected,
onPinPadDisConnected: onPinPadDisConnected,
onPinPadConnectionFailed: onPinPadConnectionFailed,
onPinPadConfigurationUpdate: onPinPadConfigurationUpdate,
onPinPadTMSUpdateCompleted: onPinPadTMSUpdateCompleted,
onPinPadTMSUpdateFailed: onPinPadTMSUpdateFailed,
);
nmi.initialize(params);
}
selectPinPad() {
setState(() {
isLoading = true;
});
nmi = FlutterNmi.instance(
onPinPadInitializationCompleted: onPinPadInitializationCompleted,
onPinPadInitializationFailed: onPinPadInitializationFailed,
onPinPadConnectionStarted: onPinPadConnectionStarted,
onPinPadConnected: onPinPadConnected,
onPinPadDisConnected: onPinPadDisConnected,
onPinPadConnectionFailed: onPinPadConnectionFailed,
onPinPadConfigurationUpdate: onPinPadConfigurationUpdate,
onPinPadTMSUpdateCompleted: onPinPadTMSUpdateCompleted,
onPinPadTMSUpdateFailed: onPinPadTMSUpdateFailed,
);
nmi.selectPinPad();
}
getPinPadStatus() {
setState(() {
isLoading = true;
});
isPinPadStatus = true;
var params = {
"action": Action.kPinPadStatus,
"api_key": "VZueqyW43Ya8WgMD4Yx4G8qn6mED3yCq",
"sandbox": "1",
"device_type": NMIDevice.kBBPOS,
};
nmi = FlutterNmi.instance(
onPinPadInitializationCompleted: onPinPadInitializationCompleted,
onPinPadInitializationFailed: onPinPadInitializationFailed,
onPinPadConnectionStarted: onPinPadConnectionStarted,
onPinPadConnected: onPinPadConnected,
onPinPadDisConnected: onPinPadDisConnected,
onPinPadConnectionFailed: onPinPadConnectionFailed,
onPinPadConfigurationUpdate: onPinPadConfigurationUpdate,
onPinPadTMSUpdateCompleted: onPinPadTMSUpdateCompleted,
onPinPadTMSUpdateFailed: onPinPadTMSUpdateFailed,
onPinPadStatusUpdated: onPinPadStatusUpdated,
);
nmi.initialize(params);
}
requestRefund() {
setState(() {
isLoading = true;
});
var params = {
"api_key": "VZueqyW43Ya8WgMD4Yx4G8qn6mED3yCq",
"sandbox": "1",
"device_type": NMIDevice.kBBPOS,
"currency": "USD",
"transactionId": transactionIdController.text,
"amount": amountController.text,
};
nmi = FlutterNmi.instance(
onTransactionStatusUpdate: onTransactionStatusUpdate,
onTransactionFailed: onTransactionFailed,
onTransactionCompleted: onTransactionCompleted,
);
mShowWarningDialog = false;
nmi.requestRefund(params);
}
cancelTransaction() {
nmi.cancelTransaction();
}
disconnectPinPad() {
nmi.disconnectPinPad();
}
onPinPadInitializationFailed() {
if (kDebugMode) {
print("Flutter ==== onPinPad Initialization Failed");
}
setState(() {
isLoading = false;
transactionStatus = "初始化PIN Pad失败";
});
}
onPinPadInitializationCompleted() {
if (kDebugMode) {
print("Flutter ==== onPinPad Initialization Completed");
}
setState(() {
//isLoading = false;
transactionStatus = "初始化PIN Pad完成";
});
}
onPinPadConnected(value) {
if (kDebugMode) {
print("Flutter ==== onPinPad Connection Completed $value");
}
setState(() {
transactionStatus = "连接到PIN Pad";
});
/*if (isTMSUpdate) {
nmi.requestTMSUpdate();
} else if (isPinPadStatus) {
nmi.getPinPadStatus();
}*/
}
onPinPadConnectionFailed() {
if (kDebugMode) {
print("Flutter ==== onPinPad Connection Failed");
}
setState(() {
isLoading = false;
transactionStatus = "连接到PIN Pad失败";
});
}
onPinPadDisConnected() {
if (kDebugMode) {
print("Flutter ==== onPinPad DisConnected");
}
setState(() {
isLoading = false;
transactionStatus = "断开连接PIN Pad";
});
}
onPinPadConfigurationUpdate(value) {
if (kDebugMode) {
print("Flutter ==== onPinPad Configuration Update");
}
setState(() {
transactionStatus = ((value as String).replaceAll("_", " "));
});
}
onPinPadConnectionStarted() {
if (kDebugMode) {
print("Flutter ==== onPinPad Connection Started");
}
setState(() {
transactionStatus = "正在连接到PIN Pad...";
});
}
onTransactionStatusUpdate(value) {
if (kDebugMode) {
print("Flutter ==== onPinPad Status Update");
}
setState(() {
transactionStatus = ((value as String).replaceAll("_", " "));
});
}
onPinPadTMSUpdateCompleted() {
if (kDebugMode) {
print("Flutter ==== TMS Update Completed");
}
setState(() {
isLoading = false;
transactionStatus = "TMS更新完成";
});
}
onPinPadTMSUpdateFailed(value) {
if (kDebugMode) {
print("Flutter ==== TMS Update Failed $value");
}
setState(() {
isLoading = false;
transactionStatus = "TMS更新失败。$value";
});
}
onTransactionFailed(value) {
if (kDebugMode) {
print("Flutter ==== Transaction Failed $value");
}
setState(() {
isLoading = false;
transactionStatus = "交易失败\n$value";
});
}
onTransactionCompleted(value) {
if (kDebugMode) {
print("Flutter ==== Transaction Completed $value");
}
if (mShowWarningDialog) {
showWarningDialog(mBuilderContext!);
}
setState(() {
isLoading = false;
transactionStatus = "交易完成";
});
}
onTransactionTerminated() {
if (kDebugMode) {
print("Flutter ==== Transaction Terminated");
}
setState(() {
isLoading = false;
transactionStatus = "交易终止";
});
}
onPinPadStatusUpdated(value) {
setState(() {
isLoading = false;
transactionStatus = "PIN Pad状态更新";
});
if (kDebugMode) {
print("Flutter ==== Transaction Completed $value");
}
}
showWarningDialog(BuildContext context) {
timer = Timer.periodic(const Duration(seconds: 1), (Timer t) {
FlutterBeep.beep();
});
showDialog(
context: context,
builder: (_) {
Future.delayed(const Duration(seconds: 5), () {
timer!.cancel();
Navigator.of(context).pop();
});
return Dialog(
insetPadding: const EdgeInsets.symmetric(horizontal: 16),
elevation: 0,
backgroundColor: Colors.white,
child: StatefulBuilder(
builder: (BuildContext _, StateSetter _setState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(
Icons.warning,
color: Colors.yellow,
size: 100,
),
],
),
Row(
children: [
Expanded(
child: Container(
margin: const EdgeInsets.only(
top: 20, left: 15, right: 15),
child: const Text(
"请不要忘记取出卡片",
style: TextStyle(fontSize: 20),
),
),
),
],
),
const SizedBox(
height: 10,
),
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Container(
margin: const EdgeInsets.only(top: 20, bottom: 20),
padding: const EdgeInsets.only(
top: 5, bottom: 5, right: 20, left: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(
color: Colors.black,
width: 1,
),
boxShadow: const [
BoxShadow(
color: Colors.white,
spreadRadius: 5,
offset: Offset(0, 3),
),
],
),
child: const Text("关闭"),
),
)
],
);
},
),
);
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter NMI Demo'),
),
body: Builder(
builder: (context) {
mBuilderContext = context;
return SingleChildScrollView(
child: Column(
children: [
Visibility(
visible: isLoading,
child: Container(
margin: const EdgeInsets.only(top: 40),
child: const CircularProgressIndicator(
backgroundColor: Colors.grey,
color: Colors.purple,
strokeWidth: 5,
),
),
),
const SizedBox(
height: 20,
),
Text(transactionStatus),
const SizedBox(
height: 20,
),
GestureDetector(
child: Container(
padding: const EdgeInsets.all(20),
child: const Text("支付\$10"),
color: (isLoading == true) ? Colors.grey : Colors.amber,
),
onTap: () {
if (isLoading == false) {
initialize();
}
},
),
const SizedBox(
height: 20,
),
GestureDetector(
child: Container(
padding: const EdgeInsets.all(20),
child: const Text("请求TMS更新"),
color: (isLoading == true) ? Colors.grey : Colors.amber,
),
onTap: () {
if (isLoading == false) {
requestTMSUpdate();
}
},
),
const SizedBox(
height: 20,
),
GestureDetector(
child: Container(
padding: const EdgeInsets.all(20),
child: const Text("选择PIN Pad"),
color: (isLoading == true) ? Colors.grey : Colors.amber,
),
onTap: () {
if (isLoading == false) {
selectPinPad();
}
},
),
const SizedBox(
height: 20,
),
GestureDetector(
child: Container(
padding: const EdgeInsets.all(20),
child: const Text("取消交易"),
color: Colors.amber,
),
onTap: () {
cancelTransaction();
},
),
const SizedBox(
height: 40,
),
GestureDetector(
child: Container(
padding: const EdgeInsets.all(20),
child: const Text("获取PIN Pad状态"),
color: (isLoading == true) ? Colors.grey : Colors.amber,
),
onTap: () {
if (isLoading == false) {
getPinPadStatus();
}
},
),
const SizedBox(
height: 40,
),
GestureDetector(
child: Container(
padding: const EdgeInsets.all(20),
child: const Text("断开PIN Pad连接"),
color: (isLoading == true) ? Colors.grey : Colors.amber,
),
onTap: () {
if (isLoading == false) {
disconnectPinPad();
}
},
),
const SizedBox(
height: 40,
),
Row(
children: [
const SizedBox(
width: 20,
),
Expanded(
child: TextField(
controller: amountController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: '输入退款金额',
),
),
),
const SizedBox(
width: 20,
),
Expanded(
child: TextField(
controller: transactionIdController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: '输入交易ID',
),
),
),
const SizedBox(
width: 20,
),
],
),
const SizedBox(
height: 20,
),
GestureDetector(
child: Container(
padding: const EdgeInsets.all(20),
child: const Text("请求退款"),
color: (isLoading == true) ? Colors.grey : Colors.amber,
),
onTap: () {
if (isLoading == false) {
if (amountController.text != "" && transactionIdController.text != "") {
requestRefund();
}
}
},
),
const SizedBox(
height: 20,
),
GestureDetector(
child: const Text("打开对话框"),
onTap: () {
showWarningDialog(context);
},
)
/*const SizedBox(
height: 40,
),
GestureDetector(
child: Container(
padding: const EdgeInsets.all(20),
child: const Text("打开签名页面"),
color: (isLoading == true) ? Colors.grey : Colors.amber,
),
onTap: () {
goToSignaturePad();
},
),*/
],
),
);
},
),
),
);
}
}
更多关于Flutter支付处理插件flutter_nmi的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter支付处理插件flutter_nmi的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_nmi
是一个用于处理支付的 Flutter 插件,它集成了 NMI (Network Merchants, Inc.) 支付网关。使用这个插件,你可以在 Flutter 应用中处理信用卡支付等操作。以下是如何使用 flutter_nmi
插件的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 flutter_nmi
插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_nmi: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 配置插件
在 flutter_nmi
插件中,你需要配置 NMI 的 API 密钥和其他必要的参数。通常,这些配置可以在应用的初始化阶段完成。
import 'package:flutter_nmi/flutter_nmi.dart';
void configureNMI() {
FlutterNmi.configure(
apiKey: 'your_nmi_api_key',
// 其他配置参数
);
}
3. 处理支付
使用 flutter_nmi
插件处理支付通常涉及以下几个步骤:
-
创建支付请求:你需要创建一个支付请求对象,包含支付金额、信用卡信息等。
-
发起支付请求:使用
FlutterNmi
提供的方法发起支付请求。 -
处理支付结果:根据支付结果更新 UI 或执行其他操作。
以下是一个简单的支付处理示例:
import 'package:flutter/material.dart';
import 'package:flutter_nmi/flutter_nmi.dart';
class PaymentScreen extends StatefulWidget {
[@override](/user/override)
_PaymentScreenState createState() => _PaymentScreenState();
}
class _PaymentScreenState extends State<PaymentScreen> {
final _formKey = GlobalKey<FormState>();
final _cardNumberController = TextEditingController();
final _expiryDateController = TextEditingController();
final _cvvController = TextEditingController();
Future<void> _processPayment() async {
if (_formKey.currentState.validate()) {
final paymentRequest = PaymentRequest(
amount: 100.0, // 支付金额
cardNumber: _cardNumberController.text,
expiryDate: _expiryDateController.text,
cvv: _cvvController.text,
// 其他支付信息
);
try {
final paymentResponse = await FlutterNmi.processPayment(paymentRequest);
if (paymentResponse.success) {
// 支付成功
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Payment successful!')),
);
} else {
// 支付失败
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Payment failed: ${paymentResponse.message}')),
);
}
} catch (e) {
// 处理异常
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('An error occurred: $e')),
);
}
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Payment')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _cardNumberController,
decoration: InputDecoration(labelText: 'Card Number'),
validator: (value) {
if (value.isEmpty) {
return 'Please enter card number';
}
return null;
},
),
TextFormField(
controller: _expiryDateController,
decoration: InputDecoration(labelText: 'Expiry Date'),
validator: (value) {
if (value.isEmpty) {
return 'Please enter expiry date';
}
return null;
},
),
TextFormField(
controller: _cvvController,
decoration: InputDecoration(labelText: 'CVV'),
validator: (value) {
if (value.isEmpty) {
return 'Please enter CVV';
}
return null;
},
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _processPayment,
child: Text('Pay Now'),
),
],
),
),
),
);
}
}