Flutter支付集成插件flutter_adyen_cse的使用

Flutter支付集成插件flutter_adyen_cse的使用

Adyen Payment客户端加密库适用于Flutter项目。

它适用于那些不需要使用Adyen Drop-in集成,而只需要对卡信息进行tokenize或使用自定义界面来输入卡数据的项目。

需求

检查应用兼容性:

  • Android最低SDK版本:21 - Android Lollipop
  • iOS最低构建目标:iOS 12.2

获取您的客户端加密公钥

在使用flutter_adyen_cse插件时,您需要设置为publicKey。要获取您的公钥,请按以下步骤操作:

  1. 使用公司级别的账户登录到您的客户区域
  2. 导航至开发者 > API凭证
  3. 在用户列表中点击您的Web服务用户(ws@Company.[您的公司账户])。 这将打开编辑Web服务用户页面。
  4. 客户端侧加密面板中,复制客户端加密公钥

使用

第一步 - 初始化flutter_adyen_cse插件

import 'package:flutter_adyen_cse/flutter_adyen_cse.dart';
import 'package:flutter_adyen_cse/models/models.dart';

try {
  await FlutterAdyenCse.initAdyenCse(AdyenCseConfig(
    publicKey: '<您的客户端加密公钥>'
  ));
} on PlatformException {
  rethrow;
}

第二步 - 加密卡数据

import 'dart:developer';

import 'package:flutter_adyen_cse/flutter_adyen_cse.dart';
import 'package:flutter_adyen_cse/models/models.dart';

try {
  final AdyenCseEncryptedCard? encryptedCard =
      await FlutterAdyenCse.encryptCard(AdyenCseCard(
    cardNumber: '4242424242424242',
    expiryMonth: '12',
    expiryYear: '2026',
    securityCode: '737',
  ));

  if (encryptedCard != null) log(encryptedCard.toJson().toString());
} on PlatformException {
  rethrow;
}

第三步 - 使用加密后的卡数据

加密后的卡数据存储在AdyenCseEncryptedCard对象中,您可以根据需要使用这些数据。

示例应用

您可以在我们的示例应用中查看如何使用flutter_adyen_cse插件。

示例应用截图

参考资料


示例代码

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:flutter_adyen_cse/flutter_adyen_cse.dart';
import 'package:flutter_adyen_cse/models/models.dart';

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> {
  final TextEditingController _numberController = TextEditingController();
  final TextEditingController _expMonthController = TextEditingController();
  final TextEditingController _expYearController = TextEditingController();
  final TextEditingController _cvvController = TextEditingController();
  Map<String, String>? result;

  [@override](/user/override)
  void initState() {
    super.initState();
    initAdyenCsePlugin();
    _numberController.text = '4242424242424242';
    _expMonthController.text = '12';
    _expYearController.text = '2026';
    _cvvController.text = '737';
  }

  Future<void> initAdyenCsePlugin() async {
    try {
      await FlutterAdyenCse.initAdyenCse(AdyenCseConfig(
        publicKey: const String.fromEnvironment('ADYEN_PK', defaultValue: ''),
      ));
    } on PlatformException {
      rethrow;
    }
  }

  Future<void> encryptCard() async {
    try {
      final AdyenCseEncryptedCard? encryptedCard =
          await FlutterAdyenCse.encryptCard(AdyenCseCard(
        cardNumber: _numberController.value.text,
        expiryMonth: _expMonthController.value.text,
        expiryYear: _expYearController.value.text,
        securityCode: _cvvController.value.text,
      ));

      if (encryptedCard != null) {
        setState(() {
          result = encryptedCard.toJson();
        });
      }
    } on PlatformException {
      rethrow;
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: const Text('Adyen CSE demo'),
          ),
          body: Padding(
            padding: const EdgeInsets.all(20),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                TextFormField(
                  controller: _numberController,
                  decoration: const InputDecoration(label: Text('卡号')),
                ),
                Row(
                  children: [
                    Expanded(
                      child: TextFormField(
                        controller: _expMonthController,
                        decoration: const InputDecoration(label: Text('有效期月')),
                      ),
                    ),
                    const SizedBox(width: 30),
                    Expanded(
                      child: TextFormField(
                        controller: _expYearController,
                        decoration: const InputDecoration(label: Text('有效期年')),
                      ),
                    ),
                  ],
                ),
                TextFormField(
                  controller: _cvvController,
                  decoration: const InputDecoration(label: Text('CVV')),
                ),
                Padding(
                  padding: const EdgeInsets.all(20),
                  child: MaterialButton(
                    onPressed: () => encryptCard(),
                    child: const Text(
                      '加密卡',
                      style: TextStyle(
                        color: Colors.white,
                      ),
                    ),
                    color: Colors.blue,
                  ),
                ),
                const Divider(
                  color: Colors.black54,
                ),
                Padding(
                  padding: const EdgeInsets.symmetric(vertical: 20),
                  child: Row(
                    children: const [
                      Text('结果:'),
                    ],
                  ),
                ),
                Expanded(
                  child: Material(
                    type: MaterialType.card,
                    borderRadius: BorderRadius.circular(10),
                    color: Colors.grey[200],
                    child: result != null
                        ? ListView.separated(
                            itemCount: result!.keys.length,
                            itemBuilder: (context, index) => Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                Padding(
                                  padding:
                                      const EdgeInsets.symmetric(vertical: 10),
                                  child: Text(
                                    result!.keys.elementAt(index),
                                    style: const TextStyle(
                                      fontWeight: FontWeight.bold,
                                    ),
                                  ),
                                ),
                                Text(result!.values.elementAt(index)),
                              ],
                            ),
                            separatorBuilder: (context, index) =>
                                const SizedBox(
                              height: 20,
                            ),
                          )
                        : Container(),
                  ),
                ),
              ],
            ),
          ),
        ),
      );
}

