Преглед изворни кода

Stripe的支付Service封装以及路由相关配置

liukai пре 2 недеља
родитељ
комит
111e7b2481

+ 0 - 4
app/lib/main.dart

@@ -41,10 +41,6 @@ void main() async {
   //交给初始化构造器去统一初始化
   await AppInitializer.initializeRunalone();
 
-  // Stripe 公钥
-  // Stripe.publishableKey = 'pk_test_51RMmxaRpg7SPAcNndAqMUMEOkRFsY5mL0JqJmdunL3vspxrYsGjGARQddaVu3ZQVEy1e1WTF8yalt0cYZCY8sK9R0005VIg5mC';
-  // await Stripe.instance.applySettings();
-
   //组件路由的注入
   ComponentServiceManager()
     ..addServiceProvider(mainServiceProvider)

+ 6 - 20
packages/cpt_form/lib/modules/apply/vm/apply_view_model.dart

@@ -5,11 +5,13 @@ import 'package:domain/entity/form_content_entity.dart';
 import 'package:domain/entity/form_list_entity.dart';
 import 'package:domain/repository/form_repository.dart';
 import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:plugin_platform/platform_export.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/picker/date_picker_util.dart';
 import '../../form/form_page.dart';
@@ -170,26 +172,10 @@ class ApplyViewModel extends _$ApplyViewModel with DioCancelableMixin {
     // }
 
     //TODO 测试Stripe支付
-    // Stripe.instance.initPaymentSheet(paymentSheetParameters: paymentSheetParameters)
-
-    // 使用 Stripe 收集支付信息
-    // final paymentMethod = await Stripe.instance.createPaymentMethod( params: PaymentMethodParams.card(paymentMethodData: PaymentMethodData.card()));
-
-    PaymentIntent paymentIntentResult = await Stripe.instance.confirmPayment(
-      paymentIntentClientSecret: 'pi_3RNlYBRpg7SPAcNn1CwGxP7e',
-      data: PaymentMethodParams.card(
-        paymentMethodData: PaymentMethodData(
-          billingDetails: BillingDetails(
-            email: 'liukai2530533@163.com', // 用户邮箱(可选)
-          ),
-        ),
-      ),
-    );
+    // 测试卡号
+    // 4242 4242 4242 4242 – Visa (无需 3D)
+    // 4000 0025 0000 3155 – 需要 3D Secure 验证
+    ComponentServiceManager().paymentService.executePayment(orderId: "123456");
 
-    if (paymentIntentResult.status == PaymentIntentsStatus.Succeeded) {
-      ToastEngine.show('Payment successful!');
-    } else {
-      NotifyEngine.showError('Payment failed: ${paymentIntentResult.status}');
-    }
   }
 }

+ 1 - 1
packages/cpt_payment/lib/modules/choose_card/choose_card_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'choose_card_view_model.dart';
 // **************************************************************************
 
 String _$chooseCardViewModelHash() =>
-    r'695dfc67ae41a495d3df9ee35782c4dc4e881154';
+    r'91730dc6c7e7eff35f79d336db212d6001acfbfc';
 
 /// See also [ChooseCardViewModel].
 @ProviderFor(ChooseCardViewModel)

+ 1 - 1
packages/cpt_payment/lib/modules/payment/manage/manage_view_model.g.dart

@@ -6,7 +6,7 @@ part of 'manage_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$manageViewModelHash() => r'f4c5c44517f9bd9640d429bf8f95209aae685b8a';
+String _$manageViewModelHash() => r'b09fe6224f9fcff8d9fad1722f538895f55747e6';
 
 /// See also [ManageViewModel].
 @ProviderFor(ManageViewModel)

+ 1 - 1
packages/cpt_payment/lib/modules/payment/payment/payment_list_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'payment_list_view_model.dart';
 // **************************************************************************
 
 String _$paymentListViewModelHash() =>
-    r'640d7c8a8415a9987bb43e592076c0ebc70c0f30';
+    r'aac4515525c2ec4c013bb07ad3da281258cef311';
 
 /// See also [PaymentListViewModel].
 @ProviderFor(PaymentListViewModel)

+ 109 - 0
packages/cpt_payment/lib/provider/stripe_service.dart

