Flutter支付功能插件olo_pay_sdk的使用
Flutter支付功能插件olo_pay_sdk的使用
目录
关于Olo Pay
Olo Pay是一款为帮助餐厅增长、保护和支持其数字订购和配送业务而设计的电子商务支付解决方案。Olo Pay特别为数字餐厅订购而设计,以解决我们从数千家商户那里听到的挑战和关注。
关于Flutter SDK
Olo Pay Flutter SDK允许合作伙伴轻松地在其结账流程中添加PCI合规的信用卡输入部件和数字钱包(Apple Pay & Google Pay),并无缝集成到Olo Ordering API。
使用该插件受《Olo Pay SDK许可》条款的约束。
此SDK文档提供了如何在Flutter应用中使用Flutter SDK的信息。有关将Olo Pay集成到您的支付解决方案中的更多信息,包括设置、测试和认证信息,请参阅我们的《Olo Pay开发者门户文档》(注意:需要Olo开发者帐户)。
设置
Android特定设置步骤
支持的版本
最低支持版本是Android API 23。Android应用的最低API版本必须设置为23或更高。
活动设置
默认情况下,当生成新应用时,Flutter会创建一个活动(通常命名为MainActivity
),它继承自FlutterActivity
。
但某些Olo Pay SDK方面(如下文所述)要求应用的主要活动继承自FlutterFragmentActivity
。
要切换基本活动类型,请找到应用程序的MainActivity
类,并将其更改为继承自FlutterFragmentActivity
:
class MainActivity: FlutterFragmentActivity() {
}
单行文本框
尝试在未使用FlutterFragmentActivity
的情况下使用CardDetailsSingleLineTextView
部件将会导致显示带有消息的占位符,提示切换到FlutterFragmentActivity
。调试控制台也会记录一条消息。
Google Pay
尝试在未使用FlutterFragmentActivity
的情况下初始化Google Pay将会导致invalidGooglePaySetup
错误码。调试控制台也会记录一条消息。
主题设置
Android应用的主题需要使用Theme.AppCompat
或Theme.MaterialComponents
主题之一(直接或间接)才能使用SDK提供的部件。
要查找主题名称,请打开Android应用的AndroidManifest.xml
文件,并查找android:theme
属性。这可能在应用的<application>
或<activity>
标签(或两者)中指定。
找到主题名称后,定位定义它的文件。这通常在res/values/styles.xml
中。注意,如果您的应用支持多种配置,则可能会在不同的文件中有多处主题定义(例如res/values-night/styles.xml
)。
重要提示: 所有主题定义都必须更新为使用批准的主题。
注意: 如果您在Android Studio中打开项目并使用Android项目视图,则所有版本的styles.xml
文件都会在逻辑上分组在res/values/styles
文件夹下,这使得更容易找到所有版本的styles.xml
文件。
示例:
<!-- 父属性指定了适当的主题 -->
<style name="LaunchTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- 自定义主题定义 -->
</style>
iOS特定设置步骤
支持的版本
最低支持版本是iOS 13。iOS应用的设置必须设置为针对iOS 13或更新版本。
CocoaPods设置
在您的应用的Podfile顶部添加以下行:
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/ololabs/podspecs.git'
在终端中,导航到您的应用的iOS文件夹(通常是<projectName>/ios
),然后运行以下命令:
pod install
开始使用
以下是将SDK集成到应用中的高级概述:
支付方法(新卡和数字钱包)
此方法用于未以前保存在Olo上的卡片,包括新信用卡和数字钱包。通过这种方式,信用卡输入部件和数字钱包都返回一个PaymentMethod
实例,然后可以使用该实例通过Olo的订购API提交篮子。具体细节如下:
- 导入SDK:
import 'package:olo_pay_sdk/olo_pay_sdk.dart';
- 初始化Olo Pay(见
OloPaySdk.initializeOloPay()
) - 创建
PaymentMethod
- 信用卡部件
- 在您的应用中添加一个信用卡详情部件
- 使用部件的
onControllerCreated()
回调获取控制器实例 - 通过调用控制器上的
createPaymentMethod()
创建一个PaymentMethod
- 数字钱包
- 设置
OloPaySdk.onDigitalWalletReady
并等待回调指示数字钱包是否可用 - 根据品牌指南添加Apple Pay和Google Pay按钮
- 通过
OloPaySdk.createDigitalWalletPaymentMethod()
创建一个支付方法
- 设置
- 信用卡部件
- 使用
PaymentMethod
详细信息向Olo的订购API提交订单
CVV令牌(以前保存的卡片)
此方法用于已经保存在Olo上的卡片,您希望在提交篮子和处理付款之前重新验证保存卡片的CVV。CvvTextField
部件将提供一个CvvUpdateToken
实例,然后可以使用该实例通过Olo的订购API提交篮子。具体细节如下:
- 导入SDK:
import 'package:olo_pay_sdk/olo_pay_sdk.dart';
- 初始化Olo Pay(见
OloPaySdk.initializeOloPay()
) - 创建
CvvUpdateToken
- 在您的应用中添加
CvvTextField
部件 - 使用部件的
onControllerCreated()
回调获取控制器实例 - 通过调用控制器上的
createCvvUpdateToken()
创建一个CvvUpdateToken
- 在您的应用中添加
- 使用
CvvUpdateToken
详细信息向Olo的订购API提交订单
处理异常
当调用SDK中的函数时,有可能失败。发生这种情况时,返回的错误对象将是一个PlatformException
,并包含code
和message
属性,指示方法调用失败的原因。
code
属性始终映射到ErrorCodes
中的值。
请参阅每个方法的文档,了解如果出现错误将返回哪些可能的错误代码。
示例
try {
const paymentMethodData = await oloPaySdk.createDigitalWalletPaymentMethod();
// 处理支付方法数据
} on PlatformException catch (e) {
if (e.code == ErrorCodes.generalError) {
// 处理异常
}
}
原生视图部件
Olo Pay SDK中的部件用于在应用中显示信用卡输入字段,并且卡详细信息对开发人员不可访问,以帮助减少维护PCI合规性的努力。
与标准Flutter部件的区别
Olo Pay SDK中的部件托管原生Android和iOS视图,这些行为与标准Flutter部件不同。这些差异的详细信息如下。
尺寸差异
最大的差异之一是原生部件需要定义特定的高度。内部,Olo Pay SDK中的部件被包装在一个具有默认高度的ConstrainedBox
中,大多数场景中都能正常工作。如果需要更改默认值,可以传递约束条件。
Olo Pay SDK中的部件会根据指定的边界调整其视图大小。请参阅每个部件的文档,了解推荐的高度和尺寸方法。
注意: 在v1.2.0
之前的CardDetailsSingleLineTextField
在Android和iOS上的行为有所不同。请参阅CardDetailsSingleLineTextField
文档以了解详细信息。
可用部件
信用卡详情部件
CardDetailsSingleLineTextField
- 这个部件在一个输入字段中显示所有信用卡详情,是显示信用卡输入视图最紧凑的方式。CardDetailsFormTextField
- 这个部件将在SDK的未来版本中提供。
CVV详情部件
CvvTextField
- 这个部件显示一个单输入字段,可用于对保存卡片的CVV代码进行重新验证。
示例代码
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:olo_pay_sdk/olo_pay_sdk.dart';
import 'package:pay/pay.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Olo Pay SDK Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color.fromRGBO(1, 160, 219, 1)),
useMaterial3: true,
),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// 步骤1:创建插件实例
final _oloPaySdkPlugin = OloPaySdk();
// 控制器类允许与部件交互
CardDetailsSingleLineTextFieldController? _cardInputController;
String _status = '';
bool _sdkInitialized = false;
bool _digitalWalletsReady = false;
bool _enabled = true;
bool _showAll = false;
[@override](/user/override)
void initState() {
super.initState();
initOloPaySDK();
}
void onSingleLineControllerCreated(CardDetailsSingleLineTextFieldController controller) {
_cardInputController = controller;
}
void updatePaymentMethod(PaymentMethod paymentMethod) {
updateStatus("Payment Method\n${paymentMethod.toString()}");
}
void updateStatus(String status) {
setState(() {
_status = status;
});
}
void onInputChanged(
bool isValid, Map<CardField, CardFieldState> fieldStates,
) {
// 在这里添加代码以处理此回调
// log('onInputChanged: $isValid');
}
void onValidStateChanged(
bool isValid, Map<CardField, CardFieldState> fieldStates,
) {
// 在这里添加代码以处理此回调
// log('onValidStateChanged: $isValid');
}
void onFocusChanged(
CardField? focusedField, bool isValid, Map<CardField, CardFieldState> fieldStates,
) {
// 在这里添加代码以处理此回调
// log('onFocusChanged: $focusedField');
}
void onDigitalWalletReady(bool isReady) {
setState(() {
_digitalWalletsReady = isReady;
});
}
// 步骤2:初始化Olo Pay SDK
Future<void> initOloPaySDK() async {
var sdkInitialized = false;
try {
_oloPaySdkPlugin.onDigitalWalletReady = onDigitalWalletReady;
const OloPaySetupParameters sdkParams = OloPaySetupParameters(
productionEnvironment: false,
);
const GooglePaySetupParameters googlePayParams = GooglePaySetupParameters(
countryCode: "US",
merchantName: "Foosburgers",
productionEnvironment: false,
);
const ApplePaySetupParameters applePayParams = ApplePaySetupParameters(
merchantId: "merchant.com.olopaysdktestharness",
companyLabel: "SDK Test",
);
await _oloPaySdkPlugin.initializeOloPay(
oloPayParams: sdkParams,
googlePayParams: googlePayParams,
applePayParams: applePayParams,
);
} on PlatformException catch (e) {
updateStatus(e.message!);
}
setState(() {
_sdkInitialized = true;
});
}
Future<void> createPaymentMethod() async {
try {
var paymentMethod = await _cardInputController?.createPaymentMethod();
if (paymentMethod != null) {
// 一旦生成了支付方法,就可以使用它来提交订单到Olo订购API
updatePaymentMethod(paymentMethod);
}
} on PlatformException {
// 在这里处理异常
}
}
Future<void> createDigitalWalletPaymentMethod() async {
const DigitalWalletPaymentParameters paymentParams = DigitalWalletPaymentParameters(amount: 1.21);
try {
PaymentMethod? paymentMethod = await _oloPaySdkPlugin
.createDigitalWalletPaymentMethod(paymentParams);
if (paymentMethod == null) {
// 用户取消了数字钱包流程
updateStatus("用户取消");
} else {
// 一旦生成了支付方法,就可以使用它来提交订单到Olo订购API
updatePaymentMethod(paymentMethod);
}
} on PlatformException catch (e) {
updateStatus(e.message!);
}
}
Future<void> clear() async {
try {
await _cardInputController?.clearFields();
updateStatus("");
} on PlatformException catch (e) {
updateStatus(e.message!);
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text("Olo Pay SDK Demo"),
),
body: SingleChildScrollView(
child: Center(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
const Text(
"SDK已初始化: ",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(_sdkInitialized.toString())
],
),
Row(
children: [
const Text(
"数字钱包已就绪: ",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(_digitalWalletsReady.toString())
],
),
const SizedBox(height: 16.0),
if (_sdkInitialized) // SDK必须初始化后才能显示文本字段
CardDetailsSingleLineTextField(
// 步骤3:提供回调以获取控制器实例
onControllerCreated: onSingleLineControllerCreated,
onInputChanged: onInputChanged,
onValidStateChanged: onValidStateChanged,
onFocusChanged: onFocusChanged,
),
const SizedBox(height: 16.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
// 步骤4a:使用信用卡输入部件创建支付方法
onPressed: createPaymentMethod,
child: const Text("提交"),
),
ElevatedButton(
onPressed: clear,
child: const Text("清除"),
),
],
),
const SizedBox(height: 16.0),
Row(
children: [
if (defaultTargetPlatform == TargetPlatform.android && _digitalWalletsReady)
Expanded(
child: RawGooglePayButton(
type: GooglePayButtonType.buy,
// 步骤4b:通过Google Pay创建支付方法
onPressed: createDigitalWalletPaymentMethod,
),
),
if (defaultTargetPlatform == TargetPlatform.iOS && _digitalWalletsReady)
Expanded(
child: RawApplePayButton(
type: ApplePayButtonType.buy,
// 步骤4c:通过Apple Pay创建支付方法
onPressed: createDigitalWalletPaymentMethod,
),
),
],
),
const SizedBox(height: 8.0),
Text(
_status,
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.blue,
fontSize: 18.0,
),
),
],
),
),
),
),
);
}
}
更多关于Flutter支付功能插件olo_pay_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter支付功能插件olo_pay_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter支付功能插件olo_pay_sdk
的代码示例。这个示例将展示如何集成并使用该插件进行支付。
首先,确保你已经在pubspec.yaml
文件中添加了olo_pay_sdk
依赖:
dependencies:
flutter:
sdk: flutter
olo_pay_sdk: ^最新版本号 # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你可以按照以下步骤进行支付功能的集成:
- 导入插件
在你的Dart文件中(例如main.dart
),导入olo_pay_sdk
:
import 'package:olo_pay_sdk/olo_pay_sdk.dart';
- 初始化支付插件
在应用的初始化部分(例如在MyApp
类的initState
方法中),你可以进行插件的初始化(如果需要的话,有些支付SDK可能需要初始化步骤):
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
// 初始化支付插件(如果需要的话)
// OloPaySdk.init(); // 假设有初始化方法,根据文档调整
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('支付功能示例'),
),
body: Center(
child: PaymentButton(),
),
),
);
}
}
- 创建支付按钮并处理支付逻辑
创建一个按钮用于触发支付,并在按钮点击事件中处理支付逻辑:
class PaymentButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () async {
// 构建支付参数(根据olo_pay_sdk的文档调整)
Map<String, dynamic> payParams = {
'orderId': 'your_order_id', // 订单ID
'amount': '100.00', // 支付金额
'currency': 'CNY', // 货币类型
// 其他必要的支付参数...
};
try {
// 调用支付方法
OloPayResult result = await OloPaySdk.pay(payParams);
if (result.success) {
// 支付成功处理
print('支付成功: ${result.message}');
} else {
// 支付失败处理
print('支付失败: ${result.message}');
}
} catch (e) {
// 错误处理
print('支付发生错误: $e');
}
},
child: Text('支付'),
);
}
}
- 处理支付结果
在上面的代码中,OloPayResult
是一个假设的返回类型,用于封装支付结果。实际使用时,你需要根据olo_pay_sdk
的文档来调整这部分代码。通常,支付SDK会提供一个结果类,包含支付是否成功、错误消息等信息。
- 错误处理和用户反馈
在实际应用中,你需要添加更多的错误处理和用户反馈逻辑,例如显示加载指示器、处理网络错误等。
请注意,上述代码是一个简化的示例,具体实现细节可能会根据olo_pay_sdk
的实际API和文档有所不同。务必参考最新的SDK文档和示例代码来进行集成。
另外,由于支付功能涉及敏感信息和资金安全,务必在正式环境中进行充分的测试和验证,确保支付流程的稳定性和安全性。