import '../core/network/api_client.dart'; import '../core/network/endpoints.dart'; /// 充值套餐档位(《03-接口文档》8.1,后台实时可配,前端不硬编码) class RechargePackage { const RechargePackage({ required this.id, required this.amountYuan, required this.points, this.bonus = 0, }); final int id; final int amountYuan; final int points; /// 赠送积分(角标「赠 x 积分」) final int bonus; /// 到账总积分 = 基础 + 赠送 int get totalPoints => points + bonus; factory RechargePackage.fromJson(Map json) => RechargePackage( id: (json['id'] as num).toInt(), amountYuan: (json['amount_yuan'] as num).toInt(), points: (json['points'] as num).toInt(), bonus: (json['bonus'] as num?)?.toInt() ?? 0, ); } /// 自定义金额配置 class CustomRechargeConfig { const CustomRechargeConfig({ this.enabled = false, this.minYuan = 1, this.maxYuan = 10000, this.pointsPerYuan = 10, }); final bool enabled; final int minYuan; final int maxYuan; final int pointsPerYuan; bool inRange(int yuan) => yuan >= minYuan && yuan <= maxYuan; factory CustomRechargeConfig.fromJson(Map json) => CustomRechargeConfig( enabled: json['enabled'] as bool? ?? false, minYuan: (json['min_yuan'] as num?)?.toInt() ?? 1, maxYuan: (json['max_yuan'] as num?)?.toInt() ?? 10000, pointsPerYuan: (json['points_per_yuan'] as num?)?.toInt() ?? 10, ); } /// 支付方式(1支付宝 2微信 3USDT) class PayMethod { const PayMethod({required this.method, required this.name}); final int method; final String name; bool get isUsdt => method == 3; factory PayMethod.fromJson(Map json) => PayMethod( method: (json['method'] as num).toInt(), name: json['name'] as String, ); } /// 8.1 套餐列表响应 class PackagesResult { const PackagesResult({ this.packages = const [], this.custom = const CustomRechargeConfig(), this.payMethods = const [], this.usdtRate = 0, }); final List packages; final CustomRechargeConfig custom; final List payMethods; final double usdtRate; factory PackagesResult.fromJson(Map json) => PackagesResult( packages: ((json['packages'] as List?) ?? const []) .whereType>() .map(RechargePackage.fromJson) .toList(), custom: CustomRechargeConfig.fromJson( (json['custom'] as Map?) ?? const {}, ), payMethods: ((json['pay_methods'] as List?) ?? const []) .whereType>() .map(PayMethod.fromJson) .toList(), usdtRate: (json['usdt_rate'] as num?)?.toDouble() ?? 0, ); } /// 8.2 创建充值订单响应 /// 支付宝/微信:pay_params 供 SDK 调起;USDT:地址 + 金额(含尾差)+ 网络 class RechargeOrderInfo { const RechargeOrderInfo({ required this.orderNo, required this.payMethod, required this.amountYuan, required this.points, this.expireAt = '', this.payParams = const {}, this.usdtRate, this.usdtAmount, this.receiveAddress, this.network, }); final String orderNo; final int payMethod; final int amountYuan; final int points; final String expireAt; /// 支付宝 order_string / 微信 appid+prepayid 等 final Map payParams; final double? usdtRate; final String? usdtAmount; final String? receiveAddress; final String? network; bool get isUsdt => payMethod == 3; factory RechargeOrderInfo.fromJson(Map json) => RechargeOrderInfo( orderNo: json['order_no'] as String, payMethod: (json['pay_method'] as num).toInt(), amountYuan: (json['amount_yuan'] as num).toInt(), points: (json['points'] as num).toInt(), expireAt: (json['expire_at'] as String?) ?? '', payParams: (json['pay_params'] as Map?) ?? const {}, usdtRate: (json['usdt_rate'] as num?)?.toDouble(), usdtAmount: json['usdt_amount'] as String?, receiveAddress: json['receive_address'] as String?, network: json['network'] as String?, ); } /// 8.3 查询订单响应(App 轮询用) class OrderStatusInfo { const OrderStatusInfo({ required this.orderNo, required this.status, this.statusText = '', this.points = 0, this.paidAt, this.walletPoints = 0, }); final String orderNo; /// 0待支付 1已支付 2已关闭 3已退款 final int status; final String statusText; final int points; final String? paidAt; /// 查单时服务端附带的当前钱包积分 final int walletPoints; bool get isPending => status == 0; bool get isPaid => status == 1; factory OrderStatusInfo.fromJson(Map json) => OrderStatusInfo( orderNo: json['order_no'] as String, status: (json['status'] as num).toInt(), statusText: (json['status_text'] as String?) ?? '', points: (json['points'] as num?)?.toInt() ?? 0, paidAt: json['paid_at'] as String?, walletPoints: (json['wallet_points'] as num?)?.toInt() ?? 0, ); } /// 支付服务(《03-接口文档》第 8 章,均需登录) class PaymentService { PaymentService._(); /// 8.1 充值套餐列表 static Future fetchPackages() async { final data = await ApiClient.get>(Endpoints.payPackages); return PackagesResult.fromJson(data); } /// 8.2 创建充值订单 /// 错误码:1001 金额不在可选档位 static Future createRecharge({ required int amountYuan, required int payMethod, }) async { final data = await ApiClient.post>( Endpoints.recharge, data: {'amount_yuan': amountYuan, 'pay_method': payMethod}, ); return RechargeOrderInfo.fromJson(data); } /// 8.3 查询订单状态 /// 错误码:3001 订单不存在 static Future fetchOrder(String orderNo) async { final data = await ApiClient.get>( Endpoints.orderDetail(orderNo), ); return OrderStatusInfo.fromJson(data); } /// 8.4 取消订单(仅待支付可取消) /// 错误码:3001 订单不存在,3002 订单状态异常 static Future cancelOrder(String orderNo) async { await ApiClient.post>( Endpoints.orderCancel(orderNo), ); } }