From 69556c0b047acb9fffac0a73b492e7eb3c36e778 Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Tue, 23 Sep 2025 12:08:20 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/services/pay_service.dart | 175 +++++++++ .../payment/bindings/payment_binding.dart | 9 + .../controllers/payment_controller.dart | 85 ++++ lib/modules/payment/views/payment_view.dart | 365 ++++++++++++++++++ lib/modules/settings/views/settings_view.dart | 23 ++ lib/routes/app_pages.dart | 9 + lib/routes/app_routes.dart | 3 + 7 files changed, 669 insertions(+) create mode 100644 lib/data/services/pay_service.dart create mode 100644 lib/modules/payment/bindings/payment_binding.dart create mode 100644 lib/modules/payment/controllers/payment_controller.dart create mode 100644 lib/modules/payment/views/payment_view.dart diff --git a/lib/data/services/pay_service.dart b/lib/data/services/pay_service.dart new file mode 100644 index 000000000..82b241e04 --- /dev/null +++ b/lib/data/services/pay_service.dart @@ -0,0 +1,175 @@ +import 'package:get/get.dart'; +import 'package:fluwx/fluwx.dart'; +import '../../modules/login/controllers/weixinLogin.dart'; + +/// 支付结果回调 +typedef PaymentResultCallback = void Function(bool success, String? message); + +/// 支付服务 +class PayService extends GetxService { + late FlWX _flwx; + + @override + void onInit() { + super.onInit(); + _flwx = FlWX(); + } + + /// 微信支付 + /// + /// [paymentData] 支付参数,包含以下字段: + /// - appId: 应用ID + /// - partnerId: 商户号 + /// - prepayId: 预支付交易会话ID + /// - packageValue: 扩展字段,固定值"Sign=WXPay" + /// - nonceStr: 随机字符串 + /// - timestamp: 时间戳 + /// - sign: 签名 + /// + /// [onResult] 支付结果回调 + Future wechatPay({ + required Map paymentData, + PaymentResultCallback? onResult, + }) async { + try { + // 检查微信是否安装 + if (!await _flwx.isInstalled) { + onResult?.call(false, '微信未安装'); + return false; + } + + // 将支付数据转换为Payment对象 + final payment = paymentData.toPayment(); + if (payment == null) { + onResult?.call(false, '支付参数格式错误'); + return false; + } + + // 调用微信支付 + final result = await _flwx.pay( + payment, + onSuccess: () { + onResult?.call(true, '支付成功'); + }, + onResponse: (response) { + if (response.errCode == 0) { + onResult?.call(true, '支付成功'); + } else if (response.errCode == -2) { + onResult?.call(false, '用户取消支付'); + } else { + onResult?.call(false, '支付失败: ${response.errStr}'); + } + }, + ); + + return result; + } catch (e) { + onResult?.call(false, '支付异常: $e'); + return false; + } + } + + /// 创建微信支付订单 + /// + /// [orderInfo] 订单信息,包含: + /// - orderId: 订单ID + /// - amount: 支付金额(分) + /// - description: 商品描述 + /// - userId: 用户ID + /// + /// 返回支付参数,用于调用 [wechatPay] 方法 + Future?> createWechatPayOrder({ + required String orderId, + required int amount, + required String description, + String? userId, + }) async { + try { + // TODO: 这里需要调用后端API创建支付订单 + // 示例代码,实际需要根据后端接口调整 + + // final response = await Api.createPayOrder({ + // 'orderId': orderId, + // 'amount': amount, + // 'description': description, + // 'userId': userId, + // 'payType': 'wechat', + // }); + + // if (response['success'] == true) { + // return response['data'] as Map; + // } + + // 临时返回示例数据结构,实际使用时需要删除 + return { + 'appId': 'your_app_id', + 'partnerId': 'your_partner_id', + 'prepayId': 'prepay_id_from_server', + 'packageValue': 'Sign=WXPay', + 'nonceStr': 'random_string', + 'timestamp': DateTime.now().millisecondsSinceEpoch ~/ 1000, + 'sign': 'signature_from_server', + }; + } catch (e) { + print('创建支付订单失败: $e'); + return null; + } + } + + /// 查询支付结果 + /// + /// [orderId] 订单ID + /// 返回支付状态:success, failed, pending + Future queryPaymentStatus(String orderId) async { + try { + // TODO: 调用后端API查询支付状态 + // final response = await Api.queryPaymentStatus({'orderId': orderId}); + // return response['status'] as String?; + + // 临时返回,实际使用时需要删除 + return 'pending'; + } catch (e) { + print('查询支付状态失败: $e'); + return null; + } + } + + /// 完整的支付流程 + /// + /// [orderId] 订单ID + /// [amount] 支付金额(分) + /// [description] 商品描述 + /// [userId] 用户ID + /// [onResult] 支付结果回调 + Future processWechatPayment({ + required String orderId, + required int amount, + required String description, + String? userId, + PaymentResultCallback? onResult, + }) async { + try { + // 1. 创建支付订单 + final paymentData = await createWechatPayOrder( + orderId: orderId, + amount: amount, + description: description, + userId: userId, + ); + + if (paymentData == null) { + onResult?.call(false, '创建支付订单失败'); + return false; + } + + // 2. 调用微信支付 + return await wechatPay( + paymentData: paymentData, + onResult: onResult, + ); + } catch (e) { + onResult?.call(false, '支付流程异常: $e'); + return false; + } + } +} \ No newline at end of file diff --git a/lib/modules/payment/bindings/payment_binding.dart b/lib/modules/payment/bindings/payment_binding.dart new file mode 100644 index 000000000..fb38d6f9d --- /dev/null +++ b/lib/modules/payment/bindings/payment_binding.dart @@ -0,0 +1,9 @@ +import 'package:get/get.dart'; +import '../controllers/payment_controller.dart'; + +class PaymentBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => PaymentController()); + } +} \ No newline at end of file diff --git a/lib/modules/payment/controllers/payment_controller.dart b/lib/modules/payment/controllers/payment_controller.dart new file mode 100644 index 000000000..f7b4178ff --- /dev/null +++ b/lib/modules/payment/controllers/payment_controller.dart @@ -0,0 +1,85 @@ +import 'package:get/get.dart'; +import '../../../data/services/pay_service.dart'; + +class PaymentController extends GetxController { + final PayService _payService = Get.find(); + + // 支付状态 + final RxBool isLoading = false.obs; + final RxString paymentStatus = ''.obs; + final RxString errorMessage = ''.obs; + + // 测试订单信息 + final RxString testOrderId = ''.obs; + final RxDouble testAmount = 0.01.obs; // 测试金额 1分钱 + + @override + void onInit() { + super.onInit(); + // 生成测试订单ID + testOrderId.value = 'test_${DateTime.now().millisecondsSinceEpoch}'; + } + + /// 测试微信支付 + Future testWechatPayment() async { + try { + isLoading.value = true; + paymentStatus.value = '正在发起支付...'; + errorMessage.value = ''; + + // 调用支付服务,使用回调处理结果 + final launched = await _payService.processWechatPayment( + orderId: testOrderId.value, + amount: (testAmount.value * 100).toInt(), // 转换为分 + description: '微信支付测试', + onResult: (success, message) { + // 支付结果回调 + isLoading.value = false; + + if (success) { + paymentStatus.value = '支付成功!'; + errorMessage.value = ''; + Get.snackbar( + '支付成功', + message ?? '微信支付测试完成', + snackPosition: SnackPosition.TOP, + ); + } else { + paymentStatus.value = '支付失败'; + errorMessage.value = message ?? '未知错误'; + Get.snackbar( + '支付失败', + message ?? '未知错误', + snackPosition: SnackPosition.TOP, + ); + } + }, + ); + + if (!launched) { + // 如果支付没有成功启动 + isLoading.value = false; + paymentStatus.value = '支付启动失败'; + errorMessage.value = '无法启动微信支付'; + Get.snackbar('支付启动失败', '无法启动微信支付'); + } + } catch (e) { + isLoading.value = false; + paymentStatus.value = '支付异常'; + errorMessage.value = e.toString(); + Get.snackbar('支付异常', e.toString()); + } + } + + /// 重置状态 + void resetStatus() { + paymentStatus.value = ''; + errorMessage.value = ''; + testOrderId.value = 'test_${DateTime.now().millisecondsSinceEpoch}'; + } + + /// 更新测试金额 + void updateTestAmount(double amount) { + testAmount.value = amount; + } +} diff --git a/lib/modules/payment/views/payment_view.dart b/lib/modules/payment/views/payment_view.dart new file mode 100644 index 000000000..04a1a7480 --- /dev/null +++ b/lib/modules/payment/views/payment_view.dart @@ -0,0 +1,365 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import '../controllers/payment_controller.dart'; + +class PaymentView extends GetView { + const PaymentView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final isDarkMode = Theme.of(context).brightness == Brightness.dark; + + return Scaffold( + backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], + appBar: AppBar( + backgroundColor: isDarkMode ? Colors.black : Colors.white, + elevation: 0.5, + title: Text( + '微信支付测试', + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + centerTitle: true, + leading: IconButton( + icon: Icon( + Icons.arrow_back_ios, + color: isDarkMode ? Colors.white : Colors.black, + ), + onPressed: () => Get.back(), + ), + ), + body: SingleChildScrollView( + padding: EdgeInsets.all(16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildTestInfoCard(isDarkMode), + SizedBox(height: 20.h), + _buildAmountSelector(isDarkMode), + SizedBox(height: 20.h), + _buildPaymentButton(isDarkMode), + SizedBox(height: 20.h), + _buildStatusCard(isDarkMode), + SizedBox(height: 20.h), + _buildInstructions(isDarkMode), + ], + ), + ), + ); + } + + /// 测试信息卡片 + Widget _buildTestInfoCard(bool isDarkMode) { + return Container( + padding: EdgeInsets.all(16.w), + decoration: BoxDecoration( + color: isDarkMode ? Colors.grey[900] : Colors.white, + borderRadius: BorderRadius.circular(12.r), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '测试订单信息', + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + SizedBox(height: 12.h), + Obx(() => _buildInfoRow('订单ID', controller.testOrderId.value, isDarkMode)), + SizedBox(height: 8.h), + _buildInfoRow('商品描述', '微信支付测试', isDarkMode), + SizedBox(height: 8.h), + Obx(() => _buildInfoRow('支付金额', '¥${controller.testAmount.value.toStringAsFixed(2)}', isDarkMode)), + ], + ), + ); + } + + /// 信息行 + Widget _buildInfoRow(String label, String value, bool isDarkMode) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 80.w, + child: Text( + '$label:', + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.grey[400] : Colors.grey[600], + ), + ), + ), + Expanded( + child: Text( + value, + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + ), + ], + ); + } + + /// 金额选择器 + Widget _buildAmountSelector(bool isDarkMode) { + final amounts = [0.01, 0.10, 1.00, 10.00]; + + return Container( + padding: EdgeInsets.all(16.w), + decoration: BoxDecoration( + color: isDarkMode ? Colors.grey[900] : Colors.white, + borderRadius: BorderRadius.circular(12.r), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '选择测试金额', + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + SizedBox(height: 12.h), + Wrap( + spacing: 12.w, + runSpacing: 8.h, + children: amounts.map((amount) { + return Obx(() => GestureDetector( + onTap: () => controller.updateTestAmount(amount), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), + decoration: BoxDecoration( + color: controller.testAmount.value == amount + ? Colors.blue[600] + : (isDarkMode ? Colors.grey[800] : Colors.grey[200]), + borderRadius: BorderRadius.circular(20.r), + ), + child: Text( + '¥${amount.toStringAsFixed(2)}', + style: TextStyle( + fontSize: 14.sp, + color: controller.testAmount.value == amount + ? Colors.white + : (isDarkMode ? Colors.white : Colors.black), + ), + ), + ), + )); + }).toList(), + ), + ], + ), + ); + } + + /// 支付按钮 + Widget _buildPaymentButton(bool isDarkMode) { + return Obx(() => SizedBox( + width: double.infinity, + height: 50.h, + child: ElevatedButton( + onPressed: controller.isLoading.value ? null : controller.testWechatPayment, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green[600], + foregroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12.r), + ), + elevation: 2, + ), + child: controller.isLoading.value + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 20.w, + height: 20.w, + child: const CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation(Colors.white), + ), + ), + SizedBox(width: 12.w), + const Text('处理中...'), + ], + ) + : Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.payment, size: 20.w), + SizedBox(width: 8.w), + Text( + '发起微信支付', + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + )); + } + + /// 状态卡片 + Widget _buildStatusCard(bool isDarkMode) { + return Obx(() { + if (controller.paymentStatus.value.isEmpty) { + return const SizedBox.shrink(); + } + + final isError = controller.errorMessage.value.isNotEmpty; + + return Container( + padding: EdgeInsets.all(16.w), + decoration: BoxDecoration( + color: isError + ? (isDarkMode ? Colors.red[900] : Colors.red[50]) + : (isDarkMode ? Colors.green[900] : Colors.green[50]), + borderRadius: BorderRadius.circular(12.r), + border: Border.all( + color: isError ? Colors.red[300]! : Colors.green[300]!, + width: 1, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + isError ? Icons.error : Icons.check_circle, + color: isError ? Colors.red[600] : Colors.green[600], + size: 20.w, + ), + SizedBox(width: 8.w), + Text( + '支付状态', + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w600, + color: isError ? Colors.red[600] : Colors.green[600], + ), + ), + ], + ), + SizedBox(height: 8.h), + Text( + controller.paymentStatus.value, + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + if (controller.errorMessage.value.isNotEmpty) ...[ + SizedBox(height: 8.h), + Text( + '错误信息: ${controller.errorMessage.value}', + style: TextStyle( + fontSize: 12.sp, + color: Colors.red[600], + ), + ), + ], + SizedBox(height: 12.h), + SizedBox( + width: double.infinity, + child: OutlinedButton( + onPressed: controller.resetStatus, + style: OutlinedButton.styleFrom( + side: BorderSide( + color: isError ? Colors.red[600]! : Colors.green[600]!, + ), + ), + child: Text( + '重新测试', + style: TextStyle( + color: isError ? Colors.red[600] : Colors.green[600], + ), + ), + ), + ), + ], + ), + ); + }); + } + + /// 使用说明 + Widget _buildInstructions(bool isDarkMode) { + return Container( + padding: EdgeInsets.all(16.w), + decoration: BoxDecoration( + color: isDarkMode ? Colors.grey[900] : Colors.blue[50], + borderRadius: BorderRadius.circular(12.r), + border: Border.all( + color: Colors.blue[200]!, + width: 1, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.info_outline, + color: Colors.blue[600], + size: 20.w, + ), + SizedBox(width: 8.w), + Text( + '使用说明', + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w600, + color: Colors.blue[600], + ), + ), + ], + ), + SizedBox(height: 12.h), + Text( + '1. 选择测试金额(建议使用0.01元进行测试)\n' + '2. 点击"发起微信支付"按钮\n' + '3. 系统将调用微信支付SDK\n' + '4. 在微信中完成支付流程\n' + '5. 返回应用查看支付结果\n\n' + '注意:这是测试环境,实际不会产生真实扣费', + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.grey[300] : Colors.grey[700], + height: 1.5, + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/modules/settings/views/settings_view.dart b/lib/modules/settings/views/settings_view.dart index d36801018..912b6644e 100644 --- a/lib/modules/settings/views/settings_view.dart +++ b/lib/modules/settings/views/settings_view.dart @@ -516,6 +516,29 @@ class SettingsView extends GetView { // : Colors.grey[200]), // //BLE测试 + // 支付测试 + _buildSimpleNavigationSetting( + title: '支付测试', + subtitle: '测试微信支付功能', + icon: Icons.payment, + iconBgColor: isDarkMode + ? Colors.green[900]!.withOpacity(0.3) + : Colors.green[100]!, + iconColor: + isDarkMode ? Colors.green[300]! : Colors.green[600]!, + titleColor: isDarkMode ? Colors.white : null, + subtitleColor: isDarkMode ? Colors.white70 : null, + onTap: () { + Get.toNamed(Routes.payment); + }, + isDarkMode: isDarkMode, + ), + Divider( + height: 1, + color: isDarkMode + ? Colors.white.withOpacity(0.1) + : Colors.grey[200]), + Obx(() => controller.showDebugInfo.value ? _buildSimpleNavigationSetting( title: 'opus解码测试', diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart index 7b8c533f2..6e1082812 100644 --- a/lib/routes/app_pages.dart +++ b/lib/routes/app_pages.dart @@ -63,6 +63,8 @@ import '../modules/music/views/music_playlist_view.dart'; import '../modules/music/bindings/music_playlist_binding.dart'; import '../modules/FTFTranslation/bindings/FTFTranslation_binding.dart'; import '../modules/FTFTranslation/views/FTFTranslation_view.dart'; +import '../modules/payment/bindings/payment_binding.dart'; +import '../modules/payment/views/payment_view.dart'; abstract class AppPages { static final pages = [ @@ -288,5 +290,12 @@ abstract class AppPages { page: () => const QqmusicPlaylistView(), binding: QQMusicPlaylistBinding(), ), + GetPage( + name: Routes.payment, + page: () => const PaymentView(), + binding: PaymentBinding(), + transition: Transition.rightToLeft, + transitionDuration: Duration(milliseconds: 250), + ), ]; } diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 3a4fc6973..f2e78cbf6 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -63,4 +63,7 @@ abstract class Routes { static const ble = '/ble'; // ble设备管理 static const qqmusic = '/qqmusic'; + + // 支付相关 + static const payment = '/payment'; // 支付测试页面 } From 872c7429ffb86c9a82ba38f8c575cfabcffe5ca1 Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Tue, 23 Sep 2025 12:12:24 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=AF=BC=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=AF=BC=E8=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent_service/Sources/agent_service/AgentServiceImpl.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift index 6b2415e07..5f8eedde6 100644 --- a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift +++ b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift @@ -986,7 +986,7 @@ private func jsonToString(_ json: [String: Any]) -> String? { // 处理导航卡片 private func processNavigationCard(_ cardNavigation: [String: Any]) -> Bool { let start = cardNavigation["start"] as? String ?? "" - let destination = cardNavigation["end"] as? String ?? "" + let destination = cardNavigation["destination"] as? String ?? "" let endlatitude = cardNavigation["endlatitude"] as? String ?? "" let endlongitude = cardNavigation["endlongitude"] as? String ?? "" let mode = cardNavigation["mode"] as? String ?? "driving" From 431007544842304d844ff367ef29163bd0b0f70a Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Thu, 25 Sep 2025 10:50:50 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/bindings/initial_binding.dart | 4 + lib/data/services/network/api.dart | 9 ++ lib/data/services/pay_service.dart | 120 +++++++++++------- .../login/controllers/weixinLogin.dart | 9 ++ 4 files changed, 93 insertions(+), 49 deletions(-) diff --git a/lib/core/bindings/initial_binding.dart b/lib/core/bindings/initial_binding.dart index 00c74738a..7968424ff 100644 --- a/lib/core/bindings/initial_binding.dart +++ b/lib/core/bindings/initial_binding.dart @@ -1,3 +1,4 @@ +import 'package:voitrans/data/services/pay_service.dart'; import 'package:voitrans/data/services/qq_music.dart'; import '../../../data/services/user_portrait.dart'; @@ -87,6 +88,9 @@ class InitialBinding extends Bindings { // OTA检查服务 Get.lazyPut(() => OtaCheckService(), fenix: true); + // 支付服务 + Get.lazyPut(() => PayService(), fenix: true); + // 杰理蓝牙服务 // // 语言管理器(需要最先初始化) diff --git a/lib/data/services/network/api.dart b/lib/data/services/network/api.dart index 499c93939..8e36e726c 100644 --- a/lib/data/services/network/api.dart +++ b/lib/data/services/network/api.dart @@ -171,4 +171,13 @@ class Api { params: params, ); } + + //创建支付订单 + static paycreateorder([params]) { + return DioManager().request( + NWMethod.post, + '/api/home/pay_createorder', + params: params, + ); + } } diff --git a/lib/data/services/pay_service.dart b/lib/data/services/pay_service.dart index 82b241e04..1a398dc03 100644 --- a/lib/data/services/pay_service.dart +++ b/lib/data/services/pay_service.dart @@ -1,9 +1,9 @@ import 'package:get/get.dart'; -import 'package:fluwx/fluwx.dart'; +import 'package:voitrans/data/services/network/api.dart'; + import '../../modules/login/controllers/weixinLogin.dart'; -/// 支付结果回调 -typedef PaymentResultCallback = void Function(bool success, String? message); +typedef PaymentResultCallback = void Function(bool success, String message); /// 支付服务 class PayService extends GetxService { @@ -12,11 +12,20 @@ class PayService extends GetxService { @override void onInit() { super.onInit(); + //微信 + FlWX().register( + appSecret: '9ceb39df312b3ba95a229b2aa0d15496', + appId: 'wx4b5ec8957ad5e425', + partnerId: '1719983673', + universalLink: 'https://voitrans.net/app/', + params: FlWXCallbackParams(onHttp: (url) async { + return ''; + })); _flwx = FlWX(); } /// 微信支付 - /// + /// /// [paymentData] 支付参数,包含以下字段: /// - appId: 应用ID /// - partnerId: 商户号 @@ -25,7 +34,7 @@ class PayService extends GetxService { /// - nonceStr: 随机字符串 /// - timestamp: 时间戳 /// - sign: 签名 - /// + /// /// [onResult] 支付结果回调 Future wechatPay({ required Map paymentData, @@ -70,54 +79,65 @@ class PayService extends GetxService { } /// 创建微信支付订单 - /// - /// [orderInfo] 订单信息,包含: - /// - orderId: 订单ID - /// - amount: 支付金额(分) - /// - description: 商品描述 - /// - userId: 用户ID - /// + /// + /// [productId] 商品ID + /// [productName] 商品名称 + /// [productDesc] 商品描述 + /// [amount] 支付金额(分) + /// [paymentMethod] 支付方式(1=微信支付) + /// [clientIp] 客户端IP(可选) + /// [notifyUrl] 通知URL(可选) + /// [extraData] 扩展数据(可选) + /// /// 返回支付参数,用于调用 [wechatPay] 方法 Future?> createWechatPayOrder({ - required String orderId, + required String productId, + required String productName, + String? productDesc, required int amount, - required String description, - String? userId, + int paymentMethod = 4, // 1表示微信支付 + String? clientIp, + String? notifyUrl, + String? extraData, }) async { try { - // TODO: 这里需要调用后端API创建支付订单 - // 示例代码,实际需要根据后端接口调整 - - // final response = await Api.createPayOrder({ - // 'orderId': orderId, - // 'amount': amount, - // 'description': description, - // 'userId': userId, - // 'payType': 'wechat', - // }); - - // if (response['success'] == true) { - // return response['data'] as Map; - // } - - // 临时返回示例数据结构,实际使用时需要删除 - return { - 'appId': 'your_app_id', - 'partnerId': 'your_partner_id', - 'prepayId': 'prepay_id_from_server', - 'packageValue': 'Sign=WXPay', - 'nonceStr': 'random_string', - 'timestamp': DateTime.now().millisecondsSinceEpoch ~/ 1000, - 'sign': 'signature_from_server', - }; + // 调用后端API创建支付订单 + final response = await Api.paycreateorder({ + 'product_id': productId, + 'product_name': productName, + 'product_desc': productDesc ?? '', + 'amount': amount, + 'payment_method': paymentMethod, + 'client_ip': clientIp ?? '', + 'notify_url': notifyUrl ?? '', + 'extra_data': extraData ?? '', + }); + print('创建支付订单: $response'); + // 检查响应是否成功 + if (response != null) { + final pay_params = response["pay_params"] as Map; + // 返回微信支付所需的参数 + return { + 'appId': pay_params['appid'], + 'partnerId': pay_params['partnerid'], + 'prepayId': pay_params['prepayid'], + 'packageValue': pay_params['package'] ?? 'Sign=WXPay', + 'nonceStr': pay_params['noncestr'], + 'timestamp': pay_params['timestamp'], + 'sign': pay_params['sign'], + }; + } else { + print('创建支付订单失败: ${response?['message'] ?? '未知错误'}'); + return null; + } } catch (e) { - print('创建支付订单失败: $e'); + print('创建支付订单异常: $e'); return null; } } /// 查询支付结果 - /// + /// /// [orderId] 订单ID /// 返回支付状态:success, failed, pending Future queryPaymentStatus(String orderId) async { @@ -125,7 +145,7 @@ class PayService extends GetxService { // TODO: 调用后端API查询支付状态 // final response = await Api.queryPaymentStatus({'orderId': orderId}); // return response['status'] as String?; - + // 临时返回,实际使用时需要删除 return 'pending'; } catch (e) { @@ -135,7 +155,7 @@ class PayService extends GetxService { } /// 完整的支付流程 - /// + /// /// [orderId] 订单ID /// [amount] 支付金额(分) /// [description] 商品描述 @@ -151,10 +171,12 @@ class PayService extends GetxService { try { // 1. 创建支付订单 final paymentData = await createWechatPayOrder( - orderId: orderId, - amount: amount, - description: description, - userId: userId, + productId: 'prod_001', + productName: '会员充值', + productDesc: '1个月会员服务', + amount: 1, // 29.99元,单位:分 + paymentMethod: 4, // 微信支付 + notifyUrl: 'https://api.ideapsound.com/api/home/pay_wechatnotify', ); if (paymentData == null) { @@ -172,4 +194,4 @@ class PayService extends GetxService { return false; } } -} \ No newline at end of file +} diff --git a/lib/modules/login/controllers/weixinLogin.dart b/lib/modules/login/controllers/weixinLogin.dart index 38819a60a..89345511e 100644 --- a/lib/modules/login/controllers/weixinLogin.dart +++ b/lib/modules/login/controllers/weixinLogin.dart @@ -73,6 +73,11 @@ class FlWX { /// 获取当前设置的 appSecret String? get appSecret => _appSecret; + String? _partnerId; + + /// 获取当前设置的 partnerId + String? get partnerId => _partnerId; + String _appName = ''; String token = ''; String code = ''; @@ -109,6 +114,9 @@ class FlWX { /// 用于获取用户信息 String? appSecret, + /// 商户号 + String? partnerId, + /// app名称(用于分享时使用) String appName = '', @@ -123,6 +131,7 @@ class FlWX { _isRegister = true; _appId = appId; _appSecret = appSecret; + _partnerId = partnerId; _appName = appName; _shareThumbnail = shareThumbnail; _params = params;