Flutter支付集成插件youcan_pay的使用

Flutter支付集成插件youcan_pay的使用

本插件为Dart/Flutter项目提供了与YouCan Pay API的简单集成。通过它,你可以轻松地在你的项目中实现支付功能。

关键特性

  • 易于使用的API方法,这些方法基于文档中的API端点。
  • 开发者友好的接口,让你感觉就像在家里一样舒适。
  • 支持所有API端点。
  • 配置一次,处处可用。

代码进度

  • [x] 支付
  • [x] 账户
  • [x] 货币
  • [x] 转账
  • [x] 发票
  • [x] 账户余额历史
  • [x] 提现
  • [x] 入金
  • [x] 完全独立的Flutter集成

测试进度

  • [x] 支付
  • [x] 账户
  • [x] 货币
  • [x] 转账
  • [x] 发票
  • [x] 账户余额历史
  • [x] 提现
  • [x] 入金
  • [-] Flutter支付集成

使用方法

快速概述

YouCan Pay API

该插件通过模块化的方式提供了对API的访问。每个模块都可以通过唯一的单例实例 YouCanPay.instance 访问:

YouCanPay.instance.account;
YouCanPay.instance.balanceHistory; 
YouCanPay.instance.currencies; 
YouCanPay.instance.deposits; 
YouCanPay.instance.invoices; 
YouCanPay.instance.payments; 
YouCanPay.instance.transfers;
YouCanPay.instance.withdrawals; 

每个模块都有与其相关的API调用方法。例如,注册账户的API可以通过以下代码调用:

RegisterResponse registerResponse = await YouCanPay.instance.account.register(
   email: "john@example.com",
   firstName: "John",
   lastName: "Doe",
   password: "123456789",
   phone: "+212611223344",
);
Flutter支付集成

YouCanPay.instance 现在提供了一个 flutter 模块的访问方式:

YouCanPay.instance.flutter;

这提供了一个意见化的独立支付集成,完全可配置且即开即用。这是一个处理支付的示例:

YouCanPay.instance.flutter.processPay(
    context,
    paymentToken: "THE_TOKEN_OF_PAYMENT",
    pubKey: "YOUR_PUBLIC_KEY",
    card: YouCanPayCard(
      cardHolderName: "Anas Fikhi",
      creditCard: 4242424242424242,
      cvv: 112,
      expireDate: YouCanPayExpireDate(month: 12, year: 2024),
    ),
    on3dsVerificationFailed: (context, res) {
      _snackBar(res.message);
    },
    onPaymentFailed: (exception, stacktrace) {
      _snackBar(exception.message);
    },
    onPaymentSuccessWithout3dsVerification: (res) {
      _snackBar(res.message);
    },
    onPaymentSuccessWith3dsVerification: (context, res) {
      _snackBar(res.transactionId);
    },
  );
  • onPaymentSuccessWithout3dsVerification:如果支付成功并且无需3DS验证,则会调用此回调。
  • onPaymentSuccessWith3dsVerification:如果支付成功但需要3DS验证,则会调用此回调。
  • on3dsVerificationFailed:如果用户在Web视图中验证失败(如手动取消支付),则会调用此回调。
  • onPaymentFailed:如果支付直接失败(如卡信息无效、余额不足等),则会调用此回调。

测试/开发注意事项

  • 你可能想使用测试卡进行测试。通过 YouCanPayCard 工厂可以方便地使用测试卡:
YouCanPayCard.testingNo3dsSuccessCard();
YouCanPayCard.testing3dsSuccessCard();
YouCanPayCard.testing3dsRejectedCard();
YouCanPayCard.testingNo3dsNoFundsCard();
  • 当你设置沙箱模式进行测试时,请确保你在YouCan Pay仪表板中设置了成功和错误URL,以便在应用中模拟支付流程。

错误处理

所有方法都会抛出异常,如果发生错误,你可以捕获并处理它们。

方式1

你可以触发 YouCanPayException 异常并捕获它,然后使用其消息:

try {  
    RegisterResponse registerResponse = await YouCanPay.instance.account.register(...);
    print(registerResponse.message);
  } on YouCanPayException catch (e) {
    print(e.message); // 打印API返回的错误消息
    print(e.statusCode); // 打印响应的状态码
  } catch(e) {
    print(e);
  }

方式2

APIs暴露了一些预定义的错误代码,你可以在开发过程中遇到。通过这个包,你可以根据每个错误执行不同的操作:

