Flutter支付处理插件mollie_flutter的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter支付处理插件mollie_flutter的使用

新闻

随着版本0.8.0的发布,Mollie插件现在支持从您的应用直接发起客户端请求。此功能目前处于测试阶段。

当前支持的API包括:

  • 订单API
  • 客户API
  • 订阅API
  • 支付API
  • 发票API(新测试版)

路线图

接下来将添加对以下API的支持:

  • 发货API
  • 退款API
  • 争议API

开始使用

在您能够使用插件之前,必须设置一些东西以实现iOS和Android的浏览器切换:

ANDROID

  1. AndroidManifest.xml文件中设置scheme。这一步是因为如果用户开始结账过程,该插件会切换到浏览器并打开Mollie的结账页面。完成后,浏览器将返回到您的应用。scheme将帮助浏览器打开正确的应用。

修改您的AndroidManifest.xml文件如下。确保您使用了一个唯一的主机名和scheme名称。主机名和scheme在下一步中非常重要。我们将在本例中使用payment-return作为主机名,mollie作为scheme。

<intent-filter>
     <data
       android:host="payment-return"
       android:scheme="mollie" />
     <action android:name="android.intent.action.MAIN"/>
     <category android:name="android.intent.category.LAUNCHER"/>
     <action android:name="android.intent.action.VIEW" />
     <category android:name="android.intent.category.DEFAULT" />
     <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>

您的AndroidManifest.xml文件可能看起来像这样:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.plugon.mollie_example">

    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="mollie_example"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <intent-filter>
                <data
                    android:host="payment-return"
                    android:scheme="mollie" />
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
        </activity>
    </application>
</manifest>
  1. 打开MainActivity.java文件,在其中粘贴以下代码:
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    if (Intent.ACTION_VIEW.equals(intent.getAction())) {
        getFlutterView().pushRoute("paymentDone");
    }
}

更改路由名称为完成支付后想要调用的路由名称。

您的MainActivity.java文件可能看起来像这样:

public class MainActivity extends FlutterActivity {

  boolean isSuccess;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
  }

  @Override
  protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    if (Intent.ACTION_VIEW.equals(intent.getAction())) {
        getFlutterView().pushRoute("paymentDone");
    }
  }
}

iOS

  1. 打开您的AppDelegate.swift文件,并粘贴以下代码:
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    if (url.host! == "payment-return") {

        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        controller.pushRoute("paymentDone");

        return true;
    }

    return false;
}

确保payment-return部分与您的AndroidManifest.xml中的android:host相匹配。

  1. 打开您的Info.plist文件。右键单击空白区域并选择添加行以创建一个新的键。

您会被提示从下拉菜单中选择一个键。滚动到底部并选择URL类型。这将创建一个数组项。您可以进一步点击展开它,并选择Item 0。展开该行,您应该看到URL标识符。双击值字段并填写您的标识符。通常情况下,这将是与您的Bundle ID相同,例如com.mollie.MollieApp。点击Item 0旁边的加号按钮,并从下拉菜单中选择URL Schemes。展开URL Schemes行,另一个Item 0将会出现。在值字段中输入您要处理的scheme,例如mollie-app。确保选择一个唯一的scheme。

使用插件

MollieCheckout小部件支持客户端方法和客户端-服务器方法。我们将向您展示这两种实现方式。如果您想使用客户端方法,请跳过此步骤,直接进入“使用插件”。

如果您正在使用客户端-服务器架构,您首先需要在例如Heroku上设置您的服务器。在以下示例中,我们将使用Node.js和Express.js进行API调用。

  1. 设置好您的Node.js服务器后,您需要安装Mollie包。进入您的工作目录并键入:
npm install @mollie/api-client@beta --save

有关详细说明,请访问https://github.com/mollie/mollie-api-node

  1. 初始化Mollie:
const { createMollieClient } = require('@mollie/api-client');
const mollieClient = createMollieClient({ apiKey: 'test_AFkJP7UuC3wddaeGasdG2UffGTdkmd8re'});

您可以在Mollie仪表板的开发者选项卡中找到您的API测试和公开密钥。

  1. 创建订单:
const { createMollieClient } = require('@mollie/api-client');
const mollieClient = createMollieClient({ apiKey: 'test_AFkJP7UuC3wddaeGasdG2UffGTdkmd8re'});

