From 7b8f0318e285db99125004e418fe80efe35e6701 Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Mon, 10 Nov 2025 16:00:18 +0800 Subject: [PATCH] =?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/data/services/pay_service.dart | 78 +++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/lib/data/services/pay_service.dart b/lib/data/services/pay_service.dart index ac34fbd39..c58275c25 100644 --- a/lib/data/services/pay_service.dart +++ b/lib/data/services/pay_service.dart @@ -1,4 +1,5 @@ import 'package:get/get.dart'; +import 'dart:convert'; import 'package:voitrans/data/services/network/api.dart'; import 'package:tobias/tobias.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -361,7 +362,7 @@ class PayService extends GetxService { required String productName, String? productDesc, required int amount, - int paymentMethod = 2, // 2表示支付宝 + int paymentMethod = 3, // 2表示支付宝 String? clientIp, String? notifyUrl, String? extraData, @@ -445,9 +446,73 @@ class PayService extends GetxService { 'extra_data': extraData ?? '', }); - // 兼容不同字段命名,尽量从返回中提取可用的支付URL if (response != null) { - final candidates = [ + // 1) 提取并缓存平台订单号(用于回查) + String? appOrderId; + const candidates = [ + 'order_id', + 'orderId', + 'out_trade_no', + 'outTradeNo', + ]; + for (final key in candidates) { + final v = response[key]; + if (v is String && v.isNotEmpty) { + appOrderId = v; + break; + } + } + final data = response['data']; + if (appOrderId == null && data is Map) { + for (final key in candidates) { + final v = data[key]; + if (v is String && v.isNotEmpty) { + appOrderId = v; + break; + } + } + } + _lastOrderId = appOrderId; // 记录APP侧订单号(如 APP2025...),用于 pay_askorder + + // 2) 优先解析 paypal_pay_params 字段(后端返回JSON字符串,含 links) + String? rawParams; + final topParams = response['paypal_pay_params']; + final dataParams = + (data is Map) ? data['paypal_pay_params'] : null; + if (topParams is String && topParams.isNotEmpty) { + rawParams = topParams; + } else if (dataParams is String && dataParams.isNotEmpty) { + rawParams = dataParams; + } + + if (rawParams != null) { + try { + final parsed = jsonDecode(rawParams); + if (parsed is Map) { + final links = parsed['links']; + if (links is List) { + for (final item in links) { + if (item is Map) { + final rel = item['rel']?.toString(); + final hrefRaw = item['href']?.toString(); + if (rel == 'approve' && + hrefRaw != null && + hrefRaw.isNotEmpty) { + // 清理日志中可能出现的反引号等噪音字符 + final href = hrefRaw.replaceAll('`', '').trim(); + return href; + } + } + } + } + } + } catch (e) { + print('解析 paypal_pay_params 失败: $e'); + } + } + + // 3) 回退:尝试从常见字段直接取URL + final urlKeys = [ 'paypal_pay_url', 'approval_url', 'paypalApprovalUrl', @@ -455,16 +520,14 @@ class PayService extends GetxService { 'payment_url', 'url', ]; - for (final key in candidates) { + for (final key in urlKeys) { final url = response[key]; if (url is String && url.isNotEmpty) { return url; } } - - final data = response['data']; if (data is Map) { - for (final key in candidates) { + for (final key in urlKeys) { final url = data[key]; if (url is String && url.isNotEmpty) { return url; @@ -472,6 +535,7 @@ class PayService extends GetxService { } } } + print('创建 PayPal 订单失败或未返回有效URL: $response'); return null; } catch (e) {