try {  
    RegisterResponse registerResponse = await YouCanPay.instance.account.register(...);
    print(registerResponse.message);
  } on YouCanPayException catch (e) {
    switch (e) {
      case YouCanPayNotFoundException():
        print("未找到");
        break;

      case YouCanPayBadRequestException():
        print("请求错误");
        break;

      case YouCanPayServerErrorException():
        print("服务器错误");
        break;

      case YouCanPayUnAuthorizedException():
        print("未授权");
        break;

      case YouCanPayUnprocessableEntityException():
        print("无法处理实体");
        break;

      default:
        print("未知错误");
    }

    print(e.message);
    print(e.statusCode);    
  
    } catch(e) {
    print(e);
  }

你可以根据自己的需求处理错误。作为额外的好处,你还可以使用 statusCode 来处理错误。

文档

支付

Tokenize Payment

你可以通过 tokenize 方法来tokenize一个新的支付:

TokenizeResponse response = await YouCanPay.instance.payments.tokenize(
    amount: 150000,
    priKey: "pri_sandbox_9f410153-b941-47f5-9154-c1981",
    currency: "MAD",
    orderId: "orderId",
  );

print(response.token); // ...
CashPlus Gateway

这将使用CashPlus Gateway处理支付:

final res = await YouCanPay.instance.payments.cashPlusInit(
    pubKey: "YOUR_PUBLIC_KEY",
    tokenId: "PAYMENT_TOKEN",
  );

print(res.tokenId);
print(res.transactionId);
Card Gateway Sale

这将处理支付。但是,基于支付状态的不同,响应也会不同,因此你需要检查并处理每种情况:

  • 如果支付成功,你会得到一个 SuccessfulPayResponse 对象。
  • 如果支付需要3DS验证,你会得到一个 Verification3dsPayResponse 对象。
  • 如果支付不成功(例如,卡上没有足够的资金),将会抛出 YouCanPayUnprocessableEntityException 异常,详情见错误处理
  • 如果响应不符合预期,你将得到一个 UnknownPayResponse 对象,其中包含解码后的JSON响应。
final res = await YouCanPay.instance.payments.pay(
  pubKey: "YOUR_PUBLIC_KEY",
  tokenId: "PAYMENT_TOKEN",
  cardHolderName: "Anas FIKHI",
  creditCard: 4242424242424242,
  cvv: 112,
  expireDate: YouCanPayExpireDate(month: 10, year: 24),
);

if (payResponse is SuccessfulPayResponse) {
  print("支付成功");
  print(payResponse.transactionId);
  print(payResponse.message);
  print(payResponse.orderId);
} else if (payResponse is Verification3dsPayResponse) {
  print("3DS验证支付");
  print(payResponse.redirectUrl);
  print(payResponse.returnUrl);
  print(payResponse.transactionId);
} else if (payResponse is UnknownPayResponse) {
  print("未知支付");
  print(payResponse.decodedJsonResponse);
}
Card Gateway Authorization

这将使用授权操作处理支付。这比销售操作更快,因为它只授权支付,并在30秒内异步完成捕获。

final res = await YouCanPay.instance.payments.authorize(
  pubKey: "YOUR_PUBLIC_KEY",
  tokenId: "PAYMENT_TOKEN",
  cardHolderName: "Anas FIKHI",
  creditCard: 4242424242424242,
  cvv: 112,
  expireDate: YouCanPayExpireDate(month: 10, year: 24),
);

if (payResponse is SuccessfulPayResponse) {
  print("支付成功");
  print(payResponse.transactionId);
  print(payResponse.message);
  print(payResponse.orderId);
} else if (payResponse is Verification3dsPayResponse) {
  print("3DS验证支付");
  print(payResponse.redirectUrl);
  print(payResponse.returnUrl);
  print(payResponse.transactionId);
} else if (payResponse is UnknownPayResponse) {
  print("未知支付");
  print(payResponse.decodedJsonResponse);
}

账户

注册账户

你可以通过 register 方法创建一个新账户:

final res = await YouCanPay.instance.account.register(
  email: "john@example.com",
  firstName: "John",
  lastName: "Doe",
  password: "123456789",
  phone: "+212611223344", 
);

print(res.message);
认证

你可以通过 login 方法认证一个用户,它会返回一个包含用户token的 AuthenticateResponse 对象,你可以在接下来的请求中使用该token。

final res = await YouCanPay.instance.account.login(
  emailOrPhone: email,
  password: password,
);

