import 'package:flutter/foundation.dart'; import 'package:pshared/models/payment/payment.dart'; import 'package:pshared/provider/organizations.dart'; import 'package:pshared/provider/payment/quotation/quotation.dart'; import 'package:pshared/provider/resource.dart'; import 'package:pshared/service/payment/service.dart'; import 'package:pshared/utils/exception.dart'; class PaymentProvider extends ChangeNotifier { late OrganizationsProvider _organization; late QuotationProvider _quotation; Resource _payment = Resource( data: null, isLoading: false, error: null, ); bool _isLoaded = false; void update(OrganizationsProvider organization, QuotationProvider quotation) { _quotation = quotation; _organization = organization; } Payment? get payment => _payment.data; bool get isLoading => _payment.isLoading; Exception? get error => _payment.error; bool get isReady => _isLoaded && !_payment.isLoading && _payment.error == null; void _setResource(Resource payment) { _payment = payment; notifyListeners(); } Future pay({ String? idempotencyKey, String? clientPaymentRef, Map? metadata, }) async { if (!_organization.isOrganizationSet) throw StateError('Organization is not set'); final quoteRef = _quotation.quotation?.quoteRef; if (quoteRef == null || quoteRef.isEmpty) { throw StateError('Quotation reference is not set'); } final expiresAt = _quotation.quoteExpiresAt; if (expiresAt != null && expiresAt.isBefore(DateTime.now().toUtc())) { throw StateError('Quotation is expired'); } _setResource(_payment.copyWith(isLoading: true, error: null)); try { final resolvedIdempotencyKey = idempotencyKey ?? _quotation.quotation?.idempotencyKey; final response = await PaymentService.pay( _organization.current.id, quoteRef, idempotencyKey: resolvedIdempotencyKey, clientPaymentRef: clientPaymentRef, metadata: metadata, ); _isLoaded = true; _setResource( _payment.copyWith(data: response, isLoading: false, error: null), ); } catch (e) { _setResource( _payment.copyWith(data: null, error: toException(e), isLoading: false), ); } return _payment.data; } void reset() { _setResource(Resource(data: null, isLoading: false, error: null)); _isLoaded = false; } }