@@ -0,0 +1,109 @@
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:shared/utils/log_utils.dart';
+
+//定义一个top-level(全局)变量,页面引入该文件后可以直接使用
+var stripeService = StripeService();
+
+class StripeService {
+
+  StripeService._internal();
+
+  //保存单例
+  static final StripeService _singleton = StripeService._internal();
+
+  //工厂构造函数
+  factory StripeService() => _singleton;
+
+
+  bool _isInitialized = false;
+
+  //初始化 Stripe
+  Future<void> _ensureInitialized() async {
+    if (_isInitialized) return;
+
+    Stripe.publishableKey = 'pk_test_51RMmxaRpg7SPAcNndAqMUMEOkRFsY5mL0JqJmdunL3vspxrYsGjGARQddaVu3ZQVEy1e1WTF8yalt0cYZCY8sK9R0005VIg5mC';
+    await Stripe.instance.applySettings();
+
+    Log.d("Stripe 初始化完成");
+    _isInitialized = true;
+  }
+
+  ///执行支付
+  Future<bool> executePayment({
+    required String orderId,
+  }) async {
+    try {
+      await _ensureInitialized();
+
+      // 实际开发中应从服务端获取 clientSecret
+      final clientSecret = await _fetchPaymentIntent(orderId);
+
+      await _initializePaymentSheet(clientSecret);
+      await Stripe.instance.presentPaymentSheet();
+      Log.d("presentPaymentSheet 关闭,用户操作完成 !");
+      return await _verifyPaymentResult(clientSecret);
+    } on StripeException catch (e) {
+      _handleStripeError(e);
+      return false;
+    } catch (e) {
+      _handleGenericError(e);
+      return false;
+    }
+  }
+
+  ///调用网络请求
+  Future<String> _fetchPaymentIntent(String orderId) async {
+    // 实际开发中调用后端接口获取
+    return "pi_3ROERGRpg7SPAcNn0sPDWCQI_secret_EZPly9t0IbKqaKA2CQwkUNIjd";
+  }
+
+  Future<void> _initializePaymentSheet(String clientSecret) async {
+    await Stripe.instance.initPaymentSheet(
+      paymentSheetParameters: SetupPaymentSheetParameters(
+        customFlow: false,
+        paymentIntentClientSecret: clientSecret,
+        merchantDisplayName: 'Your App Demo',
+        style: ThemeMode.light,
+        allowsDelayedPaymentMethods: false,
+      ),
+    );
+  }
+
+  Future<bool> _verifyPaymentResult(String clientSecret) async {
+    final paymentIntent = await Stripe.instance.retrievePaymentIntent(clientSecret);
+
+    switch (paymentIntent.status) {
+      case PaymentIntentsStatus.Succeeded:
+        NotifyEngine.showSuccess('支付成功');
+        return true;
+      case PaymentIntentsStatus.RequiresPaymentMethod:
+        NotifyEngine.showFailure('支付方式无效');
+        return false;
+      case PaymentIntentsStatus.Processing:
+        return await _handleProcessingPayment(clientSecret);
+      default:
+        return false;
+    }
+  }
+
+  Future<bool> _handleProcessingPayment(String clientSecret) async {
+    // 处理需要等待的支付状态
+    await Future.delayed(const Duration(seconds: 2));
+    final updatedIntent = await Stripe.instance.retrievePaymentIntent(clientSecret);
+
+    return updatedIntent.status == PaymentIntentsStatus.Succeeded;
+  }
+
+  void _handleStripeError(StripeException e) {
+    final errorMessage = e.error.localizedMessage ?? '支付失败';
+    Log.e('Stripe Error: ${e.error.code} - $errorMessage');
+    NotifyEngine.showError(errorMessage);
+  }
+
+  void _handleGenericError(dynamic e) {
+    Log.e('System Error: $e');
+    NotifyEngine.showError('支付系统异常');
+  }
+}

+ 6 - 0
packages/cpt_payment/lib/router/component/payment_component_service.dart

@@ -3,6 +3,7 @@
  */
 import 'package:cpt_payment/modules/add_card/add_card_page.dart';
 import 'package:cpt_payment/modules/choose_card/choose_card_page.dart';
+import 'package:cpt_payment/provider/stripe_service.dart';
 import 'package:router/componentRouter/payment_service.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -31,4 +32,9 @@ class PaymentComponentService extends PaymentService {
   void startChooseCardPage() {
     ChooseCardPage.startInstance();
   }
+
+  @override
+  Future<bool> executePayment({required String orderId}) {
+    return stripeService.executePayment(orderId: orderId);
+  }
 }

+ 0 - 1
packages/cs_router/lib/componentRouter/form_service.dart

@@ -4,5 +4,4 @@
 abstract class FormService {
 
   void startFormPage();
-
 }

+ 3 - 0
packages/cs_router/lib/componentRouter/payment_service.dart

@@ -9,4 +9,7 @@ abstract class PaymentService {
 
   void startAddCardPage();
 
+  Future<bool> executePayment({
+    required String orderId,
+  });
 }