xe_create_order_handler.dart
5.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import 'dart:async';
import 'dart:convert';
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/data/repositories/user_auth_repository.dart';
import 'package:appframe/services/dispatcher.dart';
import 'package:flutter/foundation.dart';
import 'package:fluwx/fluwx.dart';
class XeCreateOrderHandler extends MessageHandler {
late final Fluwx _fluwx;
late final UserAuthRepository _userAuthRepository;
late FluwxCancelable _fluwxCancelable;
// 支付结果 Completer,用于将异步回调转为 await
Completer<WeChatPaymentResponse>? _payCompleter;
// 超时定时器
Timer? _timeoutTimer;
XeCreateOrderHandler() {
_fluwx = getIt.get<Fluwx>();
_userAuthRepository = getIt.get<UserAuthRepository>();
}
@override
Future<dynamic> handleMessage(params) async {
// 从 params 中提取支付参数
final String chargeCode = params['chargeCode'] as String? ?? '';
final int durationType = params['durationType'] as int? ?? 0;
final int duration = params['duration'] as int? ?? 0;
final int totalFee = params['totalFee'] as int? ?? 0;
final bool renew = params['renew'] as bool? ?? false;
final String phone = params['phone'] as String? ?? '';
final String userCode = params['userCode'] as String? ?? '';
final String tbxStuId = params['tbxStuId'] as String? ?? '';
final String stuId = params['stuId'] as String? ?? '';
// ext 为 JSON 格式字符串
final String ext = params['ext'] as String? ?? '{}';
// 解析 ext
final Map<String, dynamic> extMap = jsonDecode(ext);
final useCoin = extMap['useCoin'] as bool? ?? false;
debugPrint('PayHandler params: chargeCode=$chargeCode, durationType=$durationType, '
'duration=$duration, totalFee=$totalFee, renew=$renew, '
'phone=$phone, userCode=$userCode, tbxStuId=$tbxStuId, stuId=$stuId, '
'ext=$ext');
// 1. 检查微信是否安装
if (!await _fluwx.isWeChatInstalled) {
throw Exception('设备上未安装微信App,不支持微信支付');
}
// 2. 请求后端获取预支付订单信息
final deviceType = 'android';
var result = await _userAuthRepository.createOrder(userCode, tbxStuId, chargeCode, duration, durationType, totalFee,
renew, phone, stuId, ext, useCoin ? 1 : 0, deviceType);
if (result == null) {
throw Exception('获取支付信息失败');
}
var data = result['data'] as Map<String, dynamic>?;
if (data == null) {
throw Exception('支付参数获取失败');
}
// 3. 从后端响应中提取预支付ID
final prepayId = data['prepayId'] as String?;
if (prepayId == null || prepayId.isEmpty) {
throw Exception('预支付订单ID获取失败');
}
// 4. 从后端响应中提取支付参数(nonceStr、timestamp、paySign 由后端生成)
final appId = Constant.wxAppId;
final partnerId = Constant.wxPartnerId;
final packageValue = 'Sign=WXPay';
final nonceStr = data['nonceStr'] as String;
final timestamp = data['timeStamp'] as int;
final paySign = data['paySign'] as String;
final wxTradeNo = data['wxTradeNo'] as String;
debugPrint('prepayId: $prepayId');
debugPrint('nonceStr: $nonceStr');
debugPrint('timestamp: $timestamp');
debugPrint('paySign: $paySign');
debugPrint('appId: $appId');
debugPrint('partnerId: $partnerId');
debugPrint('packageValue: $packageValue');
debugPrint('wxTradeNo: $wxTradeNo');
if (nonceStr.isEmpty || paySign.isEmpty || wxTradeNo.isEmpty) {
throw Exception('支付参数获取失败');
}
// 5. 注册支付结果监听器
_payCompleter = Completer<WeChatPaymentResponse>();
_fluwxCancelable = _fluwx.addSubscriber(_responseListener);
// 6. 启动超时兜底(60秒 * 10)
_timeoutTimer = Timer(const Duration(seconds: 600), () {
if (_payCompleter != null && !_payCompleter!.isCompleted) {
_payCompleter!.completeError(TimeoutException('支付超时'));
}
});
// 7. 调用 fluwx.pay() 拉起微信支付
final payResult = await _fluwx.pay(
which: Payment(
// 微信开放平台 AppID
appId: appId,
// 商户号(固定)
partnerId: partnerId,
// 预支付ID(后端返回)
prepayId: prepayId,
// 固定值 Sign=WXPay
packageValue: packageValue,
// 随机字符串(后端返回)
nonceStr: nonceStr,
// 时间戳(后端返回,秒级)
timestamp: timestamp,
// 签名(后端生成)
sign: paySign,
),
);
if (!payResult) {
_cleanup();
throw Exception('拉起微信支付失败');
}
// 8. 等待支付结果回调
try {
final response = await _payCompleter!.future;
if (response.isSuccessful) {
debugPrint('wechat pay success: ${response.errStr}');
return {"orderUnique": wxTradeNo, "orderState": 1};
} else if (response.errCode == -2) {
debugPrint('wechat pay cancel: ${response.errStr}');
// 用户取消支付
// throw Exception('已取消支付');
return {"orderUnique": wxTradeNo, "orderState": 0};
} else {
debugPrint('wechat pay failed: ${response.errStr}');
// 支付失败
throw Exception('支付失败');
}
} catch (e) {
debugPrint('wechat pay error: $e');
throw Exception('支付异常:$e');
} finally {
_cleanup();
}
}
/// Fluwx 响应监听器
void _responseListener(WeChatResponse response) {
if (response is WeChatPaymentResponse) {
_timeoutTimer?.cancel();
if (_payCompleter != null && !_payCompleter!.isCompleted) {
_payCompleter!.complete(response);
}
}
}
/// 清理资源
void _cleanup() {
_fluwxCancelable.cancel();
_timeoutTimer?.cancel();
_timeoutTimer = null;
_payCompleter = null;
}
}