更多关于Flutter支付集成插件flutter_adyen_cse的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter支付集成插件flutter_adyen_cse的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中集成并使用flutter_adyen_cse插件的一个基本示例。这个插件允许你使用Adyen的客户端加密解决方案(Client-Side Encryption, CSE)来处理支付。

首先,确保你已经在pubspec.yaml文件中添加了flutter_adyen_cse依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_adyen_cse: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,你需要配置Adyen的相关信息,并在你的Flutter应用中实现支付流程。以下是一个简化的代码示例,展示了如何初始化插件并处理支付。

1. 配置Adyen信息

android/app/src/main/AndroidManifest.xml中,你可能需要添加一些必要的权限和配置,比如网络权限:

<uses-permission android:name="android.permission.INTERNET"/>

对于iOS,你可能需要在ios/Runner/Info.plist中添加一些配置,但通常flutter_adyen_cse插件不会直接要求这些,除非你有特定的需求。

2. 初始化插件和处理支付

在你的Dart代码中,你可以这样使用flutter_adyen_cse插件:

import 'package:flutter/material.dart';
import 'package:flutter_adyen_cse/flutter_adyen_cse.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PaymentScreen(),
    );
  }
}

class PaymentScreen extends StatefulWidget {
  @override
  _PaymentScreenState createState() => _PaymentScreenState();
}

class _PaymentScreenState extends State<PaymentScreen> {
  final AdyenCSE _adyenCSE = AdyenCSE();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Adyen Payment Integration'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            // 替换为你的Adyen配置信息
            final String clientKey = 'your_adyen_client_key';
            final String publicKey = 'your_adyen_public_key';
            final String environment = 'test'; // 或 'live'

            // 初始化AdyenCSE
            await _adyenCSE.init(clientKey: clientKey, publicKey: publicKey, environment: environment);

            // 创建支付数据
            final Map<String, dynamic> paymentData = {
              'amount': {
                'currency': 'USD',
                'value': 1000, // 金额,单位为最小货币单位(例如,1000代表10.00美元)
              },
              'merchantAccount': 'your_merchant_account',
              'reference': 'unique_payment_reference',
              'paymentMethod': {
                'type': 'scheme',
                'number': '4111111111111111', // 测试卡号
                'expiryMonth': '12',
                'expiryYear': '25',
                'cvc': '737',
              },
              // 可以根据需要添加其他支付信息
            };

            try {
              // 处理支付
              final Map<String, dynamic> result = await _adyenCSE.makePayment(paymentData);
              print('Payment result: $result');

              // 根据结果处理支付成功或失败逻辑
              if (result['resultCode'] == 'Authorised') {
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: Text('Payment Successful'),
                    content: Text('Payment has been successfully authorised.'),
                    actions: <Widget>[
                      TextButton(
                        child: Text('OK'),
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                      ),
                    ],
                  ),
                );
              } else {
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: Text('Payment Failed'),
                    content: Text('Payment failed with result code: ${result['resultCode']}'),
                    actions: <Widget>[
                      TextButton(
                        child: Text('OK'),
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                      ),
                    ],
                  ),
                );
              }
            } catch (e) {
              print('Error during payment: $e');
              showDialog(
                context: context,
                builder: (context) => AlertDialog(
                  title: Text('Error'),
                  content: Text('An error occurred during payment: $e'),
                  actions: <Widget>[
                    TextButton(
                      child: Text('OK'),
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                    ),
                  ],
                ),
              );
            }
          },
          child: Text('Make Payment'),
        ),
      ),
    );
  }
}

注意事项

  1. 安全性:不要在生产环境中硬编码敏感信息,如Adyen的clientKey和publicKey。考虑使用环境变量或安全的密钥管理服务。
  2. 错误处理:上面的代码示例中包含了基本的错误处理,但在实际应用中,你可能需要更复杂的错误处理逻辑。
  3. UI/UX:上面的示例使用了简单的对话框来显示支付结果。在实际应用中,你可能需要设计更友好的用户界面。
  4. 测试环境:确保在测试环境中测试支付流程,然后再在生产环境中部署。

这个示例提供了一个基本的框架,你可以根据自己的需求进行扩展和修改。

回到顶部