Flutter插件skipcash的介绍与使用
Flutter插件skipcash的介绍与使用
skipcash-flutter
是一个用于在你的 Flutter 应用中集成 Skipcash 的插件。通过此插件,用户可以通过苹果支付(Apple Pay)或嵌入式网页视图(WebView)进行支付。
步骤 1: 添加依赖
首先,在 pubspec.yaml
文件中添加 skipcash-flutter
依赖:
dependencies:
skipcash-flutter:
然后运行 flutter pub get
来获取依赖。
步骤 2: 初始化插件
接下来,你需要初始化 skipcash-flutter
插件,并设置一些必要的参数。以下是示例代码:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:skipcash/payment_response_class.dart';
import 'package:skipcash/payment_page_response_class.dart';
import 'package:skipcash/skipcash.dart';
void main() {
runApp(const MaterialApp(
home: MyApp(), // Wrap MyApp with MaterialApp
));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _newPayment = Skipcash(
merchantIdentifier: "merchant.vendex.skipcash.payme", // iOS - required when integrating (in-app applepay) here you should pass your merchantIdentifier
createPaymentLinkEndPoint: "", /* required only if you're using the webview embedded with this package otherwise leave it empty - this is an endpoint you should setup at your backend server,
it basically sends the customer data your endpoint from where you will be creating a new payment by calling skipcash server
then the same endpoint should return skipcash server response back for the plugin to complete the process.
*/
authorizationHeader: "" // optional - set your endpoint authorization header
);
StreamSubscription<dynamic>? _applePayResponseSubscription; // iOS - applepay
StreamSubscription<dynamic>? responseScPaymentDataSubscription; // Android/iOS - pay via webview
final TextEditingController _firstNameController = TextEditingController();
final TextEditingController _lastNameController = TextEditingController();
final TextEditingController _phoneController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _amountController = TextEditingController();
var loadingIndicator;
[@override](/user/override)
void initState() {
super.initState();
loadingIndicator = false;
_setupApplePayResponseListener(); // iOS - in-app applepay
scPaymentDataResponseListener(); // Android/iOS - pay via webview
}
[@override](/user/override)
void dispose() {
// release resources upon exiting the screen
_applePayResponseSubscription?.cancel(); // iOS - in-app applepay
responseScPaymentDataSubscription?.cancel(); // Android/iOS - pay via webview
super.dispose();
}
// 监听苹果支付响应
void _setupApplePayResponseListener() { // iOS - native applepay
_applePayResponseSubscription = _newPayment.applePayResponseStream.listen((response) {
setState(() {
loadingIndicator = false;
});
PaymentResponse paymentResponse = PaymentResponse.fromJson(response);
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('SkipCash In-App ApplePay'),
content: Text(
"IsSuccess: ${paymentResponse.isSuccess} | transactionId: ${paymentResponse.transactionId} | errorMessage: ${paymentResponse.errorMessage} | returnCode: ${paymentResponse.returnCode}"
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK'),
),
],
);
},
);
});
}
// 嵌入式 WebView 示例。
void scPaymentDataResponseListener() { // Android/iOS - pay via webview
_applePayResponseSubscription = _newPayment.responseScPaymentPageStream.listen((response) {
setState(() {
loadingIndicator = false;
});
PaymentPageResponse paymentPageResponse = PaymentPageResponse.fromJson(response);
debugPrint(response.toString());
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('SkipCash PaymentPage Response'),
content: Text(
"id: ${paymentPageResponse.id} | statusId: ${paymentPageResponse.statusId} | status: ${paymentPageResponse.status} | transId: ${paymentPageResponse.transId} | custom1: ${paymentPageResponse.custom1}"
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK'),
),
],
);
},
);
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('skipcash package - example app'),
),
body: Center(
child: Stack(
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 280,
child:
TextField(
controller: _firstNameController,
decoration: const InputDecoration(labelText: 'First Name'),
),
),
SizedBox(
width: 280,
child:
TextField(
controller: _lastNameController,
decoration: const InputDecoration(labelText: 'Last Name'),
),
),
SizedBox(
width: 280,
child:
TextField(
controller: _phoneController,
decoration: const InputDecoration(labelText: 'Phone Number'),
),
),
SizedBox(
width: 280,
child:
TextField(
controller: _emailController,
decoration: const InputDecoration(labelText: 'Email'),
),
),
SizedBox(
width: 300,
child:
TextField(
controller: _amountController,
decoration: const InputDecoration(
labelText: 'Amount',
hintText: "ex.valid values format: 1 and 1.2 and 1.25"
),
),
),
const SizedBox(
height: 30,
),
SizedBox(
width: 220,
child: ElevatedButton(
onPressed: () async {
bool hasCards;
try {
// 检查钱包中是否有卡片
hasCards = await _newPayment.isWalletHasCards() ?? false;
if(hasCards){
// 如果有卡片,则设置支付详情
String firstName = _firstNameController.text;
String lastName = _lastNameController.text;
String phone = _phoneController.text;
String email = _emailController.text;
String amount = _amountController.text;
if(firstName.isEmpty || lastName.isEmpty || phone.isEmpty
|| email.isEmpty || amount.isEmpty || amount == "0.0"){
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Invalid Details'),
content: const Text(
"Please fill all of the fields, Also amount must be above 0.0, i.e 1.0 at least."
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK'),
),
],
);
},
);
return;
}
_newPayment.setFirstName(firstName);
_newPayment.setLastName(lastName);
_newPayment.setEmail(email);
_newPayment.setPhone(phone);
_newPayment.setAmount(amount);
_newPayment.setProcessApplePayEndPoint(""); // 你的处理支付的端点
_newPayment.setMerchantName(""); // 官方业务名称 - 苹果要求,将在支付表单中出现
_newPayment.setTransactionId(""); // 交易 (应唯一) 跟踪内部系统中的订单交易
_newPayment.setWebhookUrl(""); // 可选 - 推荐你阅读关于webhooks的相关文档
// -> 这里 https://dev.skipcash.app/doc/api-integration/web-hooks/
_newPayment.setCustom1(""); _newPayment.setCustom2(""); // 可选
_newPayment.setCustom3(""); _newPayment.setCustom4(""); // 可选
_newPayment.setCustom5(""); _newPayment.setCustom6(""); // 可选
_newPayment.setCustom7(""); _newPayment.setCustom8(""); // 可选
_newPayment.setCustom9(""); _newPayment.setCustom10(""); // 可选
_newPayment.clearPaymentSummaries(); // 清除摘要后添加新的
_newPayment.addPaymentSummaryItem("Tax", "0.0"); // 可选 - 为客户提供支付摘要
setState(() {
loadingIndicator = true;
});
_newPayment.startPayment(); // 开始支付 (applepay)
} else {
/*
如果钱包中没有可用的卡片,则提示客户添加一张新卡。
*/
_newPayment.setupNewCard();
}
} on PlatformException {
hasCards = false;
}
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/skipcash.png',
width: 24,
height: 24,
),
const SizedBox(width: 8),
const Text(
"Pay Using ApplePay",
style: TextStyle(color: Color.fromRGBO(1, 125, 251, 1.0)),
)
],
),
),
),
SizedBox(
width: 220,
child: ElevatedButton(
onPressed: () async {
_newPayment.setupNewCard();
},
child: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Setup new card in wallet",
style: TextStyle(color: Color.fromRGBO(1, 125, 251, 1.0)),
)
],
),
),
),
SizedBox(
width: 300,
child: ElevatedButton(
onPressed: (){
String firstName = _firstNameController.text;
String lastName = _lastNameController.text;
String phone = _phoneController.text;
String email = _emailController.text; // 如果电子邮件不是平台要求的
// 你可以使用这种格式 phone@yourdomain.com
String amount = _amountController.text;
if(firstName.isEmpty || lastName.isEmpty || phone.isEmpty
|| email.isEmpty || amount.isEmpty || amount == "0.0"){
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Invalid Details'),
content: const Text(
"Please fill all of the fields, Also amount must be above 0.0, i.e 1.0 at least."
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK'),
),
],
);
},
);
return;
}
_newPayment.setFirstName(firstName);
_newPayment.setLastName(lastName);
_newPayment.setEmail(email);
_newPayment.setPhone(phone);
_newPayment.setAmount(amount);
_newPayment.setTransactionId("TX1TEST"); // 你的内部订单ID (唯一)
_newPayment.setWebhookUrl(""); // 可选但重要
// 阅读关于webhooks的相关文档 -> 这里 https://dev.skipcash.app/doc/api-integration/web-hooks/
_newPayment.setCustom1(""); _newPayment.setCustom2(""); // 可选
_newPayment.setCustom3(""); _newPayment.setCustom4(""); // 可选
_newPayment.setCustom5(""); _newPayment.setCustom6(""); // 可选
_newPayment.setCustom7(""); _newPayment.setCustom8(""); // 可选
_newPayment.setCustom9(""); _newPayment.setCustom10("");// 可选
_newPayment.setSubject("Creating a payment from example app."); // 可选 - 出现在支付页面
_newPayment.setDescription("Please pay to complete the orderX!"); // 可选 - 出现在支付页面
// 下面是一些选项用于调整WEBVIEW屏幕头部 (安卓)
/*
对于颜色,请使用完整的十六进制表示法
而不是缩写表示法;因为它可能会导致一些问题。
示例:
(全十六进制) #FFFFFF - 白色 (正确 ✅)
(缩写十六进制) #FFF - 白色 (错误 ❌)
*/
_newPayment.setPaymentModalTitle("Test Payment"); // 支付模态窗口标题
_newPayment.setCancelColour("#000000"); // 安卓专用
_newPayment.setHeaderBackgroundColour("#FFFFFF"); // 安卓专用
_newPayment.setHeaderTitleColour("#000000"); // 安卓专用
if(_newPayment.createPaymentLinkEndPoint.isNotEmpty){
if(_newPayment.getFirstName().isNotEmpty && _newPayment.getLastName().isNotEmpty && _newPayment.getEmail().isNotEmpty && _newPayment.getPhone().isNotEmpty && _newPayment.getAmount().isNotEmpty){
setState(() {
loadingIndicator = true;
});
// 安卓 - 为了检查错误,过滤日志使用关键字 'showPaymentModal'
_newPayment.showPaymentModal(
"", // 返回URL可以是任何正确的URL,
// 它主要由SkipCash服务器用来将客户端重定向回您的网站,带有与
// 客户所做的交易相关的参数。在这里它用于获取交易详情传递给你的flutter代码的响应监听器
// 以完成你的*(订单)过程。
);
}
}
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/skipcash.png',
width: 24,
height: 24,
),
const SizedBox(width: 8),
const Text(
"Android/iOS - Native WebView",
style: TextStyle(color: Color.fromRGBO(1, 125, 251, 1.0)),
)
],
),
),
),
],
),
),
if (loadingIndicator)
Container(
color: Colors.black54,
child: Center(
child: Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: const CircularProgressIndicator(),
),
),
),
],
)
),
);
}
}
更多关于Flutter插件skipcash的介绍与使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter插件skipcash的介绍与使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
SkipCash
是一个可能用于处理支付或金融交易的 Flutter 插件,但关于它的具体功能和使用方式,目前没有公开的详细文档或广泛的使用案例。以下是一些关于如何探索和使用未知 Flutter 插件(如 SkipCash
)的潜在方法和步骤:
1. 查找插件的来源
- Pub.dev 搜索: 在 pub.dev 上搜索
SkipCash
,查看是否有相关的插件发布。如果有,可以查看其文档、版本、依赖和示例代码。 - GitHub 搜索: 在 GitHub 上搜索
SkipCash
,看是否有开源的代码库。开源项目通常会有 README 文件和使用说明。 - 联系开发者: 如果插件是某个公司或开发者发布的,尝试通过他们的官网或联系方式获取更多信息。
2. 分析插件的功能
- 插件名称推测:
SkipCash
可能是一个与支付、金融或跳过某些流程相关的插件。例如:- 支付网关集成(如信用卡、移动支付)。
- 跳过某些验证步骤或简化流程。
- 现金管理或财务相关的功能。
- 查看源代码: 如果插件是开源的,下载其源代码,查看
README
文件和主要功能类,了解其设计目的和使用方法。
3. 集成插件到 Flutter 项目
- 在
pubspec.yaml
中添加依赖:dependencies: skipcash: ^1.0.0 # 替换为实际版本号
- 运行
flutter pub get
安装插件。 - 导入插件并尝试使用其提供的 API:
import 'package:skipcash/skipcash.dart';
4. 测试和调试
- 运行示例代码(如果有)。
- 尝试调用插件的 API,观察其行为和返回值。
- 使用
print
或调试工具检查插件的输出和日志。
5. 处理未知问题
- 错误处理: 如果插件抛出错误或异常,查看错误信息并尝试解决。
- 社区支持: 在 Flutter 社区(如 Stack Overflow、GitHub Issues)中提问,寻求帮助。
- 替代方案: 如果
SkipCash
无法满足需求,可以寻找其他类似的插件或自行实现所需功能。
6. 假设使用案例
假设 SkipCash
是一个支付插件,以下是一个可能的使用示例:
import 'package:skipcash/skipcash.dart';
void main() async {
// 初始化插件
await SkipCash.initialize(apiKey: 'YOUR_API_KEY');
// 发起支付
final paymentResult = await SkipCash.makePayment(
amount: 100.0,
currency: 'USD',
description: 'Test Payment',
);
if (paymentResult.isSuccess) {
print('Payment successful: ${paymentResult.transactionId}');
} else {
print('Payment failed: ${paymentResult.errorMessage}');
}
}