当前位置:   article > 正文

【原创 附源码】Flutter集成Apple支付详细流程(附源码)

【原创 附源码】Flutter集成Apple支付详细流程(附源码)

最近有时间,特意整理了一下之前使用过的Flutter平台的海外支付,附源码及demo可供参考

这篇文章只记录Apple支付的详细流程,其他相关Flutter文章链接如下:

【原创 附源码】Flutter集成谷歌支付详细流程(附源码)

【原创 附源码】Flutter安卓及iOS海外登录--Google登录最详细流程

【原创 附源码】Flutter安卓及iOS海外登录--Tiktok登录最详细流程

【原创 附源码】Flutter安卓及iOS海外登录--Facebook登录最详细流程

【原创 附源码】Flutter安卓及iOS海外登录--Apple登录最详细流程

让我们开始吧

一 Apple开发者平台添加内购商品

首先使用苹果开发者账户登录苹果开发者平台

Sign In - Apple

点击【App】 

 

添加新的苹果内购商品

 

添加的时候页面的指引很清晰,就不赘述了,苹果添加内购商品比较简单,加完就可以了。

然后去创建沙盒账户用来做苹果支付测试,回到首页,点击【用户和访问】

点击沙盒,然后添加一个苹果测试账户,这个账户可以是个假的邮箱,不需要是正式的Apple id,比如你可以设置为88888@qq.com类似之类的账户

 

添加完点击创建即可

二 flutter 代码集成

使用到的第三方插件:

in_app_purchase: ^3.1.5

插件官网地址:in_app_purchase | Flutter package

将插件添加至yaml文件,然后执行flutter pub get

执行完了记得去IOS和安卓端分别执行pod install 和 gradle sync同步一下第三方插件

然后在项目中新建dart文件,命名为:BuyEngine.dart