app.post("/your/custom/path",(req,res) => {

  mollieClient.orders.create(req.body).then(order => {
    res.send(order);
  }).catch(error => {
    res.send(error);
  });
});

使用插件

导入插件

import 'package:mollie_flutter/mollie.dart';

创建一个新的MollieOrderRequest

MollieOrderRequest requestOrder = new MollieOrderRequest(
      amount: MollieAmount(
          value: "1396.00",
          currency: "EUR"
      ),
      orderNumber: "900",
      redirectUrl: "mollie://payment-return",
      locale: "de_DE",
      webhookUrl: 'https://example.org/webhook',
      billingAddress: new MollieAddress(
        organizationName: 'Mollie B.V.',
        streetAndNumber: 'Keizersgracht 313',
        city: 'Amsterdam',
        region: 'Noord-Holland',
        postalCode: '1234AB',
        country: 'DE',
        title: 'Dhr.',
        givenName: 'Piet',
        familyName: 'Mondriaan',
        email: 'piet@mondriaan.com',
        phone: '+31309202070',
      ),
      shippingAddress: new MollieAddress(
        organizationName: 'Mollie B.V.',
        streetAndNumber: 'Keizersgracht 313',
        city: 'Amsterdam',
        region: 'Noord-Holland',
        postalCode: '1234AB',
        country: 'DE',
        title: 'Dhr.',
        givenName: 'Piet',
        familyName: 'Mondriaan',
        email: 'piet@mondriaan.com',
        phone: '+31309202070',
      ),
      products: [
        MollieProductRequest(
          type: 'physical',
          sku: '5702016116977',
          name: 'LEGO 42083 Bugatti Chiron',
          productUrl: 'https://shop.lego.com/nl-NL/Bugatti-Chiron-42083',
          imageUrl: 'https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?',
          quantity: 2,
          vatRate: '21.00',
          unitPrice: MollieAmount(
            currency: 'EUR',
            value: '399.00',
          ),
          totalAmount: MollieAmount(
            currency: 'EUR',
            value: '698.00',
          ),
          discountAmount: MollieAmount(
            currency: 'EUR',
            value: '100.00',
          ),
          vatAmount: MollieAmount(
            currency: 'EUR',
            value: '121.14',
          ),
        ),
        MollieProductRequest(
          type: 'physical',
          sku: '5702016116977',
          name: 'LEGO 42083 Bugatti Chiron',
          productUrl: 'https://shop.lego.com/nl-NL/Bugatti-Chiron-42083',
          imageUrl: 'https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?',
          quantity: 2,
          vatRate: '21.00',
          unitPrice: MollieAmount(
            currency: 'EUR',
            value: '399.00',
          ),
          totalAmount: MollieAmount(
            currency: 'EUR',
            value: '698.00',
          ),
          discountAmount: MollieAmount(
            currency: 'EUR',
            value: '100.00',
          ),
          vatAmount: MollieAmount(
            currency: 'EUR',
            value: '121.14',
          ),
        )
      ]
  );

重要:设置MollieOrderRequest中的redirectUrl属性

MollieOrderRequest order = new MollieOrderRequest(
      ...
      redirectUrl: "mollie://payment-return",
      ...
);

redirectUrl应遵循此模式scheme://host。对于我们的示例,应该是mollie://payment-return

参考表

使用molliepayment-return为例:

文件 Scheme Host RedirectUrl
AndroidManifest android:scheme=“mollie” android:host=“payment-return” mollie://payment-return
Info.plist URL Schemes -> item0 -> “mollie” 在AppDelegate.swift中设置"payment-return"(见顶部) mollie://payment-return

调用您的API端点或使用客户端实例发送MollieOrderRequest以检索订单对象

对于客户端-服务器架构:

Future<void> createOrder(MollieOrderRequest order) async{
  /// 发送POST请求到您的服务器,并带有创建的MollieOrderRequest
  var orderResponse = await http.post(
      "http://yourserver.herokuapp.com/mollie/create/order",
      headers: {"Content-Type": "application/json"},
      body: order.toJson()
  );

  /// 从您的服务器获取订单对象并解析
  var data = json.decode(orderResponse.body);
  MollieOrderResponse res = MollieOrderResponse.build(data);

  /// 设置当前订单以便从其他小部件轻松检索此订单
  Mollie.setCurrentOrder(res);

  /// 使用浏览器切换启动结账过程
  Mollie.startPayment(res.checkoutUrl);
}

