import 'package:dio/dio.dart'; import 'package:hgdj/tools_base/net/base_resp_bean.dart'; import 'package:hgdj/tools_base/net/http_manager.dart'; import 'package:uuid/uuid.dart'; /// 购买相关接口 class BuyService { /// /product/buy 一律带 X-Request-ID。 /// [requestId] 由调用方持有时才是幂等键:一笔业务被拆成多次请求时(如短剧「充值成功后 /// 自动补一次解锁」)复用同一个 id,服务端直接回首次结果,不会重复扣费。 /// 不传就现生成一个,只作服务端链路追踪用——连点下单由 PayManager 的全屏 loading 挡着 static Options _idempotent(String? requestId) => Options( headers: {'X-Request-ID': requestId ?? const Uuid().v4()}, ); ///购买视频 [productType] 见 PayManager 的 ProductType ///[contentID] 子内容ID(短剧买单集时传这一集的 id,productID 仍是剧 id) ///[checkoutContextId] 付费墙下发的结算上下文,服务端据此对账/归因 ///[requestId] 幂等键,见 [_idempotent];不传则自动生成一个仅供追踪的 id ///[jsonTransformation] 需要把返回体解析成模型时传,不传则 data 为原始 json static Future buyVideo( String? productID, int? productType, { String? couponId, // 优惠卷ID int? goldVideoCouponNum, //金币视频抵用券金币面值, String? serviceId, // 裸聊服务ID String? source, // 来源页面标识 String? contentID, String? checkoutContextId, String? requestId, Function(Map json)? jsonTransformation, }) async { final param = { 'productID': productID, 'productType': productType, 'contentID': contentID, 'checkoutContextId': checkoutContextId, 'couponId': couponId, 'goldVideoCouponNum': goldVideoCouponNum, 'serviceId': serviceId, 'source': source, 'isH5': false, }; param.removeWhere((k, v) => v == null); return httpManager.fetchResponseByPOST( '/product/buy', param: param, options: _idempotent(requestId), jsonTransformation: jsonTransformation, ); } ///金币购买vip ///[finalPayStatus]: 预售业务,true 付尾款, false 付预定款;null 非预售业务; ///[couponId] 金币加赠券券id ///[source] 来源页面标识 ///[experimentId]/[experimentVariant]/[sessionId] VIP 卡皮 A/B:与 /mine/topay 对齐回传 ///[requestId] 幂等键,见 [_idempotent] static Future buyVip(int? productType, String? productID, String? productName, int? discountedPrice, {String? couponId = "", bool? finalPayStatus, String? source, String? experimentId, String? experimentVariant, String? sessionId, String? mediaId, String? contentId, String? checkoutContextId, String? requestId}) async { final param = { 'productType': productType, 'productID': productID, 'productName': productName, 'discountedPrice': discountedPrice, 'couponId': couponId, 'finalPayStatus': finalPayStatus, 'source': source, // 短剧付费墙开卡归因,字段名与 /mine/topay 那套对齐 'mediaId': mediaId, 'contentId': contentId, 'checkoutContextId': checkoutContextId, // 空值不传,避免参数错误(DISABLED / 无实验时上游不填) 'experimentId': (experimentId != null && experimentId.isNotEmpty) ? experimentId : null, 'experimentVariant': (experimentVariant != null && experimentVariant.isNotEmpty) ? experimentVariant : null, 'sessionId': (sessionId != null && sessionId.isNotEmpty) ? sessionId : null, }; param.removeWhere((k, v) => v == null); return httpManager.fetchResponseByPOST('/product/buy', param: param, options: _idempotent(requestId)); } }