然后将以下代码放入:

  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'package:in_app_purchase/in_app_purchase.dart';
  4. import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
  5. import 'package:in_app_purchase_android/in_app_purchase_android.dart';
  6. class BuyEngin{
  7. StreamSubscription<List<PurchaseDetails>> _subscription;
  8. InAppPurchase _inAppPurchase;
  9. List<ProductDetails> _products; //内购的商品对象集合
  10. //初始化购买组件
  11. void initializeInAppPurchase() {
  12. // 初始化in_app_purchase插件
  13. _inAppPurchase = InAppPurchase.instance;
  14. //监听购买的事件
  15. final Stream<List<PurchaseDetails>> purchaseUpdated = _inAppPurchase.purchaseStream;
  16. _subscription = purchaseUpdated.listen((purchaseDetailsList) {
  17. _listenToPurchaseUpdated(purchaseDetailsList);
  18. }, onDone: () {
  19. _subscription.cancel();
  20. }, onError: (error) {
  21. error.printError();
  22. print("购买失败了");
  23. });
  24. }
  25. void resumePurchase(){
  26. _inAppPurchase.restorePurchases();
  27. }
  28. /// 加载全部的商品
  29. void buyProduct(String productId) async {
  30. print("请求商品id " + productId);
  31. List<String> _outProducts = [productId];
  32. final bool available = await _inAppPurchase.isAvailable();
  33. if (!available) {
  34. // ToastUtil.showToast("无法连接到商店");
  35. print("无法连接到商店");
  36. return;
  37. }
  38. //开始购买
  39. // ToastUtil.showToast("连接成功-开始查询全部商品");
  40. print("连接成功-开始查询全部商品");
  41. List<String> _kIds = _outProducts;
  42. final ProductDetailsResponse response = await _inAppPurchase.queryProductDetails(_kIds.toSet());
  43. print("商品获取结果 " + response.productDetails.toString());
  44. if (response.notFoundIDs.isNotEmpty) {
  45. // ToastUtil.showToast("无法找到指定的商品");
  46. print("无法找到指定的商品");
  47. // ToastUtil.showToast("无法找到指定的商品 数量 " + response.productDetails.length.toString());
  48. return;
  49. }
  50. // 处理查询到的商品列表
  51. List<ProductDetails> products = response.productDetails;
  52. print("products ==== " + products.length.toString());
  53. if (products.isNotEmpty) {
  54. //赋值内购商品集合
  55. _products = products;
  56. }
  57. print("全部商品加载完成了,可以启动购买了,总共商品数量为:${products.length}");
  58. //先恢复可重复购买
  59. // await _inAppPurchase. ();
  60. startPurchase(productId);
  61. }
  62. // 调用此函数以启动购买过程
  63. void startPurchase(String productId) async {
  64. print("购买的商品id为" + productId);
  65. if (_products != null && _products.isNotEmpty) {
  66. // ToastUtil.showToast("准备开始启动购买流程");
  67. try {
  68. ProductDetails productDetails = _getProduct(productId);
  69. print("一切正常,开始购买,信息如下:title: ${productDetails.title} desc:${productDetails.description} "
  70. "price:${productDetails.price} currencyCode:${productDetails.currencyCode} currencySymbol:${productDetails.currencySymbol}");
  71. _inAppPurchase.buyConsumable(purchaseParam: PurchaseParam(productDetails: productDetails));
  72. } catch (e) {
  73. e.printError();
  74. print("购买失败了");
  75. }
  76. } else {
  77. print("当前没有商品无法调用购买逻辑");
  78. }
  79. }
  80. // 根据产品ID获取产品信息
  81. ProductDetails _getProduct(String productId) {
  82. return _products.firstWhere((product) => product.id == productId);
  83. }
  84. /// 内购的购买更新监听
  85. void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) async {
  86. for (PurchaseDetails purchase in purchaseDetailsList) {
  87. if (purchase.status == PurchaseStatus.pending) {
  88. // 等待支付完成
  89. _handlePending();
  90. } else if (purchase.status == PurchaseStatus.canceled) {
  91. // 取消支付
  92. _handleCancel(purchase);
  93. } else if (purchase.status == PurchaseStatus.error) {
  94. // 购买失败
  95. _handleError(purchase.error);
  96. } else if (purchase.status == PurchaseStatus.purchased || purchase.status == PurchaseStatus.restored) {
  97. // ToastUtil.showToast(DataConfig.getShowName("Pay_Success_Tip"));
  98. //完成购买, 到服务器验证
  99. if (Platform.isAndroid) {
  100. var googleDetail = purchase as GooglePlayPurchaseDetails;
  101. checkAndroidPayInfo(googleDetail);
  102. } else if (Platform.isIOS) {
  103. var appstoreDetail = purchase as AppStorePurchaseDetails;
  104. checkApplePayInfo(appstoreDetail);
  105. }
  106. }
  107. }
  108. }
  109. /// 购买失败
  110. void _handleError(IAPError iapError) {
  111. // ToastUtil.showToast("${DataConfig.getShowName("Purchase_Failed")}:${iapError?.code} message${iapError?.message}");
  112. }
  113. /// 等待支付
  114. void _handlePending() {
  115. print("等待支付");
  116. }
  117. /// 取消支付
  118. void _handleCancel(PurchaseDetails purchase) {
  119. _inAppPurchase.completePurchase(purchase);
  120. }
  121. /// Android支付成功的校验
  122. void checkAndroidPayInfo(GooglePlayPurchaseDetails googleDetail) async {
  123. _inAppPurchase.completePurchase(googleDetail);
  124. print("安卓支付交易ID为" + googleDetail.purchaseID);
  125. print("安卓支付验证收据为" + googleDetail.verificationData.serverVerificationData);
  126. }
  127. /// Apple支付成功的校验
  128. void checkApplePayInfo(AppStorePurchaseDetails appstoreDetail) async {
  129. _inAppPurchase.completePurchase(appstoreDetail);
  130. print("Apple支付交易ID为" + appstoreDetail.purchaseID);
  131. print("Apple支付验证收据为" + appstoreDetail.verificationData.serverVerificationData);
  132. }
  133. @override
  134. void onClose() {
  135. if (Platform.isIOS) {
  136. final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
  137. _inAppPurchase.getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
  138. iosPlatformAddition.setDelegate(null);
  139. }
  140. _subscription.cancel();
  141. }
  142. }

至此集成完毕,开始测试苹果支付

三 支付测试 

在调用苹果支付的地方提前初始化购买插件:

  1. BuyEngin _buyEngin = BuyEngin();
  2. _buyEngin.initializeInAppPurchase();

然后调用即可:

_buyEngin.buyProduct("应用内商品ID");

应用内商品ID就是你在APP Store Connect配置的应用内购买商品的product ID

如果一切正常,则会正常唤醒苹果支付(记得是在科学上网的环境下测试)

源码地址:GitHub - TheRuningAnt/FGTALogin: 使用Flutter 去集成海外平台第三方登录,包含Google、Tiktok、Facebook、Apple登录 

(注:直接调用该demo的苹果支付无法支付成功,因为该demo使用的bundle ID是测试ID,并未正式上线,但是功能是经过使用真实上线的bundle ID支付验证过的,如需使用该demo进行苹果支付测试,可将IOS工程下的bundlle ID替换为你自己的包名然后进行测试)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/124398?site
推荐阅读
相关标签
  

闽ICP备14008679号