对于直接从客户端调用。只需调用一次client.init()函数:

Future<void> createOrder(MollieOrderRequest order) async{
  client.init("test_TUIAGS980q2ezahdoas");

  var createdOrder = await client.orders.create(order);

  /// 设置当前订单以便从其他小部件轻松检索此订单
  Mollie.setCurrentOrder(createdOrder);

  /// 使用浏览器切换启动结账过程
  Mollie.startPayment(createdOrder.checkoutUrl);
}

使用MollieCheckout小部件显示多个支付方法

[@override](/user/override)
Widget build(BuildContext context) {
  return MollieCheckout(
    order: requestOrder,
    onMethodSelected: (order) {
      createOrder(order);
    },
    useCredit: true,
    usePaypal: true,
    useSepa: true,
    useSofort: true,
    useIdeal: true,
    useApplePay: true
  );
}

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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用mollie_flutter插件进行支付处理的示例代码。这个插件允许你集成Mollie支付网关到你的Flutter应用中。

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

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

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

接下来,你需要在Mollie仪表盘上创建一个API密钥,并将其添加到你的Flutter应用中。出于安全考虑,不建议在客户端代码中硬编码API密钥,而是应该通过安全的方式(如环境变量或服务器端存储)来获取它。

以下是一个简单的示例,展示如何使用mollie_flutter插件进行支付处理:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Mollie Payment Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: PaymentScreen(),
    );
  }
}

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

class _PaymentScreenState extends State<PaymentScreen> {
  final String apiKey = 'your_mollie_api_key_here';  // 请替换为你的Mollie API密钥

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Mollie Payment Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            // 创建Mollie客户端
            final mollieClient = MollieClient(apiKey: apiKey);

            // 创建支付意图(在实际应用中,你通常会在服务器端完成这一步)
            // 这里我们假设已经有了一个支付意图的ID
            final paymentIntentId = 'your_payment_intent_id_here';  // 请替换为实际的支付意图ID

            try {
              // 初始化支付
              final paymentResult = await mollieClient.initializePayment(
                paymentIntentId: paymentIntentId,
                returnUrl: Uri.parse('your_return_url_here'),  // 支付完成后返回的URL
              );

              if (paymentResult.status == PaymentStatus.completed) {
                // 支付成功处理
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: Text('Payment Successful'),
                    content: Text('Payment has been successfully completed.'),
                    actions: <Widget>[
                      TextButton(
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                        child: Text('OK'),
                      ),
                    ],
                  ),
                );
              } else if (paymentResult.status == PaymentStatus.pending) {
                // 支付待处理(可能需要用户进一步操作,如3D Secure验证)
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: Text('Payment Pending'),
                    content: Text('Payment is pending. Please complete the payment process.'),
                    actions: <Widget>[
                      TextButton(
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                        child: Text('OK'),
                      ),
                    ],
                  ),
                );
              } else {
                // 支付失败处理
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: Text('Payment Failed'),
                    content: Text('Payment has failed. Please try again.'),
                    actions: <Widget>[
                      TextButton(
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                        child: Text('OK'),
                      ),
                    ],
                  ),
                );
              }
            } catch (e) {
              // 错误处理
              showDialog(
                context: context,
                builder: (context) => AlertDialog(
                  title: Text('Error'),
                  content: Text('An error occurred: ${e.message}'),
                  actions: <Widget>[
                    TextButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text('OK'),
                    ),
                  ],
                ),
              );
            }
          },
          child: Text('Initiate Payment'),
        ),
      ),
    );
  }
}

注意

  1. 在实际应用中,创建支付意图(Payment Intent)的过程通常应该在服务器端完成,因为涉及到敏感信息的处理。
  2. your_mollie_api_key_hereyour_payment_intent_id_here需要替换为你自己的Mollie API密钥和支付意图ID。
  3. your_return_url_here需要替换为支付完成后Mollie重定向回你的应用的URL。

这个示例代码展示了如何使用mollie_flutter插件初始化支付并处理支付结果。在实际应用中,你可能需要根据具体需求对代码进行调整。

回到顶部