print(res.token);
账户信息

你可以通过 me 方法获取用户的相关信息,该方法只需要用户的token。

final res = await YouCanPay.instance.account.me(
  token: "THE_USER_TOKEN",
);

print(res.email);
print(res.address);
print(res.phone);
更新账户信息

为了更新用户的账户信息,你可以使用 updateAccount 方法:

final res = await YouCanPay.instance.account.updateAccount(
  token: "TOKEN_OF_THE_USER",
  firstName: "anas fikhi",
  adress: "...",
);

print(res.message);
更新账户密码

为了更新用户的密码,你可以使用 updatePassword 方法:

final res = await YouCanPay.instance.account.updatePassword(
  token: "TOKEN_OF_THE_USER",
  password: "newPassword",
);

print(res.message);
账户统计

为了获取用户的账户统计信息,你可以使用 stats 方法:

final res = await YouCanPay.instance.account.stats(
  token: "TOKEN_OF_THE_USER",
  fromDate: DateTime.now().subtract(Duration(days: 5)),
  toDate: DateTime.now(),
  interval: YouCanPayStatsInterval.thisWeek,
);

print(res.totalRevenue);
print(res.paidTransactionsByDates);
刷新认证token

为了刷新用户的认证token,你可以使用 refreshToken 方法:

final res = await YouCanPay.instance.account.refreshToken(
  token: "TOKEN_OF_THE_USER",
);

print(res.token); // 新的token
登出

为了登出一个用户,你可以使用 logout 方法。该方法将使当前用户的token失效,用户将不能再使用该token,直到再次登录。

final res = await YouCanPay.instance.account.logout(
  token: "TOKEN_OF_THE_USER",
);

print(res.message);

货币

转换率

你可以通过 conversionRates 方法获取货币的转换率:

final res = await YouCanPay.instance.currencies.conversionRates(
  token: "TOKEN_OF_THE_USER",
);

print(res.baseCurrency);
print(res.conversionRates["MAD"]);
print(res.conversionRates["USD"]);

转账

创建转账

你可以通过 create 方法创建一个新的转账:

final res = await YouCanPay.instance.transfers.create(
  token: "TOKEN_OF_THE_USER",
  amount: 1000,
  identifier: "work@gwhyyy.com",
);

print(res.id); // 转账的id
列出转账

要列出所有用户的转账,你可以使用 transfers 方法:

final res = await YouCanPay.instance.transfers.transfers(
  token: "TOKEN_OF_THE_USER",
);

print(res.data.map((e) => e.id).toList()); // 转账的id列表
最近的收款人

要获取最近的收款人,你可以使用 recentRecipients 方法:

final res = await YouCanPay.instance.transfers.recentRecipients(
  token: "TOKEN_OF_THE_USER",
);

print(res.data.map((e) => e.id).toList()); // 最近的收款人的id列表

发票

创建发票

你可以通过 create 方法创建一个新的发票:

final res = await YouCanPay.instance.invoices.create(
  token: "TOKEN_OF_THE_USER",
  amount: 4000,
  contactOption: 1,
  name: "anas fikhi",
  currency: "MAD",
);

print(res.id);
print(res.alias);
print(res.displayAmount);
列出发票

要列出所有用户的发票,你可以使用 invoices 方法:

final res = await YouCanPay.instance.invoices.invoices(
  token: "TOKEN_OF_THE_USER",
);

print(res.data.map((e) => e.id).toList()); // 发票的id列表
Tokenize发票

你可以通过 tokenize 方法tokenize一个发票:

final res = await YouCanPay.instance.invoices.tokenize(
  token: "TOKEN_OF_THE_USER",
  invoiceId: "INVOICE_ID",
);

print(res.tokenID);

账户余额历史

列表账户余额历史

要列出所有用户的账户余额历史,你可以使用 balanceHistory 方法:

final res = await YouCanPay.instance.balanceHistory.history(
  token: "TOKEN_OF_THE_USER",
);

print(res.data.map((e) => e.id).toList()); // 账户余额历史项目的id列表

提现

创建提现

你可以通过 create 方法创建一个新的提现:

final res = await YouCanPay.instance.withdrawals.create(
  token: "TOKEN_OF_THE_USER",
  paymentMethod: YouCanPayPaymentsMethod.bank_account,
  amount: 500,
);

print(res.message);
列出提现

要获取提现的列表,你可以使用 withdrawals 方法:

final res = await YouCanPay.instance.withdrawals.withdrawals(
  token: "TOKEN_OF_THE_USER",
);

print(res.data.map((e) => e.id).toList()); // 提现的id列表

入金

Tokenize

为了tokenize一个入金,你可以使用 tokenize 方法:

final res = await YouCanPay.instance.deposits.tokenize(
  token: "TOKEN_OF_THE_USER",
  amount: 1000,
  currency: 'MAD',
);

print(res.tokenId);

想要贡献?

欢迎贡献于这个项目,只需fork该项目并提交pull request,我们会很高兴审查并合并它。以下是你可能需要做的任务:

  • [] 查找并纠正文档中的错误。
  • [] 处理任何意外的行为。
  • [] 重构或添加新的功能到包中。
  • [] 使包更易于开发者使用。

问题

如果你发现任何问题,请在这里报告:https://github.com/anasfik/youcan_pay/issues


示例代码

import 'dart:math';

import 'package:youcan_pay/youcan_pay.dart';

void main() async {
  final random = Random().nextInt(99999999);

  final email = "example$random@gmail.com";
  final phone = "+2126$random";
  final password = "12345678";

  try {
    final res = await YouCanPay.instance.account.register(
      email: email,
      firstName: "John",
      lastName: "Doe",
      password: password,
      phone: phone,
    );

    print(res.message);
  } on YouCanPayException catch (e) {
    print(e);
  }
  late String token;

  try {
    final res = await YouCanPay.instance.account.login(
      emailOrPhone: email,
      password: password,
    );
    token = res.token;
    print(res.token);
  } on YouCanPayException catch (e) {
    print(e.message);
    print(e.statusCode);
  }

  try {
    final res = await YouCanPay.instance.currencies.conversionRates(
      token: token,
    );

    print(res.baseCurrency);
    print(res.conversionRates["MAD"]);
    print(res.conversionRates["USD"]);
  } on YouCanPayException catch (e) {
    print(e.message);
    print(e.statusCode);
  }
}

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

1 回复

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


在Flutter中集成支付功能,可以使用youcan_pay插件来实现多种支付渠道的集成。以下是一个基本的代码案例,展示了如何在Flutter项目中使用youcan_pay插件进行支付功能的集成。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加youcan_pay插件的依赖:

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

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

2. 配置Android和iOS

根据你使用的平台(Android或iOS),你可能需要进行一些额外的配置。例如,在Android上,你可能需要在AndroidManifest.xml中添加一些权限和配置。在iOS上,你可能需要在Info.plist中添加一些配置。具体配置请参考youcan_pay插件的官方文档。

3. 初始化插件并调用支付功能

以下是一个简单的示例,展示了如何在Flutter应用中初始化youcan_pay插件并调用支付功能:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter YouCanPay Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              // 初始化 YouCanPay 插件
              await YouCanPay.init({
                "app_id": "你的AppID", // 替换为你的实际AppID
                "private_key": "你的PrivateKey", // 替换为你的实际PrivateKey
                "debug": true, // 是否为调试模式
              });

              // 构建支付订单信息
              var order = {
                "out_trade_no": "1234567890", // 订单号
                "total_fee": "100", // 订单金额,单位为分
                "subject": "测试订单", // 订单标题
                "body": "这是一个测试订单", // 订单描述
                "notify_url": "https://你的通知地址.com/notify", // 支付结果通知地址
              };

              try {
                // 调用支付功能
                var result = await YouCanPay.pay(order);
                print("支付结果: $result");

                if (result["status"] == "success") {
                  // 支付成功处理逻辑
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text("支付成功")),
                  );
                } else {
                  // 支付失败处理逻辑
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text("支付失败: ${result["msg"]}")),
                  );
                }
              } catch (e) {
                // 捕获异常并处理
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text("支付异常: $e")),
                );
              }
            },
            child: Text('支付'),
          ),
        ),
      ),
    );
  }
}

注意事项

  1. 安全性:不要在客户端代码中硬编码敏感信息,如AppID和PrivateKey。考虑使用安全存储方式,如Flutter的KeystoreKeychain服务。
  2. 支付回调:确保你的通知地址能够正确处理支付结果通知,以便更新订单状态。
  3. 错误处理:在实际应用中,应该添加更详细的错误处理逻辑,以应对各种可能的异常情况。

以上代码提供了一个基本的框架,你可以根据实际需求进行扩展和修改。详细的使用说明和更多功能请参考youcan_pay插件的官方文档。

回到顶部